PHP4 - PHP5 : Compatibilité ?

Signaler
Messages postés
14008
Date d'inscription
samedi 29 décembre 2001
Statut
Modérateur
Dernière intervention
28 août 2015
-
Messages postés
2483
Date d'inscription
jeudi 30 novembre 2006
Statut
Membre
Dernière intervention
14 janvier 2011
-
Salut
Me voilà dans un langage que je ne maîtrise pas du tout.
J'ai actuellement un petit site créé en PHP4.
Mon hébergeur veut me faire passer en PHP5.

Déjà, première intérogation : Les pages en version 4 sont-elles compatibles avec la 5 ?
Ce basculement impose t-il une refonte importante du code existant ?

Pour faire mes essais, mon hébergeur suggère de basculer le port 80 vers le port 81. Soit.

Mes premiers pas tombent sur le problème :
Dans mon fichier "functions-site.inc", le serveur bute sur cette ligne
function commonSetUp() {
  @session_start();
  $interface = & new interface($GLOBALS['interfaces'][0]['maquette']);

qui me renvoie l'erreur suivante :
Parse error: syntax error, unexpected T_INTERFACE, expecting T_STRING or T_VARIABLE or '$' in /home/local/apache/ [...] /require/functions-site.inc on line 100

Je remarque cette même structure de ligne un peu partout dans le code :
Y a t-il une nouvelle syntaxe autour de ce = & new (dont je ne comprends pas le sens, d'ailleurs)

Vala
Jack, MVP VB
NB : Je ne répondrai pas aux messages privés

Le savoir est la seule matière qui s'accroit quand on la partage (Socrate)

9 réponses

Messages postés
14008
Date d'inscription
samedi 29 décembre 2001
Statut
Modérateur
Dernière intervention
28 août 2015
74
Ah, je suis sur une piste : "interface" est devenu un mot clé du langage 5
Messages postés
14008
Date d'inscription
samedi 29 décembre 2001
Statut
Modérateur
Dernière intervention
28 août 2015
74
Bon, après avoir tenté de remplacer le mot "interface" (réservé PHP5) par "clsInterface", j'obtiens maintenant l'erreur suivante :
Fatal error: Cannot re-assign $this in /home/.../classes/interface.inc(54) : runtime-created function on line 1
La ligne 54 est le ; de fin de syntaxe d'une function maintenant nommée clsInterface.

Ce qui m'intrigue dans la syntaxe PHP (que je ne comprends pas tjrs), c'est que ma Classe et ma Function portent le même nom, "interface" renommée en "clsInterface".
De plus, dans les autres fichiers du site, on trouve ceci ce genre de syntaxe :
$GLOBALS['interfaces'][0]['maquette'] = ...
c'est à dire, encore un "interface" mais cette fois-ci avec un S final

Comment s'y retrouver ... parce qu'il y a aussi le nom du fichier "interface.inc" auquel je n'ai pas touché.
Pour moi, pas clair tout ça ...

Vala
Jack, MVP VB
NB : Je ne répondrai pas aux messages privés

Le savoir est la seule matière qui s'accroit quand on la partage (Socrate)
Messages postés
2483
Date d'inscription
jeudi 30 novembre 2006
Statut
Membre
Dernière intervention
14 janvier 2011
16
Salut,

C'est pas évident comme ça de te dire ce qui va pas... Si tu nous montrais un peu de code (après tout, t'es bien torse poil sur la photo, tu peux bien faire ça !) on pourrait sûrement te donner plus d'informations. Notamment le fichier interface.inc ;)

Le mot interface n'est gênant que quand il peut être confondu avec le mot clé interface. Une chaîne, une variable, avec un s, un nom de fichier, tout ça sont des cas qui ne posent pas de problème. Par contre, je suis vraiment curieux de voir ton code qui produit cette belle erreur, ne serait-ce que pour ma culture générale

--
Neige

N'hésitez pas à lire la doc
Messages postés
14008
Date d'inscription
samedi 29 décembre 2001
Statut
Modérateur
Dernière intervention
28 août 2015
74
lol, merci pour ton message.
J'espère que ma nudité ne t'a pas choqué ...

Voilà the code :

$GLOBALS['clsInterface'] = null;

   function getmicrotime() {
list($usec, $sec) = explode(" ",microtime());
    	return ($usec+$sec);
   } 

class clsInterface { 
   var $maquette;
   var $variables = array();
   var $start;
   // menu locator
   var $locator;
   // boutton
   var $maquettebtn;

   function clsInterface ($file) {
if (!file_exists($file)) {
        	die('Un problème d\'ordre majeur s\'est produit');
}
 	$this->locator = array();
   	$this->locator['niveau'] = 0;

   	// création de la function de flush :
   	$flushsite = create_function('$str','	
$this = & $GLOBALS["clsInterface"];
$this->variables["[BODY]"] = $str;
$this->variables["[EXECTIME]"] = round(getmicrotime()-($this->start),4);
$this->variables["[LOCATOR]"] = $this->locator["start"].$this->locator["string"];
return str_replace(array_keys($this->variables),
array_values($this->variables),$this->maquette);
   			');
$this->start = getmicrotime();

// chargement de la maquette 
$this->maquette = file_get_contents($file);
$GLOBALS['clsInterface'] = & $this;
ob_start($flushsite);
   }


Désolé, toutes les majuscules partent au lavage dans les balises de Code
Messages postés
2483
Date d'inscription
jeudi 30 novembre 2006
Statut
Membre
Dernière intervention
14 janvier 2011
16
Mouais... Je suis pas habitué à create_function() n'ayant jamais vraiment compris dans quel cas on pouvait vraiment en avoir besoin...
Il semble que PHP n'aime pas que tu utilises :
$this =
dans le code de ta fonction créée à la volée.
En fait, j'imagine que pour PHP, le contexte d'exécution est au sein de la classe, donc quand il exécute cette fonction anonyme, $this est déjà défini et n'est autre que l'instance de la classe qui exécute cette fonction (suis-je clair ?)

Bref... j'ai comme l'impression que ce que tu essayes de faire, c'est un singleton... Si j'ai bon, dis-le moi, je te proposerai d'implémenter ce design pattern qui est mon préféré pour cette classe qui te tient tant à coeur.



P.S. : Ouais, alors ces capitales qui foutent le camp dans chaque morceau de code, ça me gonfle quelque chose de bien, là... J'en ai même fait un message à ... euh je sais pas, j'ai utilisé le formulaire de contact... Mais vraiment, c'est casse bonbon...

--
Neige

N'hésitez pas à lire la doc
Messages postés
3708
Date d'inscription
lundi 5 juillet 2004
Statut
Membre
Dernière intervention
27 avril 2012
27
Salut,

Perso je casserai tout et repartirai du début
Je n'ai pas bien saisi le but de la classe, peux tu en dire plus ???
Ca me semble en tous cas fort complexe. Il est sans doute possible de simplifier grandement.

Je suis de l'avis de Neige :
$this = ... il n'aime pas. Même chose pour &$this. J'ai l'impression également que certaines variables ne sont pas définies, ... et je doute de la nécessité de la fonction anonyme (idem pour getmicrotime())

c'est que ma Classe et ma Function portent le même nom

Il s'agit du constructeur en PHP4 (cf doc) qui équivaut à __construct() en PHP5

Cordialement,


Kohntark -
Messages postés
14008
Date d'inscription
samedi 29 décembre 2001
Statut
Modérateur
Dernière intervention
28 août 2015
74
Merci mille fois de vous pencher sur mon cas, j'aprécie.
Je ne l'ai pas précisé, mais ce code marche parfaitement en version 4.
Donc je pense que s'il manquait des définitions, je serais déjà embété.

Bon, comme il faut une vue d'ensemble du code, qu'un forum n'est pas l'endroit rêvé et surtout que je ne suis pas assez instruit dans ce langage pour apporter les réponses, je vais m'en remettre aux pros pour revoir l'ensemble.
Si vraiment vous aviez du temps à perdre, je peux vous transmettre le zip (454ko), mais ce que je voulais surtout, c'était savoir si ce n'était pas qu'une banale histoire de virgule ou un problème de structure : j'ai ma réponse.

NeigeDHiver, Kohntark : merci beaucoup pour ces indications.

Vala
Jack, MVP VB
NB : Je ne répondrai pas aux messages privés

Le savoir est la seule matière qui s'accroit quand on la partage (Socrate)
Messages postés
2483
Date d'inscription
jeudi 30 novembre 2006
Statut
Membre
Dernière intervention
14 janvier 2011
16
Non, ce n'est pas qu'un problème de virgule ;)

PHP5 a apporté BEAUCOUP de nouveautés pour tout ce qui concerne la gestion des objets. Je ne m'étais jamais posé la question du contexte d'exécution d'une fonction anonyme dans un constructeur (c'est quand même bien spécifique, hein !), mais ton exemple le montre bien : une fonction anonyme, même définie avec des guillemets simples n'empêche pas PHP5 de considérer $this comme référence à l'objet "courant".

Je ne sais pas si l'intégralité du code est nécessaire. Si ta classe est bien un singleton, alors ce n'est qu'au niveau du constructeur que cela se joue. Voici un exemple rapide de comment implémenter ça :

<?php

class clsinterface {
  private static $instance;

  public static function getinstance($file = NULL) {
    if (null $file && null self::$instance) {
      throw new Exception('File is required to create a new instance');
    }
    null self::$instance or self::$instance new self($file);
    return self::$instance;
  }

  private function __construct($file) {
    if (!file_exists($file)) {
      throw new Exception("Le fichier $file n'existe pas");
    }
  }
}?>

Attention, il y a des majuscules... : clsInterface, Exception et getInstance (bon, seule la majuscule à Exception est indispensable, car définie comme ça en interne par PHP)

Pour ce qui est de ta fonction anynyme, je ne comprends pas pourquoi tu utilises une fonction anonyme. En fait, ouais, plus j'y pense, plus je me dis que je ne comprends pas dans quel cas on peut vraiment avoir besoin d'une fonction anonyme...
Dans ton cas présent, tu pourrais avoir simplement une méthode de ton objet :
  public function flush($str) {
    $this->variables["[body]"] = $str;
    $this->variables["[exectime]"] = round(getmicrotime()-($this->start),4);
    $this->variables["[locator]"] = $this->locator["start"].$this->locator["string"];
    return str_replace(array_keys($this->variables), array_values($this->variables),$this->maquette);


Et voici ton constructeur, avec ob_start() :
  private function __construct($file) {
    if (!file_exists($file)) {
      throw new Exception("Le fichier $file n'existe pas");
    }
    ob_start(array($this, 'flush'));
  }



P.S. : il est vraiment idiot cet éditeur, non seulement il supprime les majuscules dans un langage sensible à la casse, mais en plus si le code ne commence pas par <? il ne sait plus coloriser... Bien la peine de lui indiquer le langage dans la balise code... :/
--
Neige

N'hésitez pas à lire la doc
Messages postés
2483
Date d'inscription
jeudi 30 novembre 2006
Statut
Membre
Dernière intervention
14 janvier 2011
16
En fait... Non, rien d'absurde... C'est lors de l'exécution de la fonction anonyme, au moment du vidage du tampon (ob_get_* ou ob_end_flush) la fonction anonyme est exécutée, et il n'est pas possible alors de redéfinir $this. Oui, c'est que c'est pas une construction naturelle, ton truc là... Donc peut-être que pour PHP4 cette fonction anonyme n'a simplement pas le même contexte d'exécution (et peu importe en fait que celle-ci soit définie avec des guillemets simples ou doubles, ce n'est pas au moment de la définition que $this est interprété, mais bien au moment de l'exécution).

Il n'en reste pas moins que le code que je te propose me paraît plus clair que le tien ;)

J'ai oublié de préciser, mais le singleton ne s'instancie pas directement, il faut appeler :
$interface = clsinterface::getinstance('/path/to/my/file.ext');


--
Neige

N'hésitez pas à lire la doc