8723 sujets

Développement web côté serveur, CMS

Pages :
Bonjour,
le passage d'un serveur à php 8 peut-il apporter des dysfonctionnements sur un script php qui fonctionnait bien sur la version précédente ? Et dans ce cas, à quoi faut-il prêter attention dans le code ?
Modifié par niuxe (09 Jan 2024 - 09:36)
Merci,

j'ai parcouru les avertissements, c'est un peu complexe pour moi qui débute en php. Reprendre un code que j'ai eu de la peine à faire fonctionner en y apportant des adaptations n'est pas une partie de plaisir, et un peu une déception. Smiley decu
On change de version, hop, ça ne fonctionne plus totalement. Est-ce qu'il existe un validateur à jour qui indiquerait les fonctions obsolètes ?
Salut,

Même avec plus d'expérience, les migrations ne sont jamais une partie de plaisir Smiley lol
Comme te l'indique Niuxe, prendre connaissance des "Breaking changes" de chacune des version de PHP te permettra de savoir d'avance quelles fonctions ne sont plus supportées. L'idée n'est pas de comprendre tous ces breaking changes, mais plutôt de déterminer si ton script est concerné par l'un ou plusieurs de ces changements.

La stratégie, c'est d'y aller petit à petit, et de tester ton code à chaque mise à jour. Au pire, les erreurs t'aideront à migrer peu à peu. Il te suffira de les corriger une par une jusqu'à ce que ton code fonctionne correctement.

a écrit :
Est-ce qu'il existe un validateur à jour qui indiquerait les fonctions obsolètes ?

Ton IDE devrait d'ores et déjà être un bon allié là-dessus. Par exemple, avec VS Code et l'extension PHP Intelephense, tu peux très facilement changer la version de PHP du linter. De cette façon, l'éditeur de code soulignera en rouge les fonctions disparues, et en bleu les fonctions dépréciées, qui disparaitront bientôt.
Avec un autre IDE comme PHP Storm, cela est natif il me semble.

Et puis, dans tous les cas, si tu ne parviens pas à migrer une partie de ton code, tu sais où poster pour demander de l'aide Smiley cligne

Bon courage !
Modifié par Loraga (08 Jan 2024 - 20:40)
Modérateur
Bongota a écrit :
Est-ce qu'il existe un validateur à jour qui indiquerait les fonctions obsolètes ?


Le seul validateur que tu as, c'est ton php installé dans ton système. Je pense que tu devrais t'installer x debug¹. J'ai regardé en Z cette video qui devrait t'aider. Sur un Unix like, ce sera légèrement différent pour la config (endroit des fichiers de config).


Loraga a écrit :
Salut,

Même avec plus d'expérience, les migrations ne sont jamais une partie de plaisir Smiley lol
...
Et puis, dans tous les cas, si tu ne parviens pas à migrer une partie de ton code, tu sais où poster pour demander de l'aide Smiley cligne

+1
Loraga a écrit :
Avec un autre IDE comme PHP Storm, cela est natif il me semble.

Les produits de Jetbrains sont excellents.
@bongota: il y a eclipse php


¹ Attention, la config se fait dans le php.ini d'apache et/ou dans le php-cli. Tout dépend comment tu lances ton application (apache VS php en mode serveur de développement)
Modifié par niuxe (08 Jan 2024 - 21:06)
Merci pour toutes les réponses, du taf...
Pour m'en sortir momentanément, je peux utiliser la méthode bourrin, changer la version de php sur le serveur de mon hébergeur, ce qui est possible. J'ai un site chez eux qui est sous php 7 et mon fichier php fonctionne sur ce site. Toujours chez eux, je prends un nouvel hébergement pour un autre site sur lequel il y a le même fichier php. Je regarde leur configuration et je vois que sur cet hébergement, ils sont passés à php 8.
Le problème est sur le formulaire. Ce formulaire fonctionne toujours avec php 8, le message est bien envoyé. C'est la partie mots interdits qui ne fonctionne plus. J'avais passé un temps fou dessus pour arriver à le mettre en place. Smiley fache
Je vais faire un pen. Un peu de temps SVP.

