Embed a PHP file into INI - php

I'd like to insert a line, similar to include('path to php file.php'), into php.ini.
Actually I already found this solution from the Internet, however I don't remember which parameter is used in php.ini in this case.
For what: I want to execute a short code (written by php) before every php script from my web server.

If I understand you correctly, you're looking to run a PHP script before all files on your server? If so, the auto-prepend-file directive in php.ini configuration is perfect for this. From the help docs:
Specifies the name of a file that is automatically parsed before the
main file. The file is included as if it was called with the require
function, so include_path is used.
The special value none disables auto-prepending.
Sample Code:
# Inside either main php.ini or child file
auto_prepend_file=/path/to/your/global/php/file.php
Note that PHP also gives the ability to append a file after every script interpretation as well. There is also a previous SO entry for this with additional information. HTH.

You must be searching for auto_prepend_file or auto_append_file, i.e.:
auto_prepend_file string
Specifies the name of a file that is automatically parsed before the
main file. The file is included as if it was called with the require
function, so include_path is used.
auto_append_file string
Specifies the name of a file that is automatically parsed after the
main file. The file is included as if it was called with the require
function, so include_path is used.
Usage php.ini:
auto_prepend_file="/path/to/prepend.php"
auto_append_file="/path/to/append.php"

Related

Set php.ini directives for each site

I have multiple sites running on Apache2 and PHP on Ubuntu Server. I know PHP has a php.ini file that lets you set values for upload_max_filesize, max_file_uploads , upload_tmp_dir etc. But that applies one value to all sites.
How can set directives for each site? For Eg: I'd like to set upload_max_filesize to 50M for sitea.com and upload_max_filesize to 5M for siteb.com.
Similarly, I'd like to set unique a session.name for each sites. How can this be done? I read there's something called PHP_INI_USER, PHP_INI_PERDIR, PHP_INI_SYSTEM, PHP_INI_ALL, so how can I do this?
You can use .htaccess files per site (or even per-folder) to set PHP configuration values - at least for most settings: if you look in the configuration directives documentation, for every setting that is marked as either PHP_INI_PERDIR or PHP_INI_ALL you can set these in a .htaccess file using the php_value or php_flag commands as documented in PHP's "How to change configuration settings" document.
For example to set upload_max_filesize in a website, create a .htaccess file at the document root of that website and put in it the text:
php_value upload_max_filesize 24M
Unfortunately, max_file_uploads and upload_tmp_dir are settings marked as PHP_INI_SYSTEM and you cannot change them in a .htaccess file...
How can set directives for each site? For Eg: I'd like to set upload_max_filesize to 50M for sitea.com and upload_max_filesize to 5M for siteb.com.
The comment by Mike 'Pomax' Kamermans explicitly states how this should be done. However PHP manual documentation can be a little off-putting.
Also some clarifiers re the other answers here:
Using a PHP parser file (as described by Lajos Arpad) adds some security risks and a pile of coding, syntax and some processing overhead that really isn't needed.
.htaccess does work for setting custom ini directives for some PHP installations but if you're using "FastCGI" or "CGI" (and possibly suPHP) PHP installations then this will infact crash your website with a 500 error, so instead use a local .user.ini file as described here. How do I find out my SAPI?
ONLY if you are running PHP as an Apache module (eg mod_php), use .htaccess. How do I find out my SAPI?
PHP suPHP/FastCGI/CGI SAPI
So, how should your aspiration be completed?
1) Look up the Core PHP.ini details.
Read your PHP.ini file for your current version of PHP.
Around line 180 (for PHP 8.1) it should say something like this:
;==================;
; php.ini Options ;
;==================;
; Name for user-defined php.ini (.htaccess) files. Default is ".user.ini"
user_ini.filename = ".account-php81.ini"
Make a note of this value and I would suggest customising this value (as shown in this example). This value is the file name of the file which will sit in each unique account on the server, holding the account specific "local" settings for the global PHP.ini file.
The file typically sits in the public_html folder so should begin with a . so as to set as hidden by default (see more about this later on). If the file doesn't exist an an account no core PHP settings are changed.
2) Remember/Set the Filename and Create the New Rules
So you now know/ have set the name for your custom PHP file; now generate the file in your account and you can then set the PHP.ini settings you want to customise for this account alone.
For example;
file: /home/sitea.com_account/public_html/.account-php81.ini
Would contain the following example information:
;
; Some optional comment text here for human consumption
;
session.cookie_secure=1
session.save_path=/home/sitea.com_account/sessions
session.name=session-sitea
error_log=/home/sitea.com_account/errors/PHP_errors.log
upload_max_filesize=50M
This information is parsed by PHP and overwrites any corresponding values in the core PHP.ini but only for this account.
3) Customise for Each Account as Needed
For example, for your siteb.com php user ini file it would look more like this:
file: /home/siteb.com_account/public_html/.account-php81.ini
Would contain the following example information:
;
; Some optional comment text here for human consumption
;
session.cookie_secure=1
session.save_path=/home/siteb.com_account/session_b
session.name=site-b-UniqueSession
error_log=/home/siteb.com_account/errors/PHP_errors.log
upload_max_filesize=5M
You can then check that these account settings are set correctly by exploring phpinfo() on each account and noting the local and core differences as displayed.
4) Test And Confirm
The core user.ini file in the /public_html/ path should be all you need for every child file/folder on that account to process (This can sometimes depend on your exact LAMP server setup and your PHP handler).
As I say, once you've set a test ini file you should run phpinfo() to check its values are implemented.
If you don't want to use phpinfo() then you can just as easily use [ini_get](https://www.php.net/manual/en/function.ini-get) to dump sensitive data out to the error log rather than to the browser.
<?php
error_log("ini data for this account: ".ini_get('upload_max_filesize'));
exit;
5) Security
The user.ini file is typically started with a . character to hide it in the directory, but that doesn't make it untouchable by browser agents, therefore it's best practise to add a few lines to your .htaccess to deny access to this file.
<Files .account-php81.ini>
Require all denied
</Files>
Some Final Thoughts:
Core PHP.ini values do change in new versions of PHP and so this is why it's best practise to have different local .ini files for different PHP versions (.account-php80.ini, .account-php81.ini, etc.). Note that each php.ini core will need to explicitly call their respective local user.ini file, as referenced in step 1 above.
The principles of the above are outlined in the PHP Manual and it must be noted:
If you are running PHP as Apache module, use .htaccess files for the same effect.
Your settings are in php.ini indeed. Yet, if you have multiple sites to set, then you can set values inside the .htaccess file in the root of the site folder.
However, you can create a json file somewhere on your server, let's assume it's at /path/settings.json of the format of:
{
sitename1: {
setting1: value1
setting2: value2
},
sitename2: {
setting1: value3
setting2: value4
}
}
Now, you can create a deploy.php file at all your sites that will run cat /path/settings.json via exec, like
if (exec('cat /path/settings/json', $output, $retval)) {
$currentSettings = json_decode($output, true)['mysitename'];
}
You will then have an array of key-value pairs that can be looped and the setting will be known, like:
$script = "";
foreach ($currentSettings as $key => $value) {
$script .= "ini_set('{$key}', '{$value}');\n";
}
and then save $script into a file, let's call it init.php for now. You require_once this file and then you can maintain a single json file and deploy it per site by running a single cli command. You can even create an sh file that runs all deployment commands so you will be able to deploy everything via a one-liner.

