This post is an ongoing work in progress stating the known factors and problems with Shared Hosting, WordPress, FastCGI, .user.ini files, Zend and PHP5.3.x and of course newer versions of PHP.
Update – 4-1-2013: It appears that most web hosts are not choosing to use FastCGI and .user.ini files instead of php.ini files by default for PHP5.3.x and higher versions. I assume this is because of the known problematic issues that come with FastCGI and PHP applications such as WordPress, Joomla, etc. In regards to BPS Pro directly I have noticed that using the automated P-Security php.ini tools to create custom php.ini files causes the custom php.ini file to be ignored/rejected or worse. At this time the best method to create a custom php.ini file if your PHP Server version is 5.3.x or higher is to manually create the custom php.ini file using the setup steps in this Forum Topic: http://forum.ait-pro.com/forums/topic/custom-php-ini-file-setup-php5-3-x/.
To simplify this setup a new tool will be added to P-Security that will copy the Server’s Default php.ini file to the Document Root folder. Manually editing of the custom php.ini file will still be required since automating this process causes the Server to reject/ignore the custom php.ini file, but a simpler manual editing method will created when the new tool is created in P-Security. Pending for BPS Pro 5.8.
Real World Scenario/Problems for a website on Shared Hosting, using PHP5.3.x and not using FastCGI
The ini_set function offers a very limited amount of directive settings that can be changed using ini_set. Several php.ini options that will allow a website owner to significantly increase their website security cannot be changed/set using ini_set. zend_extensions and extensions cannot be changed/set using ini_set, which means the user could not add things such as the ionCube Loader using ini_set. Max file upload size also cannot be changed/set using ini_set, which means the user cannot change or control whether file uploads are allowed or not and also change the max upload file size limit for file uploads. Would the website owner need to call their web host in order to increase the max file upload size limit? And would the web host perform such a request?
GoDaddy has FastCGI integrated into PHP5.3.x by default and has configured the Server to still allow php.ini files to be recognized on the website owner’s website when using PHP5.3.x. So a .user.ini file would not be required, which is the typical requirement for PHP5.3.x. So the question remains is the FcgidMaxRequestLen directive set to the default setting of 128Kb / 131072 bytes or is it set to a higher limit.
Possible Long Term Web Host Solution to the FastCGI, PHP5.3.x problem on Shared Hosting
It looks like a possible long term solution is available and would require that Hosts include FcgidMaxRequestLen 33554432 (or other similar and relevant size settings) as a standard setting in the Server’s httpd.conf file for Shared Hosting. This of course places the burden on the Host to make this change. I have not personally tested this, but it appears to be a logical working solution.
Previous Conclusion: Overall what I see is that either WordPress website owners will have to completely sacrifice the capability to be able to change ALL directive settings (an alternative solution using ini_set in the wp-config.php file (see below examples) allows setting most directive settings) for their websites if they are using PHP5.3.x and newer versions of PHP if they do not choose FastCGI. The problem with choosing FastCGI is that FastCGI causes intermittent 500 Internal Server Errors for WordPress websites and apparently other PHP based apps as well. Reverting back to PHP5.2.x allows the use of php.ini files instead of .user.ini files, but this is obviously not a good long term solution. This post covers the known problematic issues and will hopefully at some point result in a long term permanent solution for this issue.
If you have VPS or Dedicated Hosting none of these issues apply to you – please skip to the VPS and Dedicated Hosting section below.
The Factors Involved:
Apache mod_fcgid - FastCGI protocol. See ”Special PHP considerations…” section.
FastCGI and WordPress - WordPress does not work well with FastCGI because FastCGI application output is buffered by default. The result of using FastCGI with WordPress is that a WordPress website will experience intermittent 500 Internal Server Errors.
PHP5.3.x – PHP5.4.x .user.ini files - PHP5.3.x – PHP5.4.x uses .user.ini files by default instead of php.ini files ONLY if your Server is using CGI/FastCGI. This does not apply if your server is using Dynamic Shared Objects (DSO) / mod_php / Apache. The standard traditional method of adding php_flag and php_value directives into an .htaccess file still apply when using PHP5.3.x – PHP5.4.x with DSO / mod_php / Apache.
“These files are processed only by the CGI/FastCGI SAPI. This functionality obsoletes the PECL htscanner extension. If you are using Apache, use .htaccess files for the same effect.”
Zend .user.ini GUI options - Zend Servers include .user.ini directive options within the GUI by default to work with PHP5.3.x and future versions of PHP. The directives below can also be added to the Server’s php.ini file. Not to be confused with the new .user.ini file usage, which is strictly on the user’s website / Hosting Account end. Example: A Server’s php.ini file will be located in a Protected Server folder location (/usr/local/lib/php.ini) and a .user.ini file will be located under the website owner’s Hosting Account folders (/xxxx/public_html/.user.ini).
; php.ini Options ;
; Name for user-defined php.ini (.htaccess) files. Default is “.user.ini”
;user_ini.filename = “.user.ini”
; To disable this feature set this option to empty value
; TTL for user-defined php.ini files (time-to-live) in seconds. Default is 300 seconds (5 minutes)
;user_ini.cache_ttl = 300
The PHP5.3.x – PHP5.4.x .user.ini Dilemma for WordPress Websites
If you have a WordPress website and you switch to FastCGI to allow a .user.ini file to work on your website then you can expect that your website will experience intermittent 500 Internal Server Errors due to the known output buffering problem with WordPress and FastCGI. This is obviously not a viable solution to switch to FastCGI. So what can you do if you have a WordPress website on Shared Hosting (VPS and Dedicated Hosting allows you direct access to your Server’s php.ini file so you would not be using a .user.ini file) and you need to change / modify your directive settings?
Solutions / Options
Revert back to PHP5.2.x: If your web host allows you to switch back to PHP5.2.x in your host control panel then this is the best solution at this time if you need to be able to change directive settings in a php.ini file such as increasing file upload size limits, increasing memory limits, increasing your website security, but most importantly to be able to use disable_functions and zend directives. The obvious problem with this is PHP is moving forward with releasing newer versions of PHP. So this is obviously not a good long term solution.
Alternative Solution: If you are unable to switch back to PHP5.2.x from PHP5.3.x you can use the PHP ini_set() functions in your WordPress wp-config.php file to allow you to control some directive settings for your website. NOTE: There are a several directive settings that you cannot add using this method and the most important directive that cannot be added using this ini_set() method is disable_functions. Not being able to add zend directives using this method is another concern as I have come across a fair amount of web hosts who have the Zend Engine installed/enabled, but the relative Optimizer(PHP5.2.x) / Guard(PHP5.3.x) extensions are not loaded by default, which means they are not in use at all. So in these cases you would not be able to correct a web host’s mistake (in the case of PHP5.2.x with Zend Optimizer should always be loaded by default and PHP5.3.x with Zend Guard Loader is of course completely an optional decision) of not adding the extensions by adding the correct extensions in your own relative php.ini (PHP5.2.x)/ .user.ini (PHP5.3.x) file. Also you cannot turn file uploads on or off or change the allowed max size limits of file uploads.
Directive value/settings that can be changed using ini_set
@error_reporting(E_ALL|E_STRICT); @ini_set('log_errors','On'); @ini_set('error_log','/path/to/php_error_log'); // add the actual path to your php error log @ini_set('log_errors_max_len','1024'); @ini_set('ignore_repeated_errors','On'); @ini_set('ignore_repeated_source','Off'); @ini_set('memory_limit','64M'); @ini_set('allow_url_include','Off'); @ini_set('display_errors','Off'); @ini_set('display_startup_errors','Off'); @ini_set('engine','On'); @ini_set('implicit_flush','Off'); @ini_set('max_execution_time','30'); @ini_set('magic_quotes_runtime','Off'); @ini_set('report_memleaks','On'); @ini_set('mysql.trace_mode','Off'); @ini_set('mysql.connect_timeout','30'); @ini_set('define_syslog_variables','Off');
NOTE: I have seen that a couple of Hosts disable the ini_set function in the Server’s php.ini file with the disable_functions directive. If your Host has disabled ini_set then you will need to contact them to remove this function from the disabled_functions directive. This function should not be disabled by default.
Looking at Apache and mod_fcgid directly
“Any program assigned to the handler fcgid-script is processed using the FastCGI protocol; mod_fcgid starts a sufficient number instances of the program to handle concurrent requests, and these programs remain running to handle further incoming requests. This is significantly faster than using the default mod_cgi or mod_cgid modules to launch the program upon each request. However, the programs invoked by mod_fcgid continue to consume resources, so the administrator must weigh the impact of invoking a particular program once per request against the resources required to leave a sufficient number of instances running continuously.”
“Special PHP considerations
By default, PHP FastCGI processes exit after handling 500 requests, and they may exit after this module has already connected to the application and sent the next request. When that occurs, an error will be logged and 500 Internal Server Error will be returned to the client. This PHP behavior can be disabled by setting PHP_FCGI_MAX_REQUESTS to 0, but that can be a problem if the PHP application leaks resources. Alternatively, PHP_FCGI_MAX_REQUESTS can be set to a much higher value than the default to reduce the frequency of this problem. FcgidMaxRequestsPerProcess can be set to a value less than or equal to PHP_FCGI_MAX_REQUESTS to resolve the problem.
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.
The popular APC opcode cache for PHP cannot share a cache between PHP FastCGI processes unless PHP manages the child processes. Thus, the effectiveness of the cache is limited with mod_fcgid; concurrent PHP requests will use different opcode caches.”
“FastCGI is a protocol for interfacing interactive programs with a web server. FastCGI is a variation on the earlier Common Gateway Interface (CGI); FastCGI’s main aim is to reduce the overhead associated with interfacing the web server and CGI programs, allowing a server to handle more web page requests at once.”
Summary – apparently this is a problem for other PHP apps such as Joomla etc as well and “Special PHP considerations” explains why that is
It appears that a long term solution could be that if Host’s use/configure FcgidMaxRequestLen 33554432 as a standard in the httpd.conf file then maybe this is all that would be needed. That still leaves the question of the APC opcode cache sharing trade-off. I have not personally tested this solution below, but it makes logical sense. Still researching ….
Note: If the Suhosin-Extension (not the Patch) is installed on your Server then – “Suhosin‘s features are all configured through the php.ini configuration file.” I assume that Suhosin directives will work in a .user.ini file, but I have not been able to confirm this. Suhosin directives cannot be added/changed/modified using ini_set.
Note: If your Server is using PHP5.3.x and you have an application that needs ionCube and if the ionCube loader extension is not loaded by default in your host Server’s php.ini file and you are not using FastCGI then since this is a zend directive you cannot use ini_set and .user.ini files will not work you will need to contact your web host to have them add the appropriate ionCube loader extension (see below) in the Server’s default php.ini file. Or of course you can revert back to PHP5.2.x and then create your own custom php.ini file and add the ionCube Loader extension to your custom php.in file.
VPS and Dedicated Hosting – Using WordPress and FastCGI together without problems – Possible long term solution for Shared Hosting as well?
I have now come across this info below in several places while googling and it appears to be a working solution to using WordPress and FastCGI. And actually if your Host includes this solution as a standard then maybe this is all that would be needed to permanently solve the issue. That still leaves the question of the APC opcode cache sharing trade-off. I have not personally tested this solution below, but it makes logical sense.
“The reason this seems to be happening is that FastCGI is running low on memory.
By default the Apache configuration does not include a statement to allocate enough memory,
but we can do this by adding the following line to httpd.conf (thanks to Baldock for this tip):
Previous Testing Results on GoDaddy Hosting using a FastCGI handler & PHP5.2.x
Using the GoDaddy handler for FastCGI: AddHandler x-httpd-php5 .php
Intermittent 500 Internal Server Errors – site was inaccessible for periods lasting up to 15 minutes.
Significant increase in page load speed – fluctuated between an increase of 1-6 seconds compared to using CGI handlers.
GoDaddy Handlers for CGI (not FastCGI):
AddHandler x-httpd-php5-cgi .php
AddHandler x-httpd-php5-cgi .php5