Windows下搭建PHP本地开发环境
一直以来,我都是使用新浪的SAE作为我本地的PHP开发环境。SAE使用起来非常方便,是个纯绿色的软件包,可以从这里下载,使用之前首先配置sae.conf
文件中的DocumentRoot
参数为网站根目录(也就是你PHP开发的目录),然后运行init.cmd
脚本即可(Win7以上系统可能需要以管理员身份运行)。 我将SAE作为我的本地开发环境,官方的SAE只包含了PHP、Apache和Redis,而我的生产环境是PHP + Nginx + MySQL。这样不仅需要安装MySQL,而且不能和生产环境的Nginx保持一致,导致很多生产上的Nginx重写规则,在本地要再写一份Apache版的,虽然差异不大,但是依然感觉很麻烦。所以就想打造一个自己的PHP开发环境,像SAE一样绿色版,并且支持Apache和Nginx两个服务器。
一、搭建步骤
我们按PHP、Apache和Nginx的顺序来搭建PHP的本地开发环境,MySQL没有包含其中,以后有机会再做。这次的重点是学习Apache和Nginx的配置以及PHP是怎么和这两大Web服务器交互的。
1.1 PHP
首先,我们在这里下载PHP的Windows版本,我们直接下载编译好的Zip包即可。这里要特别注意的是,PHP for Windows有多种不同的版本,VC9和VC11,TS和NTS,x86和x64等。
- VC9 vs VC11:代表使用哪个VS版本编译的,VC9表示Visual Studio 2008,VC11表示Visual Studio 2012
- TS vs NTS:TS代表线程安全,也就是说支持多线程,PHP以模块形式加载到Web服务器中需要使用TS;NTS代表只支持单线程,在CLI/CGI/FastCGI等模式下建议使用NTS
- x86 vs x64:使用32位还是64位,x64目前是实验版本
综上所述,这里我们选择PHP 5.6 (5.6.9) VC11 x86 Thread Safe。
1.2 Apache
Apache官网上并没有提供Windows上的可执行文件供下载,而是只提供了源码和编译安装步骤。我们这里省去编译可能会带来的问题和麻烦,直接使用第三方编译好的可执行文件。我们有很多不同的选择,下面是Apache官方提供的选择列表:
这里我们使用Apache Lounge提供的httpd-2.4.12-win32-VC11.zip,这是因为上面提到的PHP中一些SAPI就是使用Apache Lounge提供的二进制文件来编译的。注意选择和上面PHP一样的VC11和32位版本。
1.3 Nginx
比较流行的Nginx for Windows有两种不同的版本,一种是官方提供的使用native Win32 API的原生版本,另一种是利用Cygwin模拟编译出来的版本。这里我们选择原生版本。
二、PHP的两种配置方式
将可执行文件都下下来之后,我们就需要对其进行配置了。首先我们以下图所示结构对刚下载的软件包进行组织:
webserver
目录用于存放Web服务器的二进制文件,譬如Apache和Nginx,之后可以添加lighttpd,IIS等;database
目录用于存放数据库相关文件,譬如MySQL、Redis和Memcached等;interpreter
目录用于存放脚本解析文件,如PHP、Perl、Python等。 PHP一般有两种配置方式:一种方式是以Apache的模块mod_php
运行在Apache服务器中,这种方式最传统最著名,历史也最为悠久,在Nginx服务器没流行起来的时代,Apache统治了Web服务器的绝大部分,当时几乎都是以mod_php
方式来配置的。这种配置方式虽然简单而且运行效率很高,但是这种配置不够灵活,导致Web服务器臃肿,也导致Apache服务器会占用更多的内存。于是出现了第二种配置方式CGI/FastCGI
,CGI由于其效率低下已经基本上被FastCGI替代了。这种配置方式将Web服务器和PHP解析器解耦分离开来,PHP和Web服务器使用两个进程,甚至可以运行在两个不同服务器上,两者之间通过CGI/FastCGI协议进行通信。关于CGI/FastCGI/PHP-FPM的资料网上有很多,可以参考这里、这里和这里了解下。关于PHP的两种配置方式可以参考这里、这里和这里。 下面我们就以这两种方式分别来配置我们刚下载的Apache和Nginx。
2.1 mod_php
Apache支持以模块的方式来配置PHP,这个模块就是mod_php5.so
,要注意的是mod_php
是Linux下的名称,在Windows下的名称是php5apache2_4.dll
。php5apache2_4.dll
这个文件只包含在TS版的PHP打包中,如果你下载的是NTS版的可能找不到这个文件,因为Apache以模块形式载入PHP需要保证其是线程安全的。Nginx暂时还不支持这种配置方式。 参考PHP官方文档,我们在webserver\Apache-2.4\conf\httpd.conf
文件中加入下面的代码来完成配置:
#
# mod_php
#
LoadModule php5_module "full-path-of-php5apache2_4.dll"
PHPIniDir "full-path-of-php.ini-dir"
AddType application/x-httpd-php .php
确保配置文件中的ServerRoot
和DocumentRoot
路径正确,然后运行webserver\Apache-2.4\bin\httpd.exe
即可。可以在htdocs
目录下新建一个PHP文件,使用phpinfo()
方法来确保PHP和Apache已经正确运行。
2.2 CGI / FastCGI / PHP-FPM
在Windows环境下通过CGI方式解析PHP脚本一般使用的是PHP自带的php-cgi.exe
程序。该程序运行方式如下:
php-cgi.exe -b 127.0.0.1:9000 -c path/to/php.ini
一旦按上面的方式运行php-cgi.exe
程序之后就可以通过9000端口使用CGI协议来和它进行通信解析PHP脚本了。然后我们参考这里,在Nginx的配置文件中配上下面的代码(Nginx的配置文件位于webservernginx-1.9.0confnginx.conf):
#
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
location ~ \.php$ {
root html;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
配置好了以后,运行webserver\nginx-1.9.0\nginx.exe
即可。在html
目录下新建一个PHP文件,使用phpinfo()
方法确保PHP和Nginx正确运行。可以看到mod_php
方式配置简单,而且只要运行Web服务器即可,FastCGI
方式不仅要运行Web服务器,还要运行FastCGI解析程序。 当然不仅仅是Nginx支持FastCGI这种配置方式,几乎所有其他的Web服务器都支持这种配置方式,譬如:Apache、IIS和lighttpd等。如果你想在Apache上使用这种配置,可以使用mod_fcgid
扩展模块,在httpd.conf
配置文件中添加如下代码:
#
# fast_cgi
#
LoadModule fcgid_module modules/mod_fcgid.so
FcgidInitialEnv PHPRC "c:/php"
FcgidWrapper "c:/php/php-cgi.exe" .php
AddHandler fcgid-script .php
另外要提出的一点是,这里不管是mod_php
方式还是FastCGI
方式,我们都使用的是PHP的线程安全(TS)版本。而一般推荐做法是mod_php
使用多线程(TS)版本,FastCGI
使用单线程(NTS)版本,使用NTS版本不仅可以提高性能,也是为了和PHP的扩展(有很多PHP扩展是非线程安全的)保持兼容。
2.3 总结
为了方便,我写了两个批处理程序来启动Apache和Nginx。完整的版本可以看这里。 start-apache.bat
文件:
@echo off
set APACHEROOT="path/to/webserver/Apache-2.4"
set PHPROOT="path/to/interpreter/php-5.6.9"
echo Starting Apache...
copy "%APACHEROOT:~1,-1%\conf\httpd.conf.bak" "%APACHEROOT:~1,-1%\conf\httpd.conf" /Y
utils\fnr.exe --cl --dir "%APACHEROOT:~1,-1%\conf" --fileMask "httpd.conf" --find "
start-nginx.bat
文件:
@echo off
set NGINXROOT="path/to/webserver/nginx-1.9.0"
set PHPROOT="path/to/interpreter/php-5.6.9"
echo Starting PHP FastCGI...
utils\RunHiddenConsole "%PHPROOT:~1,-1%\php-cgi.exe" -b 9000 -c "%PHPROOT:~1,-1%\php.ini-development"
echo Starting Nginx...
utils\RunHiddenConsole "%NGINXROOT:~1,-1%\nginx.exe" -p "%NGINXROOT:~1,-1%"
pause
三、PHP SAPI
上面介绍了PHP的两种不同的配置方式,这两种配置都可以使PHP工作,实现这一点其实要归功于PHP的SAPI
。SAPI(Server Application Programming Interface)是服务器应用编程接口的缩写,PHP通过SAPI
提供了一组接口供应用和PHP内核之间进行数据交互。PHP提供很多种形式的接口,包括apache、apache2filter、apache2handler、cgi 、cgi-fcgi、cli、cli-server、embed、isapi、litespeed
等等。但是常用的只有5种形式,CLI/CGI
(单进程)、Multiprocess
(多进程,PHP可以编译成Apache下的prefork MPM
模式和APXS
模块)、Multithreaded
(多线程,Apache2的Worker MPM
模块)、FastCGI
和Embedded
(内嵌)。可以使用PHP的php_sapi_name()
函数获取当前的SAPI接口类型。参考这里和这里了解更多。另外在简明现代魔法上有一个系列的文章对SAPI进行了详细的介绍:
- PHP内核探索:从SAPI接口开始
- PHP内核探索:一次请求的开始与结束
- PHP内核探索:一次请求生命周期
- PHP内核探索:单进程SAPI生命周期
- PHP内核探索:多进程/线程的SAPI生命周期
- PHP内核探索:Zend引擎
- PHP内核探索:再次探讨SAPI
- PHP内核探索:Apache模块介绍
- PHP内核探索:通过mod_php5支持PHP
- PHP内核探索:Apache运行与钩子函数
- PHP内核探索:嵌入式PHP
- PHP内核探索:PHP的FastCGI
- PHP内核探索:如何执行PHP脚本
- PHP内核探索:PHP脚本的执行细节
参考
- PHP For Windows
- Using Apache HTTP Server on Microsoft Windows
- Apache Lounge
- nginx for Windows
- 什么是CGI、FastCGI、PHP-CGI、PHP-FPM、Spawn-FCGI?
- 概念了解:CGI,FastCGI,PHP-CGI与PHP-FPM
- 搞不清FastCgi与PHP-fpm之间是个什么样的关系
- mod_php vs FastCGI vs PHP-FPM
- [[好文]mod_php和mod_fastcgi和php-fpm的介绍,对比,和性能数据](http://wenku.baidu.com/view/887de969561252d380eb6e92.html)
- mod_php和mod_fastcgi(待整理)
- Microsoft Windows 下的 Apache 2.x
- php-fcgi on Windows
- windows下配置nginx+php环境
- Thread Safe PHP with FastCGI on IIS 7 or not?
- 【问底】王帅:深入PHP内核(二)——SAPI探究
- 第二章 » 第二节 SAPI概述 | TIPI: 深入理解PHP内核