I want to set my own (php2.ini) file, with just a few lines that must overwrite the first php.ini settings - only for those lines.
So I start looking on google and it seems like what I need is the parse_ini_file function.
Ok. Now, in index.php I have:
parse_ini_file("php2.ini");
phpinfo();
exit();
But those settings from php2.ini are not loaded...
Trying to see if the file php2.ini is read-it and it is, beacause if I set parse_ini_file("php2-not-exist.ini"), it tells me that the file cannot be found. So the file php2.ini is read, but the settings are not overwritten.
The php2.ini file has inside the next lines:
error_log = "errors.log"
display_errors = "0"
max_execution_time = "300"
upload_max_filesize = "60M"
post_max_size = "60M"
date.timezone = "Europe/Bucharest"
default_charset = "UTF-8"
mbstring.internal_encoding = "UTF-8"
mbstring.http_output = "UTF-8"
mbstring.encoding_translation = "On"
mbstring.func_overload = "6"
Trying to let this file with just one line like post_max_size = "60M", but still not overwriting the general php.ini settings.
What am I missing here?
I know that some settings can be setted only and only using the php.ini file configuration. So setting a second file with parse_ini_file witch is a function from php... something is not correct, because some servers doesn't allow you to edit the general php.ini file. So how can the php let you set a second php ini file if you don't have access to the general one ? I don't know if that has something to do with my problem. I'm just saying that maybe here is the problem.
Right now I'm using wamp with php 5.5.12. I just want when I upload my website up, to be all done. I know that some hosting servers lets you to have a second php.ini file that must be uploaded in public_html or whatever folder it is. This is why I want to set my php2.ini file. To have the website clean when I'll upload to hosting.
Thank you.
The php parse_ini_file() function reads an ini file into an associative array. It does not set them up as settings like the php.ini file.
There is not a convenience function to override the server settings like this. What you may want here are .user.ini (the leading dot is important) files:
Since PHP 5.3.0, PHP includes support for configuration INI files on a per-directory basis.
and:
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']). In case the PHP file is outside the document root, only its directory is scanned.
For full documentation on that feature, take a look at http://php.net/manual/en/configuration.file.per-user.php.
Note that only a subset of settings can be changed here:
Only INI settings with the modes PHP_INI_PERDIR and PHP_INI_USER will be recognized in .user.ini-style INI files.
Related
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.
I am trying to use PHP's built-in function get_browser(). I followed the instructions in this useful post, but I'm still getting the error
browscap ini directive not set.
I downloaded the php_browscap.ini file and moved it into the same directory as my .htaccess file, so that its location is home/hostname/subdomain/php_browscap.ini Since I do not have access to my php.ini file, I am trying to edit the browscap property using .htaccess. This is what I entered:
php_value browscap home/hostname/subdomain/php_browscap.ini
I don't know if it matters, but below that there's some Rewrite Engine code.
As forementioned, I am still getting the error above. What did I do wrong?
Thanks.
The browscap PHP value has a changeable mode of PHP_INI_SYSTEM meaning it can only be set in php.ini or httpd.conf (not .htaccess).
Do a phpinfo() to understand your PHP runtime config. If your system is configure as "CGI/FastCGI" then it is probably running suPHP as the PHP initiator. In this case you can specify your own php.ini file. By default suPHP looks in the script directory but you can override this by the following directive in your .htaccess file:
suPHP_ConfigPath (expects a path name)
This option tells mod_suphp which path to pass on to the PHP-interpreter (by setting the PHPRC environment variable). Do NOT refer to a file but to the directory the file resists in.
E.g.: If you want to use "/path/to/server/config/php.ini", use "suPHP_Config/path/to/server/config".
If you don't use this option, PHP will use its compiled in default path.
Also you must use a properly formed path in your browsercap directive e.g.
browscap="/home/hostname/subdomain/php_browscap.ini"
(Note the leading /)
Addendum
I've just check and the Dreamhost shared hosting plan uses suEXEC. With suEXEC you can normally override the php.ini patch by copying the system php.ini (phpinfo() tells you where to find this) into a private directory, say _private as well as the browsercap.ini then adding
SetEnv PHPRC /home/hostname/_private
to your .htaccess file. If this doesn't work then the issue is specific to Dreamhost's suEXEC config and you need to ask this Q on http://discussion.dreamhost.com/
There are two potential problems here.
Perhaps your host does not allow you to override ini settings in the .htaccess file.
Maybe browscap does not like the path you have provided. Try:
php_value browscap /home/hostname/subdomain/php_browscap.ini
And ensure that permissions on that file allow the web user to read it.
If you are on a shared hosting and do not have access to the system php.ini then you can use the following standalone replacement of php's native "get_browser()" implementation.
https://github.com/garetjax/phpbrowscap
I've set magic_quotes_gpc = Off in php.ini,but I see it's still On in phpinfo();
First of all, you must be sure you modified the right php.ini file : there can be many files called php.ini -- and only one is "the right one".
You can see which php.ini file is used in the output of phpinfo() : there should be an entry called Configuration File (php.ini) Path that indicates the directory in which php.ini is looked for, and an entry called Loaded Configuration File that indicates the full path+name of the php.ini file that's used.
Then : don't forget to restart the webserver, so the modifications to php.ini are taken into account (Not sure that's necessary with IIS, but as it's required with Apache, I suppose it cannot hurt with IIS)
If that doesn't change a thing : what if you try to modify another directive : is the modification taken into account ?
As an alternative, you can disable it from your script too:
// disable magic_quotes_runtime
if (get_magic_quotes_runtime())
{
#set_magic_quotes_runtime(0);
}
You can check the php.ini file that was loaded via the php_ini_loaded_file function. Restart your web server.
On my installation the c:\php\php.ini file was named php ini. So phpmyinfo() was not loading it, despite the PATH environment variable including C:\php\. (Check this in a DOS prompt with SET PATH).
So rename it to php.ini.
It was difficult to spot in Windows Explorer.
I opened the notepad, inserted 3 lines in it, saved it as php.ini, and uploaded it in public_html, but I am still getting an error that requires to first switch the magic quotes off. The syntax of the three lines is as following:
magic_quotes_gpc = 0
magic_quotes_runtime = 0
magic_quotes_sybase = 0
What am I doing wrong?
use phpinfo() function to see what php.ini file you're actually using
You can probably alter these settings in a .htaccess configuration file as well:
php_flag magic_quotes_gpc off
php_flag magic_quotes_runtime off
php_flag magic_quotes_sybase off
See PHP: How to change configuration settings.
Most hosting companies lets you define a local ini file. Check their support pages, and see where you should put your php.ini file for it to be read by the php engine. If they have an option for this, you don't have to worry about restarting the server.
If you can't find any info about it, create a page with the following code:
<?php phpinfo(); ?>
And look for the property named "Configuration File (php.ini) Path". This is where you should put the file.
It's not meant to be placed in the public_html folder... it should be in your PHP installation folder.
Php.ini is not usually located in public_html. If you can't access your real php.ini, try writing
php_flag magic_quotes_gpc off
in a .htaccess file (in public_html).
Most hosting companies won't let you play around with the php.ini unless you rent a dedicated server from them. On that, you could try on page php.ini settings like the following:
ini_set("magic_quotes_gpc", "0");
ini_set("magic_quotes_runtime", "0");
ini_set("magic_quotes_sybase", "0");
If that doesn't work, then you'll have to ask your hosting company about it.
On CentOS 8 run
service php-fpm restart
To read the edited php.ini file
Well, you have to change your main php.ini which I don't think is in public_html.
Moreover, in order to see the changes you have to restart your php engine.
We have PHP 5.2.6 deployed to c:\php and in that folder there is the php.ini file. On Windows, can a website override these settings similar to the way that apache has .htaccess? e.g.
DirectoryIndex index.php index.html
<IfModule mod_php5.c>
php_flag magic_quotes_gpc off
php_flag register_globals off
</IfModule>
<IfModule mod_php4.c>
php_flag magic_quotes_gpc off
php_flag register_globals off
</IfModule>
Update:
I was aware of ini_set() but wondered if there was a declarative way to do this in a configuration file in the website rather than in script.
I would recommend doing all you can to avoid changing register_globals to on as it's a major security hole.
But you can try using init_set() to change the settings within your PHP code, although some settings cannot be changed once PHP has started running. (These are somewhat server dependent I believe.)
You can override the directives in the php.ini file several ways, but not all directives can be changed by each method. See the php.ini directives page in the manual for a list of the directives and the methods that will work on each one.
The last column in the table lists the methods that will work on that particular method. In increasing level of access:
PHP_INI_USER - Can be set in user
scripts with ini_set() (or any higher method)
PHP_INI_PERDIR - Can be set using
the .htacess file with php_value
for string values or php_flag for
binary values (or any higher method)
PHP_INI_SYSTEM - Can
be set using php.ini or httpd.conf
only (both require access to the server's configuration files)
PHP_INI_ALL - Can be set using
any of the above methods
ini_set should do what you're after -
$option = 'magic_quotes_gpc';
echo "Value of $option => ", ini_get($option);
ini_set($option,0);
echo "New value of $option => ", ini_get($option);
A caveat here is that just because you can set the value at run-time doesn't mean it will work as expected, e.g. setting register_globals at runtime will be of little use as that setting has already done it's job by the time your script starts.
From http://us.php.net/configuration.changes:
Changing PHP configuration via the Windows registry
When running PHP on Windows, the configuration values can be modified on a per-directory basis using the Windows registry. The configuration values are stored in the registry key HKLM\SOFTWARE\PHP\Per Directory Values, in the sub-keys corresponding to the path names. For example, configuration values for the directory c:\inetpub\wwwroot would be stored in the key HKLM\SOFTWARE\PHP\Per Directory Values\c\inetpub\wwwroot. The settings for the directory would be active for any script running from this directory or any subdirectory of it. The values under the key should have the name of the PHP configuration directive and the string value. PHP constants in the values are not parsed. However, only configuration values changeable in PHP_INI_USER can be set this way, PHP_INI_PERDIR values can not.
...Haven't actually tried this yet, so your mileage may vary.
I just found a new way of doing this.
First of all, I used phpinfo() to find the PHP.ini being used by my Hosting provider.
Thereafter, I uploaded a file containing the following code to my Hosting space:
$fsrc = fopen($pathToIni,'r');
$fdest = fopen($myHostingDir,'w+');
$len = stream_copy_to_stream($fsrc,$fdest);
fclose($fsrc);
fclose($fdest);
echo $len;
This effectively copied the php.ini to my Hosting space. Thereafter, I downloaded that php.ini, changed the register_globals to off (for which I did all this), and uploaded it to the root of my Hosting space. Bingo, there you go.
I have relied on the fact that IIS uses the complete php.ini if available in a directory. You cannot override only specific settings like that using .htaccess on Apache.
For cgi environments, there is a module called htscanner. It basically fakes .htaccess behavior and allows per directory configurations. Unfortunately I have no experience with this on Windows, let alone with IIS6.