PHP 7 et @lex Guestbook

Vos idées et demandes pour la prochaine mise à jour du script sont les bienvenues ici - Your ideas and suggestions for the next update.

Modérateurs : boulmontjj, Pierre G., Malabar, Otomatic

Otomatic
Modérateur
Modérateur
Messages : 677
Inscription : Ven 11 Août 2006, 09:33
Localisation : Paris
Contact :

PHP 7 et @lex Guestbook

Messagepar Otomatic » Mar 09 Fév 2016, 11:24

Bonjour,

PHP 7 signe la disparition de MySQL, non pas du gestionnaire de base de données, mais de l'extension mysql.
Il faut donc impérativement utiliser les extensions mysqli ou PDO mysql à la place.
PDO mysql je connais un peu, mais pas trop, alors que mysqli présente beaucoup d'analogies avec mysql.
PHP 7 signe aussi l'obsolescence de l'utilisation du nom d'une class comme nom de la fonction constructeur de ladite class.

Donc, à la condition que toutes les autres modifications déjà préconisées pour PHP 5.4, 5.5 et 5.6 ainsi que le passage en utf-8 aient été réalisées, voici les modifications à effectuer pour PHP 7.

Je tiens à signaler que j'écris cette procédure à posteriori et que je peux oublier une modification effectuée.

La première chose à faire est de passer à mysqli et tant qu'à faire, autant aussi améliorer les choses, comme pouvoir voir, en mode debug, toutes les requêtes ainsi que leur temps d'exécution ; pourquoi ? Simplement parce que c'est quelque chose que j'utilise de base sur mes sites et que je n'ai pas eu à réinventer l'eau tiède.
Commençont par créer quelques fonctions supplémentaires pour MySQLi.
Créer un fichier (utf-8) agb\db\mysql_functions.php qui doit contenir :

Code : Tout sélectionner

<?php
//Fonctions générales
//Affiche les requêtes
function see_saved_queries() {
  global $f_db_connexion;
  $saved_queries = $f_db_connexion->get_saved_queries();
  $nb_queries = count($saved_queries);
  $output = '';
  $output .= "<div id='sql_requete' style='margin-top:15px;'>\n";
  if($nb_queries > 0) {
    $output .= "<table style='border:1px solid #CC9966;border-collapse:collapse;margin:auto;background-color:#fbf4e2;padding:0;width:95%;font-size:0.80em;'>\n";
    $output .= "<caption>Queries to database</caption>\n";
    $output .= "<tr><th>#</th><th>Duration&nbsp;(s)</th><th style='width-min:500px;'>Queries ".TYPE_BASE_ALEX."</th></tr>\n";
    $query_time_total = 0.0;
        $i = 0;
        foreach($saved_queries as $cur_query) {
        $query_time_total += $cur_query[1];
        $output .= "<tr><td style='text-align:right;'>".(++$i)."</td>";
        $output .= "<td style='text-align:center;'>".(($cur_query[1] != 0) ? sprintf('%.6f',$cur_query[1]) : '&nbsp;')."</td>";
        $output .= "<td>".alex_htmlspecialchars($cur_query[0])."</td></tr>\n";
      }
      $output .= "<tr><td colspan='3' style='text-align:center;'>Total duration of queries : ".sprintf('%.6f',$query_time_total)." s</td></tr>\n";
      $output .= "</table>\n";
   }
   else $output .= "<p>No saved queries to display</p>\n";
  $output .= "</div>\n";
  return $output;
}

// Affiche un message d'erreur
function sql_error($message) {
   global $f_db_connexion,$SCRIPT_ENCODAGE;
   header("content-type:text/html; charset=$SCRIPT_ENCODAGE");
   $html = "<div style='border:4px solid red;background-color:white;margin:10px;'>\n<p style='font-weight:bold;color:red;'>Sorry, but an error occurred</p>\n";
   $html .= "<p>".nl2br($message)."</p>\n";
   $html .= "</div>\n";
   echo $html;
   if(defined('SEE_QUERIES')) {
      if(isset($f_db_connexion) && $f_db_connexion !== false) {
         echo "<div style='border:0;'background-color:white;margin:10px;'>\n";
         echo "<p style='text-align:center;font-weight:bold;'>Previous queries</p>\n";
         see_saved_queries();
         echo "</div>\n";
      }
   }
   exit;
}

//Fin des fonctions générales
?>

Pour que la class d'origine mysql reste compatible, on va légèrement la modifier.
Dans le fichier agb\db\MySQL.php, juste après
// originale class by phpbb group : http://www.phpbb.com
ajouter :

Code : Tout sélectionner

//On s'assure que MySQL est supporté
if (!function_exists('mysql_connect')) exit('Cet environnement ne supporte pas MySQL qui est requis pour utiliser cette classe');

À la fin du même fichier, juste avant ?> insérer :

Code : Tout sélectionner

define('TYPE_BASE_ALEX','MySQL');
include($chem_absolu."db/mysql_functions.".$alex_livre_ext);

Remplacer :

Code : Tout sélectionner

function alex_livre_sql($sqlserver, $sqluser, $sqlpassword, $database, $persistency = false)

par

Code : Tout sélectionner

function __construct($sqlserver, $sqluser, $sqlpassword, $database, $persistency = false)


Ensuite, pour ne rien changer à tous les appels mysql, nous allons créer une class mysqli mais de même nom que la class mysql d'origine.
Dans un fichier (utf-8) agb\db\MySQLi.php mettre :

Code : Tout sélectionner

<?php

//On s'assure que MySQLi est supporté
if (!function_exists('mysqli_connect')) exit('This environment does not support MySQLi that is required to use this class');

class alex_livre_sql {

  public $db_connect_id;
  public $query_result;
  public $saved_queries = array();
  public $row = array();
   public $rowset = array();
  public $num_queries = 0;

  //Connexion à Mysql puis à la base de données
  function __construct($db_host, $db_username, $db_password, $db_name, $persistency) {
    $this->db_connect_id = @mysqli_connect($db_host, $db_username, $db_password, $db_name);
    if ($this->db_connect_id) {
            if (defined('NAMES_UTF8'))
               $this->set_names('utf8');
         return $this->db_connect_id;
    }
    else sql_error("Could not connect to MySQL or to database.\nMySQL said : ".mysqli_connect_error());
  }

  function sql_close() {
    if ($this->db_connect_id) {
      if ($this->query_result) @mysqli_free_result($this->query_result);
      return @mysqli_close($this->db_connect_id);
    }
    else return false;
  }

  function sql_query($sql) {
    if (defined('SEE_QUERIES')) $q_start = microtime(true);
    $this->query_result = @mysqli_query($this->db_connect_id, $sql);
    if ($this->query_result !== false) {
      if (defined('SEE_QUERIES')) $this->saved_queries[] = array($sql, (microtime(true) - $q_start));
      ++$this->num_queries;
      return $this->query_result;
    }
    else {
      if (defined('SEE_QUERIES')) $this->saved_queries[] = array($sql, 0);
         sql_error("Query error.\nQuery is:".$sql."\nError ".@mysqli_errno($this->db_connect_id)."\nError message: ".@mysqli_error($this->db_connect_id)."\n");
      return false;
    }
  }

  function sql_numrows($query_id = 0) {
    return ($query_id) ? @mysqli_num_rows($query_id) : false;
  }

  function sql_affectedrows() {
    return ($this->db_connect_id) ? @mysqli_affected_rows($this->db_connect_id) : false;
  }

   function sql_numfields($query_id = 0)   {
      if(!$query_id)
         $query_id = $this->query_result;
      return ($query_id) ? @mysqli_num_fields($query_id) : false;
   }

   function sql_fieldname($offset, $query_id = 0) {
      if(!$query_id)
         $query_id = $this->query_result;
      return ($query_id) ? @mysqli_field_name($query_id, $offset) : false;
   }

   function sql_fieldtype($offset, $query_id = 0) {
      if(!$query_id)
         $query_id = $this->query_result;
      return ($query_id) ? @mysqli_field_type($query_id, $offset) : false;
   }

   function sql_fetchrow($query_id = 0)   {
      if(!$query_id)
         $query_id = $this->query_result;
      if($query_id) {
         $this->row[(int)$query_id] = @mysqli_fetch_array($query_id);
         return $this->row[(int)$query_id];
      }
      else
         return false;
   }

