SAE/BAE/全平台静态文件加速CDN – Layer

一直记得SAE上有个很好很有名的CDN脚本叫SaeLayerCDN,最近突然想Layer难道没有BAE版本的么。Google翻了一下,还真没有BAE上能用的,于是在github上fork了一份SaeLayer的源码,开始移植。

移植的时候就打算做SAE/BAE/标准PHP几个平台的通用版,一开始叫LayerBAE,后来索性就叫Layer了,原作者起名的意图好像就是说处于网站和静态服务器之间的一个“加速层”吧,所以干脆就叫Layer比较好了。当然你要叫BAELayer或者LayerBAE什么的都随意啦~

主要的改进就是让他支持了SAE和BAE或者是本地的缓存三种平台,然后增加了一些配置更加方便使用,增加了刷新缓存的功能,还有就是用了比较灵活的组装,如果想增加平台的话只要再加几个文件就能轻松拓展了。

这个项目的下一步开发方向就如Issues所写吧,这里会更新项目动态。

项目地址:Layer

至于安装方法我就不多写了,和SaeLayerCDN一样。

Google Authenticator / D令牌 网页版

Google的两步验证想必大家都有听说过或者用过吧,至于D令牌则是DnsPod的两步验证,用的其实也是Google Authenticator的一模一样的算法,而Google Authenticator的算法实际上是一个叫做HOTP(参考)的东西。
由于算法是开源的,那也就是说可以用任何方法来实现它。这里我直接选了我最熟悉的php来写。考虑到这个东西肯定有人已经写过了,所以Google一下找到了这么一个神奇的类库(参考)。这个类库可以实现一些简单的功能,比如生成当前时间的二次认证的token,比如验证一个token和它的secret key是不是一致(前后差距可以有两分钟)之类的。用法我就不仔细说了,自己戳到参考链接里面可以看到详细的用法和完整的源码,这里我来说说我写的这个HOTP网页版怎么用。

由于代码比较长,所以我把代码贴到了Gist里,!猛戳这里查看!,直接从上面把代码复制下来放到一个php文件里面就好了。

看到开头的配置部分,修改对应的参数就能使用了。第一个密码是打开这个网页的需要密码,为了保密性而防止其他人使用的一个验证措施。后面是对应的账户标题和密钥。前面的标题可以随便写,只要自己能记住这个密钥是哪个账户的就行了,而后面的密钥要怎么获取呢?在DnsPod和Google绑定两步令牌的时候,我们看到的都是二维码。但是这个二维码下面会有一行小字,类似于“无法扫描二维码?”或者“手动输入绑定”之类的,点击就能看到一个密钥。把里面的空格去掉,无视大小写粘贴到php里面就行了。
首次打开的时候会让你输入密码,输入在php里面设定的那个密码就行。或者你也可以这样访问它:http://your/path/to/totp.php?key=你的密码 , 这样就不需要输入密码也能够看到你的令牌了。它会30s自动刷新,要保证你的服务器时间和标准时间误差不超过2分钟哦,不然密码就没用了。至于时区倒是不那么重要,反正是基于GMT标准时的。

bpcs_uploader 更新:快速初始化、内置app key、正常使用离线下载

如题,这次的更新主要是以下几个方面:

1.加入快速初始化功能:只要敲入quickinit命令,即可进入快速初始化流程,只需一个y键和一个浏览器~

2.内置的app key:随快速初始化功能附赠

3.正常使用离线下载:现在百度PCS的离线下载API开放了,于是就可以离线下载HTTP文件了~

嘛,以上。欲知详情,点击bpcs_uploader项目主页~

bpcs_uploader – 百度网盘上传脚本

碎碎念先:寒假都快结束了,这才第二发……好吧,这个脚本纯属无聊的作品。之前不是有用脚本上传dropbox的嘛,我寻思着写个百度网盘的用用看。我那蹩脚的Prel和shell script根本没法完成这种略微有点技术含量的东西,所以完全使用php来写了。

项目主页:http://oott123.github.com/bpcs_uploader

嗯……只在cygwin和一台Centos上测试过,未在其它系统上通过测试。

系统要求

Linux (or cygwin) with php & curl installed.

使用方法

$ chmod +x bpcsuploader.php
$ ./bpcs
uploader.php

