I'm making use of a GD Library on my application which requires me to modify my php.ini to work. I understand if I uncomment to extension=fileinfo.so the application will work as required, but my challenge is that I don't have access to my shared host server configurations.
My question, Is there a way around using ini_set('', '')
Thanks ahead
Shared hosting has disabled ini_set() function for security reason
if the hosting provider turn on ini_set() to you, you can have full access to php variable control, which the hosting provider don't want
for your purpose, you can do it through .htaccess file within your application root folder
two directives are permitted using .htaccess
php_flag <boolean-flag-name> on|off
php_value <flag-name> <flag-value>
php_flag should be used for on/off values
For example, the following .htaccess file will disable globals, set the maximum file upload size to 20MB, and allow PHP scripts to run for 10 minutes (600 seconds):
php_flag register_globals off
php_value upload_max_filesize 20M
php_value max_execution_time 600
You can also use ini_set function. in php scripts which allows you to change a setting within your application at runtime. The function accepts two arguments:
ini_set(flag-name, flag-value),
Example
<?php
ini_set('register_globals', 0);
ini_set('upload_max_filesize', '20M');
ini_set('max_execution_time', 600);
?>
We can query the php interpreter before changing these value to query, we can use ini_get() method
ini_get(flag-name)
Returns the configuration value. I’d recommend checking your configuration change and taking appropriate action. Don’t assume ini_get() will always work.
ini_get_all([extension])
Returns all configuration values as an associative array. The optional extension parameter returns options specific to that extension, e.g. ‘allow_url_fopen’.
get_cfg_var(flag-name)
Returns the original configuration value from php.ini (not any overrides set in .htaccess or by ini_set).
ini_restore(flag-name)
Returns a configuration option to its original value.
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'm building a web app dealing with online file storage/access. In my local environment I used .htaccess to set
php_value upload_max_filesize 100M
php_value post_max_size 101M
After testing the app on a variety of servers I found that not all setups allow you to use the .htaccess method of modifying the ini settings. The solution I'm thinking of is to check for that permission during the install script and depending on what is allowed use either .htaccess, user directory php.ini, or ini_set(); for that particular installation.
ini_set() apparently doesn't work for post_max_upload. For some reason even though my php.ini has
user_ini.filename = ".user.ini"
it won't read the 2 directives in that file. Neither will it read the same information in the application directory named php.ini
And the .htaccess directives stated above result in a 500 Sever Misconfiguration Error. There's has to be a way to change the post_max_upload and upload_max_filesize on the fly.
The problem is that i don't know how to check for what is and isn't allowed on a particular server. Can someone help with that?
Your max execution time may be cutting the upload process short..
This is what I use in my admin area .htaccess -- maybe you can try these settings.
Don't use these settings globally, only set them for the .htaccess that has your upload or admin scripts isolated from the rest of your site, or else you might encounter problems with such a high amount of execution time.
php_value upload_max_filesize 30M
php_value post_max_size 30M
php_value max_execution_time 600
php_value max_input_time 200
If you can't get anything working perhaps your host has disabled .htaccess and ini setting changes...
One possible issue here is that I was trying to add the 2 lines in the original post to a php.ini file by themselves. Perhaps this is basic for some, but apparently you can't do that? It seems that you need to redeclare all of the rest of the php.ini settings into a directory-specific php.ini, and then just change the applicable lines.
This seems kind of a funky way to do things, though, so maybe I'm wrong... Can anyone tell me with more confidence that indeed this is the case, or that I'm mistaken?
I want to change the php setting but from ".php" page not php.ini. The settings I want to change is
upload_max_filesize, post_max_size and memory_limit
You can try it with a .htaccess file, if you have AllowOverride Options:
Place a file named .htaccess to your webroot:
php_value upload_max_filesize 10000
php_value post_max_size 10000
php_value memory_limit 10000
The only one of those that can be changed from within PHP is the last one, which can be changed with ini_set like this:
ini_set('memory_limit', '32M');
PHP always processes the client request before the PHP script is started. This means that uploaded files are already uploaded and posted forms are already fully posted beforeb he script starts. The upload and post settings can therefore not be set in the script, ebcause they are already irrelevant when the PHP script is started.
If your server administrator hasn't prevented it, you can use ini_set() to change the memory limit:
ini_set("memory_limit","16000000"); // abbreviations like "16M" work only
// in php.ini, always use full numbers here
The two other options are needed before the PHP script is loaded, there is no way to change those in php.ini.
Use
ini_set ('key', 'value');
Note that not all the available options can be changed using ini_set(). Here'is a list: ini.list
Read more in ini_set reference;
I want to change the php setting but from ".php" page not php.ini. The settings I want to change is
upload_max_filesize, post_max_size and memory_limit
You can try it with a .htaccess file, if you have AllowOverride Options:
Place a file named .htaccess to your webroot:
php_value upload_max_filesize 10000
php_value post_max_size 10000
php_value memory_limit 10000
The only one of those that can be changed from within PHP is the last one, which can be changed with ini_set like this:
ini_set('memory_limit', '32M');
PHP always processes the client request before the PHP script is started. This means that uploaded files are already uploaded and posted forms are already fully posted beforeb he script starts. The upload and post settings can therefore not be set in the script, ebcause they are already irrelevant when the PHP script is started.
If your server administrator hasn't prevented it, you can use ini_set() to change the memory limit:
ini_set("memory_limit","16000000"); // abbreviations like "16M" work only
// in php.ini, always use full numbers here
The two other options are needed before the PHP script is loaded, there is no way to change those in php.ini.
Use
ini_set ('key', 'value');
Note that not all the available options can be changed using ini_set(). Here'is a list: ini.list
Read more in ini_set reference;
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.