Run code before every file

I built a website using PHP 5.3 (with Apache 2.4).
I have global file that needs to run before every page (to set timezone and more global settings).
So in each file I must to remember to include it in the top of the page. It is not convenient.
Is there any way to set a boot file that runs automatically before every file?
For example you can use this php config directive:
http://www.php.net/manual/en/ini.core.php#ini.auto-prepend-file
auto_prepend_file string
Specifies the name of a file that is automatically parsed before the
main file. The file is included as if it was called with the require
function, so include_path is used.

PHP scripts missing <?php won't run

I've downloaded a module library for Yii in which every PHP file starts with this:
<?
...rather than:
<?php
On my local Apache server, these files get loaded as flat files, rather than as executable scripts, though the files are all modded as writable and executable. Is there a way to force these files to be run as PHP, or do I have to modify all the files (and there are probably a hundred of them).
You will have to enable short_php_tag from php.ini Or better change <? to <?php in your file.
Tells PHP whether the short form () of PHP's open tag should be
allowed. If you want to use PHP in combination with XML, you can
disable this option in order to use inline. Otherwise, you
can print it with PHP, for example: '; ?>'. Also, if disabled, you must use the long form of
the PHP open tag ().
You need to activate the
short_open_tag
in the php.ini from "Off" to "On".
Dont forget to reload/restart the apache
you can add a .htaccess file with the following line to make it work:
php_value short_tags on

Execute php script before every php script?

How would I run this before every php script besides putting it in all of them?
if ($_SERVER['REMOTE_ADDR'] == '123.123.123.123')
{
$_SERVER['REMOTE_ADDR'] = $_SERVER['HTTP_X_REAL_IP'];
}
I basically want the same affect as putting that at the top of every script without actually doing that.
Put it in its own file and set the auto_prepend_file configuration in the php.ini / .htaccess file to point to it.
Update: Since you mentioned lighttpd in a comment, note that you can configure it like this in the global INI file with PHP 5.3:
[PATH=/vhost/domain.com]
auto_prepend_file = /vhost/domain.com/foo.php
[HOST=domain.com]
auto_prepend_file = /vhost/domain.com/foo.php
Or you can create the file /vhost/domain.com/.user.ini and do the same:
auto_prepend_file = /vhost/domain.com/foo.php
If you have the necessary rights to change your PHP configuration, auto_prepend_file is exactly what you're looking for.
auto_prepend_file
Specifies the name of a file that is automatically parsed before the main file. The file is included as if it was called with the require() function, so include_path is used.
The special value none disables auto-prepending.

How do I include a php.ini file in another php.ini file?

How do I include a php.ini file in another php.ini file?
I don't think you can "include" .ini files from the main php.ini file.
One possible solution, though, might be to use this option on the configure line, when compiling PHP:
--with-config-file-scan-dir=PATH
Set the path where to scan for configuration files
If this option is used at compile-time, PHP will look for every .ini file in this directory, in addition to the "normal" php.ini file.
I suppose this is what is used by Ubuntu, for instance, which uses a different .ini file for each downloaded extension, instead of modifying php.ini.
The path to the php.ini file is being defined with this option, on the configure line:
--with-config-file-path=PATH
Set the path in which to look for php.ini [PREFIX/lib]
Still, it probably means you'll have to re-compile PHP -- which is not that hard, btw -- the hardest part being to get the dependencies you need.
And, here is a post on the internals# mailling-list that says the same thing as I do: config files and PHP_CONFIG_FILE_SCAN_DIR
One can also define the path in ~/.bashrc
export PHP_INI_SCAN_DIR=/usr/local/lib/php.d
I installed Memcached for php and wasn't sure how to make sure that its ini was included in my php.ini file, but as it turns out, it automatically is. You can validate what is being loaded by running php --ini.
php --ini
Configuration File (php.ini) Path: /opt/local/etc/php5
Loaded Configuration File: (none)
Scan for additional .ini files in: /opt/local/var/db/php5
Additional .ini files parsed: /opt/local/var/db/php5/memcached.ini
EDIT: My answer was mistaken. This only works in .conf files, which is not the question asked. Better testing showed that it won't work in php.ini files, where include statement is ignored.
I just tested it on Debian 9 (Stretch) with PHP-FPM. From some .conf file, use this syntax:
include=/path/to/special-php.ini
or even
include=/path/to/special-dir-full-of-conf-files/*.conf
as it is used in
/etc/php/7.0/fpm/php-fpm.conf
include=/etc/php/7.0/fpm/pool.d/*.conf
By the way, this will be most useful if you split your settings by topic, and or if you want a set for development and another one for production. Then you could do it the Debian/Apache style like
/etc/php/conf-available/
/etc/php/conf-enabled/
with symliks from the second to the other and an include to that one.
It seems you cannot include one ini file into another so it gets referenced and loaded. But you can set php up to load several files by telling it which folders to look into.
When using a FastCGI setup (possibly in FPM, too, though I don't know that for sure) you can export environment variables from within the PHP wrapper.
There you could do:
export PHP_INI_SCAN_DIR=/etc/php5/cgi/conf.d:/var/www/mydomain.net/etc
/var/www/mydomain.net/etc is just an example. It's the folder where you put your additional ini files into. It seems this can be a : separated list.
Use a phpinfo.php (file called arbitrarily containing only <?php phpinfo();), open the corresponding URL in your browser and check the list of directories that are parsed and the list of files that get loaded in the top area of it.
/etc/php5/cgi/conf.d should always be included (I guess because it was compiled into the PHP executable) and possibly not really be needed.
You can't. Read online pages:
The configuration file
SUMMARY: The configuration file
(php.ini) is read when PHP starts up.
For the server module versions of PHP,
this happens only once when the web
server is started. For the CGI and CLI
version, it happens on every
invocation.
.user.ini files
SUMMARY: In addition to the main
php.ini file, PHP scans for INI files
in each directory, starting with the
directory of the requested PHP file,
and working its way up to the current
document root (as set in
$_SERVER['DOCUMENT_ROOT']). Only INI
settings with the modes PHP_INI_PERDIR
and PHP_INI_USER will be recognized in
.user.ini-style INI files.
You could try to simulate it making use of the ini_set function. But as the "man page" indicates, not all ini options can be changed using ini_set. It's definitely a useful function, though.

Categories