In order to run PHP websites, the server must understand the PHP code and generate a page to be displayed in a browser. It interprets the code based on which PHP library you are using, such as PHP 5 or PHP 7. A PHP handler is what actually loads the libraries so that they can be used for interpretation.
PHP handlers
PHP handlers determine how PHP is loaded on the server.
There are multiple different handlers that can be used for loading PHP: PHP-FPM, FastCGI or LSPHP (1). Each handler delivers the libraries through different files and implementations. Each file and implementation affects Apache’s performance, because it determines how Apache serves PHP.
(1) LSPHP is available with OpenLiteSpeed / LiteSpeed webservices, or with the CloudLinux OS over their liblsapi.
It is critical for your server’s performance that you select the handler that best suits your situation. Selecting the right handler is just as important as the PHP version itself. One handler is not necessarily always better than another, as it depends on your unique setup. What caching you need, what modules you need, etc.
Each setup has differences which may make it more secure in one case, but less in another.
CGI/FastCGI – as an External CGI module
CGI stands for ‘Common Gateway Interface’. The CGI handler will run PHP as a CGI module as opposed to an Apache module. FastCGI (aka: mod_fcgid or FCGI) is a high performance variation of CGI. It has the security/ownership benefits of suPHP in that PHP scripts will run as the actual system user as opposed to ‘nobody’. The difference with FastCGI is that it can drastically save on CPU performance and give speeds close to that of DSO. It can also be used with an opcode cacher like OpCache or APC, which can help further speed the loading of pages.
One drawback is that FastCGI has a high memory usage. This is because, rather than creating the PHP process each time it is called, like suPHP, it keeps a persistent session open in the background. This is what lets it work with an opcode caching software.
PHP-FPM – as an External daemon
An alternative PHP FastCGI implementation is PHP-FPM (FastCGI Process Manager). This mode runs PHP via a stand-alone PHP server. Apache accesses this PHP server to make queries. PHP scripts that run via PHP-FPM have many of the same features as with the older PHP handler, suPHP.
PHP-FPM is a much more complex system, but if working correctly, it will give you the absolute fastest performance. Note that memory accelerators can be used with this mode in addition to the benefits of having a separate PHP server (file caching). Memory usage with PHP-FPM can vary drastically depending on how it’s set up. At least 1 process is needed per DA User during a request for that User. We use the on-demand mode which only runs the User processes that are needed, which stick around for a while in case other requests come in, but then die after a short period to help lower the memory usage. If all of your sites are very busy, then you may be very short on RAM. The php.ini setup is on a per-User basis in a php-fpm.conf file. PHP-FPM is a much newer technology and has much less testing. Add the extra complexity, and it may not yet be the best choice for a production box. After further testing and proving itself, it may end up being the top choice.
What handler to use
If you’re lost with the above information – use the default, which is PHP-FPM.
If you run CloudLinux – always use LSPHP.
—
The next sections will assume that one is switching their PHP engine. We’ll use php1_mode for the example. Others (php2/php3/php4_mode) are done same way.
How to switch to FastCGI
To switch to FastCGI mode:
cd /usr/local/directadmin/custombuild
./build update
./build set php1_mode fastcgi
./build set use_hostname_for_alias yes
./build php
./build rewrite_confs
The use_hostname_for_alias option is used to redirect the webapps (squirrelmail, roundcube, phpmyadmin) to the hostname of the server because www.domain.com/squirrelmail will run as the User instead of webapps, which won’t work correctly (one of the few drawbacks of FastCGI).
How to switch to PHP-FPM
To switch to PHP-FPM mode:
cd /usr/local/directadmin/custombuild
./build update
./build set php1_mode php-fpm
./build set_php htscanner yes
./build mod_htscanner2
./build php
./build rewrite_confs
Mixing handlers per versions
You can mix different PHP modes for different versions, but this is not recommended as it leads to increased memory consumption. The mode can be specified for each PHP version installed in the same way that the following commands specify PHP-FPM for each PHP below:
cd /usr/local/directadmin/custombuild
./build update
./build set php1_mode php-fpm
./build set php2_mode php-fpm
./build set php3_mode php-fpm
./build set php4_mode php-fpm
./build set_php htscanner yes
./build mod_htscanner2
./build php
./build rewrite_confs
Applying php_value/php_flag from .htaccess . The htscanner
PHP handlers PHP-FPM and FastCGI need a special module to read and apply php_value/php_flag options from the .htaccess file. Only mod_php and lsphp read them natively.
Two modules required:
- mod_htscanner2 so that Apache will ignore php_options in the .htaccess instead of not opening the page due to error.
- php_htscanner2 so that PHP-FPM/FastCGI will read and apply php_options from .htaccess files.
To install:
./build set_php htscanner yes
./build mod_htscanner2
Now build htscanner for your chosen PHP version as:
./build php_htscanner2 PHP_VERSION
Or build htscanner for all enabled PHP versions using this one-liner:
grep php._release options.conf | cut -d= -f2-2 | grep -v no | awk '{ print "./build php_htscanner2 "$1 }' | sh
I want to have a different version of PHP
If you’re looking to change PHP versions in CustomBuild 2.0, say from PHP 5.6 to PHP , you’d type:
cd /usr/local/directadmin/custombuild
./build set php1_release "7.4"
./build update
./build php
./build rewrite_confs
You can have a few different versions of PHP running simultaneously.
Letting Users select between multiple different PHP versions
The release of DirectAdmin 1.56.0 allows up to 4 active PHP versions to be used, and Users can pick between them. You must be using the latest version of CustomBuild 2.0.
The first PHP version will be the default and will run all webapps. Everything else is optional.
Users can select between versions on their Domain Setup page in DirectAdmin.
The following is a sample installation of multiple PHP versions:
da build set php1_release 8.1
da build set php2_release 5.6
da build set php3_release 7.0
da build set php4_release 7.3
da build set php1_mode php-fpm
da build set php2_mode php-fpm
da build set php3_mode php-fpm
da build set php4_mode php-fpm
da build php
da build rewrite_confs
This will compile all of those PHP versions with PHP-FPM as the handler. You may change the version numbers and PHP handlers as desired.
If you need fewer than 4 PHP versions, set that given release to “no”, e.g.,
da build set php4_release no
da build rewrite_confs
To use the multiple PHP version selector, one must ensure that php_version_selector is enabled (set to ‘1’) in DirectAdmin’s configuration, which it should be by default. To confirm:
da config-get php_version_selector
If this is not enabled for some reason, enable it like so:
da config-set --restart php_version_selector 1
Using a Different PHP Version for a Subdomain
You can assign a custom PHP version to a subdomain via the User DA GUI Dashboard / Sub-Domains Setup / Document Root Override in the section “PHP Version Selector”.
This is implemented via the file /usr/local/directadmin/data/users/USERNAME/domains/DOMAIN.COM.subdomains.docroot.override, where where the format will extend the existing data, and allow you to add:
php1_select=1-4
depending on your settings in CustomBuild options.conf.
If you set php1_select=2, for example, this will make use of the php2_release and php2_mode for this subdomain.
Contents of the domain.com.subdomains.docroot.override file is one subdomain per line.
For example, if you have sub.domain.com, a sample line might look like:
sub=php1_select=2
or if there are also public_html/private_html overrides, it might look like:
sub=public_html=/domains/otherdomain.com/public_html&private_html=/domains/otherdomain.com/private_html&php1_select=2
where the data after the first = character is URL encoded.
CloudLinux PHP Selector
If you’re running CloudLinux and have php1_mode=lsphp, you will be able to use the CloudLinux PHP Selector plugin.
Note, that if you also use the DA PHP selector, the CloudLinux selection only has any effect if the domain is using the 1st DA PHP instance.
Swapping all Users’ PHP selection
In some cases, you might need to flip all User PHP selections to run additional version of PHP. We’re using 2nd version (2) in the example, if you’d like to use 3rd or 4th as the selection – just change the number.
We would recommend you backup all /usr/local/directadmin/data/users/*/domains/*.conf files before testing this script.
#!/bin/sh
#default to swap if nothing present.
for i in `ls /usr/local/directadmin/data/users/*/domains/*.conf`; do
{
if ! grep -q ^php1_select $i; then
echo php1_select=2 >> $i
continue
fi
perl -pi -e "s/^php1_select=.*/php1_select=2/" $i
};
done
exit 0
Save the script, make it executable, run it, and use the following commands to follow up with a rewrite:
cd /usr/local/directadmin/custombuild
./build update
./build rewrite_confs
Letting Users select between multiple different PHP versions
The release of DirectAdmin 1.56.0 allows up to 4 active PHP versions to be used, and Users can pick between them. You must be using the latest version of CustomBuild 2.0.
The first PHP version will be the default and will run all webapps. Everything else is optional.
Users can select between versions on their Domain Setup page in DirectAdmin.
The following is a sample installation of multiple PHP versions:
da build set php1_release 8.1
da build set php2_release 5.6
da build set php3_release 7.0
da build set php4_release 7.3
da build set php1_mode php-fpm
da build set php2_mode php-fpm
da build set php3_mode php-fpm
da build set php4_mode php-fpm
da build php
da build rewrite_confs
This will compile all of those PHP versions with PHP-FPM as the handler. You may change the version numbers and PHP handlers as desired.
If you need fewer than 4 PHP versions, set that given release to “no”, e.g.,
da build set php4_release no
da build rewrite_confs
To use the multiple PHP version selector, one must ensure that php_version_selector is enabled (set to ‘1’) in DirectAdmin’s configuration, which it should be by default. To confirm:
da config-get php_version_selector
If this is not enabled for some reason, enable it like so:
da config-set --restart php_version_selector 1
Using a Different PHP Version for a Subdomain
You can assign a custom PHP version to a subdomain via the User DA GUI Dashboard / Sub-Domains Setup / Document Root Override in the section “PHP Version Selector”.
This is implemented via the file /usr/local/directadmin/data/users/USERNAME/domains/DOMAIN.COM.subdomains.docroot.override, where where the format will extend the existing data, and allow you to add:
php1_select=1-4
depending on your settings in CustomBuild options.conf.
If you set php1_select=2, for example, this will make use of the php2_release and php2_mode for this subdomain.
Contents of the domain.com.subdomains.docroot.override file is one subdomain per line.
For example, if you have sub.domain.com, a sample line might look like:
sub=php1_select=2
or if there are also public_html/private_html overrides, it might look like:
sub=public_html=/domains/otherdomain.com/public_html&private_html=/domains/otherdomain.com/private_html&php1_select=2
where the data after the first = character is URL encoded.
CloudLinux PHP Selector
If you’re running CloudLinux and have php1_mode=lsphp, you will be able to use the CloudLinux PHP Selector plugin.
Note, that if you also use the DA PHP selector, the CloudLinux selection only has any effect if the domain is using the 1st DA PHP instance.
Swapping all Users’ PHP selection
In some cases, you might need to flip all User PHP selections to run additional version of PHP. We’re using 2nd version (2) in the example, if you’d like to use 3rd or 4th as the selection – just change the number.
We would recommend you backup all /usr/local/directadmin/data/users/*/domains/*.conf files before testing this script.
#!/bin/sh
#default to swap if nothing present.
for i in `ls /usr/local/directadmin/data/users/*/domains/*.conf`; do
{
if ! grep -q ^php1_select $i; then
echo php1_select=2 >> $i
continue
fi
perl -pi -e "s/^php1_select=.*/php1_select=2/" $i
};
done
exit 0
Save the script, make it executable, run it, and use the following commands to follow up with a rewrite:
cd /usr/local/directadmin/custombuild
./build update
./build rewrite_confs
PHP Extensions
The default PHP is compiled with most common modules and extensions. You may list all enabled modules simply by running this command:
php -m
Or create a phpinfo() page and open it in a browser.
Various websites may require some additional modules and extensions. You may extend your PHP functionality by using our CustomBuild tool.
All extensions are mainly maintained by PECL, which stands for PHP Extension Community Library. It has extensions written in C, which can be loaded into PHP to provide additional functionality.
PHP maintains an alphabetical list of all the available extensions via the php.net website
Installing extensions
DirectAdmin already provides a set of possible extensions to be easily compiled using our CustomBuild tool, including:
bz2
gmp
htscanner
igbinary
imagick
imap
ioncube
ldap
opcache
phalcon
redis
readline
suhosin
snuffleupagus
xmlrpc
zend
Those can be installed using the following commands:
cd /usr/local/directadmin/custombuild
./build update
./build set_php "imap" yes
./build "php_imap"
Add a custom module to PHP with CustomBuild
You may want to compile your PHP with a custom module. It can be done by using the –with-module flag.
- First, let’s figure out which configuration file your system is using. Type:
cd /usr/local/directadmin/custombuild
./build used_configs | grep configure.php
It might look like this:
PHP (default) configuration file: /usr/local/directadmin/custombuild/configure/php/configure.php74
Please pay attention to whether your file is located in: /usr/local/directadmin/custombuild/**configure**/php/configure.php74 or
/usr/local/directadmin/custombuild/**custom**/php/configure.php74
In case you’re already using a custom configuration file, you can skip step 2.
Please specify which filename is currently in use:
- To start customizing the compilation parameters, first we need to create a custom compilation file:
cd /usr/local/directadmin/custombuild
mkdir -p custom/php
cp -fp "configure/php/configure.php74" "custom/php/configure.php74"
- Add your –with-module line to the end of the
custom/php/{{configurephp}}file, and make sure the \ character exists at the end of all lines except the last one. The \ character tells the configure line to loop to the next line, making the line easier to read. Without the \ character to trigger the wrap, the next line is incorrectly read as a separate command. Once set, type:
./build php
- Restart Apache and if necessary, PHP-FPM.
systemctl restart httpd
systemctl restart php-fpm74
Please keep in mind that any changes to your stock DirectAdmin setup are beyond our technical support, and you do so at your own risk.
A common error people run into looks like this:
/usr/local/directadmin/custombuild/custom/php/configure.php74: line 32: --with-module: command not found
which simply means that the \ character was not correctly added on the line before the last –with-module.
Manually compiling an extension for PHP
Consider the example using the APCu extension for PHP version (without dots e.g. 56, 70, 71).
Where possible, use OpCache instead of APC/APCu.
A common optimization that can be done for PHP to improve performance is to install and Opcode caching module such as Alternative PHP Cache (APCu, or APC for php version < 5.6).
What it does is caches PHP files in memory in their parsed and compiled state. This removes the need for re-reading, parsing and compiling for each request, thus greatly lowering your system load. The cost of using this module is an increased memory usage, since that’s where the cache lives.
- Download, compile and install the module.
Take a download location for a desired extension from https://www.php.net/manual/en/extensions.alphabetical.php
wget https://github.com/krakjoe/apcu/archive/master.zip
unzip master.zip
cd apcu-master
"/usr/local/php72/bin/phpize"
./configure --with-php-config="/usr/local/php72/bin/php-config"
make
make install
This will place an apcu.so file into the PHP extensions directory, which will be mentioned after make install finishes.
- Add a custom ini file and enable the extension:
vi "/usr/local/php72/lib/php.conf.d/90-apcu.ini"
and place the code inside:
extension=apcu.so
apc.enabled=1
apc.shm_size=1000M
apc.ttl=7200
apc.user_ttl=7200
apc.enable_cli=1
apc.max_file_size=5M
Replace the 1000M with the amount of RAM you want it to use. About 40M per WordPress installation and 60M per Magento installation should be sufficient. Multiply that by the number of installations. For example, 100 WordPress installs = 4000M.
If your server does not have enough RAM to cache all of the PHP files, you must reduce the number of cached files. Use the filters option or play with the cache_by_default option to specify which files to be cached. A tip is to set apc.cache_by_default=0 in php.ini, and then apc.cache_by_default=1 in the .htaccess of the websites requiring APC optimization.
- Restart Apache:
systemctl restart httpd
Note: APC provides a tool to check memory usage. It’s a PHP page that you will find in apcu-master/apc.php. Copy the file to a web folder and open it in a web browser. In a correctly configured APC installation, the memory chart must remain stable over time.
If you have multiple versions of PHP available with CustomBuild, you have to compile the custom extension for each version.
PHP-FPM
How to switch to PHP-FPM
Use the cumulative guide maintained in general section .
Per-user php.ini settings in php-fpm
If you need to make changes to the php.ini in php-fpm, you can do so from Admin Level -> Custom Httpd Configuration -> domain.com: php-fpm 5.x and in the 2nd textarea called |CUSTOM2|. The sytnax is different from a php.ini and might look like:
php_value[memory_limit] = 256M
where it might be php_value, php_admin_value, php_flag, php_admin_flag, etc. depending on the setting.
Example:
To alter the per-user disable_functions, eg to add mail to the list, set this in CUSTOM2:
php_admin_value[disable_functions] = exec,system,passthru,shell_exec,escapeshellarg,escapeshellcmd,proc_close,proc_open,dl,popen,show_source,posix_kill,posix_mkfifo,posix_getpwuid,posix_setpgid,posix_setsid,posix_setuid,posix_setgid,posix_seteuid,posix_setegid,posix_uname,mail
Note that disable_functions is special. The caveat is that you can not override what is already defined. You can only append to that array. The phpinfo() page will show disable_functions from the CUSTOM2 section. To remove some functions from the disable_functions array (to make them available for domains), the global customization is
You can alternatively turn on the** user_ini.filename** setting, read below.
Per-path php settings, controllable by the User
Enabled by default. Php run in cgi or php-fpm can edit their php.ini file, and set something like
user_ini.filename = ".user.ini"
which will allow some of the php.ini settings to be set by the User, by creating a .user.ini file in their public_html or other web paths, in cases like php-fpm, where .htaccess files are not available for php settings.
Related: http://php.net/manual/en/configuration.file.per-user.php
Why cannot I see /tmp/ content with PHP-FPM?
With CentOS 7, you may have noticed that even though your script may working as expected, you’re not able to see the session files or temporary files in the /tmp folder.
The reason for this, is that with CentOS 7 supports a feature called:
PrivateTmp=true
What this feature does, is mounts /tmp and /var/tmp as private file systems, visible only to that process. So when php-fpm writes to /tmp, it’s not the /tmp that you can see from ssh.. it’s a virtual path, visible only to that process. Once the process stops, the virtual /tmp is removed.
Man page from systemd.exec:
PrivateTmp=
Takes a boolean argument. If true, sets up a new file system namespace for the executed processes and mounts private /tmp and /var/tmp directories inside it, that
are not shared by processes outside of the namespace. This is useful to secure access to temporary files of the process, but makes sharing between processes via
/tmp or /var/tmp impossible. All temporary data created by service will be removed after service is stopped. Defaults to false.
If you don’t like this behavior, edit /etc/systemd/system/php-fpm73.service and set PrivateTmp=false. Reload daemon units and restart php-fpm to apply changes:
systemctl daemon-reload
systemctl restart php-fpm73
PHP version 7.3 in above example. Do the same for other versions.
WARNING: server reached max_children setting
If you are getting this error:
WARNING: [pool convoice] server reached max_children setting (10), consider raising it
To raise the limit globally, change directadmin.conf value first:
cd /usr/local/directadmin/
./directadmin set php_fpm_max_children_default 100
Rewrite configs and restart php-fpm service:
cd /usr/local/directadmin/custombuild
./build rewrite_confs
service php-fpm73 restart
For a per-Domain setting change, go to:
Admin Level -> Custom Httpd Config -> domain.com: php-fpm55
When viewing the php-fpm custom config, in the |CUSTOM1| token area, set a higher value, eg:
|?MAX_CHILDREN=200|
and save. This should override the default value from the template.
I wish to have global custom PHP-FPM configuration
To create true global CUSTOM1 and CUSTOM2 pre tokens, loaded in before other tokens for the php-fpm.conf templates, all Users, all php versions, create the following files:
/usr/local/directadmin/data/templates/custom/php-fpm.conf.custom1/usr/local/directadmin/data/templates/custom/php-fpm.conf.custom2
If either exists, they’ll be added into their respective CUSTOM1 or CUSTOM2 tokens for all php-fpm.conf rewrites.
per-User global php CUSTOM tokens
With the more common use of the php version selector, you may want your custom php-fpm configs to span all php versions. 2 new textareas in the Custom Httpd Config -> domain.com: php-fpmXX page for “global php-fpm CUSTOM1” and “global php-fpm CUSTOM2”
You may edit configuration manually by modifying files:
/usr/local/directadmin/data/users/username/php/php-fpm.conf.custom1/usr/local/directadmin/data/users/username/php/php-fpm.conf.custom2
which will be set into the CUSTOM1/CUSTOM2 tokens before the php-fpm73.conf.custom1 files (for example). But both global and per-php, if present, will end up into the same token.
When you save data into either of these fields, the CUSTOM1/CUSTOM2 tokens set to span all php versions that the User may select from. The bottom 2 boxes, as before, will only apply to that given php version.
There is also the “save to all php versions” which copies your data to all custom tokens for each php version. When checked, the CUSTOM1/CUSTOM2 tokens will be saved to the php-fpm customX files, for all active php versions (as set in the options.conf).
Example:
/usr/local/directadmin/data/users/username/php/php-fpm56.custom1/usr/local/directadmin/data/users/username/php/php-fpm56.custom2/usr/local/directadmin/data/users/username/php/php-fpm72.custom1/usr/local/directadmin/data/users/username/php/php-fpm72.custom2
The php-fpmXX.conf is only written for the active/selected php version. When a User changes their php version via the Domain Setup php selector, the custom changes set by the Admin would apply through all versions, without the need for another set of the custom settings.
php-fpm check before sending to AddHandler
If you access a php file through apache/php-fpm, but it does not exist, this will throw:
No input file specified
or
File not found.
A simple solution is to not pass it to php-fpm if it’s missing, and let apache throw the usual 404 from the website’s setup. To accomplish this, a simple <If ..> check tag can be added around the AddHandler in the VirtualHosts, to look for the REQUEST_FILENAME variable.
|*if HAVE_PHP1_FPM="1"|
<FilesMatch "\.(inc|php|phtml|phps|php|PHP1_RELEASE|)$$">
<If "-f %{REQUEST_FILENAME}">
#ProxyErrorOverride on
AddHandler "proxy:unix:/usr/local/php|PHP1_RELEASE|/sockets/|USER|.sock|fcgi://localhost" .inc .php .phtml .php|PHP1_RELEASE|
</If>
</FilesMatch>
|*endif|
Per-Domain php.ini settings – start point
With the many different types of php modes, this means the method of adding custom per-domain changes can vary greatly. Check your custombuild options.conf to determine which php1_mode you’re using, and find the related guide below.
php-fpm
php-fpm is handy for multiple instances of php, allowing the User to change php version from within their User Level area. php-fpm does not support .htaccess changes as php-fpm is it’s own stand-alone php server, but you can use
- php-fpmXX.conf custom settings
- php [PATH] or [HOST] sections
- User controlled .user.ini
fastcgi
The fastcgi mode is effective, but some find it somewhat rigid in it’s flexibility (blend of suphp and php-fpm). To edit per-domain settings, you have 2 options:
- Manually create the .ini file at
/usr/local/directadmin/data/users/username/php/domain.com.iniand the call to fastcgi will read that in if it exists.
Note that it’s a full replacement and not an ‘addon’ ini, so ensure you have all settings you need in that file, as the default php.ini isn’t used here. Take a look inside the User’s httpd.conf to see which .sh script is called, and the variables passed. Then check inside that .sh script for more info on how it works.
- php [PATH] or [HOST] sections
Note that some settings like disable_functions can only be set once in the main php.ini file, and cannot be overridden by other areas, but this varies per php-mode. php-modes like php-fpm/fastcgi are much more stand-alone php instances, so you can get away with these types of overrides, away from the main php.ini.
Where is my php.ini?
Depending of a setup the location of php.ini may vary. The easiest trick to find your php.ini would be to ask php itself what it’s using, eg:
/usr/local/bin/php --ini | grep 'Loaded Configuration File'
which does assume that the php output will be in English.
Usually your php.ini will be located at (XX – PHP version, for example 73):
/usr/local/phpXX/lib/php.ini
CustomBuild 2.0 installs will also uses the php.conf.d directory to load miscellaneous .ini files into php. The files that CustomBuild will create are:
/usr/local/php74/lib/php.conf.d/10-directadmin.ini/usr/local/php74/lib/php.conf.d/50-webapps.ini
You can add your own files there if you need to add settings or load modules into php, for example /usr/local/php74/lib/php.conf.d/11-custom.ini and place custom options inside.
The ever best option is to place phpinfo() page inside a domain DocumentRoot directory, create the file phpmyinfo.php with content:
<?php
phpinfo()
?>
Next open it in browser: http://example.com/phpmyinfo.php and watch for ‘Loaded Configuration File’ and ‘Scan this dir for additional .ini files’ .
How to increase the max upload filesize
Find where is your php.ini then edit it.
Search for
; Maximum allowed size for uploaded files.
upload_max_filesize = 2M
Change the 2M to whatever new value you want, then restart apache.
Note, this setting may also be related:
; Maximum size of POST data that PHP will accept.
post_max_size = 8M
Note, some RoundCube versions have limits set in the file /var/www/html/roundcube/.htaccess so be sure to increase them there as well, if they are set.
Fatal error: Allowed memory size exhausted
If you see the error like:
Fatal error: Allowed memory size of 123456 bytes exhausted (tried to allocate 234567 bytes) in /path/file.php
Php is setup is to limit memory usage per process. If you require more, this limit can be increased.
Find where is your php.ini then edit it, search for
memory_limit = 8M
to a higher value, like 128M. Save, exit, then restart apache.
How to use per-domain or per-path settings for php
CustomBuild 2.0 uses a folder for additional php.ini files, loaded if they exist in the folder. The install path can vary depending on the php mode; in this example, we’ll use /usr/local/lib/php.conf.d but for other php modes, if the php version is 5.6, the path might be:
/usr/local/lib/php55/php.conf.d
You can determine where you php.ini and php.conf.d folder is by using the where is my php.ini guide.
Once you know the path, let’s use in our example, you can then create your custom ini file. The load of the ini files is done alphabetically, so we number the files to control in which order they’re loaded in. Usually the order doesn’t matter too much, unless you’re altering settings for a module that should be loaded first.
1. Per-domain settings
If you would like to create per-domain settings for , you could create:
/usr/local/lib/php.conf.d/30-{{domain}}.ini
And add code like:
[HOST=example.com]
session.save_path=/home/fred/tmp
upload_tmp_dir=/home/fred/tmp
2. Per-path settings
Similarly, you can alter settings on a per-path basis, say for User which is handy if you want the settings to apply to a domains under that given path (usually, on a per-User basis), edit the file:
{{phppath}}/30-{{usern}}.ini
And set, for example:
[PATH=/home/fred]
session.save_path=/home/fred/tmp
upload_tmp_dir=/home/fred/tmp
In the above examples, it is implying the use of one file for each item you want to separate. This is not required. You can use one additional file to make load times faster, but also to hide the list of domains from the phpinfo() output, as all “additional” loaded php.ini files are displayed, so if you were to use:
{{phppath}}/30-custom-domains.ini
you could add many [HOST=xx] entries into the same file, one after the other.
Based on: http://php.net/manual/en/ini.sections.php
How to allow <? and not require <?php
If you have scripts with the php tags:
<?
but php isn’t parsing the code between those tags, php may be set to require:
<?php
You can force php to allow the short tags by setting the following in your php.ini:
short_open_tag=On
How to disable magic-quotes
If you need to disable magic quotes, the easiest way is to edit your php.ini and set:
magic_quotes_gpc = Off
and then restart apache.
Another way is to edit your php configure file and remove the line:
--enable-magic-quotes \
and recompile php.
Testing which uid php is running as to debug read/write issues
Often times, a php script needs write access to disk. Most installs will use php-fpm, fastcgi or lsphp which should all run php as the given User, rather than as “apache”.
To determine what uid a php process is running as, you can use this script to get a definitive answer:
<?php
system('/usr/bin/id');
phpinfo();
?>
Save this to an info.php file in a path you’re trying to debug, then view it through Apache.
CustomBuild secure_php
One could use the CustomBuild option secure_php to make their PHP installations more secure. It will edit the php.ini for each PHP version to disable PHP functions that are commonly abused. The default setting is secure_php=no.
How to enable secure_php
To use this option, run the following commands:
cd /usr/local/directadmin/custombuild/
./build secure_php
These commands will:
- enable
secure_phpby changing it from ‘no’ to ‘yes’ in the CustomBuild configuration (/usr/local/directadmin/custombuild/options.conf) - secure each PHP installation by editing their respective `php.ini files’ settings (if applicable):
- disable_functions
- expose_php
- mysqli.allow_local_infile OR mysql.allow_local_infile
- register_globals (deprecated since PHP 5.3 and removed as of PHP 5.4)
These settings will be modified as follows:
disable_functions = exec,system,passthru,shell_exec,proc_close,proc_open,dl,popen,show_source,posix_kill,posix_mkfifo,posix_getpwuid,posix_setpgid,posix_setsid,posix_setuid,posix_setgid,posix_seteuid,posix_setegid,posix_uname
mysqli.allow_local_infile = Off
expose_php = Off
register_globals = Off
Of the modified settings, only disable_functions is added if it doesn’t exist already. The other settings will be set to ‘Off’ only if they existed already and were enabled.
You can confirm the process completed by either checking for the changes in the php.ini file, or by checking for entries similar to the following example output in the /usr/local/directadmin/custombuild/custombuild.log:
[root@host custombuild]# grep -Ri 'secure_phpini:' custombuild.log
2020-07-13 04:47:07 97.85.XXX.XXX: secure_phpini: /usr/local/lib/php.ini secured
2020-07-13 04:47:07 97.85.XXX.XXX: secure_phpini: /usr/local/php56/lib/php.ini secured
2020-07-13 04:47:07 97.85.XXX.XXX: secure_phpini: /usr/local/php70/lib/php.ini secured
2020-07-13 04:47:07 97.85.XXX.XXX: secure_phpini: /usr/local/php73/lib/php.ini secured
2020-07-13 04:47:07 97.85.XXX.XXX: secure_phpini: /usr/local/php74/lib/php.ini secured
[root@host custombuild]#
Note that for CloudLinux servers, ./build secure_php will secure /etc/cl.selector/global_php.ini and then run cagefsctl --setup-cl-selector.
How to customize the disable_functions list
If you were to try to manually edit disable_functions in a php.ini file, your customizations likely won’t be preserved and will be overwritten the next time you build PHP.
To customize the list of functions that are disabled so that you can add/remove functions from the list, you can do the following where your custom comma-delimited list of php functions to disable are
cd /usr/local/directadmin/custombuild
echo "exec,system,passthru,shell_exec,proc_close,proc_open,dl,popen,show_source,posix_kill,posix_mkfifo,posix_getpwuid,posix_setpgid,posix_setsid,posix_setuid,posix_setgid,posix_seteuid,posix_setegid,posix_uname" > custom/php_disable_functions
./build secure_php
For example, let’s say that you only want exec disabled. In that case, you’d run this:
cd /usr/local/directadmin/custombuild
echo "exec" > custom/php_disable_functions
./build secure_php
Now, you can check and confirm the disable_functions for all PHP versions like so:
grep disable_functions /usr/local/php*/lib/php.ini
How to revert secure_php changes
If for some reason you decide that you need to revert these changes, there are a few ways to do so, but beware that this first method will involve overwriting any customizations you have already by replacing the php.ini with a default php.ini.
cd /usr/local/directadmin/custombuild; ./build set secure_php no; ./build set php_ini yes; ./build php_ini
Make sure to run ./build set php_ini no when you are done so that the php.ini isn’t rebuilt anew each time you ./build php or ./build all.
If you just need to revert the changes done to disable_functions, you may consider the following option, which would allow you to retain any other customizations you have.
- Simply overwrite any list of functions in
custom/php_disable_functionsto an empty string and run./build secure_phpagain:
echo "" > custom/php_disable_functions
./build secure_php
That should clear the disable_functions so that no functions are disabled via this setting.