   function sql_fetchrowset($query_id = 0)   {
      if(!$query_id)
         $query_id = $this->query_result;
      if($query_id)   {
         unset($this->rowset[$query_id]);
         unset($this->row[$query_id]);
         while($this->rowset[$query_id] = @mysqli_fetch_array($query_id))
         {
            $result[] = $this->rowset[$query_id];
         }
         return $result;
      }
      else
         return false;
   }
   function sql_fetchfield($field, $rownum = -1, $query_id = 0) {
      if(!$query_id)
         $query_id = $this->query_result;
      if($query_id)   {
         if($rownum > -1)
            $result = @mysqli_result($query_id, $rownum, $field);
         else   {
            if(empty($this->row[$query_id]) && empty($this->rowset[$query_id]))   {
               if($this->sql_fetchrow())
                  $result = $this->row[$query_id][$field];
            }
            else {
               if($this->rowset[$query_id])
                  $result = $this->rowset[$query_id][$field];
               else if($this->row[$query_id])
                  $result = $this->row[$query_id][$field];
            }
         }
         return $result;
      }
      else
         return false;
   }

   function sql_rowseek($rownum, $query_id = 0) {
      if(!$query_id)
         $query_id = $this->query_result;
      return ($query_id) ? @mysqli_data_seek($query_id, $rownum) : false;
   }

   function sql_nextid(){
      return ($this->db_connect_id) ? @mysqli_insert_id($this->db_connect_id) : false;
   }

   function sql_freeresult($query_id = 0) {
      if(!$query_id)
         $query_id = $this->query_result;
      if ( $query_id )   {
         unset($this->row[$query_id]);
         unset($this->rowset[$query_id]);
         @mysqli_free_result($query_id);
         return true;
      }
      else
         return false;
   }

   //[modif oto] ajout pour SET NAMES utf8
   function set_names($names)   {
      return $this->sql_query('SET NAMES \''.$names.'\'');
   }

  function get_saved_queries() {
    return $this->saved_queries;
  }
}
define('TYPE_BASE_ALEX','MySQLi');

include($chem_absolu."db/mysql_functions.".$alex_livre_ext);

?>

Au début du fichier agb\config\config_base.php, juste après <?php, on ajoute les lignes qui n'existeraient pas :

Code : Tout sélectionner

<?php
define('NAMES_UTF8', 1);
//define('SEE_QUERIES', 1);
//$database_type = "MySQL";
$database_type = "MySQLi";

Nota : Il « suffit » de commenter la ligne $database_type = "MySQLi"; et de décommenter //$database_type = "MySQL"; pour revenir au fonctionnement normal avec mysql.
Et, pour voir les requêtes effectuées sur une page, il faut décommenter //define('SEE_QUERIES', 1); et ne pas oublier de le re-commenter après les essais.

D'origine, les appels à une class de gestion de basse de données se font par variable, par exemple dans agb\include\livre_include.php par
include($chem_absolu."db/".$database_type.".".$alex_livre_ext);
donc, pas besoin de modifier.

Théoriquement, nous en avons terminé avec le remplacement de mysql par mysqli.
J'écris "théoriquement" car, comme noté en préambule, cette procédure est écrite a posteriori et je peux ne pas me rappeler d'autres modifications.

on en arrive maintenant à la gestion des erreurs du style :
Deprecated: Methods with the same name as their class will not be constructors in a future version of PHP; ErrorManager has a deprecated constructor in xxx\templates\modelixe\ErrorManager.php on line 52
On pourrait en rester là et masquer les avertissements, mais, rien ne dit qu'avec PHP 7.0.5 ou autre, ça ne se transformera pas en erreur fatale, donc, il est préférable de traiter ce problème dès maintenant.

On traite d'abord la class « Parent » ErrorManager :
Dans le fichier agb\templates\modelixe\ErrorManager.php remplacer :

Code : Tout sélectionner

