10

How can i check if server configuration allows me to set an option like:

ini_set('upload_max_filesize', '8M');

in a PHP script? Here is a list of php.ini directives but i can't really figure out how to make a check before tring to change that value.

hakre
  • 193,403
  • 52
  • 435
  • 836
  • Blocking? who will be changing ini settings on your server? – Damien Pirsy Dec 17 '11 at 11:03
  • I think you can't block them. The settings you can set at runtime are allowed to set. – djot Dec 17 '11 at 11:03
  • read this comment: http://www.php.net/manual/en/function.ini-set.php#30424 – yasar Dec 17 '11 at 11:03
  • This needs more detail. What exactly is your issue, which option do you want to "block" and what do you want to happen instead? – Pekka Dec 17 '11 at 11:05
  • @Polmonino Your update completely changes your original question; why you asked how to _block_ the use of ini_set() then?? – Damien Pirsy Dec 17 '11 at 11:14
  • @DamienPirsy because i can test it blocking an tring to change the directive. –  Dec 17 '11 at 11:19
  • Not all settings can be changed within your code, and upload_max_filesize is one that cannot - logically, by the time the script executes, the file has already been uploaded/rejected as too large - in the list of settings, only those marked PHP_INI_USER or PHP_INI_ALL can be set using ini_set() from within your scripts – Mark Baker Dec 17 '11 at 11:32
  • @MarkBaker upload_max_filesize can be modified during runtime in versions <= 4.2.3 – Filip Roséen - refp Dec 17 '11 at 14:52

3 Answers3

11

Check if I'm allowed to use ini_set for some option, how?

ini_set will return the old value on success, and false* on failure. With this knowledge you can write a statement checking if your call went through, like the below.

$result = ini_set ("some_option", "some_value");
$failure = (version_compare(PHP_VERSION, '5.3.0') >= 0) ? false : '';
if ($result === $failure)
   echo "Unable to use ini_set to change 'some_option'!";

(*): Note the return value changed in PHP 5.3.0 from '' (an empty string) to false. So you need to check your current PHP version as well.


Another method is to use ini_get_all which will provide you with details regarding every option available, and it's access level.

$all_option_details = ini_get_all ();

/* see the comments in this post regarding PHP_INI_USER vs INI_USER
 * seems like someone writing the relevant PHP documentation fcuked up
 *
 * props to @soulmerge */

if ($all_option_details['upload_max_filesize']['access'] & INI_USER)
   echo "we are allowed to change upload_max_filesize from with ini_set!";

I'd like to disable the use of ini_set for some option(s), how?

There are a few methods of making options unchangeable runtime (in a way disabling ini_set), among them are the following two which you can read more about at the provided link.

php_admin_value name value

Sets the value of the specified directive. This can not be used in .htaccess files. Any directive type set with php_admin_value can not be overridden by .htaccess or ini_set(). To clear a previously set value use none as the value.

 

php_admin_flag name on|off

Used to set a boolean configuration directive. This can not be used in .htaccess files. Any directive type set with php_admin_flag can not be overridden by .htaccess or ini_set().


Example (taken from this documentation)

<IfModule mod_php5.c>
  php_value include_path ".:/usr/local/lib/php"
  php_admin_flag engine on
</IfModule>

<IfModule mod_php4.c>
  php_value include_path ".:/usr/local/lib/php"
  php_admin_flag engine on
</IfModule>
Filip Roséen - refp
  • 62,493
  • 20
  • 150
  • 196
  • I'm tring your method but on my system (local development) echoing `PHP_INI_USER` gives me undefined _Use of undefined constant PHP_INI_USER_... –  Dec 17 '11 at 12:46
  • According to the documentation `PHP_INI_USER` has a value of `1`, therefor we should use this value instead (ie. don't use the constant) – Filip Roséen - refp Dec 17 '11 at 13:07
  • Using magic numbers instead of constants is never a good idea, if the constant is missing, there must be a reason for that. According to the documentation of `ini_get_all()` the $details parameter was introduced in PHP 5.3. Looks like Polmonino is using an earlier version of PHP. – soulmerge Dec 17 '11 at 13:24
  • @soulmerge Yes, I agree with you. Though there is nothing saying (in the docs) that PHP_INI_USER actually is defined as a constant, that was an assumption from my part, which turned out to be incorrect. With a proper comment (you can get away with using "magical numbers", or just define your own constant - with a comment describing what is going on) – Filip Roséen - refp Dec 17 '11 at 13:25
  • 2
    You are right, this looks like a documentation error on php.net: The constant is actually called `INI_USER` (http://www.php.net/manual/en/reserved.constants.php), not `PHP_INI_USER` (http://www.php.net/manual/en/configuration.changes.modes.php) – soulmerge Dec 17 '11 at 13:34
  • I've PHP Version 5.3.8 on windows x64, so there is something wrong with PHP documentation... –  Dec 17 '11 at 13:56
  • @refp will your solution work even if the server use suhosin (see soulmerge anwser)? –  Dec 17 '11 at 13:58
  • @Polmonino AFAIK it should work, and I cannot find anything in the documentation of suhosin saying that it could prevent this functionality. – Filip Roséen - refp Dec 17 '11 at 14:54
  • @refp there is something wrong here. Even if max_execution_time as access = 7 (INI_ALL) calling ini_set('max_execution_time', "120") is not workig... any clue? –  Dec 17 '11 at 20:05
  • ini_set will only set the value of which the time limit counter will start at, you'll need to use [`set_time_limit`](http://php.net/manual/en/function.set-time-limit.php) to reset the counter. – Filip Roséen - refp Dec 17 '11 at 20:10
  • @Polmonino are you looking for an alternative answer? Please elaborate your question then so I can help you out, otherwise please mark the answer as accepted. – Filip Roséen - refp Dec 20 '11 at 15:53
3

It is impossible to know what your real limit is unless you try to set the desired value. There might be the suhosin patch installed, for example, which could prevent you from changing the value at all.

So your only option for checking if it is possible is to try it and check the return value (which you should to in any case):

$oldValue = ini_get('upload_max_filesize');
if (ini_set('upload_max_filesize', '8M') === false) {
    die("Couldn't update upload file size.");
}
if (ini_set('upload_max_filesize', $oldValue) === false) {
    die("Error resetting upload file size.");
}
// you can safely assume that it is possible to set
// upload_max_filesize to 8M from this line onward.
soulmerge
  • 73,842
  • 19
  • 118
  • 155
  • Check my post for alternative methods, you don't HAVE to call `ini_set` to see if it's possible to change the value. Also, you should write `ini_set (...) === false`, the above could potentially lie due to implicit conversion rules. – Filip Roséen - refp Dec 17 '11 at 11:42
-3
echo ini_get (<BLA>);
ini_set (<BLA>);
echo ini_get (<BLA>);
djot
  • 2,952
  • 4
  • 19
  • 28