IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage PHP Discussion :

Passage par référence dans un appel de méthode [PHP 5.4]


Sujet :

Langage PHP

  1. #1
    Membre habitué

    Inscrit en
    février 2007
    Messages
    223
    Détails du profil
    Informations personnelles :
    Âge : 50

    Informations forums :
    Inscription : février 2007
    Messages : 223
    Points : 160
    Points
    160
    Par défaut Passage par référence dans un appel de méthode
    J'ai écris une fonction qui permet de faire du rechercher / remplacer sur plusieurs variables d'un coup :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    function replace_all_by($arr_fields, $arr_replace_by){
    	foreach ($arr_fields as &$field){
    		foreach ($arr_replace_by as $arr_replace_by_key => $arr_replace_by_value){
    			$field = str_replace($arr_replace_by_key, $arr_replace_by_value, $field);
    		}
    	}
    }
    $explanation_title = str_replace('%explanation_title%', $user->lang['INTRODUCIATOR_MOD_DEFAULT_MESSAGE_TITLE'], $params['explanation_message_title']);
    $explanation_text = str_replace('%explanation_text%', $user->lang['INTRODUCIATOR_MOD_DEFAULT_MESSAGE_TEXT'], $params['explanation_message_text']);
    $rules_title = str_replace('%rules_title%', $user->lang['INTRODUCIATOR_MOD_DEFAULT_RULES_TITLE'], $params['explanation_message_rules_title']);
    $rules_text = str_replace('%rules_text%',generate_text_for_display($forum_rules['rules'], $forum_rules['rules_uid'], $forum_rules['rules_bitfield'], $forum_rules['rules_options']), $params['explanation_message_rules_text']);
    $link_goto_forum = $user->lang['INTRODUCIATOR_MOD_DEFAULT_LINK_GOTO_FORUM'];
    $link_post_forum = $user->lang['INTRODUCIATOR_MOD_DEFAULT_LINK_POST_FORUM'];
    // Replace in each string the predefined fields
    replace_all_by(
    	array(
    		&$explanation_title,
    		&$explanation_text,
    		&$rules_title,
    		&$rules_text,
    		&$link_goto_forum,
    		&$link_post_forum
    	),
    	array(
    		'%forum_name%'	=> $forum_name,
    		'%forum_url%'	=> append_sid("{$phpbb_root_path}viewforum.$phpEx", 'f=' . $params['fk_forum_id']),
    		'%forum_post%'	=> append_sid("{$phpbb_root_path}posting.$phpEx", 'mode=post&f=' . $params['fk_forum_id']),
    	)
    );
    Ce code est une partie d'un MOD Introduciator de phpBB. Or ce code est refusé car :
    Le passage de variable par référence est déprécié a partir de php 5.4, ton mod ne sera donc pas fonctionnel sous php 5.4 tout comme l'utilisation du mot-clé var qui est propre a php 4 et déprécié (standard strict) en php5 également.
    J'ai donc installé la dernière version wampserver qui permet de tester avec PHP version 5.5.12
    Et ce code passe sans aucun problème. J'essaie de comprendre ce qui va ou pas, si la remarque est judicieuse ou pas...
    Le problème est en fait le array que je crée, justement avec des '&' devant les variables pour passer des références et qui semblerai poser des problèmes sous php 5.4 or ça passe sans problème pour moi...

    Donc, est-ce que ce code est valide pour php 5.5, si oui ou non, pourquoi ? J'aimerais comprendre.
    La personne qui m'a fait cette remarque, m'a dit C'est quand même mon métier mais sans expliquer. En effet, lorsque je crée une fonction avec des références, si je passe un &$ma_variable à cette fonction php me fait une erreur, mais pour un array, ça a l'air de passer... Peut-être parce que array c'est un mot clef du langage ? Et qu'on a le droit de créer un tableau sur des références ?

    Sinon, comment modifier ce code pour qu'il soit conforme ?

  2. #2
    Membre expert
    Avatar de Spartacusply
    Homme Profil pro
    Développeur Web
    Inscrit en
    mai 2011
    Messages
    1 723
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : mai 2011
    Messages : 1 723
    Points : 3 274
    Points
    3 274
    Par défaut
    C'est ta manière de faire qui est dépréciée, pas du tout le passage par référence, je t'invite à lire ceci et plus particulièrement :

    Note: Il n'y a pas de signe de référence dans l'appel de la fonction, uniquement sur sa définition. La définition de la fonction en elle-même est suffisante pour passer correctement des arguments par référence. A partir de PHP 5.3.0, vous devriez recevoir une alerte disant que "Call-time pass-by-reference" est obsolète, lorsque vous utilisez un & dans foo(&$a);. Et à partir de PHP 5.4.0, call-time pass-by-reference a été supprimé, l'utiliser lèvera une erreur fatale.
    qui est ce qu'à voulu dire la personne à l'origine de la citation ci-dessus.

    Si tu as bien compris ce qui est écrit ci-dessus, corriger ton erreur est très simple.
    Un message utile vous a aidé ? N'oubliez pas le

    www.simplifions.fr - Simplifier vos comptes entre amis !

  3. #3
    Membre habitué

    Inscrit en
    février 2007
    Messages
    223
    Détails du profil
    Informations personnelles :
    Âge : 50

    Informations forums :
    Inscription : février 2007
    Messages : 223
    Points : 160
    Points
    160
    Par défaut
    J'ai très bien compris mon erreur, j'ai très bien compris ce qui est déprécié (ajouter un '&' lors de l'appel car ceci est déjà écrit dans le prototype de la méthode).
    Par contre, non, corriger ce n'est pas simple car si j'enlève les & dans le tableau (array), les variables seront passées en valeur et donc, pas d'effet de bord lors de la modification des valeurs dans la fonction et donc lors du retour les variables passées en arguments dans le array créée ne sont pas modifiées...
    Si j'ajoute le & dans la fonction : idem. Le tableau est passé par référence mais pas les arguments qui le compose et donc même résultat.
    Ou alors passer un $$ ? Un truc dans le genre ?
    De plus, pourquoi dans ce cas là, mon PHP qui est en version 5.5 sous wampserver ne provoque aucun warning de dépréciation ? (alors que le fait de faire appel d'une méthode avec un & dans l'appel (et dans la signature) provoque en effet cette erreur).
    Tu en penses quoi ?

  4. #4
    Membre expert
    Avatar de Spartacusply
    Homme Profil pro
    Développeur Web
    Inscrit en
    mai 2011
    Messages
    1 723
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : mai 2011
    Messages : 1 723
    Points : 3 274
    Points
    3 274
    Par défaut
    Voici un code qui est fonctionn et qui est entièrement valide :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    function replace_all_by(&$array) {
        foreach ($array as &$field) {
            $field = 'zz ';
        }
    }
     
    $a = 'a';
    $b = 'b';
    $c = 'c';
     
    $array = array(
        &$a,
        &$b,
        &$c,
    );
     
    replace_all_by($array);
     
    echo $a;
    echo $b;
    echo $c;
     
    // Affiche: 'zz zz zz'
    Tu ne peut passer directement 'array' en paramètre car il n'y a que les variable qui peuvent être passé par référence (ce qui paraît logique).
    Un message utile vous a aidé ? N'oubliez pas le

    www.simplifions.fr - Simplifier vos comptes entre amis !

  5. #5
    Membre habitué

    Inscrit en
    février 2007
    Messages
    223
    Détails du profil
    Informations personnelles :
    Âge : 50

    Informations forums :
    Inscription : février 2007
    Messages : 223
    Points : 160
    Points
    160
    Par défaut
    Ce que je fais ? Passer un array en copie (par valeur) dont les éléments sont des références. Ça ne pose pas de problème.
    Ton code fonctionne aussi mais un appel du type suivant ne fonctionne pas :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    replace_all_by(array(
        &$a,
        &$b,
        &$c,
    ));
    En effet, cela fonctionne si l'argument array de la fonction replace_all_by est de type passage par copie ($array) et ne fonctionne pas si est de type passage par référence (&$array) car le tableau est construit en même temps que l'appel (en C++ on a un joli warning si on crée une instance d'une classe lors de l'appel à une fonction qui prend une référence en entré (&))

    Citation Envoyé par Spartacusply
    Tu ne peut passer directement 'array' en paramètre car il n'y a que les variable qui peuvent être passé par référence (ce qui paraît logique).
    Donc d'après ce que tu dis on peut passer des références dans un tableau d'éléments, ok, je pense que c'est justement cette ligne qui pose problème à mon interlocuteur.
    On se rapproche de la vérité ?

  6. #6
    Membre expert
    Avatar de Spartacusply
    Homme Profil pro
    Développeur Web
    Inscrit en
    mai 2011
    Messages
    1 723
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : mai 2011
    Messages : 1 723
    Points : 3 274
    Points
    3 274
    Par défaut
    En fait en te relisant, en me relisant et relisant sa remarque que je me rend compte que le problème, c'est la remarque, qui en effet n'est pas judicieuse (et même pire, est tout simplement fausse).

    Ton code, tout comme un code comme celui-ci est totalement valide php 5.x :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    function replace_all_by($array) {
        foreach ($array as &$field) {
            $field = 'zz ';
        }
    }
     
    $a = 'a';
    $b = 'b';
    $c = 'c';
     
    replace_all_by(array(
        &$a,
        &$b,
        &$c,
    ));
     
    echo $a;
    echo $b;
    echo $c; 
    //Affiche zz zz zz
    Cette remarque :

    Le passage de variable par référence est déprécié a partir de php 5.4, ton mod ne sera donc pas fonctionnel sous php 5.4
    est fausse ! Le passage de variable par référence n'est absolument pas déprécié, c'est le passage de référence dans l'appel de la fonction qui est déprécié (qui plus est un code déprécié n'est pas pour autant non fonctionnel mais bon passons...).

    En gros, ce code n'est plus valide :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    function foo(&$var) {
      $var++;
    }
    $a=5;
    foo (&$a);
    mais il suffit d'enlever la référence lors de l'appel de la fonction pour que celui-ci le redevienne.

    Bref, ton code est tout à fait valide, et qui plus est ne sera vraisemblablement pas dépréciée avant un bon bout de temps.
    Un message utile vous a aidé ? N'oubliez pas le

    www.simplifions.fr - Simplifier vos comptes entre amis !

  7. #7
    Membre habitué

    Inscrit en
    février 2007
    Messages
    223
    Détails du profil
    Informations personnelles :
    Âge : 50

    Informations forums :
    Inscription : février 2007
    Messages : 223
    Points : 160
    Points
    160
    Par défaut
    J'en était arrivé aux mêmes conclusions que toi... Mais je suis expert C++, pas PHP donc quand il me dit 'C'est quand même mon métier' ... et bien je veux bien douter de mes compétences PHP...

  8. #8
    Membre expert
    Avatar de Spartacusply
    Homme Profil pro
    Développeur Web
    Inscrit en
    mai 2011
    Messages
    1 723
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : mai 2011
    Messages : 1 723
    Points : 3 274
    Points
    3 274
    Par défaut
    Voici la version sans référence, sans doute un peu plus proche des "Coding Guidelines", mais beaucoup moins "user-friendly" :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    function foo($array) {
        $res = array();
        foreach ($array as $val) {
            $res[] = ++$val;
        }
        return $res;
    }
     
    $a = 2;
    $b = 5;
    $c = 10;
     
    list($a, $b, $c) = foo(array($a, $b, $c));
     
    echo "$a\n";
    echo "$b\n";
    echo "$c\n";
    Un message utile vous a aidé ? N'oubliez pas le

    www.simplifions.fr - Simplifier vos comptes entre amis !

  9. #9
    Membre habitué

    Inscrit en
    février 2007
    Messages
    223
    Détails du profil
    Informations personnelles :
    Âge : 50

    Informations forums :
    Inscription : février 2007
    Messages : 223
    Points : 160
    Points
    160
    Par défaut
    Je vais garder ma fonction user friendly qui est correcte au niveau syntaxe et non déprecated...
    Je n'ai pas envie de tout changer et faire des trucs pas super propre alors que ce code est correct...
    Merci beaucoup de ton aide.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [Smarty] php 5.4 et passage par référence dans Smarty
    Par Rhimo dans le forum Bibliothèques et frameworks
    Réponses: 2
    Dernier message: 23/07/2013, 16h51
  2. Réponses: 5
    Dernier message: 21/03/2012, 18h12
  3. Réponses: 2
    Dernier message: 30/03/2009, 12h21
  4. Réponses: 1
    Dernier message: 25/05/2007, 17h35
  5. Problème très rapide de passage par référence
    Par Noxexplorer dans le forum ASP
    Réponses: 2
    Dernier message: 23/06/2005, 10h02

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo