闻说Nginx向来有性能高、并发性强、占用内存少的优势,更有“反向代理”和“负载均衡”的特点。而使用Nginx+PHP作开发环境,性能更是比Apache+PHP高数倍。本文以各程序当前最新的版本为例,介绍在Windows(x64)下搭建Nginx+PHP+MySQL+phpMyAdmin经典开发环境的方法。
1. 应用软件包以初始路径设置
Nginx(当前最新1.7.9):http://nginx.org/download/;
PHP(当前最新5.6.6RC1):http://windows.php.net/qa/,选择VC11 x86 Thread Safe版本;
MySQL(当前最新5.6.23):http://dev.mysql.com/downloads/mysql,建议选择Windows (x86, 64-bit) ZIP Archive,也可使用Windows (x86, 64-bit) MySQL Installer MSI安装版;
phpMyAdmin(当前最新4.3.9):http://www.phpmyadmin.net/home_page/index.php;
RunHiddenConsole:本程序下载地址略;
假设所有应用的安装目录为C:Server,目录内文件夹结构如下图:(下面的教程将按照本目录中的文件夹名称作例)
2. 配置MySQL
本教程以Zip版的MySQL包为例,习惯使管理用界面MySQL的可以安装MSI版本,具体方法略。
解压Zip包,把MySQL所有文件复制到C:ServerMySQL中(此时C:ServerMySQL中应包含bin、data等文件夹);
运行cmd,进入MySQL目录:cd C:ServerMySQLin (保证当前目录在C盘下,否则使用cd ../命令返回C盘目录);
安装MySQL:MySQLd --install MySQL56
运行SQL:net start MySQL56
修改MySQL密码:MySQL -u root -p ;
正常情况下会出现Enter password:的内容,直接回车即可(密码为空),这时会出现mysql>的字样;
输入use mysql;后回车,显示Database changed;
输入UPDATE user SET password=PASSWORD('$pwd'), user='$user' WHERE user='root';后回车,其中$pwd和$user分别为自己定义的密码和用户名,输入后显示Query OK, 3 rows affected (0.00 sec),这时用户名及密码已修改;
输入flush privileges;后回车,刷新数据库。
此时数据库已配置完成,只要运行MySQL.exe就可以打开数据库了,为了方便,写几个.bat批处理作MySQL的安装、卸载、启动、停止操作:
install.bat:
cd C:ServerMySQLin
MySQLd --install MySQL56
uninstall.bat:sc delete MySQL56
start.bat:net start MySQL56
stop.bat:net stop MySQL56
将4个bat文件写好后,以后要执行相应的操作,直接执行bat程序就可以了。为了查看执行结果,可以在所有bat文件最后加一句pause。
3. 配置PHP
这里选择的php版本php-5.6.6RC1-Win32-VC11-x86。虽然PHP在Nginx下是FastCgi方式运行的,理论上配搭非线程安全(nts)版,但由于是在Windows环境下,还是选择线程安全版来保证其稳定性,而且经过测试,nts在连接数据库失败时(比如故意关闭MySQL服务而连接数据库),会出现php-cgi强退的现象,而线程安全版则能正常显示连接错误,因此还是用nts来保证稳定性比较好。
解压压缩包,把php5的文件复制到C:Serverphp下;
复制php.ini-development并命名新文件为php.ini(也可复制php.ini-produceion,前者用于开发而后者用于正式生产,看情况,初学者建议用development),打开php.ini;
在#736行,找到extension_dir = ,将前面的分号去掉并改为extension_dir = "C:Serverphpext",表示定义了extension的路径并生效;
在#704行,找到always_populate_raw_post_data = -1,将前面的分号去掉,表示此句生效(这个设置主要用于PHP中使用"php://input"获取post源数据);
在#927行,找到data.timezone = ,将前面的分号去掉并改为data.timezone=PRC,表示定义了时区并生效(用于PHP中date()、time()函数);
从#878行开始,选择自己需要的dll扩展模块并使其生效,常用的模块有以下:
php_curl.dll:用于curl模拟Http请求;
php_mysql和php_mysqli:用于mysql连接,mysql必选;
php_mbstring:用于支持各种编码,mysql必选;
php_openssl:用于https请求;
php_gd2:用于GD2图库相关函数;
在#773行,找到cgi.fix_pathinfo=1,将前面的分号去掉,表示此句生效;
针对5.5以上版本,还要将php目录下的"libeay32.dll", "ssleay32.dll", "libssh2.dll"三个dll文件复制到C:WindowsSystem32,x64系统还要复制到C:WindowssysWOW64,否则curl等一些函数库将无效。
PHP随Nginx运行,不需要单独启动,至此已配置完成。
4. 配置Nginx
Nginx配置与Apache原理一样,但是相对简单一些。
在#44行,改为root C:Serverlocalhost,表示网站的根目录位置;
在#45行,改为index index.html index.htm index.php,表示支持更多类型的默认首页;
在#65-#71行,把前面的井号去掉,表示配置生效,改为:
root C:Serverlocalhost;
fastcgi_pass 127.0.0.1:9000;
include fastcgi.conf;
其中,root为网站根目录,与#44行配置相同,fastcgi_pass为php绑定的端口,后面会介绍;
在#32行,加入fastcgi_intercept_errors on; ,表示将fastcgi(PHP)的错误交回Nginx处理;
在#48行,将error_page前的井号去掉,表示该配置生效,将404错误定向到/404.html页面上(或默认),否则访问不存在的php时只会显示no input file specified的文字,不会显示404。
此时Nginx也配置好了,可以试运行一下。
打开cmd,进入Nginx目录:cd C:ServerNginx;
启动Nginx:nginx
打开另一个cmd,进入php目录:cd C:Serverphp;
启动php:php-cgi -b 127.0.0.1:9000,此处127.0.0.1:9000则为fastcgi_pass绑定的地址和端口。
打开浏览器,进入127.0.0.1,发现网页出现403 Forbidden,因为C:Serverlocalhost下没有index首页,但可以证明Nginx+php已经运行起来了。
为了方便,依然可以写几个bat控制Nginx的开始和结束:(需要用到RunHiddenConsole)
start.bat:
cd C:ServerNginx
start Nginx
cd C:Server
RunHiddenConsole phpphp-cgi -b 127.0.0.1:9000
stop.bat:
taskkill /f /im Nginx.exe
taskkill /f /im php-cgi.exe
taskkill /f /im conhost.exe
5. 配置phpMyAdmin
解压phpMyAdmin压缩包后将文件复制到C:ServerlocalhostphpMyAdmin,注意现在暂时放在localhost中方便调试,打开librariesconfig.default.php:
在#252行,将$cfg['Servers'][$i]['user'] = 'root';中的root改为MySQL的用户名;
在#259行,在$cfg['Servers'][$i]['password'] = '';中输入MySQL的密码;
在#39行,在$cfg['PmaAbsoluteUri'] = '';中输入服务器的地址(本地服务器则http://127.0.0.1)
打开浏览器,进入http://127.0.0.1/phpMyAdmin/index.php,按照提示登录即可。
另外,如果在本地测试状态时,为了方便不用每次都输密码进入,可以这样:
在#230行,将$cfg['Servers'][$i]['auth_type'] = 'cookie';中的cookie改为config,这样下次访问index.php就直接登录了。
6. 建立虚拟目录
同样的,Nginx跟Apache一样也有虚拟目录的功能,如第1点中的目录结构,phpMyAdmin不在默认目录localhost中,但仍然可以用http://127.0.0.1/phpMyAdmin访问,虚拟目录提供了一个目录映射的功能。打开Nginx ginx.conf:
在location /{}后 (#47行位置)加入:
location /phpMyAdmin/ {
alias C:/Server/phpMyAdmin;
index index.php
}
location ~ ^/phpMyAdmin/(.*.php)$ {
alias C:/Server/phpMyAdmin/$1;
fastcgi_pass 127.0.0.1:9000;
include fastcgi.conf;
}
Nginx用alias表示目录映射关系,第一句location表示用/phpMyAdmin/表示Server/phpMyAdmin的实际路径,并用index.php表示默认路径;第二句表示匹配/phpMyAdmin/下以php为扩展名的文件,与php设置一样绑定127.0.0.1:9000端口。
打开浏览器进入127.0.0.1/phpMyAdmin/index.php,正常情况下可以登录到数据库(当然MySQL要启动)。
简单地解释一下Nginx+FastCGI的工作模式。Nginx不像Apache那样提供标准模块,所有外部程序的调用必须通过FastCFI接口(socket)来实现。所以PHP必须绑定在socket上,通过FastCGI与Nginx通信。当Nginx接收到请求后,通过FastCGI把请求转发到wrapper(绑定在该socket上,用于启动PHP程序),wrapper接收后产生一个新PHP线程,等待PHP处理后接收由脚本产生的数据,再通过FastCGI将数据传给Nginx。本例中,wrapper绑定在127.0.0.1:9000上,通过这个socket,Nginx可以和PHP交换数据。
现在做一个实例:打开localhost文件夹,在里面新建两个文件index.php,test.php。
在test.php中写:
<?php
echo 'test';
?>
在index.php中写:
<?php
echo file_get_contents("http://127.0.0.1/test.php");
?>
然后在浏览器中进入:http://127.0.0.1/index.php。
这个程序很简单,就是通过index.php请求本地的test.php,将test.php的输出结果在浏览器中输出。但是可以发现,程序每次都要读取40秒左右,而且会出现500的结果。在Apache中测试这个程序,发现不需1秒程序就会执行完,但在Nginx中却一直出现500的结果。
这个原因跟Nginx的FastCGI特性有关。引用这个实例,主要是引出Nginx的特点之一,负载均衡。这个实例的现象可以用负载均衡解决。至于负载均衡的意义,以及其具体实现方法,下一节将详细介绍。