modération: suppression lien
Modifié par niuxe (09 Jan 2024 - 09:36)
J'ai regardé un peu mon code php et comparé avec le tableau des fonctionnalités obsolètes.
Apparemment, il n'y a rien de suspect, car je ne vois aucune fonction qui aurait bougé au passage vers php 8. Le développeur du script avait d'ailleurs déjà utilisé les changements apportés. Par exemple "foreach" à la place de "each". Ailleurs, je ne vois rien de spécial.
Je donne la partie de code qui ne fonctionne pas. Je précise de nouveau, le message du formulaire est envoyé sans problème, c'est la détection des mots interdits qui ne va pas.

<?php
function isValidEmail($email)
 {
    return preg_match('/^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))/i', $email);
}
function remplacerAccents($chaine){
    $a = ['à','á','â','ã','ä','å', 'æ','?','?','?','?','?','?','À','Á','Â','Ã','Ä','Å', 'Æ','ç','Ç','Ð','?','?','?','?','?','?','?','?','?','?','?','?','È','É','Ê','Ë','è','é','ê','ë','?','?','?','?','?','?','?','?','ƒ', '?', '?','?','?','?','?','?','?','?','?','?','?','?','?','Ì','Í','Î','Ï','ì','í','î','ï','?','?','?','?','?','?','?','?', '?', '?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','ñ','Ñ','?','?','?','?','?','?','?','?','?','Ò','Ó','Ô','Õ','Ö','ð','ò','ó','ô','õ','ö','ø','Ø','?','?','?','?', 'Œ', 'œ','?','?','?','?','?','?','ß','?','?','?','?','?','?','?','Š','š','?','?','?','?','?','?','Ù','Ú','Û','Ü','?','?','?','?','?','?','?','?','?','?','?','?','ù','ú','û','ü','?','?','×','Ý','?','?','Ÿ','ý','ÿ','?','?','?','?','Ž','ž','?'];
    $b = ['a','a','a','a','a','a','ae','A','a','A','a','A','a','A','A','A','A','A','A','AE','c','C','D','C','c','C','c','C','c','C','c','D','d','D','d','E','E','E','E','e','e','e','e','E','e','E','e','E','e','E','e','f','fi','fl','G','g','G','g','G','g','G','g','H','h','H','h','I','I','I','I','i','i','i','i','I','i','I','i','I','i','I','i','IJ','ij','J','j','K','k','k','L','l','L','l','L','l','L','l','L','l','n','N','N','n','N','n','N','n','n','N','n','O','O','O','O','O','o','o','o','o','o','o','o','O','O','o','O','o','OE','oe','R','r','R','r','R','R','s','S','S','s','S','s','S','s','S','s','T','t','T','t','T','t','U','U','U','U','U','u','U','u','U','u','U','u','U','u','U','u','u','u','u','u','W','w','x','Y','Y','y','Y','y','y','Z','z','Z','z','Z','z','Z'];
    return str_replace($a, $b, $chaine);
}
function mot_interdit($message){
    
    //on enlève tous les accents du message de la personne
    //et on met en minuscule toutes les lettres
    $message = strtolower(remplacerAccents($message));
    
    //ouvre le fichier interdictions.txt ligne par ligne grâce à file()
    $mots = file("interdictions.txt");
    
    //vérifie mot par mot si il est trouvé dans le message de l'utilisateur
    foreach($mots as $mot){
        
        //met aussi les mots contenu dans le txt en minuscule et sans accent
        //trim() permet d'enlever le saut de ligne entre chaque mot contenu dans le txt
        $mot = trim(strtolower(remplacerAccents($mot)));
        
        //le "\b" permet de dire "ce mot", pas "contenu dans le texte", sinon le mot "jour" serait refusé si vous mettez "bonjour"
        if(preg_match("#\b{$mot}\b#", $message)){
            
            //on retourne le mot interdit pour en informer la personne qui poste afin qu'elle puisse solutionner l'erreur facilement
            return $mot;            
        }
       //si non trouvé, on renvoie "false".
    }
   return false; 
}
//traite le formulaire envoyé
if(isset($_POST['message'])){
    
    //si un mot interdit est trouvé dans le message
    $mot_interdit = mot_interdit($_POST['message']);
    
    if($mot_interdit){// Ici, j'ai enlevé "!== false" qui avait été mis par le développeur et qui empêchait la détection des mots interdits !!!
               
      echo "<h1 style=text-align:center;margin-top:2em;>Le mot <b style='color:red'>$mot_interdit</b> est interdit, veuillez ne pas utiliser l'utiliser</h1>";
      
      echo "<h1 style=text-align:center;margin-top:2em;>Votre message n'a pas été expédié</h1";
    
    //sinon non trouvé, on valide le formulaire
    }else{
        
        echo "<h1 style=text-align:center;margin-top:2em;>Le message a été expédié</h1>";
        
        /*continuer le traitement du formulaire ici*/
                
        $retour = mail('iello@ecrisdroit.fr', 'Envoi depuis le formulaire', 
$_POST['message'],
$_POST['mailpost'], '');
    if ($retour);        
    }
}
?>  
 

