Auteur Message
Administrateur
Avatar de l’utilisateur
Ce sujet donnera des solutions à des erreurs silencieuses personnellement rencontré.

D’abord, justement pour rendre les erreurs moins silencieuses, une astuce pour avoir comme un “ php.ini ” qui s’applique automatiquement à tous les sous répertoires au lieu de devoir le copier dans chaque sous‑répertoire (ce qui est fastidieux, sujet aux oublis et peut dissuader d’organiser en répertoires). Parfois même, “ php.ini ” n’est cherché que dans un répertoire et pas dans ses sous‑répertoires, même s’il y est présent. Note : même je ne recommande plus ce fichier, plutôt que le copier, on peut aussi faire des liens symboliques vers le fichier en amont, plus haut dans la hiérarchie des répertoires.

L’astuce est d’utiliser un fichier “ .user.ini ” au lieu de “ php.ini ”, mais ça ne fonctionne qu’avec PHP en mode CGI ou FastCGI, ce qui presque toujours le cas, ça ne fonctionne pas avec PHP en mode module Apache. Notez bien le point initial dans le nom, ce qui en fait d’ailleurs un fichier caché. Le nom est mal choisi (on peut le changer chez soi, mais peut‑être pas sur un hébergement web), rien n’indique que c’est un fichier spécifique à PHP, mais bien d’autres noms de fichier sont dans le même cas, après‑tout, alors pourquoi en dire plus de mal qu’avec d’autres.

Il faut éviter d’y mettre des commentaires, même si c’est permis, parce qu’il y a des bugs. Dans un de ces fichiers, j’ai ajouté un commentaire sur plusieurs lignes, une ligne ouvrait une parenthèse qui était fermée sur la seconde, et bien que c’était un commentaire, ça a été vu comme une erreur de syntaxe, empêchant de lire le fichier et donc d’appliquer ses directives.

Par exemple, avec « mon » PHP 8.3, ce commentaire rendait le fichier incorrecte :

Code : 

# See https://www.php.net/manual/en/configuration.file.per-user.php
# php.ini does not always work and it seems to be working, the behaviour
# may differs from that of the specification (ex. php.ini looked for only
# in the current script's directory, not beyond/outer).


Exemple à utiliser localement pour un site sur votre ordi’, pas pour un site sur le web, comme ça indique d’afficher les erreurs aussi dans la réponse aux requêtes :

Code : 

error_reporting = E_ALL | E_STRICT;
log_errors = On;
display_errors = On;
error_log = "/votre-repertoire/php-errors.log";


Pour un site sur le web, mieux vaudrait ceci :

Code : 

error_reporting = E_ALL | E_STRICT;
log_errors = On;
display_errors = Off;
error_log = "/votre-repertoire/php-errors.log";


Voir : .user.ini files (php.net).
Profil
Administrateur
Avatar de l’utilisateur
Pour la conjonction logique, éviter le “ and ”, préférer le “ && ” qui est à ne pas confondre avec le “ & ”.

“ and ” est une mauvaise surprise, parce que “ $a = $b and $c ” ne se lit pas comme on le croit spontanément. Au lieu de se lire “ $a = ($b and $c) ” ça se lit “ ($a = $b) and $c ”, parce que l’opérateur “ and ” est moins prioritaire que l’opérateur d’affectation “ = ” , alors la variable $a reçoit la valeur 1, de $c, et seulement ensuite la conjonction entre la première expression (dont la valeur est maintenant celle de $a) et la seconde, est testée.

Code : 

php > $b = 1;
php > $c = 0;
php > $a = $b and $c;

On s’attend à ce que $a soit faux (vide ou nul ou zéro ou etc), mais mauvaise surprise :

Code : 

php > echo $a;
1


Code : 

php > echo ($a = $b and $c);
php >

“ $a = $b ” est évalué, qui renvoi 1 comme $a a été affecté à 1, ensuite la conjonction entre 1 et 0 est testé et elle renvoi faux, c’est à dire par exemple vide, pour PHP.

Code : 

php > $a = ($b and $c);
php > echo $a;
php >

C’est le résultat auquel on s’attend, mais pour l’obtenir, il faut ajouter des parenthèses qu’on ne s’attend pas à devoir ajouter.

On peut chercher une erreur longtemps comme ça, après s’être relu, parce que ce qu’on a écrit n’est pas interprété comme on le croirait.

Avec “ && ”, c’est bien le résultat attendu :

Code : 

php > $b = 1;
php > $c = 0;
php > $a = $b && $c;
php > echo $a;
php >


Mais attention à ne pas confondre “ && ” et “ & ” ; c’est parfois logiquement la même chose, mais généralement pas. Le “ & ”, c’est le “ bitwise‑and ”, celui des masques binaires et du langage assembleur :

Code : 

php > echo (2 && 1);
1

Normal.

Code : 

php > echo (2 & 1);
0

Pourquoi n’est ce plus pareil ? Parce que 2, c’est 10 en binaire et la conjonction des deux masques binaires 10 et 01, c’est 00.

Code : 

php > echo (3 & 1);
1

3, c’est 11 en binaire et la conjonction des deux masques binaire 11 et 01, c’est 01.

Ceci s’applique à PHP, mais pas nécessairement à tout ce qui en dépend. Par exemple, les forum phpBB, utilisent un langage de template, avec lequel l’opérateur “ and ” a bien le comportement attendu. Note : il doit être écrit en majuscule, malgré que les autres instructions s’écrivent en majuscule ; mais ça déborde un peu du sujet, c’était juste pour le dire, comme ça peut aussi être une source d’erreurs.
Profil
Administrateur
Avatar de l’utilisateur
Les constructeurs qui semblent ignorés : une conséquence des évolutions de PHP à travers ses versions.

Avant, le nom d’un constructeur devait être le même que celui de la classe, c’est ce qui le distinguait comme constructeur.

Exemple :

Code : 

// À ne plus faire avec les nouvelles versions.
class abc {
function abc () {

}
}

Avec classe écrite ainsi, avec les nouvelles versions de PHP, “ new abc() ”, n’appelle pas le constructeur. Normalement, il y a des versions de transition, qui renvoient des messages d’avertissements, pour cet exemple, en signalant que cette classe utilise un ancien style de constructeur ; mais encore faut‑il vérifier les logs d’erreurs ou même en avoir ou qu’ils soient bien configurés, et même s’ils sont vérifiés, avoir le temps de s’en occuper. Aussi, comme PHP est un langage interprété et non‑pas compilé, seules les classes utilisées dans une période, généreront des messages pendant cette période et les autres classes pourront réserver des mauvaises surprises loin plus tard avec une version ultérieure qui ne sera plus une version de transition pour cet aspect et n’indiquera plus rien, ne laissant qu’une erreur silencieuse et incompréhensible.

Depuis un peu longtemps déjà, les auteurs du langage ont décidé que ce qui distingue un constructeur, c’est le nom spécial “ __construct ”, avec deux tirets-bas (alias blancs soulignés).

Exemple :

Code : 

// À toujours faire avec les nouvelles versions,
// mais jamais avec les anciennes.
class abc {
function __construct () {

}
}


Voir : Old style constructor (exakat.readthedocs.io).
Profil