分类目录归档:编程技术

涵盖PHP、Java、.Net开发技术有关的内容,或原创分享,或转载学习。

使用Composer管理PHP依赖关系

简介

现在软件规模越来越大,PHP项目的开发模式和许多年前已经有了很大变化。记得初学PHP那会儿,boblog是一个很好的例子,几乎可以代表PHP项目的开发模式。当时PHP 5.x以上的版本刚开始流行,仍然有大量的生产环境使用PHP4.x。由于历史遗留的问题,OOP思想在PHP项目中还不是那么广泛流行。随着PHP5.3的发布,PHP项目规模的扩大,在其他语言领域大展身手的OOP开发模式也在PHP中崭露头角。

大型项目不可能是从头开始的,使用社区已经提供的资源可以为项目带来很大的便利。然而各自为政的打包方式、依赖关系的处理,导致了很难将两个开源项目集成到一起。虽然有pear这种PHP官方支持的包管理工具,但是依然没有很好的统一的依赖关系管理的办法。直到Composer的出现。

Composer的依赖关系管理风格,看上去更像Java的Maven。项目编译和打包、依赖关系的解决都可以很轻松的实现。再也不用费神去寻找或者更新第三方库,或者将他们集成到一起。这一切全部都可以交给Composer来完成。

继续阅读

[翻译]使用PHPUnit进行测试驱动开发

单元测试在软件开发过程中举足轻重,测试先行编程(Test-First Programming),极限编程(XP)和测试驱动开发(TDD)在实践中被广泛的使用,单元测试允许通过编程语言进行契约式设计。

在代码编写完成后,你可以使用PHPUnit来编写测试。然而在错误出现之前创建测试,测试才显得更有一样。所以与其在代码编写完成几个月之后再为它创建测试用例,不如尽早的赶在出现瑕疵的几天甚至几分钟内创建这些测试用例。尽管如此,人们自然而然的可以想到,为何不在瑕疵出现之前,就提前编写好这些测试呢?

测试先行编程是极限编程和测试驱动开发的一部分,基于这种思想我们来实现编程的“极限化”。在现在的电脑运行环境下,我们每天可以将数以千计的测试用例执行个几千次。利用测试的反馈,可以及时地改进每次开发引入的新特性,同时便于利用自动化测试检查可能新被引入的Bug。

继续阅读

更新到PHP5.5.0的编译选项

httpd-2.4.4

./configure --enable-so --enable-deflate=shared --enable-ssl=shared --enable-dav=shared --enable-vhost-alias=shared --enable-rewrite=shared --with-mpm=worker

php-5.5.0

./configure --prefix=/usr/local/php-5.5.0 --with-apxs2=/usr/local/httpd-2.4.4/bin/apxs --with-openssl --with-pcre-regex --with-zlib --enable-bcmath --with-bz2 --enable-calendar --with-curl --enable-exif --enable-ftp --with-gd --with-gettext --with-mhash --enable-intl --enable-mbstring --with-mcrypt --with-mysql --with-mysqli --enable-opcache --enable-pcntl --with-pdo-mysql --enable-soap --enable-sockets --enable-sysvmsg --enable-sysvsem --enable-sysvshm --with-pear

mysql-5.5.32

cmake -DCMAKE_INSTALL_PREFIX=/usr/local/mysql-5.5.32 -DWITH_INNOBASE_STORAGE_ENGINE=1 -DWITH_ARCHIVE_STORAGE_ENGINE=1 -DWITH_BLACKHOLE_STORAGE_ENGINE=1 -DDEFAULT_CHARSET=utf8 -DDEFAULT_COLLATION=utf8_general_ci

并发访问、事务安全,蛋疼的Bug

上线的系统出了个Bug,数据库出现了脏数据,做了一半的事务居然提交了,觉得有点不可思议。但是不可思议的事情居然还大量发生了。

检查相关功能,Bug功能出现在一个自己实现的cron机制触发的定时任务中。由于PHP没有常驻系统的机制,因此计划任务或者定时任务这种东西只能依靠流量驱动,或者利用Linux系统的CRON服务。为了不增加运维人员的维护压力,就选择了前者,使用流量来驱动定时任务检查和触发。

结果,悲剧鸟。 继续阅读

Linux下C语言实现的一个多线程Socket服务器端

话说,最近开始神奇地拿C/C++做开发了。。

从最开始的时候就觉得,C/C++神马,做开发是无比蛋疼的。。

嘛,既然是工作需要,那就上吧。TAT。这次补上C/C++和.NET,这样主流开发语言就基本上都做过东西了。。哈,听起来很牛X的样子。我只是个菜鸟。。

以上跑题———-下转正题。

话说一般做C/C++的系统肯定会遇到的技术点,比如GUI,多线程,网络通讯,数据库等等。当然你非要说做单机的“火车订票系统”,那也没办法。当然实际的应用场景肯定不是这样的。

今天晚上就试着自己摸索摸索如何在Linux平台上用C语言实现一个服务器端。