Ce code va lire un simple fichier "interdit.txt" dans lequel sont rangés les mots interdits. J'ai laissé les commentaires du développeur.
Sur au autre de mes sites, le même script php fonctionne correctement, avec php 7.4. Par précaution et afin d'éviter les erreurs, j'ai recopié de nouveau le même code d'un site à l'autre. Mais je ne suis pas à l'abri d'un autre loup quelque part.
Modérateur
Bonjour,

Peut-être une histoire de charset et de fonctions php de traitement de chaîne (mb_strtolower() à la place de strtolower() par exemple) ?

Quand tu dis "C'est la partie mots interdits qui ne fonctionne plus", c'est trop vague. C'est quoi le symptôme ? C'est quoi le ou les messages d'erreur s'il y en a ?

Amicalement,

Edit: on ne peut pas tester ton code, car certains caractères ont été remplacés par des ?
Modifié par parsimonhi (10 Jan 2024 - 17:03)
Modérateur
Bonjour,

en regardant ton code, le return false; me semble être au mauvais endroit, ne devrait-il pas être encapsuler dans un else sous le commentaire //si non trouvé, on renvoie "false" ?
A priori la fonction mot_interdit() te renvoi toujours false vue d'ici .. d'où ta modif : // Ici, j'ai enlevé "!== false" qui avait été mis par le développeur et qui empêchait la détection des mots interdits !!!

Je dirais aussi que si le dernier mot de la liste n'est pas trouvé, tu auras aussi droit à un false. peut-être vaudrait-il faire un break sur la boucle dés le premier mot interdit trouvé pour avoir effectivement un mot interdit en retour Smiley cligne

cdt
Modifié par gcyrillus (10 Jan 2024 - 17:28)
Modérateur
Bonjour,
gcyrillus a écrit :
A priori la fonction mot_interdit() te renvoi toujours false vue d'ici ...

??? T'es sûr ?

Amicalement,
Modérateur
parsimonhi a écrit :
Bonjour,

??? T'es sûr ?

Amicalement,

j'ai bien l'impression quelle est derriere la boucle à la toute fin de la fonction, j'ai peut-être ma lu ou pas compris la fonction. Smiley cligne
Cdt

edit en P.S. Autant pour moi :
a écrit :
Si appelée depuis une fonction, la commande return termine immédiatement la fonction et retourne l'argument qui lui est passé. return interrompt aussi l'exécution de commande eval() ou de scripts.

Modifié par gcyrillus (10 Jan 2024 - 18:00)
@parsimonhi
plutôt que de longues explications, tu vas sur mon site, le formulaire est en bas dans le footer.
https://musiquenvrac.fr
Tu tentes d'envoyer un message avec un mot en écriture inclusive, par exemple Celeux, dans une phrase. Le formulaire va refuser d'envoyer le message et t'afficher une alerte. Si tu ne mets pas d'écriture inclusive, le message part. C'est exactement le même code que celui que j'ai montré dans ce post, avec en plus une (petite) protection par pot de miel en JavaScript. Mais je ne crois pas que cette partie interfère avec le reste.
J'avais justement corrigé cette partie ("!== false" ) parce que ça ne fonctionnait pas. Malgré mon peu de connaissances en php, à force d'inspecter le code, j'avais trouvé ce problème. Et ça a fonctionné de suite après la modif. Le développeur, prévenu, l'a admis, mais il a corrigé son code ailleurs. J'ai gardé ma modification, puisqu'elle fonctionnait.
Pour les ?, je ne sais pas. Smiley decu
Le site musiquenvrac est chez le même hébergeur, mais avec php 7.4. Le nouveau site dont le formulaire ne fonctionne pas bien est sous php 8 (ou 8.2, je ne me souviens plus).
Modifié par Bongota (10 Jan 2024 - 18:13)
Modérateur
Bonjour,

gcyrillus a écrit :