function ErrorManager($errorManagerSystem = '', $level = '', $escape = '', $file = '', $alarme = ''){

par :

Code : Tout sélectionner

function __construct($errorManagerSystem = '', $level = '', $escape = '', $file = '', $alarme = ''){

Puis on va traiter la class « Enfant » Modelixe :
Dans le fichier agb\templates\modelixe\ModeliXe.php remplacer

Code : Tout sélectionner

    function ModeliXe ($template, $sessionParameter = '', $templateFileParameter = '', $cacheDelay = -1, $ok_cache = false, $chem_template = ''){

      $this -> ok_cache = $ok_cache;
      if ($chem_template){
         $this -> mXTemplatePath = $chem_template;
      }

        $this -> ErrorManager();

par

Code : Tout sélectionner

    function __construct($template, $sessionParameter = '', $templateFileParameter = '', $cacheDelay = -1, $ok_cache = false, $chem_template = ''){
       parent::__construct();
      $this -> ok_cache = $ok_cache;
      if ($chem_template){
         $this -> mXTemplatePath = $chem_template;
      }

        //$this -> ErrorManager();


Il y a peut-être mieux à faire ou à faire autrement, toujours est-il que @lex Guestbook semble fonctionner correctement sous PHP 7.0.3 et MySQL 5.7.11 sans générer d'erreur ou d'avertissement.

Et voilou :pausecaffé:

Je répète : À n'effectuer qu'après sauvegarde des fichiers à modifier. J'ai pu oublier une modification.
Ce n'est pas par ce que l'erreur se propage qu'elle devient vérité. Gandhi

Jean-Pierre
Messages : 208
Inscription : Mer 09 Août 2006, 10:19
Contact :

Re: PHP 7 et @lex Guestbook

Messagepar Jean-Pierre » Dim 28 Fév 2016, 18:19

Bonjour :hello:

Merci Oto de débroussailler autant devant nous.

En effet et à mon avis, lorsque la version 7 de PHP sera devenue "obligatoire", si jamais aucune nouvelle version d'@lex Guestbook n'est sortie entre ; ce sera le déclin signé, voire la disparition de ce merveilleux Livre d'Or.

Hé oui tout le monde ne peut se prendre la tête à reprendre certaines parties de code, ni n'en a les compétences.

Je suppose que dans l'ombre nos bien aimés admins :langue1: œuvrent en ce sens ;-)

Bon courage à eux et encore merci Oto de toutes tes indications si précieuses :super:

fandemixmaster
Messages : 21
Inscription : Mar 28 Jan 2014, 16:27

Re: PHP 7 et @lex Guestbook

Messagepar fandemixmaster » Mar 21 Fév 2017, 01:05

Merci beaucoup :)

milef77
Messages : 7
Inscription : Mer 10 Oct 2018, 16:51

Re: PHP 7 et @lex Guestbook

Messagepar milef77 » Lun 22 Oct 2018, 13:15

Bonjour,
J'ai remarqué que le fichier agb\db\mysql_functions.php contenait "list(, $cur_query) = each($saved_queries);" à la ligne 15.

Je ne suis pas expert PHP et serait-il possible d'avoir la translation avec "foreach".

Merci d'avance.

Cordialement.

PS : Merci beaucoup pour tout ce travail de mise à niveau.

Otomatic
Modérateur
Modérateur
Messages : 677
Inscription : Ven 11 Août 2006, 09:33
Localisation : Paris
Contact :

Re: PHP 7 et @lex Guestbook

Messagepar Otomatic » Mar 23 Oct 2018, 09:31

Bonjour,

:( Je ne l'avais pas vu celle-là :siffle:
Faut dire que je n'ai sans doute pas effectué certains essais, comme celui de "voir les requêtes" sous PHP 7.2 vu que ça date de 2016 !
Je reviendrais lorsque le problème sera corrigé....

Je pense que ça va attendre un certain temps (© Fernand Raynaud) je suis en train de faire les mises à jour des "addons" MySQL 5.5.62, 5.6.42, 5.7.24, 8.0.13 et Apache 2.4.37 pour Wampserver 3.1.4 :merci:
Ce n'est pas par ce que l'erreur se propage qu'elle devient vérité. Gandhi

Otomatic
Modérateur
Modérateur
Messages : 677
Inscription : Ven 11 Août 2006, 09:33
Localisation : Paris
Contact :

Re: PHP 7 et @lex Guestbook

Messagepar Otomatic » Mar 23 Oct 2018, 19:56

Bonsoir,
J'ai la solution, mais je ne pourrais la donner que jeudi. En déplacement, pas de pc, et donner du code via Smartphone, c'est vraiment pas pratique.
Ce n'est pas par ce que l'erreur se propage qu'elle devient vérité. Gandhi

Malabar
Admin
Admin
Messages : 4063
Inscription : Lun 07 Août 2006, 09:46
Localisation : Lorient
Contact :

Re: PHP 7 et @lex Guestbook

Messagepar Malabar » Mer 24 Oct 2018, 08:04

Nous ne sommes pas à quelques jours près ;)
Merci d'avance
Le mâle à barre (Maxime)

Otomatic
Modérateur
Modérateur
Messages : 677
Inscription : Ven 11 Août 2006, 09:33
Localisation : Paris
Contact :

Re: PHP 7 et @lex Guestbook

Messagepar Otomatic » Jeu 25 Oct 2018, 10:07

Bonjour,

Remplacer

Code : Tout sélectionner

      for($i=0;$i < $nb_queries;$i++) {
        list(, $cur_query) = each($saved_queries);

par

Code : Tout sélectionner

        $i = 0;
        foreach($saved_queries as $cur_query) {

Remplacer

Code : Tout sélectionner

        $output .= "<tr><td style='text-align:right;'>".($i+1)."</td>";

par

Code : Tout sélectionner

        $output .= "<tr><td style='text-align:right;'>".(++$i)."</td>";

Pas forcément facile à voir, c'est $i+1 qui est remplacé par ++$i
On peut aussi remplacer, dans la ligne 11 width:756px par width:95%
Nota : Le message précédent comportant la procédure a été modifié en conséquence.

Pendant qu'on y est, il reste encore un each(...) dans le fichier agb\templates\modelixe\ErrorManager.php. Vu qu'il s'agit de la gestion d'erreur, à moins d'avoir une erreur, ce n'était pas visible sous PHP 7.2.x, donc, dans ce fichier, remplacer :

Code : Tout sélectionner

while (list($key, $val) = each($tab)){

par

Code : Tout sélectionner

foreach($tab as $key => $val) {
Ce n'est pas par ce que l'erreur se propage qu'elle devient vérité. Gandhi

milef77
Messages : 7
Inscription : Mer 10 Oct 2018, 16:51

Re: PHP 7 et @lex Guestbook

Messagepar milef77 » Ven 26 Oct 2018, 11:03

Bonjour,

Merci beaucoup pour ces corrections, mais je n'ai pas trouvé la deuxième correction dans le fichier agb\db\mysql_functions.php.

Je n'ai trouvé dans aucun fichier la ligne suivante "$output .= "<tr><td style='text-align:right;'>".($i+1)."</td>";".

Cordialement.

Otomatic
Modérateur
Modérateur
Messages : 677
Inscription : Ven 11 Août 2006, 09:33
Localisation : Paris
Contact :

Re: PHP 7 et @lex Guestbook

Messagepar Otomatic » Ven 26 Oct 2018, 17:23

milef77 a écrit :Je n'ai trouvé dans aucun fichier la ligne suivante "$output .= "<tr><td style='text-align:right;'>".($i+1)."</td>";"


Et pourtant, dans le fichier agb\db\mysql_functions.php c'était la 2e ligne après la ligne contenant le each($saved_queries);
D'origine :

Code : Tout sélectionner

      for($i=0;$i < $nb_queries;$i++) {
        list(, $cur_query) = each($saved_queries);
        $query_time_total += $cur_query[1];
        $output .= "<tr><td style='text-align:right;'>".($i+1)."</td>";
        $output .= "<td style='text-align:center;'>".(($cur_query[1] != 0) ? sprintf('%.6f',$cur_query[1]) : '&nbsp;')."</td>";

Après modification :

Code : Tout sélectionner

        foreach($saved_queries as $cur_query) {
        $query_time_total += $cur_query[1];
        $output .= "<tr><td style='text-align:right;'>".(++$i)."</td>";
        $output .= "<td style='text-align:center;'>".(($cur_query[1] != 0) ? sprintf('%.6f',$cur_query[1]) : '&nbsp;')."</td>";
Ce n'est pas par ce que l'erreur se propage qu'elle devient vérité. Gandhi


Revenir vers « Suggestions d'amélioration du script »

Qui est en ligne ?

Utilisateurs parcourant ce forum : Aucun utilisateur inscrit et 2 invités