某天比较兴奋,决定用php按自己的思路写解数独的程序,已经完成!
http://www.aslibra.com/sodoku/
在右上角输入数独问题
一个空的格子是用一个空格代替,每行换行,最后一行不换行
暂时限制为提供最多10个解
否则会递归处理到所有解
目前还没有发现bug
希望有发现问题的朋友也指正一下
虽然没有真正自己琢磨过数独,但我用的解题思路是:
先找每行每列每个九格子的可能解
然后把只有一个可能的给算出来
多解的就对每个解进行继续处理,一直找到所有格子填满
代码以后整理。
大家可以参考资料:什么是九宫格数独?
http://www.aslibra.com/sodoku/
在右上角输入数独问题
一个空的格子是用一个空格代替,每行换行,最后一行不换行
暂时限制为提供最多10个解
否则会递归处理到所有解
目前还没有发现bug
希望有发现问题的朋友也指正一下
虽然没有真正自己琢磨过数独,但我用的解题思路是:
先找每行每列每个九格子的可能解
然后把只有一个可能的给算出来
多解的就对每个解进行继续处理,一直找到所有格子填满
代码以后整理。
大家可以参考资料:什么是九宫格数独?
闲逛博客,发现一个google题目的讨论:
题目要求大致意思:
* 给定一个集合A=[0,1,3,8](该集合中的元素都是在0,9之间的数字,但未必全部包含),指定任意一个正整数K,请用A中的元素组成一个大于K的最小正整数。
* 比如,A=[1,0] K=21 那么输出结构应该为100
我没有看他们的解法,但我一看就觉得没有那么复杂。
其实就是构造一个整数,只有两种情况
1 位数一样的数,注意最后一位是否需要大于要比较的位
2 位数多一的数,直接从最小的取,排下来就可以
先设计一个函数从集合里面挑选数字就可以完成了
我的代码(未知是否存在bug,做的时候发现bug了):
<?
/*
http://www.aslibra.com
code by hqlulu
*/
$a=array(0,1,3,8,5);
$v=108749;
$result='';
asort($a);
//取数的功能,参数为三个 集合、数字、是否要大于
function get_greater($a,$num,$greater=true){
foreach($a as $v){
if($v>=$num && !$greater)return $v;
if($v>$num && $greater)return $v;
}
return false;
}
//转换为字符串
$v=''.$v;
$len=strlen($v);
//后面的位是否必须大于该数
$greater=true;
//找到和它同样长度的整数
for($i=0;$i<$len;$i++){
$compare= ($i>0 && !$greater) ? 0 :$v[$i];
$mygreater = $greater;
if($i<$len-1) $mygreater = false;
$tmp = get_greater($a, $compare, $mygreater);
if($tmp === false){
$result='';//返回false说明找不到合适的,复位结果
break;
}else if($tmp>$v[$i]){
$greater=false;
}
$result.=$tmp;
}
//结果为空则取多一位的数
if($result==''){
//每次取比0大的数就可以了,第一位不能等于0
for($i=0;$i<=$len;$i++){
$result.= $i==0 ? get_greater($a,0) : get_greater($a,0,false);
}
}
echo $v.' result:'.$result;
?>
题目要求大致意思:
* 给定一个集合A=[0,1,3,8](该集合中的元素都是在0,9之间的数字,但未必全部包含),指定任意一个正整数K,请用A中的元素组成一个大于K的最小正整数。
* 比如,A=[1,0] K=21 那么输出结构应该为100
我没有看他们的解法,但我一看就觉得没有那么复杂。
其实就是构造一个整数,只有两种情况
1 位数一样的数,注意最后一位是否需要大于要比较的位
2 位数多一的数,直接从最小的取,排下来就可以
先设计一个函数从集合里面挑选数字就可以完成了
我的代码(未知是否存在bug,做的时候发现bug了):
<?
/*
http://www.aslibra.com
code by hqlulu
*/
$a=array(0,1,3,8,5);
$v=108749;
$result='';
asort($a);
//取数的功能,参数为三个 集合、数字、是否要大于
function get_greater($a,$num,$greater=true){
foreach($a as $v){
if($v>=$num && !$greater)return $v;
if($v>$num && $greater)return $v;
}
return false;
}
//转换为字符串
$v=''.$v;
$len=strlen($v);
//后面的位是否必须大于该数
$greater=true;
//找到和它同样长度的整数
for($i=0;$i<$len;$i++){
$compare= ($i>0 && !$greater) ? 0 :$v[$i];
$mygreater = $greater;
if($i<$len-1) $mygreater = false;
$tmp = get_greater($a, $compare, $mygreater);
if($tmp === false){
$result='';//返回false说明找不到合适的,复位结果
break;
}else if($tmp>$v[$i]){
$greater=false;
}
$result.=$tmp;
}
//结果为空则取多一位的数
if($result==''){
//每次取比0大的数就可以了,第一位不能等于0
for($i=0;$i<=$len;$i++){
$result.= $i==0 ? get_greater($a,0) : get_greater($a,0,false);
}
}
echo $v.' result:'.$result;
?>
fast-cgi是可以使用本地服务器A,调用远程B服务器的php的fast-cgi进程,一直还没相通是把A的本地文件传输给B,B执行然后返回,还是A通知B执行某个文件?
还是自己做个测试就知道:
在[B5]上安装PHP的fastcgi,在[A5]上安装的是Nginx,加fastcgi设置
文件都分布一下:
//file @A6 //
/Data/webapps/index.htm
A6 OK
/Data/webapps/test.aslibra.com/index.php
//file @B5 //
/Data/webapps/index.htm
B5 OK
/Data/webapps/test.aslibra.com/index.php
访问两个地址:
http://test.aslibra.com/index.htm
http://test.aslibra.com/index.php
结果:
也就是说:
文件使用的是对方服务器的文件,PHP文件的路径是在主服务器设置的。
有说明是要修改 cgi.fix_pathinfo=1 ,但文件说明是默认就是1了,所以估计不用修改
; cgi.fix_pathinfo provides *real* PATH_INFO/PATH_TRANSLATED support for CGI. PHP's
; previous behaviour was to set PATH_TRANSLATED to SCRIPT_FILENAME, and to not grok
; what PATH_INFO is. For more information on PATH_INFO, see the cgi specs. Setting
; this to 1 will cause PHP CGI to fix it's paths to conform to the spec. A setting
; of zero causes PHP to behave as before. Default is 1. You should fix your scripts
; to use SCRIPT_FILENAME rather than PATH_TRANSLATED.
修改成 cgi.fix_pathinfo=0 也还没发现啥不同,不知道会发生什么现象
另外,如果指定的php文件不存在,会有这样的错误:
No input file specified.
还是自己做个测试就知道:
在[B5]上安装PHP的fastcgi,在[A5]上安装的是Nginx,加fastcgi设置
#部分设置
root /Data/webapps/;
location ~ \.php$ {
fastcgi_pass 192.168.1.5:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /Data/webapps/pic.zcom.com$fastcgi_script_name;
include fastcgi_params;
}
root /Data/webapps/;
location ~ \.php$ {
fastcgi_pass 192.168.1.5:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /Data/webapps/pic.zcom.com$fastcgi_script_name;
include fastcgi_params;
}
文件都分布一下:
//file @A6 //
/Data/webapps/index.htm
A6 OK
/Data/webapps/test.aslibra.com/index.php
<pre><?phpinfo();?>
//file @B5 //
/Data/webapps/index.htm
B5 OK
/Data/webapps/test.aslibra.com/index.php
<pre><? print_r($_SERVER); ?>
访问两个地址:
http://test.aslibra.com/index.htm
http://test.aslibra.com/index.php
结果:
A6 OK
(文件在A6)
[SCRIPT_FILENAME] => /Data/webapps/test.aslibra.com/index.php
[SCRIPT_NAME] => /index.php
[REQUEST_URI] => /index.php
[DOCUMENT_URI] => /index.php
[DOCUMENT_ROOT] => /Data/webapps
[SERVER_SOFTWARE] => nginx/0.6.31
[SERVER_ADDR] => X.X.X.6
[PHP_SELF] => /index.php
(文件在B5,但注意,显示的SERVER_ADDR信息是A6的IP,对外是不知道是B5在运行的)
(文件在A6)
[SCRIPT_FILENAME] => /Data/webapps/test.aslibra.com/index.php
[SCRIPT_NAME] => /index.php
[REQUEST_URI] => /index.php
[DOCUMENT_URI] => /index.php
[DOCUMENT_ROOT] => /Data/webapps
[SERVER_SOFTWARE] => nginx/0.6.31
[SERVER_ADDR] => X.X.X.6
[PHP_SELF] => /index.php
(文件在B5,但注意,显示的SERVER_ADDR信息是A6的IP,对外是不知道是B5在运行的)
也就是说:
文件使用的是对方服务器的文件,PHP文件的路径是在主服务器设置的。
有说明是要修改 cgi.fix_pathinfo=1 ,但文件说明是默认就是1了,所以估计不用修改
; cgi.fix_pathinfo provides *real* PATH_INFO/PATH_TRANSLATED support for CGI. PHP's
; previous behaviour was to set PATH_TRANSLATED to SCRIPT_FILENAME, and to not grok
; what PATH_INFO is. For more information on PATH_INFO, see the cgi specs. Setting
; this to 1 will cause PHP CGI to fix it's paths to conform to the spec. A setting
; of zero causes PHP to behave as before. Default is 1. You should fix your scripts
; to use SCRIPT_FILENAME rather than PATH_TRANSLATED.
修改成 cgi.fix_pathinfo=0 也还没发现啥不同,不知道会发生什么现象
另外,如果指定的php文件不存在,会有这样的错误:
No input file specified.
Windows下的Memcache安装:
1. 下载memcache的windows稳定版,解压放某个盘下面,比如在c:\memcached
2. 在终端(也即cmd命令界面)下输入 ‘c:\memcached\memcached.exe -d install’ 安装
3. 再输入: ‘c:\memcached\memcached.exe -d start’ 启动。NOTE: 以后memcached将作为windows的一个服务每次开机时自动启动。这样服务器端已经安装完毕了。
4.下载php_memcache.dll,请自己查找对应的php版本的文件
5. 在C:\winnt\php.ini 加入一行 ‘extension=php_memcache.dll’
6.重新启动Apache,然后查看一下phpinfo,如果有memcache,那么就说明安装成功!
需要安装的就是服务器的Memcached的守护进程和客户端的PHP扩展php_memcache两个东西
1. 下载memcache的windows稳定版,解压放某个盘下面,比如在c:\memcached
2. 在终端(也即cmd命令界面)下输入 ‘c:\memcached\memcached.exe -d install’ 安装
3. 再输入: ‘c:\memcached\memcached.exe -d start’ 启动。NOTE: 以后memcached将作为windows的一个服务每次开机时自动启动。这样服务器端已经安装完毕了。
4.下载php_memcache.dll,请自己查找对应的php版本的文件
5. 在C:\winnt\php.ini 加入一行 ‘extension=php_memcache.dll’
6.重新启动Apache,然后查看一下phpinfo,如果有memcache,那么就说明安装成功!
需要安装的就是服务器的Memcached的守护进程和客户端的PHP扩展php_memcache两个东西
摘要:由于数据库存储的数据量越来越大,查询速度也就变的越来越慢,因此就有了缓存服务器应用的必要,本文是介绍Memcached的安装以及简单的使用
本文只介绍memcached的PHP的API,想查看其他关于Memcached的API文档案,请访问 http://www.danga.com/memcached/
1、安装Memcached
2、安装memcache PHP模块
3、测试脚本
一、环境需求
安装Memcached需要libevent库的支持,所以请在安装Memcached之前检查有没有安装libevent。测试环境还需要PHP的支持,本文假设PHP已经安装到/usr/local/php目录下,也就是在编译PHP的时候使用perfix参数指定目录(--prefix= /usr/local/php)
二、下载相关软件
Memcached下载地址 http://www.danga.com/memcached/
memcache PHP模块下载地址 http://pecl.php.net/package/memcache 推荐使用1.5版
libevent 下载地址 http://www.monkey.org/~provos/libevent/
2、安装Memcached
参数说明 -m 指定使用多少兆的缓存空间;-p 指定要监听的端口; -u 指定以哪个用户来运行
3、安装memcache PHP模块
# make
# make install
然后修改php.ini
把
extension_dir = "./"
修改为
extension_dir = "/usr/local/php/lib/php/extensions/"
并添加一行
extension=memcache.so
3、测试脚本
自己写一个PHP程序测试一下吧
本文只介绍memcached的PHP的API,想查看其他关于Memcached的API文档案,请访问 http://www.danga.com/memcached/
1、安装Memcached
2、安装memcache PHP模块
3、测试脚本
一、环境需求
安装Memcached需要libevent库的支持,所以请在安装Memcached之前检查有没有安装libevent。测试环境还需要PHP的支持,本文假设PHP已经安装到/usr/local/php目录下,也就是在编译PHP的时候使用perfix参数指定目录(--prefix= /usr/local/php)
二、下载相关软件
Memcached下载地址 http://www.danga.com/memcached/
memcache PHP模块下载地址 http://pecl.php.net/package/memcache 推荐使用1.5版
libevent 下载地址 http://www.monkey.org/~provos/libevent/
# tar vxzf libevent-1.1a.tar.gz
# cd libevent-1.1a
# ./configure
# make
# make install
建立一个符号连接:#ls -s /usr/local/lib/libevent-1.1.so.1 /usr/lib
# cd libevent-1.1a
# ./configure
# make
# make install
建立一个符号连接:#ls -s /usr/local/lib/libevent-1.1.so.1 /usr/lib
2、安装Memcached
# tar vxzf memcached-1.1.12.tar.gz
# cd memcached-1.1.12
# ./configure --prefix=/usr/local/memcached
--with-libevent=/usr
# make
# make install
# cd /usr/local/php/modules/memcached/bin
# ./memcached -d -m 50 -p 11211 -u root
# cd memcached-1.1.12
# ./configure --prefix=/usr/local/memcached
--with-libevent=/usr
# make
# make install
# cd /usr/local/php/modules/memcached/bin
# ./memcached -d -m 50 -p 11211 -u root
参数说明 -m 指定使用多少兆的缓存空间;-p 指定要监听的端口; -u 指定以哪个用户来运行
3、安装memcache PHP模块
# tar vxzf memcache-2.0.4.tgz
# cd memcache-2.0.4
# /usr/local/php/bin/phpize
#./configure --with-php-config=/usr/local/php/bin/php-config
--with-apxs=/usr/local/apache/bin/apxs
--with-gettext
--enable-socket
--enable-memcache
--enable-sysvshm
--enable-shmop
# cd memcache-2.0.4
# /usr/local/php/bin/phpize
#./configure --with-php-config=/usr/local/php/bin/php-config
--with-apxs=/usr/local/apache/bin/apxs
--with-gettext
--enable-socket
--enable-memcache
--enable-sysvshm
--enable-shmop
# make
# make install
然后修改php.ini
把
extension_dir = "./"
修改为
extension_dir = "/usr/local/php/lib/php/extensions/"
并添加一行
extension=memcache.so
3、测试脚本
自己写一个PHP程序测试一下吧
<?
$memcache = new Memcache; //创建一个memcache对象
$memcache->connect('localhost', 11211) or die ("Could not connect"); //连接Memcached服务器
$memcache->set('key', 'test'); //设置一个变量到内存中,名称是key 值是test
$get_value = $memcache->get('key'); //从内存中取出key的值
echo $get_value;
?>
$memcache = new Memcache; //创建一个memcache对象
$memcache->connect('localhost', 11211) or die ("Could not connect"); //连接Memcached服务器
$memcache->set('key', 'test'); //设置一个变量到内存中,名称是key 值是test
$get_value = $memcache->get('key'); //从内存中取出key的值
echo $get_value;
?>
原文链接:http://php-fpm.anight.org/
翻译链接 http://syre.blogbus.com/logs/20092011.html
fast-cgi是做啥用的
FastCGI是一个可伸缩的,高速地在web server和脚本语言间交互的接口。关于FastCGI技术的更多信息可以在官方网站和这里看到。
多数流行的web server都支持FastCGI。包括Apache(mod_fastcgi和mod_fcgid),Zeus,nginx和lighttpd。
FastCGI的主要优点是把动态语言和web server分离开来。这种技术允许把web server和动态语言运行在不同的主机上,以大规模扩展和改进安全性而不损失生产效率。
php-fpm可以和任何支持远端FastCGI的web server工作。
php-fpm是做啥用的
很不幸,官方网站php.net上的php在将FastCGI SAPI用于生产环境时有许多已知的问题。
下面的一些证据足以表明为什么离开了php-fpm,就很难使用FastCGI SAPI。
描述 php自带的 spawn-fcgi + spawn-php.sh + daemontools php-fpm php守护程序: pid file, log file, setsid(), setuid(), setgid(), chroot() (-) (+) (+) 进程控制,可以平滑地重启、重新载入配置和二进制模块而不丢失请求 php4 - php5 只能平滑停止 (-) (+) 限制ip地址,可以满足web server的要求 php4 (-) php5 (+) (从 5.2.2 开始) (-) (+) 根据负载动态调整进程数 (-) (-) Todo 使用用不同的uid / gid / chroot / 环境变量,不同的 php.ini 选项,不需要safe mode (-) (-) (+) 记录work process的stdout和stderr (-) (-) (+) 如果使用优化器,在遇到opcode缓存随机损坏的时候紧急重启所有进程 (-) (-) (+) 如果set_time_limit没有起作用,强制结束过期进程 (-) (-) Todo 特色功能 Error header、优化的上传支持、fastcgi_finish_request()
特色功能
所有的这些功能都是用不打断的方式。也就是说,如果你不使用他们,他们的存在不会影响php的功能,也就是透明的。
Error header
类型:方便
默认情况下,如果被访问的php脚本包含语法错误,用户会收到一个空的"200 ok"页。这是不方便的。Error header这个php.ini选项允许在这种情况下产生一个HTTP错误码,比如"HTTP/1.0 550 Server Made Big Boo",从而中断web server请求并显示一个正确的错误页。如果要实现这样的功能,需要在php.ini中添加一条fastcgi.error_header = "HTTP/1.0 550 Server Made Big Boo"
在php-5.2.4中添加了类似的功能,不过是简化的。如果被访问的php脚本包含语法错误,并且display_errors设为false, 且没有进一步的设置,会立刻返回"HTTP/1.0 500 Internal Server Error"。如果你需要设定一个不同于500的错误码(已经在许多情况下被使用)。或者想要使这个行为独立于display_errors的设置,那么 可以使用fastcgi.error_header。如果你同时使用php-5.2.5或以上版本和php-fpm,那么 fastcgi.error_header的优先级更高。
优化的上传支持
类型:优化
这个特性,就如标题那样,可以加速大POST请求的处理速度,包括文件上传。优化是通过确保请求体已写入一个临时文件,然后传递文件名而不是请求体 到fastcgi协议来实现的。目前,就我所知,只有nginx0.5.9以上才支持这个功能。显然,这种模式只在php和web server在一台机器上的时候才能用。
nginx样例配置:
location ~ \.php$ {
fastcgi_pass_request_body off;
client_body_in_file_only clean;
fastcgi_param REQUEST_BODY_FILE $request_body_file;
...
fastcgi_pass ...;
}
在php中不需要配置任何东西。如果php收到了参数REQUEST_BODY_FILE,就读取其中的请求体,如果没有,就自行从fastcgi协议中读取请求体。
结合这个特性,可以考虑对临时文件使用内存文件系统,例如tmpfs(linux):
client_body_temp_path /dev/shm/client_body_temp;
fastcgi_finish_request()
类型:优化
这个特性可以提高php处理请求的速度。如果有些处理可以在页面生成完后进行,就可以使用这种优化。比如,在memcached中保存 session就可以在页面交给web server后进行。fastcgi_finisth_request(),这一特性可以结束响应输出,web server可以立即开始交给等不及的客户端,而此刻,php可以在请求的上下文环境中处理许多事情。比如保存session,转换上传的视频,处理统计 等等。
fastcgi_finisth_request()会触发shutdown 函数运行。
FAQ
Q:php-fpm可以和ZendOptimize一起用吗?
A:完全可以。
Q:php-fpm可以和ZendPlatform、xcache、eAccelerator、APCden等等的优化器一起用吗?
A:是的。php-frpm的架构和任何一种用于高速opcode缓存的共享内存都适用。唯一的限制是:所有的worker进程只能适用一个缓存,即使它们用不同的uid/gid运行。
Q:为什么要用root运行php-fpm呢?这安全吗?
A:用root启动php-fpm只有在你打算用不同uid/gid的 php来处理请求时才有意义意。比如,在共享主机上的不同站点。因为只有在master进程用root运行的时候,才可以建立不同uid/gid的子进 程。这是相当安全的。master进程自己从来不会去处理请求。
在任何情况下,php-fpm都不会用root身份来处理请求。
Q:php-fpm可以加速请求处理速度吗?
A:不,没有影响。不过,如果你使用一些特殊特性,对于一些特定的请求可以有些许性能提升。
Q:php-fpm将来会被官方的php包含吗?
A:我很尊重php开发团队和他们的工作。相信他们能做得完美。但不幸的是,就我的经历看来,他们太忙了,似乎讨论php-fpm这个补丁会用相当多的时间,而我则完全没时间。
简要说明:
php-fpm是根据最小惊奇原则构建的。这是对于缺乏文档的唯一理由。我保证很快会建立一个wiki。如果你有问题的话,请不要犹豫在上面列出的邮件组里写邮件。
php-fpm已经在linux、macosx、Solaris和freebsd上测试通过。
确信libxml2(在某些系统上叫做libxml2-devel)已经安装。
下载php和php-fpm
$ bzip2 -cd php-5.2.5.tar.bz2 | tar xf -
$ gzip -cd php-5.2.5-fpm-0.5.7.diff.gz | patch -d php-5.2.5 -p1
$ cd php-5.2.5 && ./configure --enable-fastcgi --enable-fpm
$ make all install
编辑$prefix/etc/php-fpm.conf
运行$prefix/bin/php-cgi --fpm
检查$prefix/logs/php-fpm.log的细节
运行phpinfo()检查你的网站是否正常
master进程的pid被存放在$prefix/logs/php-fpm.pid
master进程可以理解以下信号:
SIGINT, SIGTERM 直接终止
SIGQUIT 平滑终止
SIGUSR2 平滑重载所有worker进程并重新载入配置和二进制模块
译注:创建补丁后,会产生一个补丁文件。在./configuire后会提示你打上。configure比较费时,如果直接打上补丁再./configure可以省些时间。
php-fpm还带有一个更方便的脚本,在$prefix/sbin/php-fpm。可以用php-fpm start|graceful|restart|stop来维护。稍编辑一下就可以让它使用配置文件。
翻译链接 http://syre.blogbus.com/logs/20092011.html
fast-cgi是做啥用的
FastCGI是一个可伸缩的,高速地在web server和脚本语言间交互的接口。关于FastCGI技术的更多信息可以在官方网站和这里看到。
多数流行的web server都支持FastCGI。包括Apache(mod_fastcgi和mod_fcgid),Zeus,nginx和lighttpd。
FastCGI的主要优点是把动态语言和web server分离开来。这种技术允许把web server和动态语言运行在不同的主机上,以大规模扩展和改进安全性而不损失生产效率。
php-fpm可以和任何支持远端FastCGI的web server工作。
php-fpm是做啥用的
很不幸,官方网站php.net上的php在将FastCGI SAPI用于生产环境时有许多已知的问题。
下面的一些证据足以表明为什么离开了php-fpm,就很难使用FastCGI SAPI。
描述 php自带的 spawn-fcgi + spawn-php.sh + daemontools php-fpm php守护程序: pid file, log file, setsid(), setuid(), setgid(), chroot() (-) (+) (+) 进程控制,可以平滑地重启、重新载入配置和二进制模块而不丢失请求 php4 - php5 只能平滑停止 (-) (+) 限制ip地址,可以满足web server的要求 php4 (-) php5 (+) (从 5.2.2 开始) (-) (+) 根据负载动态调整进程数 (-) (-) Todo 使用用不同的uid / gid / chroot / 环境变量,不同的 php.ini 选项,不需要safe mode (-) (-) (+) 记录work process的stdout和stderr (-) (-) (+) 如果使用优化器,在遇到opcode缓存随机损坏的时候紧急重启所有进程 (-) (-) (+) 如果set_time_limit没有起作用,强制结束过期进程 (-) (-) Todo 特色功能 Error header、优化的上传支持、fastcgi_finish_request()
特色功能
所有的这些功能都是用不打断的方式。也就是说,如果你不使用他们,他们的存在不会影响php的功能,也就是透明的。
Error header
类型:方便
默认情况下,如果被访问的php脚本包含语法错误,用户会收到一个空的"200 ok"页。这是不方便的。Error header这个php.ini选项允许在这种情况下产生一个HTTP错误码,比如"HTTP/1.0 550 Server Made Big Boo",从而中断web server请求并显示一个正确的错误页。如果要实现这样的功能,需要在php.ini中添加一条fastcgi.error_header = "HTTP/1.0 550 Server Made Big Boo"
在php-5.2.4中添加了类似的功能,不过是简化的。如果被访问的php脚本包含语法错误,并且display_errors设为false, 且没有进一步的设置,会立刻返回"HTTP/1.0 500 Internal Server Error"。如果你需要设定一个不同于500的错误码(已经在许多情况下被使用)。或者想要使这个行为独立于display_errors的设置,那么 可以使用fastcgi.error_header。如果你同时使用php-5.2.5或以上版本和php-fpm,那么 fastcgi.error_header的优先级更高。
优化的上传支持
类型:优化
这个特性,就如标题那样,可以加速大POST请求的处理速度,包括文件上传。优化是通过确保请求体已写入一个临时文件,然后传递文件名而不是请求体 到fastcgi协议来实现的。目前,就我所知,只有nginx0.5.9以上才支持这个功能。显然,这种模式只在php和web server在一台机器上的时候才能用。
nginx样例配置:
location ~ \.php$ {
fastcgi_pass_request_body off;
client_body_in_file_only clean;
fastcgi_param REQUEST_BODY_FILE $request_body_file;
...
fastcgi_pass ...;
}
在php中不需要配置任何东西。如果php收到了参数REQUEST_BODY_FILE,就读取其中的请求体,如果没有,就自行从fastcgi协议中读取请求体。
结合这个特性,可以考虑对临时文件使用内存文件系统,例如tmpfs(linux):
client_body_temp_path /dev/shm/client_body_temp;
fastcgi_finish_request()
类型:优化
这个特性可以提高php处理请求的速度。如果有些处理可以在页面生成完后进行,就可以使用这种优化。比如,在memcached中保存 session就可以在页面交给web server后进行。fastcgi_finisth_request(),这一特性可以结束响应输出,web server可以立即开始交给等不及的客户端,而此刻,php可以在请求的上下文环境中处理许多事情。比如保存session,转换上传的视频,处理统计 等等。
fastcgi_finisth_request()会触发shutdown 函数运行。
FAQ
Q:php-fpm可以和ZendOptimize一起用吗?
A:完全可以。
Q:php-fpm可以和ZendPlatform、xcache、eAccelerator、APCden等等的优化器一起用吗?
A:是的。php-frpm的架构和任何一种用于高速opcode缓存的共享内存都适用。唯一的限制是:所有的worker进程只能适用一个缓存,即使它们用不同的uid/gid运行。
Q:为什么要用root运行php-fpm呢?这安全吗?
A:用root启动php-fpm只有在你打算用不同uid/gid的 php来处理请求时才有意义意。比如,在共享主机上的不同站点。因为只有在master进程用root运行的时候,才可以建立不同uid/gid的子进 程。这是相当安全的。master进程自己从来不会去处理请求。
在任何情况下,php-fpm都不会用root身份来处理请求。
Q:php-fpm可以加速请求处理速度吗?
A:不,没有影响。不过,如果你使用一些特殊特性,对于一些特定的请求可以有些许性能提升。
Q:php-fpm将来会被官方的php包含吗?
A:我很尊重php开发团队和他们的工作。相信他们能做得完美。但不幸的是,就我的经历看来,他们太忙了,似乎讨论php-fpm这个补丁会用相当多的时间,而我则完全没时间。
简要说明:
php-fpm是根据最小惊奇原则构建的。这是对于缺乏文档的唯一理由。我保证很快会建立一个wiki。如果你有问题的话,请不要犹豫在上面列出的邮件组里写邮件。
php-fpm已经在linux、macosx、Solaris和freebsd上测试通过。
确信libxml2(在某些系统上叫做libxml2-devel)已经安装。
下载php和php-fpm
$ bzip2 -cd php-5.2.5.tar.bz2 | tar xf -
$ gzip -cd php-5.2.5-fpm-0.5.7.diff.gz | patch -d php-5.2.5 -p1
$ cd php-5.2.5 && ./configure --enable-fastcgi --enable-fpm
$ make all install
编辑$prefix/etc/php-fpm.conf
运行$prefix/bin/php-cgi --fpm
检查$prefix/logs/php-fpm.log的细节
运行phpinfo()检查你的网站是否正常
master进程的pid被存放在$prefix/logs/php-fpm.pid
master进程可以理解以下信号:
SIGINT, SIGTERM 直接终止
SIGQUIT 平滑终止
SIGUSR2 平滑重载所有worker进程并重新载入配置和二进制模块
译注:创建补丁后,会产生一个补丁文件。在./configuire后会提示你打上。configure比较费时,如果直接打上补丁再./configure可以省些时间。
php-fpm还带有一个更方便的脚本,在$prefix/sbin/php-fpm。可以用php-fpm start|graceful|restart|stop来维护。稍编辑一下就可以让它使用配置文件。
1. 尽量采用大量的PHP内置函数。
2. echo 比 print 快。
3. 不要把方法细分得过多,仔细想想你真正打算重用的是哪些代码?
4. 在执行for循环之前确定最大循环数,不要每循环一次都计算最大值。
5. 注销那些不用的变量尤其是大数组,以便释放内存。
6. 并非要用类实现所有的数据结构,数组也很有用。
7. $row[‘id’]的效率是$row[id]的7倍。
8. 在包含文件时使用完整路径,解析操作系统路径所需的时间会更少。
9. 如果你想知道脚本开始执行(译注:即服务器端收到客户端请求)的时刻,使用$_SERVER[‘REQUEST_TIME’]要好于time()。
2. echo 比 print 快。
3. 不要把方法细分得过多,仔细想想你真正打算重用的是哪些代码?
4. 在执行for循环之前确定最大循环数,不要每循环一次都计算最大值。
5. 注销那些不用的变量尤其是大数组,以便释放内存。
6. 并非要用类实现所有的数据结构,数组也很有用。
7. $row[‘id’]的效率是$row[id]的7倍。
8. 在包含文件时使用完整路径,解析操作系统路径所需的时间会更少。
9. 如果你想知道脚本开始执行(译注:即服务器端收到客户端请求)的时刻,使用$_SERVER[‘REQUEST_TIME’]要好于time()。






