最後更新: 2018-01-18
介紹
HomePage: https://wiki.apache.org/httpd/php-fcgid
* execute PHP scripts with the permissions of their owners instead of the Apache user.
* starts CGI program instances and these programs remain running to handle further incoming requests.
mod_php 的缺點:
* mod_php will be loaded into httpd's memory even when serving static pages
* mod_php forces you to load prefork (or worker)MPM
mod_fcgi Benefits:
* PHP runs into a separated process
* binary compatible alternative to mod_fastcgi.
* official Apache module
它與 suPHP 有極類似的功能
安裝
yum install mod_fcgid php-cli
把原來 Apache 的 php.conf backup 起佢
原來的 php.conf 內容:
# Centos6 Config <IfModule prefork.c> LoadModule php5_module modules/libphp5.so </IfModule> <IfModule worker.c> LoadModule php5_module modules/libphp5-zts.so </IfModule> AddHandler php5-script .php AddType text/html .php DirectoryIndex index.php AddType application/x-httpd-php-source .phps
/etc/php.ini
;Default is 1
cgi.fix_pathinfo = 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 its paths to conform to the spec.
A setting of zero causes PHP to behave as before.
You should fix your scripts to use SCRIPT_FILENAME rather than PATH_TRANSLATED.
http://www.php.net/manual/en/ini.core.php#ini.cgi.fix-pathinfo
fcgid.conf
Debian
/etc/apache2/mods-enabled/fcgid.conf
<IfModule mod_fcgid.c> AddHandler fcgid-script .fcgi FcgidConnectTimeout 20 </IfModule>
Centos6
/etc/httpd/conf.d/fcgid.conf
# 本身有的設定
LoadModule fcgid_module modules/mod_fcgid.so AddHandler fcgid-script fcg fcgi fpl # directory for AF_UNIX sockets to communicate with FastCGI applications FcgidIPCDir /var/run/mod_fcgid # shared memory on Unix to maintain state which is shared between httpd processes. FcgidProcessTableFile /var/run/mod_fcgid/fcgid_shm
# 追加 Setting, 令整 Server 行 CGI
# 可以在 Context: server config, virtual host, directory, .htaccess # 用 fcgi 去行 php AddHandler fcgid-script .php # FcgidWrapper command [ suffix ] # suffix argument restricts the use of this FCGI server to all URLs # A suffix needs to start with '.' FcgidWrapper /usr/bin/php-cgi .php # 在 php.ini 的 cgi.fix_pathinfo=1 時, 這裡都要 1 # allows PHP to provide additional path information "SCRIPT_NAME" FcgidFixPathinfo 1 # Basic Setting AddType text/html .php AddType application/x-httpd-php-source .phps DirectoryIndex index.php index.html index.htm # 所有地方都行到 CGI <Location /> # Allow execution of CGI scripts. Options +ExecCGI </Location>
Checking
在 <?php phpinfo ?> 的顯示:
由
Server API Apache 2.0 Handler
變成了
Server API: CGI/FastCGI
Apache per VirtualHost 設定
在 /etc/httpd/conf.d 內由於 php.conf 比 fcgid.conf 排後,
所以 Default 所有Website 都是用 mod_php 的
如果要個別 host 用 mod_fcgid, 那只需要在 vhost 內加以以下兩句
vhosts.conf
<VirtualHost *:80> <Directory ... > ... Options +ExecCGI ... </Directory> # fcgid AddHandler fcgid-script .php FcgidWrapper /usr/bin/php-cgi .php </VirtualHost>
php.conf
<FilesMatch \.php$> SetHandler application/x-httpd-php </FilesMatch>
To
AddHandler php5-script .php
fcgid.conf 進階設定
Timeout value
# Default: 3 # trying to connect to a FastCGI application FcgidConnectTimeout 2 # trying to read from or write to a FastCGI application. # 當 Over 了 40 秒後, Server 會見到以下的 log # [Fri Jul 11 10:23:23 2014] [warn] [client x.x.x.x] mod_fcgid: read data timeout in 40 seconds # [Fri Jul 11 10:23:23 2014] [error] [client x.x.x.x] Premature end of script headers: index.php # 此 setting 相當於 "max_execution_time" 及 "max_input_time" FcgidIOTimeout 40 # maximum time limit for request handling # The purpose of this directive is to terminate hung applications. FcgidBusyTimeout 300
Processes Management
# 同時有多少個 php-cgi 在行 # Default: 1000 ?! FcgidMaxProcesses 10 # Maximum requests a process handles before it is terminated MaxRequestsPerProcess 1000 # Idle application processes which have existed for greater than this time will be terminated # 每 FcgidIdleScanInterval(120) 查看一次有沒有 Idle proccess FcgidProcessLifeTime 3600 # Number of seconds of idle time before a process is terminated # Proccess 數量大於 FcgidMinProcessesPerClass 才觸發 FcgidIdleTimeout 240 ######################################## ProcessesPerClass # number of processes that will be retained in a process class after finishing requests FcgidMinProcessesPerClass 3 FcgidMaxProcessesPerClass 100
Process Class
A process class is the set of processes
which were started with the same executable file and
share certain other characteristics such as virtual host and identity
Buffer
# Default: 65536 <-- 64k # 當 request body 超過這數後, 其餘的會保存在 temporary file. FcgidMaxRequestInMem 65536 # response data the module will read from the FastCGI application before flushing the data to the client. FcgidOutputBufferSize 65536
Upload File
# body exceeds this amount => 500 Server Error
# Default: 131072 bytes <-- 128 kbyte
# MaxRequestLen <-- 舊名稱
# unit bytes, 10485760 = 10 Mbyte
FcgidMaxRequestLen 10485760
Wrapper script
Used by mod_fcgid to launch php-cgi processes.
Usage:
FcgidWrapper command [ suffix ]
* command: The given command is used to spawn FCGI server processes.
* suffix: argument restricts the use of this FCGI server to all URLs with the given exact path suffix.
i.e.
FcgidWrapper /home/vhosts/fcgid/mywebsite-wrapper
chmod +x mywebsite-wrapper
File: /home/vhosts/fcgid/website-wrapper
# wrapper script to invoke PHP
# Set desired PHP_FCGI_* environment variables.
# PHP FastCGI processes exit after 1000 requests by default.
# When that occurs, an error will be logged and 500 Internal Server Error will be returned to the client.
PHP_FCGI_MAX_REQUESTS=1000
export PHP_FCGI_MAX_REQUESTS
exec /usr/bin/php-cgi
FcgidCmdOptions
# options to be specified for a specific command spawned by mod_fcgid.
# server config, virtual host
Syntax: FcgidCmdOptions command option [option]
* Multiple environment variables are defined by repeating the InitialEnv option.
Example:
# mod_fcgid will terminate it after it(wrapper) has handled 2000 requests FcgidCmdOptions /usr/local/bin/wrapper \ InitialEnv MAX_REQUESTS=2000 \ MaxRequestsPerProcess 2000 \ IOTimeout 90
- ConnectTimeout seconds
- IdleTimeout seconds
- IOTimeout seconds
- MaxProcesses value
- MaxProcessLifeTime seconds
- MaxRequestsPerProcess value
- MinProcesses value
Testing result
apache:
apache + xcache:
mod_fcgid:
Troubleshoot
<1>
Page Forbidden
解決
Options .... FollowSymLinks ....
<2>
Invalid command 'php_admin_value', perhaps misspelled or defined by a module not included in the server configuration Action 'configtest' failed.
PHP 使用 HTTP_AUTHORIZATION Login
在 Server API: CGI/FastCGI 情況下使用它 # phpinfo
實現
Assign the username/pass pairs to an environment variable named HTTP_AUTHORIZATION
To setting an HTTP_AUTHORIZATION environment variable to the value of the Authorization HTTP request header
在 .htaccess 內加入
<IfModule mod_fcgid.c> # Checking if the HTTP Authorization header exists and has a value RewriteCond %{HTTP:Authorization} . # .* is a regular expression that matches any request. # The - means that the URL should not be changed. # Sets an environment variable HTTP_AUTHORIZATION with the value of the HTTP Authorization header RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}] </IfModule>
Test Code
<?php
if (!isset($_SERVER['PHP_AUTH_USER'])) {
header('WWW-Authenticate: Basic realm="My Realm"');
header('HTTP/1.0 401 Unauthorized');
echo 'Text to send if user hits Cancel button';
exit;
} else {
echo "<p>Hello {$_SERVER['PHP_AUTH_USER']}.</p>";
echo "<p>You entered {$_SERVER['PHP_AUTH_PW']} as your password.</p>";
}
?>
PHP_FCGI_CHILDREN
PHP child process management (PHP_FCGI_CHILDREN) should always be disabled with mod_fcgid,
which will only route one request at a time to application processes it has spawned;
thus, any child processes created by PHP will not be used effectively. (Additionally, the PHP child processes may not be terminated properly.)
By default, and with the environment variable setting PHP_FCGI_CHILDREN=0, PHP child process management is disabled.
phpmyadmin 的設定
Alias /phpmyadmin /usr/share/phpMyAdmin
ScriptAlias
ScriptAlias /cgi-bin/ /web/cgi-bin/
相當於
Alias /cgi-bin/ /web/cgi-bin/ <Location /cgi-bin > SetHandler cgi-script Options +ExecCGI </Location> <Directory /usr/share/phpMyAdmin/> Options +ExecCGI Deny from All Allow from 127.0.0.1 </Directory>
/etc/phpMyAdmin/config.inc.php
// Authentication method (config, http or cookie based)? $cfg['Servers'][$i]['auth_type'] = 'http';
cookie:
When using the cookie authentication (the default), the mcrypt extension is strongly suggested.
supports a wide variety of block algorithms such as DES
# pass authentication variable to CGI using following rewrite rule:
RewriteEngine On # 當有其他 rule 時, 不要加 ",L" !! RewriteRule .* - [E=REMOTE_USER:%{HTTP:Authorization}]
config:
<IfModule mod_fcgid.c> RewriteEngine On RewriteRule .* - [E=REMOTE_USER:%{HTTP:Authorization}] <Directory /usr/share/phpMyAdmin/> Options +ExecCGI Deny from All Allow from 127.0.0.1 </Directory> </IfModule>
P.S.
Server-Variables: These are variables of the form %{ NAME_OF_VARIABLE }
php-cgi 的 php.ini
link: http://datahunter.org/php.ini#php-cgi_php.ini
event apache
init───apache2─┬─apache2───2*[php-cgi] ├─apache2───65*[{apache2}] └─apache2───17*[{apache2}]
Doc
http://httpd.apache.org/mod_fcgid/mod/mod_fcgid.html