j'ai bien l'impression quelle est derriere la boucle à la toute fin de la fonction, j'ai peut-être ma lu ou pas compris la fonction. Smiley cligne


Y aussi un return true; dans la boucle quand on trouve un mot interdit.

Amicalement,
Modérateur
Bonjour,

Bongota a écrit :
@parsimonhi
plutôt que de longues explications, tu vas sur mon site, le formulaire est en bas dans le footer.


J'ai bien compris ce que tu veux faire. Mais c'est quoi qui ne marche pas en php 8.x ? Ça se manifeste comment ? Et y-a-t-il des messages d'erreur (les messages d'erreur, c'est ces trucs que rajoutent les développeurs pour aider à faire un diagnostic Smiley lol ) ?

Bongota a écrit :
Pour les ?, je ne sais pas. Smiley decu

Ils ont a priori été rajoutés quand tu as envoyé ton code sur le forum alsacreations. Mais sont-ils ou pas aussi dans ton code sur ton serveur ? Tes fichiers sont-ils bien tous en utf8 ? Y a quoi dans ton fichier des mots interdits ? Du chinois ? Ou juste des mots français sans caractères bizarres ?

Si c'est un problème de charset, on ne peut pas faire un diagnostic juste en regardant une version du site avec une version de php qui lui permet de fonctionner sans erreur !

EDIT: je pense à un problème de charset parce que les php 8.x sont moins permissifs sur cette question que les php 7.x et qu'il y a toute une série de petites modifications qui peuvent faire partir un code en erreur avec php 8.x alors que ça passait avec php 7.x.

Amicalement,
Modifié par parsimonhi (10 Jan 2024 - 18:40)
Ça se manifeste tout simplement par l'absence de détection des mots interdits entrés dans le textarea du formulaire (ceux contenus dans le fichier interdiction.txt). Le formulaire est envoyé, même si j'ai entré un mot interdit dedans. Et il n'y a aucun message d'erreur, hormis bien sûr ceux que j'ai mis avec echo sur le script.
Le fichier interdiction.txt est bien en utf8, je viens de vérifier. Les mots dedans sont des mots en français, mais en écriture inclusive. Quelques exemples, les fichier est long :
celeux
Celeux lecteurs
français
directeur
gentils
ils
il
ils
lecteurs
français
directeur
gentils

Les mots doivent êtres entrés les uns en-dessous des autres, comme le préconise le développeur. Trois fois, je l'ai contacté, son code ne fonctionnait pas, et toujours dans la détection des mots interdits. Enfin, il fonctionne sur l'autre site donné.
Je vais continuer à voir s'il n'y a pas de problèmes avec les charset.
Modifié par Bongota (10 Jan 2024 - 18:59)
Modérateur
Bonjour,

Quels mots exactement échouent ?

Comme il y a des "." dans le fichier des mots interdits, ces mots contenant des "." ne sont pas des mots, mais éventuellement plusieurs mots.

EDIT: Comme il y avait plutôt ! Smiley lol Smiley lol Smiley lol , je vois maintenant un "mot" avec un espace. À ton avis, un mot contenant un espace, c'est bien un mot ? Il fait comment ensuite ton code pour deviner que c'est un mot ?

EDIT 2: ceci étant, ça n'explique pas pourquoi ça marche en php 7 et pas en php 8

Amicalement,
Modifié par parsimonhi (10 Jan 2024 - 19:12)
Attention le · que tuas vu est un point milieu, utilisé en écriture inclusive. Possible qu'il y ait des mots avec espaces dans mon fichier, j'en ajoute toutes les semaines. De toute façon, ce ne sont pas ceux-ci qui ont échoué. Sur Linux Debian clavier français, le point milieu, c'est Alt Gr + Maj + 1. Et les mots composés avec des points milieu ou des points restent toujours des mots, surtout en écriture inclusive. Beaucoup de personnes s'aventurent dans cette graphie mais ne la maîtrisent pas. Par paresse, ne sachant faire un point milieu, elles font un point simple. Il faut aussi mettre ces mots dans le fichier.
####################
Bien, on se calme et on va manger. Ton avertissement sur le charset m'a mis la puce à l'oreille. J'ai tout simplement recopié le fichier interdiction.txt du site qui fonctionne sur le nouveau site.
Et ça fonctionne !!!! Smiley fache Smiley fache Smiley fache Smiley lol Smiley lol Smiley lol
Je ne veux même pas savoir quel était le loup sur le fichier.txt déficient (enfin, je vais quand même finalement regarder) Smiley cligne

N'empêche, il semblerait, d'après vos messages, que mon code php n'est pas parfait. On aura pas travaillé dessus pour rien. Et j'ai découvert les incompatibilités dans les mises à jour des versions php.
Reste juste une petite chose à voir. Dans le message qui s'affiche pour signaler un mot interdit, il me tronque ce mot. Par exemple si le mot interdit est "il", il met "le mot il est interdit". Un peu gênant pour celui qui lis ça. Mais je vais voir ça tout seul.
Merci pour tout.
(tiens, je vois qu'il n'est pas possible d'écrire yel sur le forum, quand j'enregistre, ça se transforme en il).
Modifié par Bongota (10 Jan 2024 - 20:08)
Modérateur
Lis et teste ce bout de code :


<?php

function slugify($text, string $divider = '-'){
    $text = preg_replace('~[^\pL\d]+~u', $divider, $text);
    $text = iconv('utf-8', 'us-ascii//TRANSLIT', $text);
    $text = preg_replace('~[^-\w]+~', '', $text);
    $text = trim($text, $divider);
    $text = preg_replace('~-+~', $divider, $text);
    $text = strtolower($text);

    if (empty($text)) {
        return 'n-a';
    }

    return $text;
}
if(!empty($_POST)){
    // nettoie les données du formulaire
    $clean_methods = [
        'trim',
        'strip_tags',
        'htmlspecialchars',
    ];
    foreach($clean_methods as $method){
        $_POST = array_map($method, $_POST);
    }

    // validation
    $_POST['errors'] = [];
    foreach($_POST as $key => $value){
        switch($key){
            case 'email':
                if(empty($value)){
                    $_POST['errors'][$key] = "Ne doit pas être vide";
                }else if(!filter_var($value, FILTER_VALIDATE_EMAIL)){
                    $_POST['errors'][$key] = "l'email ne semble pas valide";
                }
                break;
            case 'message':
                $words = file('./interdictions.txt');
                $value_slugified = slugify($value);
                if(empty($value)){
                    $_POST['errors'][$key] = "Ne doit pas être vide";
                }else{
                    $words_slugified = array_map('slugify', $words);
                    $pattern = sprintf('#\b(%s)\b#', implode('|', $words_slugified));
                    if(preg_match($pattern, $value_slugified, $word)){
                        $_POST['errors'][$key] = sprintf("Le mot <strong>%s</strong> est interdit, veuillez ne pas utiliser l'écriture inclusive", current($word));
                    }
                }
                break;
        }
    }

    if(empty($_POST['errors'])){
        // envoyer email
    }
}


?>
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title></title>
        <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/foundation-sites@6.8.1/dist/css/foundation-float.min.css" crossorigin="anonymous">
        <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/foundation-sites@6.8.1/dist/css/foundation-prototype.min.css" crossorigin="anonymous">
        <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/foundation-sites@6.8.1/dist/css/foundation-rtl.min.css" crossorigin="anonymous">
        <style>
            .grid-container{
                max-width:50rem;
            }
            input[type=text], textarea{
                margin: 0;
            }
            .input{
                margin-top: 1rem;
            }
            span.error{
                color: red;
            }
        </style>
    </head>
    <body>
        <main class="grid-container margin-vertical-3">
            <form method="post">
                <div class="input text">
                    <label>
                        <span>email</span>
                        <input type="text" name="email" value="<?= !empty($_POST['email']) ? $_POST['email'] : ''?>">
                    </label>
                    <?php if(!empty($_POST['errors']['email'] )): ?>
                    <span class="error"><?= $_POST['errors']['email']  ?></span>
                    <?php endif ?>
                </div>
                <div class="input textarea">
                    <label>
                        <span>message</span>
                        <textarea name="message"><?= !empty($_POST['message']) ? $_POST['message'] : ''?></textarea>
                    </label>
                    <?php if(!empty($_POST['errors']['message'] )): ?>
                    <span class="error"><?= $_POST['errors']['message'] ?></span>
                    <?php endif ?>
                </div>
                <div class="input submit">
                    <button class="button" type="submit">envoyer</button>
                </div>
            </form>
        </main>
    </body>
</html>

Modifié par niuxe (11 Jan 2024 - 09:36)