PHP analyse-t-il le fichier php.ini?

24

Exécution de PHP version 7.1.30 sous RHEL 7.7.

Je veux bump memory_limit, mais je ne savais pas si j'avais la bonne syntaxe (ie 256M ou 256MB). Donc, pour commencer, j'ai mis une mauvaise valeur "Hugo" dans le paramètre memory_limit. Le problème est que le résultat de phpinfo () (exécuté sous httpd) a littéralement la chaîne "Hugo" en place, c'est-à-dire:

entrez la description de l'image ici

Cela m'inquiète donc quelque peu que PHP ne vérifie pas la valeur de la ou des valeurs. (Si la valeur fournie était mauvaise, je m'attendrais à ce qu'elle revienne à une valeur par défaut, par exemple)

Quelqu'un peut-il commenter cela - en particulier, comment savoir si PHP appliquera les choses (si une chaîne arbitraire peut être fournie).

Patrick Rynhart
la source
4
Excellente question.
tink
3
De ceci: php.net/manual/en/faq.using.php#faq.using.shorthandbytes Je suppose que c'est la même chose que (int) 'HUGO'; // => 0. Ce qui commence à échouer sur ma machine à 2 Mo de mémoire utilisée.
Yoshi
Pour mémoire, la syntaxe correcte estmemory_limit 256M .
Tigger
@Yoshi Je pense que vous devriez publier votre réponse. C'est une bonne explication
Maksym Fedorov
@MaksymFedorov J'hésite car je n'ai pas vraiment de référence pour mon hypothèse. Pour l'instant, ce n'est qu'une observation.
Yoshi

Réponses:

19

La chose déroutante ici est que le paramètre ressemble à un entier avec une syntaxe spéciale, mais est défini en interne comme une chaîne. La chaîne est ensuite analysée dans une variable globale distincte chaque fois que la valeur est modifiée. Fondamentalement, le résultat de l'analyse de la chaîne en un entier n'est pas enregistré dans la table des paramètres, donc lorsque vous appelez phpinfo(), vous voyez l'entrée d'origine, pas la valeur analysée.

Vous pouvez le voir dans la source:

La syntaxe prise en charge est finalement définie dans zend_atol, qui:

  1. analyse la chaîne pour une valeur numérique, en ignorant tout texte supplémentaire
  2. se penche sur le dernier caractère de la chaîne, et multiplie la valeur précédente si elle est g, G, m, M, kouK

Une valeur sans chiffre au début sera analysée comme zéro. Lors de la définition de la variable globale, cela définira la limite de mémoire au minimum autorisé, en fonction de la constante ZEND_MM_CHUNK_SIZE.

Vous pouvez voir l'effet en définissant la limite de mémoire, puis en exécutant une boucle qui alloue rapidement une grande quantité de mémoire et en voyant ce qui apparaît dans le message d'erreur. Par exemple:

# Invalid string; sets to compiled minimum
php -r 'ini_set("memory_limit", "HUGO"); while(true) $a[]=$a;'
# -> PHP Fatal error:  Allowed memory size of 2097152 bytes exhausted

# Number followed by a string; takes the number
php -r 'ini_set("memory_limit", "4000000 HUGO"); while(true) $a[]=$a;'
# -> PHP Fatal error:  Allowed memory size of 4000000 bytes exhausted

# Number followed by a string, but ending in one of the recognised suffixes
# This finds both the number and the suffix, so is equivalent to "4M", i.e. 4MiB
php -r 'ini_set("memory_limit", "4 HUGO M"); while(true) $a[]=$a;'
# -> PHP Fatal error:  Allowed memory size of 4194304 bytes exhausted
IMSoP
la source
Merci @IMSoP pour cette excellente évaluation. Doit-on signaler ce genre de chose dans une sorte de bugtracker? Je trouve la réponse que phpinfo () génère très contre-intuitive. Et une sortie de débogage pour ce que fait php quand il rencontre des valeurs inattendues ne serait pas non plus mal.
tink
1
@tink Je suppose que vous pouvez faire une demande de fonctionnalité sur bugs.php.net , ou envoyer un message à la liste de diffusion Internals, où se déroule la plupart des coordinations. J'ai trouvé une demande similaire il y a plusieurs années , mais elle ne semble pas avoir eu de réponse.
IMSoP
Merci encore, examinera cela! :)
tink
0

Tout d'abord, nous devons d'abord comprendre comment PHP.ini fonctionne en termes de workflow d'interprétation. memory_limit est des directives pour PHP.

lors de l'utilisation avec la fonction PHP, vous devez faire quelque chose comme ça ini_set(‘memory_limit’,’256MB’). Ainsi, cette fonction définira temporairement votre valeur sur la variable interprète. Si vous voyez de plus près, vous pouvez obtenir les deux colonnes, l'une pour le local et l'autre pour le global. Cela montre la capacité des valeurs à l'individu respectivement.

Mais, lorsque vous avez défini pour global, vous devez définir un suffixe avec K, M, G respectivement. Si nous dépassons cette valeur en utilisant apache .htaccess, cela nécessite la même chose pour le PHP fpm.

Pranav Bhatt
la source
3
Je voudrais souligner que l'OP ne demande pas comment définir la limite de mémoire :)
Karolis