由于VPS上安装的php可能存在于各种地方,因此运行很可能不正常。请以使用which php得到你的php绝对路径,修改bpcs_uploader.php的头一句#!后的路径。
如果你的php是为了网站环境安装的,那么很有可能你会得到下面这条错误消息:

xxx() has been disabled for security reasons

那么说明你的环境由于安全原因禁止了部分函数的执行。请看FAQs的1。请使用那条长长的命令代替./bpcs_uploader.php。eg:php -d disable_functions -d safe_mode=Off -f bpcs_uploader.php quota

初始化

./bpcs_uploader.php init

敲下命令之后会进入初始化流程,这里分段详述设置方法。

Now start the initiation. If you have configured the uploader , it will be overwirte.
Continue? [y/N] y

确认初始化。如果之前有初始化过,那么以前的配置将会被覆盖。

Now you have to enter your baidu PSC app key . You should know that it needs a manual acting.
You can request for it via http://developer.baidu.com/dev#/create .
Make sure you have the PCS app key . if you haven't , you can use the demo key from Baidu.
It will exprire some time. who knows ? so the best way is to request for your own key.
There are a demo key from Baidu : L6g70tBRRIXLsY0Z3HwKqlRE So if you dont have the app secret , you have to re-init every month , for the access-token will expires every month.
App KEY [L6g70tBRRIXLsY0Z3HwKqlRE] :

第一步,输入App key。这里需要输入一个有PCS权限的API KEY,如果没有的话直接敲回车就好了,这里会默认使用百度提供的一个demo API KEY。不过,由于百度没有公开app secret,所以只能获取一个有效期为一个月的access token。如果有一个有PSC权限的API KEY和secret,那么就能获得一个有效期为10年的refresh token,以便长期使用。

App key has been setted to L6g70tBRRIXLsY0Z3HwKqlRE .
Now you have to enter your baidu PSC app secret. If you dont know the secret , keep it blank.
App SECRET [] :

第二步,输入App secret。如果输入了app secret,将会转到device code模式验证;或者直接输入回车使用oob模式验证。先直接回车:

Now you have to enter your app name. You can enter it later in the file [ /root/bpcsfiles/config/appname ].
* Why i have to enter app name ? see FAQs.
If your app name have Chinese characters , please swith your client to the UTF-8 mode.
Here are some chinese characters . Before you enter chinese characters , make sure you can read these characters.
如果你看到这里,说明你可以直接输入文字了。
If you cant read any chinese above , please press enter , and change it manually in the file [ /root/
bpcsfiles/config/appname ] .
If you have Enter the key [L6g70tBRRIXLsY0Z3HwKqlRE] (by default) , just press Enter.
App Name [pcstest_oauth] :

第三步,这里需要输入app name。详情见FAQ 2。因为是使用的默认的key,所以直接回车即可。

Now you have to get your oauth accesstoken by your own .
Here is a reference document .
http://developer.baidu.com/wiki/index.php?title=docs/pcs/guide/usage
example

A simple guide :
1.visit https://openapi.baidu.com/oauth/2.0/authorize?responsetype=token&clientid=L6g70tBRRIXLsY0Z3HwKqlRE&redirecturi=oob&scope=netdisk
in your broswer.
2.when it redirected to a html page , copy the url to the notepad.
3.get the access
token from it , paste it and press Enter.
access_token[] :

