Leon's blog

每天活的有趣一点

正在浏览标签为 php 的文章

有好几次碰到使用Linux的md5sum命令产出的散列值,跟PHP的md5函数,或者MySQL的md5函数产生的不一样的问题.
通常比较懒,就没细想,直接使用PHP产生的算了;没想过难道算法还会有不同.

其实没有不同的算法,md5在哪里的计算方法只有一个.原因不过是因为使用md5sum时,有时候不小心会把换行符也作为计算的内容,结果实际上是散列的对象不同,自然结果也就不同了.而在Linux命令行状态下,我通常注意不到换行的存在.

以字符串’123′为例,PHP的计算结果是:

$ php -r 'echo md5("123");'
202cb962ac59075b964b07152d234b70

比如下列语句实际上是对”123\n”进行求散列,而不是对’123′求散列.

$ echo '123' | md5sum
ba1f2511fc30423bdbb183fe33f3dd0f

正确的写法应该是通过echo的’-n’选项,让echo不要输出换行符,这样结果就一样了.

$ echo -n '123' | md5sum
202cb962ac59075b964b07152d234b70

前几天看到新浪微博的微博平台微博id升级公告,也没怎么注意.感觉就是存储上要用string代替int,浪费点空间.对php应用应该没什么影响.
倒是新浪微博的32位id这么快就不够用了,让人感叹微博发展的神速.

今天搜索一些关键字,打开微博页面时,老是报告页面找不到.才发现,这玩意还真有影响.
那些打不开的页面的URL是这样的”http://api.t.sina.com.cn/1941569665/statuses/3.3430536723516E+15″.
Google上查了一下,发现是php的json_decode函数不支持62位的BIGINT, 溢出所致.
在新的php(5.4?) json_decode里倒是有一个开关”JSON_BIGINT_AS_STRING”开关,可以使json_decode默认把BITINT当成string处理.
但是相信大家和我一样,更新php的版本的速度不会有那么快.而且大部分情况下,咱们也控制不了具体使用哪个php版本.

一个折中的办法是把微博API返回的json字符串预处理一下,然后再调用json_decode.
也就是把
“id”:12345678901234567890
换成
“id”:”12345678901234567890″

代码片段如下,希望对和我类似情况的人有用.

if (define('JSON_BIGINT_AS_STRING')) {
	$json = json_decode($data, false, 512, JSON_BIGINT_AS_STRING);
}else{
	//convert bigint to string
	$data = preg_replace('/"id":([0-9]+)/', '"id":"$1"', $data);
	$json = json_decode($data, false);
}

参考: http://drupal.org/node/985544

PHP扩展 memcache vs. memcached

抢沙发

两个扩展的介绍基本一样(memcache, memcached),没有任何特别关于他们之间区别的说明. 那我们什么时候应该用哪个扩展呢?

Stackoverflow上有比较详细的讨论: using memcache vs memcached with phpmemcache vs memcached

这里还有一个很清晰表格,对比了这两个扩展的具体特性.
主要区别是php memcached扩展比较新,几乎支持memcached的所有特性(如Delayed Get, Append/Prepend等). 但是它依赖libmemcached才能运行(在debian里面包名是libMemcached5).
所以如果你不使用如Delayed Get这样的特性,又不想多依赖libmemcached库, 完全可以使用memcache扩展. 反之请选择memcached扩展.

不过debian和ubuntu上直接用apt-get install php5-memcached安装的php memcached扩展,libmemcached库有些问题. 很多人报告不能正常使用. memcache扩展由于不依赖libmemcached库,没这个问题.
我的debian 6上也有这个毛病. 必须手工编译libmemcached才行, 命令如下.

apt-get remove php5-memcached

wget http://launchpad.net/libmemcached/1.0/0.50/+download/libmemcached-0.50.tar.gz
tar -zxvf libmemcached-0.50.tar.gz
cd libmemcached-0.50
./configure
make
make test
make install
cd ..

wget http://pecl.php.net/get/memcached-1.0.2.tgz
tar -xzvf memcached-1.0.2.tgz
cd memcached-1.0.2
phpize
./configure
make
make install

然后在/etc/php5/apache2/conf.d/memcached.ini里开启php memcached扩展.
重启apache, 应该就ok了.

你可以用这段php片段测试一下

$m = new Memcached();
var_dump($m);
echo $m->addServer('localhost', 11211);

echo $m->set('int', 99);
echo $m->set('string', 'a simple string');
echo $m->set('array', array(11, 12));
/* expire 'object' key in 5 minutes */
echo $m->set('object', new stdclass, time() + 300);


var_dump($m->get('int'));
var_dump($m->get('string'));
var_dump($m->get('array'));
var_dump($m->get('object'));

最近我编辑joomla的Gantry theme的时候,经常碰到css等文件,保存以后变成不可写“unwritable”的情况。
把这些文件的权限改成755,通过joomla一编辑保存,又变成555了。

