分类目录归档:Web Development

当一个字符串和 false 比较的时候会发生什么?

今天在写程序的时候,遇到个问题,这个问题是这样的:

我有一个表:

CREATE TABLE IF NOT EXISTS `session` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `token` varchar(32) NOT NULL,
  `profile` varchar(1000) NOT NULL,
  `created_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  PRIMARY KEY (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=41 ;

和一些数据:

(38, '395d5feaf28df01aafe0781a7f34acbe', 'a:3:{s:2:"id";s:1:"2";s:8:"username";s:7:"wanmeng";s:12:"created_time";s:19:"2011-11-18 19:37:33";}', '2011-12-03 14:14:35'), 
(39, '0e0ca06ed9ad86937f190eb9544ac935', 'a:3:{s:2:"id";s:1:"1";s:8:"username";s:6:"delphi";s:12:"created_time";s:19:"2011-11-18 13:29:40";}', '2011-12-03 14:28:36'), 
(31, '3cba76b97cf123009632bdaa5a306385', 'a:3:{s:2:"id";s:1:"1";s:8:"username";s:6:"delphi";s:12:"created_time";s:19:"2011-11-18 13:29:40";}', '2011-12-02 15:50:21'), 
(30, 'fa356333dd3ee8f1b18b8bf0a827e34c', 'a:3:{s:2:"id";s:1:"1";s:8:"username";s:6:"delphi";s:12:"created_time";s:19:"2011-11-18 13:29:40";}', '2011-12-01 15:32:47')

在我执行  SELECT * FROM session WHERE token = false 的时候,我本以为没有记录会返回,但是mysql却给我返回了2条记录:

39  0e0ca06ed9ad86937f190eb9544ac935    a:3:{s:2:"id";s:1:"1";s:8:"username";s:6:"delphi";...   2011-12-03 22:28:36 
30  fa356333dd3ee8f1b18b8bf0a827e34c    a:3:{s:2:"id";s:1:"1";s:8:"username";s:6:"delphi";...   2011-12-01 23:32:47

我猜到了问题应该是出在数据类型转换上,于是我就修改了查询语句,让字符串和null值作比较而不是false,但为什么会这样却一时半会儿没想明白,于是就在stackoverflow上提了个问题 ,结果当然是被人家当小白教育了一翻……但原因我算是知道了。

在Mysql中是没有boolean这种数据类型的,boolean在Mysql中实际上是用Tinyint表示的,0代表false,1代表true。

所以上边那个查询实际上就是相当于

SELECT * FROM session WHERE token = 0

当一个字符串和Tinyinit作比较的时候,Mysql会先将字符串转换为数字类型,数字开头的字符串取前边的可以转换的数字字符转为数字,如果字符串是字母开头的,则直接转为数字0

于是那些以字母开头和数字0开头的记录便被取出来了。

Nginx配置相关的一些问题

1.  no input file specified

这个问题其实就是Nginx传给PHP-cgi的文件名,cgi找不到。这个问题一般是由以下原因导致的:

  1. 文件真的不存在……
  2. 文件和目录的权限问题,如果nginx和php-cgi运行的用户对要获取的文件没有读取权限,就会出这个错。
  3. php.ini中的cgi.fix_pathinfo选项,如果你是用SCRIPT_FILENAME获取php文件路径的话,请将此项设为1
  4. 如果在nginx中SCRIPT_FILENAME是用$document_root$fastcgi_script_name;这种方式定义的话,需要保证$document_root在此句之前已被定义。
  5. 还有一种情况比较特殊,就是有些nginx版本的配置文件,会在fastcgi_params文件中重复定义SCRIPT_FILENAME为其它的值,把fastcgi_params中的注释掉就好了。

2. 使用$request_filename判断文件是否存在的时候,$request_filename无法正确定位文件位置

这是因为$request_filename是与server的root有关的,所以需要在server段中定义root来指出此网站所在的物理路径。

为 PHP 安装 OAuth 扩展

最近在弄Evernote的API,想通过Evernote的API将JSON格式的Google Reader分享资料导入到Evernote中。注册了Evernote沙盒账号,下载了SDK,一运行示例代码,结果这玩意儿还需要安装OAuth扩展。

上网找了一下PHP的OAuth扩展的资料,总结分享如下:

OAuth是一个基于HTTP的用户验证协议,可以使应用在无需保存用户的账号密码的情况下为用户提供安全的数据访问。PHP的OAuth扩展为OAuth认证和绑定账号提供所需的支持。

如何安装

最简单的方法就是从PECL上下载了

首先安装pecl

sudo apt-get install php-pear php5-dev make

然后运行

sudo pecl install oauth

如果遇到了/usr/include/php5/ext/pcre/php_pcre.h:29: fatal error: p…的问题,则需要安装libpcre3-dev

sudo apt-get install libpcre3-dev

安装完成后,在 /etc/php5/cgi/php.ini 中添加一行

extension=oauth.ini

但是我用pecl没能安装成功,我是自己编译安装的

首先在PHP官网下载oauth的包

将包解压到随便哪个目录,在那个目录执行

phpize
./configure
make
sudo make install

然后同样是在 /etc/php5/cgi/php.ini中添加

extension=oauth.ini

之后重启phpcgi服务就可以了。

参考资料

http://www.php.net/manual/zh/oauth.setup.php
http://pecl.php.net/package/oauth
http://djpate.com/2010/10/07/how-to-install-oauth-support-for-php-on-ubuntu/