第四步,获取access token。在浏览器中打开上述URL( https://openapi.baidu.com/oauth/2.0/authorize?responsetype=token&clientid=L6g70tBRRIXLsY0Z3HwKqlRE&redirecturi=oob&scope=netdisk ),进行授权。
授权完毕后,将会跳到一个写着“百度 Oauth2.0”的页面。复制出其中的网页URL,找到access
token=和&之间的字符串,例如: 3.**05c2ea85d52c2***************a5.2592000.136***9032.3089166538-23**47
将其复制到shell中粘贴并回车。使用这种方式初始化的用户,需要每月重新初始化。

如果第三步输入app secret的时候没有留空,将会得到下面的消息:

Now open your broswer and visit https://openapi.baidu.com/device .
Copy or input 12abcxyz when it been asks.
After granted the access to the application , be back and press Enter key .

来到这里,打开浏览器访问 https://openapi.baidu.com/device ,在“请输入设备上显示的用户授权码:”文本框中输入上面显示的授权码(这里是12abcxyz),并点击继续。看到网页上显示“请返回设备继续操作!”后,返回ssh上按下回车后,即可继续。

curl -X GET -k -L "…."
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 62 0 62 0 0 40 0 –:–:– 0:00:01 –:–:– 235
Success . Your Storage Status : 0.06G/115.00G (0.05%)
Have fun !

你所看到的输出可能和这里给出的不一样,但是只要看到了存储空间的剩余量,和【Have fun !】提示,即说明成功初始化。

查询容量(配额)

./bpcs_uploader.php quota

结果:

Your Storage Status : 0.06G/115.00G (0.05%)

上传文件

./bpcs_uploader.php upload [path_local] [path_remote]
路径格式:foo/bar/file.ext(路径中一定要包括文件名)
上传后,能在百度网盘/我的应用数据/应用名/foo/bar下找到一个叫file.ext的文件。

下载文件

./bpcs_uploader.php download [path_local] [path_remote]

删除文件

./bpcs_uploader.php delete [path_remote]

离线下载

./bpcs_uploader.php fetch [path_remote] [path_to_fetch]
注:离线下载暂时无法在一般的api key授权的情况下使用,需要另外申请开通。

FAQs

  1. 各种错误提示
    试试php -d disable_functions -d safe_mode=Off -f bpcs_uploader.php
  2. 为什么要输入app name?
    因为百度PCS的权限被限制在了/apps/appname/下。如果发现输入app name后仍然无法上传文件,请通过网页版找到【我的应用数据】找到对应的文件夹名,写入/config/appname文件。上传文件的时候会自动帮您处理文件夹,无需手动写出完整路径。

随手扒拉的一个有意思的源码

从free8上看到一个源码(http://www.free8.net/thread-72510-1-1.html),觉得蛮有意思的,随手做了一个后台,放出来给大家玩玩。

admin_panel.php是后台,没有任何验证,建议改名为比较复杂的文件名就好了。

放上一个演示先:http://summer.p.ht/simple

下载点照例是skydrive。http://sdrv.ms/X5aTQ9

三三精选PHP脚本集之压缩解压

例行吐槽:呐,寒假大礼包之一也许就是这个精选脚本集了。大概会以非常不固定的频率更新一些常用的PHP脚本吧。大部分是可以自由使用的,当然也有来路不明的。嗯,仅供学习使用,版权归原作者所有哈。

作为一个网站管理者,每天和文件打交道是必不可少的。由于众所周知的原因 ,通过FTP上传下载一些零碎的小文件,特别是上传到国外空间,那简直就是灾难。虽然部分面板提供了在线压缩/解压,而且在VPS上压缩/解压也不是一个很大的问题,但是残酷的现实是,并非每个人都有可以压缩/解压的面板,也并非每个人都有VPS。所以,利用一些PHP脚本,能够对压缩文件解压或者将网站文件备份为压缩文件,那简直是太棒了。

这次要介绍的脚本集中收录的一共有三款脚本:phpzip,一个无名的脚本和博主自己写的压缩脚本。它们各有千秋,当然也不是每一个对所有的服务器都支持的,所以需要大家去尝试总结,哪个比较好用什么的。当然,如果试过了这里所有的脚本都没法实现的话,那么你得考虑换一个空间了。

嗯,先给出下载链接。按照我的惯例,分享的文件是放在微软的SkyDrive上的,大家点开链接以后只要点上部的“下载”链接就行了,不需要考虑下面那一大片其它乱七八糟的文件——当然如果你感兴趣的话也可以看看的。不过为了符合国情,还放了一份到百度网盘,大家自己看着办。

SkyDirve:http://sdrv.ms/MMNvDZ

百度网盘:http://pan.baidu.com/share/link?shareid=185587&uk=3340806281

首先是作者不详的压缩解压脚本,姑且叫它“unzipfiles”吧。这个脚本只有两个文件,zipfile.php和unzipfile.php。顾名思义,嗯,一个是解压一个是压缩。

下载到文件后解压缩,找到zip文件处理这个文件夹。两个文件就在这里。打开zipfile.php,找到第四行左右的位置修改密码:

然后对unzipfile.php也同样操作。修改完成后保存,将这两个文件上传到你的空间。(当然,如果只要解压的话上传一个就unzipfile.php够了,压缩亦然。)

上传完成后,使用自己的电脑将要上传的文件压缩成ZIP格式。打包时请选择“添加到压缩文件…”选项,在弹出的对话框中选择ZIP格式:

如果文件比较大,将这个zip文件上传到你的空间。文件不大的话,下一步可以通过浏览器直接上传。需要注意的是,压缩文件本身和里面的内容最好是不要出现中文,否则容易乱码。

上传完成后,来到你上传的脚本页面:http://<your_url>/unzipfile.php进行操作。

在这个简明的页面中,你可以选择服务器上现有的zip文件(前提是和这个文件同目录),也可以上传zip文件。解压目录保持不变即可,验证密码填写上一部你修改的密码,点击解压,服务器就会自动帮你解压这个文件。

解压完成后会有上面的提示信息。去到FTP中,就可以看到刚刚生成的文件了。是的,由于有中文文件名,所以很干脆的乱码了:

压缩也是同样的操作,这里就不再赘述了。

然后就是第二款压缩脚本phpzip了。这款脚本很古老,但是很好用。它分为在电脑上运行的exe程序和在服务器上运行的php脚本两个部分,采用了自己独特的dat格式并搭配gzip压缩,压缩率还不错。

首先将zip.php/unzip.php上传到服务器上,然后通过浏览器访问。页面上方有一段文字,说明你的服务器是否支持zlib库。根据这个提示我们打开phpzip.exe,设置对应的选项进行压缩:

同样,也有本地上传和服务器上传两种方式。压缩后的文件扩展名是dat.gz,很独特。

phpzip主界面上有一个“集成”按钮,点击它以后就可以让phpzip和winrar等压缩软件一样在右键菜单中出现了,如图:

在phpzip目录下还有一个神秘的rm.php文件。这个文件可以帮助我们删除那些在FTP上面无法删除的文件,或者由于文件太多,在FTP上删除需要很久的文件夹。用记事本打开这个文件修改密码,然后上传并在浏览器访问。

只需要填写密码和要删除的路径,提交就会发现文件不见了。

第三款压缩脚本是博主自己写的,只有简单的将当前目录下文件全部压缩的功能,只需要上传然后在浏览器中访问就可以了,不需要其它的操作,这里就不介绍了。

总之,PHP能够帮你减少文件管理的负担,让你的生活更加轻松自在。

simsimi小黄鸡官方API发布 – 别来找我要代码了= =

自从发了两三篇simsimi的API调用以后,我的博客几乎变成了simsimi API的讨论区了OTL

本来就没什么人气,被这么一折腾倒是显得人气旺盛了= =

嗯……前两天和鸟麦说起这件事情来的时候发现小黄鸡都自己发布了官方API了,咱们就别折腾盗用了吧。

详情请戳http://developer.simsimi.com/api

不过呢,这个API需要到http://developer.simsimi.com/contact去申请key。官方说是只能用90天= =,但是,90天以后换个邮箱再申请就是啦=A=

X2审核通过不提醒的解决方法

问题描述:后台审核或删除帖子,用户收不到提醒。分析源代码,发现无理由通过/删除帖子时,系统默认不发送pm。
问题解决:在php处理流程前判断是否有理由。如果没有理由,添加一个默认的理由,这样就可以实现总是发送pm。
解决方法:

需要修改的地方:
/source/admincp/moderate/moderate_thread.php
/source/admincp/moderate/moderate_reply.php
/source/include/modcp/modcp_moderate.php
可能还有moderate/下的其它文件(按照需求来修改)

在moderate_thread.php中查找

    if(isset($_G['gp_'.$pm]) && $_G['gp_'.$pm] <> '' && $thread['authorid']) {

在moderate_reply.php中查找

    if(isset($_G['gp_'.$pm]) && $_G['gp_'.$pm] <> '' && $post['authorid']) {

在上方插入

    $_G['gp_'.$pm] = (isset($_G['gp_'.$pm]) && $_G['gp_'.$pm] <> '') ? $_G['gp_'.$pm] : '感谢您的支持,论坛有您更加精彩!';

在/source/include/modcp/modcp_moderate.php中查找

if($_G['gp_reason'] != '' && $post['authorid'] && $post['authorid'] != $_G['uid']) {

修改为

    $_G['gp_reason'] = $_G['gp_reason']!='' ? $_G['gp_reason'] :'感谢您的支持,论坛有您更加精彩!';
    if($_G['gp_reason'] != '' && $post['authorid']) {

找到

if($_G['gp_reason'] != '' && $thread['authorid'] && $thread['authorid'] != $_G['uid']) {

修改为

    $_G['gp_reason'] = $_G['gp_reason']!='' ? $_G['gp_reason'] :'感谢您的支持,论坛有您更加精彩!';
    if($_G['gp_reason'] != '' && $thread['authorid']) {

注意,每个文件中可能存在多于一个这样的修改点。(前两个文件是两个,最后那个文件是四个)

懒人下载:http://www.ctdisk.com/file/10237915

SQLite中获取随机记录的两种方法以及效率比较

SQLite这个数据库我自己也用的很多。比起mysql它的好处在于不用设置繁琐的host啊username,password,database什么的,直接一个文件上去就好了,类似于Access的方式哈(Access和SQLite能比么~!)。

之前也研究过MySQL上的随机数据获取方法,Google一下一大堆,我就不多说了。总之看了很多MySQL上的文章,SQLite的却没有多少,于是我就自己研究了一下。

我用的环境是Apache/2.2.16 (Win32) PHP/5.2.14,加上PDO的SQLite3接口。还用到一个类库是我自己写的LFPSQlite库,这个库我没有发布过,因为实在是写的太坑了,不想丢丑什么的。

言归正传。今天说的两种获取随机记录的方法,第一种是这样的:

SELECT COUNT(*) FROM 'test';
SELECT * FROM 'test' LIMIT 1 OFFSET #;

其中#是rand(0,$count-1)。

第二种是这样的

SELECT * FROM 'test' ORDER BY random() LIMIT 1;

两种方法的效率究竟如何呢?先来理论分析下。

首先第一种方法是查出数据行数,然后用偏移值来实现读取数据。这两条SQL命令应当是非常快的。第二种方法是用random()排序。虽然有LIMIT 1来限定,但是SQLite应该会将整个表排一次序,那么这个方法就应当比上面慢很多。

具体如何呢?我们来分析一下。我写了一个小脚本,因为用到了我那个没公开的库,所以脚本也就不公开了。我很无聊的把它传到了一个免费空间上,访问地址是:http://jiaowo33.cwsurf.de/sqlite/test.php?times=5 最后那个5可以改成1~200的任意值。用的数据库比较小,只有2W多行。如果你感兴趣可以下载过来看看?在/sqlite/demo.db(406KB)这个位置。

分别执行1,10,100,200次,然后我们来看看程序运行的结果:

信息: 数据库记录数:20915.
信息: 执行1次 COUNT(*)+OFFSET所需时间为0.000886917114258s.
信息: 执行1次OREDER BY RANDOM所需时间为0.0190088748932s.
信息: 效率差值:0.0181219577789s
信息: 执行10次 COUNT(*)+OFFSET所需时间为0.00564503669739s.
信息: 执行10次OREDER BY RANDOM所需时间为0.193027973175s.
信息: 效率差值:0.187382936478s
信息: 执行100次 COUNT(*)+OFFSET所需时间为0.0537490844727s.
信息: 执行100次OREDER BY RANDOM所需时间为1.947660923s.
信息: 效率差值:1.89391183853s
信息: 执行200次 COUNT(*)+OFFSET所需时间为0.105569839478s.
信息: 执行200次OREDER BY RANDOM所需时间为4.20832800865s.
信息: 效率差值:4.10275816917s

效果显而易见。count(*)的执行效率明显比order by random()要高得多。

【友情提醒】DiscuzX2.5 R20120901 切勿轻易升级!

昨天我登录卡院的后台,发现DZX2.5出了个更新。出于习惯我备份了数据库和文件,然后直接关闭网站进行后台更新了。可是这次更新并不顺利。

首先我更新到一半就无法下载/source/language/admincp.lang.php(印象中是这样的)这个文件。处于无奈我就手动更新了一下dzx。更新过程没有任何问题,后台显示为20120901版本,我就放心的打开论坛了。

但是晚上就有很多用户给我反馈说回帖的时候显示内部错误,没法显示帖子;充值卡的地方验证码输入不了等问题。我上DiscuzX官方论坛看了一眼,好像问题还不止这些。因为没更新数据库,所以我连忙把文件直接还原了。还原以后一切正常,卡院也算恢复了。

嘛。下次更新的话,一定要先去DiscuzX论坛里面看看bug反馈啥的……不然伤不起啊!