在网上Google了一下,发现碰到这个问题的人还真不少。
比如这里这里,都用一堆人说这事。Gantry theme的用户也说这事

开始我以为是apache或者php什么地方的配置有问题。但是写了个简单的php脚本,跑了一下发现没这个问题,创建出来的文件的权限很正常。

直到看到这篇文章,才发现这是个老问题,从2006就有人不停的在抱怨了。

起因就是在joomla的模板组件的controller文件administrator/components/com_templates/controller.php里有这么几行代码:

// Try to make the template file unwriteable
if (!$ftp['enabled'] && !JPath::setPermissions($file, '0555')) {
	JError::raiseNotice('SOME_ERROR_CODE', JText::_('Could not make the template file unwritable'));
}

我也没看明白,没什么不使用ftp就要把文件权限改成555?自己改成不可写,然后再告诉用户”那个文件不可写”,还不说问什么。

当然像我这样不求甚解的人很多,这几行代码就被广泛的粘贴复制了。比如本文开头提到的Gantry theme

更加好笑的是,joomla的team在不断发布新版本。在最近发布的joomla 1.6.1里,似乎处于安全性考虑,之前设置文件权限为755的地方都改成了644。而这几行代码也顺理成章的从555变种成了444。

//administrator/components/com_templates/models/source.php
// Try to make the template file unwriteable.
if (!$ftp['enabled'] && JPath::isOwner($filePath) && !JPath::setPermissions($filePath, '0444')) {
	$this->setError(JText::_('COM_TEMPLATES_ERROR_SOURCE_FILE_NOT_UNWRITABLE'));
	return false;
} else if (!$return) {
	$this->setError(JText::sprintf('COM_TEMPLATES_ERROR_FAILED_TO_SAVE_FILENAME', $fileName));
	return false;
	}

现在这个问题的解决办法,就是把555换成755,或者444改成644。至于什么时候joomla官方能给出个正解,就不知道了。

整理Eclipse for php的时候,无意间看到了这工具,Zen Coding。真是快速编辑html和css的利器,有多厉害,看看这里的演示吧。访问不到的请移步土豆

作者的主要想法是,通过把编辑器变成一个简单的脚步解释环境,来提高编码的效率。我想这也是VIM这种编辑器反而比一些的IDE效率更高的主要原因。不过Zen Coding的想法更新颖,代码更少。
例如我们要输入这样一段html代码,

<div id=”header”>
    <ul class=”navigation”>
        <li><a href=”"></a></li>
        <li><a href=”"></a></li>
        <li><a href=”"></a></li>
        <li><a href=”"></a></li>
    </ul>
</div>

以zen coding的方式,就只需要输入“div#header>ul.navigation>li*4>a”,然后按快捷键展开就好了。

心动了,来体验一下zen coding的魅力吧。这个在线的Zen Coding编辑器,是通过js,把普通的html textarea变成了不错的IDE。如何让你网站上的textarea也支持这个功能?试试这个吧。

我常用的代码编辑器是VIM和Eclispe,来看看怎么使它们支持Zen Coding吧。

首先来看看VIM

VIM下支持Zen Coding相对比较容易

  • 首先确保你的VIM版本支持python的。我使用的是Debian/squeeze下的vim-nox包,squeeze下支持python的VIM包
  • 然后下载这两个VIM插件,zencoding.vimzencoding_vim.py,拷贝到VIM的.vim/plugin目录中。
  • 再从这里,下载Zen Coding for TextMate v0.3.1.zip,把压缩包里的zencoding整个目录拷贝到.vim/plugin下。注意是目录。

OK,现在可以打开VIM试试了。进入插入模式输入“div#header>ul.navigation>li*4>a”,然后按“Ctrl+E”,看看有什么效果,呵呵。
VIM下的Zen Coding的快捷键设置如下:

插入模式下Ctrl+L :插入缩略代码
可视模式下Ctrl+L :在选中的文本前后,重复插入缩略代码
插入模式下Ctrl+E:直接在当前编辑位置,运行并插入生产的代码
插入模式下Tab:同Ctrl+E

再说说Eclipse

Eclipse下支持Zen Coding实际上是通过js做的。就像在Firefox里有Greasemonkey这样的扩展是用户可以通过js来扩充Firefox;Eclipse下也有个类似的叫Eclipse Monkey的项目。

  • 首先在Eclipse里添加这个更新站点http://download.eclipse.org/technology/dash/update,更新、安装Eclipse Monkey。
  • 然后看这个演示,就知道怎么在项目里加入zen coding的js文件,来扩展Eclipse了。

zen coding in Eclipse

Zen Coding现在是一个比较新的项目,有兴趣的可以多关心Zen Coding在Google code上的项目

参考文档:

  • http://code.google.com/p/zen-coding/issues/detail?id=16
  • http://code.google.com/p/zen-coding/wiki/AptanaHowToEn