大致了解下的多客户端服务器程序,要么是单或者少量线程的多路复用的非阻塞式,要么是一个客户端一个线程。当然两种方式各有相应的应用场景,不能谁打死谁。按照一般大学教科书上介绍的服务器带多客户端,大多数是后者,即来个请求,起一个线程为其服务。由此也能推断,这种适合于,数据通讯及时性强,长期连接的应用场景。这次介绍的就是多线程的Socket服务器端的示例。

继续阅读

把服务器上的PHP5.3升级到了PHP5.4.4

话说PHP官方发布PHP5.4已经有一阵了,根据使用的情况来看,似乎还是很不错的。从初始发布到现在升级到的PHP5.4.4,修正不少的Bug。PHP5.4新的版本,除了提供了更多新的特性,还有大幅的效率提升。这个版本趋于稳定之后,我决定把我的服务器升级到PHP5.4.4。

服务器上的软件包,一直以来都是编译安装,因此对于这些东西自己也是比较可控的。从PHP官方网站下载最新的源代码包,解压缩并且安装,这没有什么特别的。以下是我使用的安装编译参数:

./configure --prefix=/usr/local/php-5.4.4/ --with-config-file-path=/usr/local/php-5.4.4/etc --with-mysql --with-mysqli --with-iconv --with-zlib --enable-xml --enable-bcmath --enable-shmop --enable-sysvsem --enable-inline-optimization --with-curl --with-curlwrappers --enable-mbregex --enable-fpm --with-fpm-user=www --with-fpm-group=www --enable-mbstring --with-mcrypt --with-gd --enable-gd-native-ttf --with-openssl --with-mhash --enable-pcntl --enable-sockets --with-xmlrpc --enable-zip --enable-soap --with-pdo-mysql
make ZEND_EXTRA_LIBS='-liconv'
make install

继续阅读

使用netbeans进行PHP团队开发和基于xdebug进行多人远程调试

不少的非单纯PHP架构的网站系统中,PHP开发的Web系统,往往对特定的服务器环境有依赖,例如使用php开发某些面向开放平台的系统,或者带有支付接口功能的系统,都需要在真正的服务器环境上进行开发与调试。2011年中国PHP技术高峰论坛上,金山技术运营中心技术经理张宴老师介绍了PHP在金山游戏运营中的一些应用实践(传送门:2011中国PHP技术高峰论坛:PHP在金山游戏运营中的应用),在其中提到了PHP的开发团队,使用一致的Linux服务器作为开发调试平台,这样所有开发者可以使用一致的配置文件,也可以进行某些依赖于服务器的开发和测试。

文中张宴老师提到使用本地nginx服务器+远程fastcgi服务器,将本地的共享文件夹映射到远程服务器的模式,在具体实践中我稍作修改:

  1. 将Web服务器和PHP-FastCGI只架设在Linux端。
  2. 将Linux服务器上的用户工作目录建立共享,映射为开发者Windows上的虚拟驱动器。
  3. 开发者通过同样的地址访问测试,在Nginx里面配置根据来访者IP地址选择root目录。

这样一来,开发者端只需要IDE环境和映射网络驱动器,在服务器端为其建立相应的SMB账号和以开发者IP命名的工作目录。例如开发者A的IP为192.168.137.101,那么他访问192.168.137.10开发服务器时,WebRoot为/home/192.168.137.101。

但是实践中发现这么做有个问题存在,即SMB服务器的读写速度太慢,由于工作区的代码副本包含SVN信息,所以SVN提交或者更新时,经常会出现超时失败的情况。后来研究Netbeans之后,发现其自带强大的远程开发调试功能。方案大致如下:

继续阅读

PHP由于服务器时间不正确导致的IE、Chrome下SESSION丢失

今天系统联调的时候遇到了一个比较奇怪的Bug,火狐下一切正常,切换到IE和Chrome之后发现一直是未登录状态。在确认了Ajax提交的登录一切正常后,把问题定位在了PHP Session是否正常设置上。

切换到项目的Session临时目录,删除所有的SESSION文件,使用IE打开页面。发现每次刷新一次都会新增一个SESSION文件。使用IE的开发者工具(按下F12唤出面板,菜单【缓存】->【查看Cookie信息】,如图)查看Cookie列表,发现PHP的Session确实没有写进去。

继续阅读

PHP中PDO数据访问对象处理LIMIT子句的一处BUG

近期的项目中,数据访问层类使用了PDO作为底层,PDO相比mysql_*系列函数具有更高的性能和安全性。在使用时却发现了PDO对象处理带有LIMIT子句的SQL语句时,不能正确处理LIMIT子句中的占位符。例如:

$sql = "SELECT * FROM user LIMIT ?, ?";
$stmt = $pdo->prepare($sql);
$stmt->execute(array(0, 20));
.... 

在这段代码中,按照PDO文档的说法,两个问号的位置将会被0, 20这两个参数填充,并且类型将会使用和参数类型相匹配的PDO数据类型。但是执行这条语句却返回一个空集合。

var_dump($stmt->fetchAll());
// 输出 empty 

然而将问号的位置直接填写数字,是可以正常取得20条记录的。

在谷歌上搜索发现,有其他人也遇到了同样的BUG:
继续阅读