作者归档:admin

PHP unserialize出错

最近碰到一个问题,在使用PHP的unserialize函数反序列化服务端传递过来的参数时报错了:unserialize() [function.unserialize]: Error at offset 180 of 181 bytes。最后在Stackoverflow上找到了一个非常好的答案:这是由于序列化时字符串长度算错了导致的。作者还写了个校正长度的正则表达式,提供了一个用于计算序列化是否出错了的函数。导致序列化出错的原因通常是因为内容使用了双引号(”)而不是单引号(’),php与mysql编码不一致(UTF8),内容包括冒号(:)和引号(;)也会导致反序列化出错。
解决的方法是在serialize上加上base64函数,对数据做base64编码和解码:

$toDatabse = base64_encode(serialize($data));
$fromDatabase = unserialize(base64_decode($data)); 

当然更建议使用json_encode和json_decode的来处理数据的序列化和反序列化会更快,但有一些局限性(这里)继续阅读

Mysql INT和CHAR类型的隐式转换

最近碰到一个问题,由于没有对参数进行过滤和转换,直接拿到mysql里面进行查询了,大概是这样的:

select * from store where id='1}';
select * from store where id='{1}';#测试

但是前者仍然可以查出id为1的记录,后者是不行。知道mysql有隐式转换却不知道具体是怎么样的。google了下,发现隐式转换还有其他的问题,例如:

select * from store where name=0;
select * from store where name='0';

前者将会查询出所有的记录,而后者只会匹配name值为0的记录。
总结了一下大概是这些大概是以下的原因:

  • 当查询字段是INT类型,如果查询条件为CHAR,将查询条件转换为INT,如果是字符串前导都是数字将会进行截取,如果不是转换为0。
  • 当查询字段是CHAR类型,如果查询条件为INT,将查询字段为换为INT再进行比较,可能会造成全表扫描。示例2的name字段为CHAR类型,第一句查询转换为INT时都等于0,所以全部匹配了;第二句查询同为CHAR类型不发生转换,所以仅匹配值为0的记录。

mysql的隐式转换还有很多其他的坑,所以一定要指明查询条件类型,不要让mysql去做自动转换。

参考链接:
价值百万的 MySQL 的隐式类型转换
mysql字符串的隐式转换导致数据库操作异常
关于mysql 隐式转换的一个小问题
MySQL查询类型不正确不使用索引?
mysql的隐式的数据类型转换
MySQL隐式转换之坑
列类型

开启Firephp时Nginx PHP-FPM下502错误解决

在自己的电脑上调试的好好的,部署到Linux Nginx环境的时候却发现有些PHP页面在Firefox下面会返回502,在IE下面却是正常的,甚至在chrome下面也会出现502。顺着Nginx,Firefox这两个关键字,终于找到原因:原来是开启Firephp(chrome装了webug)时,Firephp的调试信息会写入的请求头里面,导致Nginx的FastCGI缓冲区超出,从而返回502。在自己的电脑上之所以不会是因为使用的是Apache。
于是顺着其他人的解答修改了nginx.conf中fastcig相关的参数:

fastcgi_buffer_size 1024k;
fastcgi_buffers 8 512k;
fastcgi_busy_buffers_size 1024k;
fastcgi_temp_file_write_size 1024k;

一开始这些参数是256,后来改成了512还是有部分页面会出现502,再改成1024终于好了。 继续阅读

Windows 8 安装Vagrant和VirtualBox

由于php的一些扩展只有在linux下面才能用,就算是Cygwin下面也不行,例如pcntl。所以就决定安装一个linux虚拟机来作为开发环境,顺带找到了另外一个东西:Vagrant。Vagrant作为一款虚拟机环境统一配置管理工具,后端可以是VirtualBox,VMWare,AWS。这样当运行环境配置完了可以方便的部署在其他机器上或给予其他开发人员,实现配置一次,到处运行的功能。当使用Vagrant管理VirtualBox是运行在命令行下面的,而不需要打开界面。

首先,安装VirtualBox,地址

然后,安装Vagrant,地址。安装完成后,将Vagrant的bin目录添加到系统的环境变量Path里面。

再然后,下载做好的虚拟机镜像,地址。我这里下载的是Ubuntu precise 64 VirtualBox,对应链接:http://files.vagrantup.com/precise64.box。这个镜像的下载速度还不错,centos的就不怎么样了,但还是建议先下载到本地硬盘在加载进来。

这时候应该先为这个虚拟机(Ubuntu precise 64)建一个目录,以便初始化和管理这个虚拟机主机。如果有多个虚拟机的话,就分别建立不同的目录来初始化。比如:E:\project\vagrant\dev。然后就在这个目录下面初始化这个镜像。

E:\project\vagrant\dev>vagrant box add Ubuntu12.04x64 "file:///f:\box\precise64.box"

注意,file后面应该是三个/而不是两个。add后面跟的是这个虚拟机的名称,也可以用base自动识别。
打开对应目录下面的配置文件Vagrantfile,配置虚拟机的ip和共享目录。

 config.vm.network "private_network", ip: "192.168.33.10"
 config.vm.synced_folder "E:/wamp/www", "/home/vagrant/www" #将前者映射到后者

初始化并启动:

E:\project\vagrant\dev>vagrant init Ubuntu12.04x64
E:\project\vagrant\dev>vagrant up

vagrant up
然后可以通过ssh连接上去管理了,这里使用Cygwin下面的ssh客户端,默认用户和密码都是vagrant。
vagrant ssh

sudo apt-get update #先更新下软件包,要不然有的可能会装不上

注意启动和连接虚拟机都需要切换到该虚拟机所在开发目录。还有一些其他的命令。

vagrant init  # 初始化
vagrant up  # 启动虚拟机
vagrant halt  # 关闭虚拟机
vagrant reload  # 重启虚拟机
vagrant ssh  # SSH 至虚拟机
vagrant status  # 查看虚拟机运行状态
vagrant destroy  # 销毁当前虚拟机
vagrant package  # 导出当前虚拟机

这里有别人推荐的一个小软件win-sshfs,可以将Linux的目录直接mount到Windows系统上作为一个根盘符。注意:这是个32位软件,可能会安装不成功,需要采用兼容模式。
sshfs
然后就可以在我的电脑里面像本地文件一样管理。

参考链接:
使用 Vagrant 打造跨平台开发环境
使用vagrant和win Sshfs支持openstack开发
Vagrant安装配置
Windows 7使用Vagrant构建虚拟开发环境
Vagrant+VirtualBox搭建统一开发环境

Cygwin 安装

在windows 8.1上安装Cygwin真的是非常蛋疼,网络一会儿就会自己停了,只能取消重试。为了装上php,找到了一个好东西:apt-cyg,Cygwin的包管理器,有点像ubuntu的apt-get,强烈推荐。
安装apt-cyg很简单,但是国内访问googlecode非常不方便,这里提供一个下载链接(注意:githut上的这个链接googlecode上不一样的).

wget http://courages.us/?attachment_id=364
chmod +x apt-cyg
mv apt-cyg /usr/local/bin/

然后就可以用了,例如查找包,安装包,指定源。这里也推荐下另外一个cygwinports(ftp://ftp.cygwinports.org/pub/cygwinports),当你找不你想要的就可以来这里找。

apt-cyg -m ftp://ftp.cygwinports.org/pub/cygwinports find php
apt-cyg -m http://mirrors.163.com/cygwin find openssl
apt-cyg install openssl

继续阅读