Browsed by
Tag: php

parseInt

parseInt

云通信系统的用户偶尔向我们反馈,分机的状态显示总是离线状态。我们从后台检查状态是正确的,检查其他用户的分机状态也都很正常,但是这位用户查询的结果确实总是离线状态。这事颇有些蹊跷,引起了我很大的兴趣去研究发生了什么。

检查之后的结果也很简单。后台返回的状态数据是字符串形式,而前端 javascript 脚本是按照整数进行判断,自然无法正常显示状态。但是为什么有些又能正确显示呢?

进一步检查后发现这与 MySQL 数据库的版本有关。我们的云系统有很多服务器,都是采用 Debian 的系统,同时也是采用 Debian 默认自带的数据库。旧 Debian 系统中的 MySQL 数据库版本比较陈旧,返回查询结果时都是采用字符串格式,哪怕字段是整数类型,返回的结果也是转换成字符串。而新的 Debian 系统已经将默认的数据库替换成 MariaDB,返回结果时严格遵循字段的类型,不会进行这类转换。

用户的虚拟通信系统部署在不同的 Debian 节点上,返回查询结果时就存在上述转换方面的差异。

解决方式自然也不复杂。可以从服务器端解决,也可以从前端解决。服务器端升级 Debian 系统就会同时将数据库升级到 MariaDB,自然就能返回整数类型的结果。当然也可以从 PHP (包括 pdo层)解决,由 PHP 对查询结果强制进行转换,将字符串又转换成整数即可。但是出于稳定性方面的考虑,我们一般不太愿意直接升级服务器系统(包括 PHP 等中间层),各节点的升级总是按年制定计划,不太可能为了这样一个小问题兴师动众地升级系统。

因此最后的解决方案就是对前端 JavaScript 脚本做一点修改。JS 提供了 parseInt 函数进行转换(如果是浮点数就是 parseFloat),无论服务器返回的是字符串还是整数,经转换后都可以按照整数进行判断。

此事反映出(1)我们对web、数据库等方面的技术技能比较欠缺,缺乏足够理解;(2)测试范围不够广泛,没有涵盖所有的用户类型;(3)系统配置不够一致,存在新旧并存的现象。我个人觉得后续工作要着力解决第(3)点的情况,尽量做到(包括开发、测试、线上)只有一个版本、只有一种系统。

升级php7

升级php7

这是一个升级的季节……

前两天刚升级完Git,感觉可以稍微轻松一下。今天收到email,WordPress 升级了! 升级也就算了,关键是进入管理界面时,扑面而来一个提示:“WordPress has detected that your site is running on an insecure version of PHP” ,这意思是:您的php版本太老了,该升级了!

查了一下当前Debian 9默认的php版本:V5.6.40,似乎不算太老啊。顺手又查了一下该系统中最新的php版本,已经是V7.0.33版本。V7的版本应该足够WordPress 使用,于是决定升级php来解决这个提示问题。

PHP毕竟是世界上最好的语言,各种插件都已经相应升级好了,都有PHP7对应的版本,因此事情就简单了,使用以下命令,直接安装即可:

sudo apt install libapache2-mod-php7.0 php7.0-fpm php7.0-gd php7.0-curl php7.0-mbstring php7.0-mcrypt php7.0-json php7.0-mysql php7.0-opcache php7.0-readline php7.0-xml php7.0-xmlrpc php7.0-zip php7.0-bz2 php-imagick

升级完php及apache的模块后,需要设置 Apache 使用最新的php7版本。也很简单,重新设置相应的模块并重启 Apache 即可:

sudo a2dismod php5
sudo a2enmod php7.0
sudo a2enmod proxy_fcgi
sudo a2enconf php7.0-fpm
sudo systemctl restart apache2
php坑:ftok

php坑:ftok

最近有个小需求,需要php程序和服务器程序之间进行一些简单通信。调研了几个进程间通信的技术,选择了消息队列方式。

消息队列技术本身不复杂,无非就是生成一个ID,然后使用该ID发送消息或者接受消息。在C程序中,使用ftok来生成ID,而php同样提供了相同名字的函数。因此,在php代码中,想当然地写下了类似语句:

$key_t = msg_get_queue(ftok("/home", 2));

让人惊讶的是,C程序始终接受不到php发送的消息。百思不解之下,使用命令查看系统的消息队列情况:

ipcs -q

结果表明php程序的确在发送消息,只是php的消息队列ID与C程序的消息队列ID居然是不一致的。重新翻看了php的手册,对ftok函数是这么描述的:

int ftok ( string $pathname , string $proj )

值得注意的是:第二个参数居然是字符串型。而在C函数中,该参数定义为int型:

key_t ftok(const char *pathname, int proj_id);

因此,在php代码中,当我们传递整数2给函数ftok时,php转换成了字符‘2’,也就是说,上述示例的php代码实际相当于以下语句:

$key_t = msg_get_queue(ftok("/home", '2'));

导致最终的计算结果与C函数不一致。修改方式也简单,在C程序中,将第二个参数修改为0x32,与php一致即可。

无法理解php为什么将第二个参数改成字符串型,实在是多此一举,而且毫无意义。

php闭合标签害死人

php闭合标签害死人

今天调试一段很简单的php代码:无非就是echo一个字符串给javascript程序,由js程序根据字符串走不同的逻辑即可。

遇到一个问题,几乎被折磨死:js得到的字符串前面总是多了一个’\n’! 排查了apache、js、php等方方面面的问题,最后居然发现是闭合标签’?>’导致的。

在php的文档中清楚地写明:解析器实际上是不解析这个闭合标签’?>’的。但是如果使用了这个标签,则后面的空格、换行等字符都会被带入后面的引用,引起多余的输出等。

在我的遭遇中,当前php引用了另外一个php文件,那个php文件在’?>’后多了一个’\n’,这个多余的换行符就被带入到当前的php中了。

解决方法也很简单,php文件都不包含闭合标签即可。话说回来了,“闭合”的意思不就是关闭了、结束了么?php解析器的处理方式真是让人感觉莫名其妙啊。

Apache无法执行php的问题

Apache无法执行php的问题

最近将开发环境从Kubuntu 12.04升级到13.04,整个过程基本顺利。然而在使用过程中,逐渐发现一些有问题的地方,升级实际上导致了一些问题。例如Apache出现的问题。

升级后,Apache运行php脚本时全部失败,在log中可以看到以下一些类似的信息:

SoftException in Application.cpp ...
premature end of script headers...

解决方法也比较简单,将libapache2-mod-suphp模块删除后重新安装即可,没有去深究其中的具体原因。从中也可以看出:linux各版本目前作得都比较不错了,可是还是总有一些小问题会时不时出现并困扰你,让你去折腾,这可能也就是为什么linux始终无法进入主流消费者领域的原因吧。

 

一款轻量级的php编辑工具gPHPEdit

一款轻量级的php编辑工具gPHPEdit

在Ubuntu环境中,一般可以采用gEdit来编辑php文件。不过gEdit有个很大的不足:无法显示php函数、类列表,毕竟gEdit只是定位在简单的文本编辑功能上。

我们也可以使用Eclipse+PDT模块,不过Eclipse实在是太重型了,不太讨人喜欢。

后来发现Ubuntu软件中心有一款非常轻型的php编辑工具:gPHPEdit。它的界面、配置、操作都与gEdit非常像,重要的是它支持对PHP文件中的函数和类进行列表,大大方便了开发工作。

安装命令如下:

sudo apt-get install gphpedit php5-cli

gPHPEdit使用php5-cli进行PHP语法检查。如果不想要语法检查功能,可以不安装php5-cli。

安装phpmailer

安装phpmailer

phpmailer是一个全功能的发送email的模块,安装很简单:

sudo apt-get install libphp-phpmailer

缺省会安装在/usr/share/php/libphp-phpmailer目录。

还需要设置php.ini文件,将上述目录加入include路径:sudo vi /etc/php5/apache2/php.ini

在该php.ini文件中,找到include_path并修改为:

include_path = “.:/usr/share/php:/usr/share/php/libphp-phpmailer”

完成修改后,重启apache2即可。

 

Apache report error: [error] (13)Permission denied: exec of ‘/cgi-bin/signup.php’ failed

Apache report error: [error] (13)Permission denied: exec of ‘/cgi-bin/signup.php’ failed

在桌面版本Ubuntu上,通过Apache2测试PHP程序时,会遇到几个问题:

(1)Apache2把PHP文件当成普通文档,没有执行php文件,反而提示文件下载并询问存放路径。

(2)Apache2提示无权读取cgi-bin目录的文件。

问题(1)是由于没有安装Apache2的php模块导致的,而问题(2)是由于Apache2没有足够的权限操作cgi-bin目录中的php文件。安装以下模块可以解决:

sudo apt-get install libapache2-mod-php5

sudo apt-get install libapache2-mod-suphp