36 votes

Redéfinir la fonction PHP ?

Si j'ai une fonction :

function this($a){
   return $a;
}

Si je voulais redéfinir la fonction, serait-ce aussi simple que de la réécrire ?

function this($a, $b){  //New this function
   return $a * $b;
}

0 votes

Pourquoi voulez-vous cela ? Une fonction doit être nommée pour décrire ce qu'elle fait. Qu'y a-t-il de mal à avoir 2 fonctions ?

1 votes

Je suis en train de modifier un script de base qui a une fonction définie et plutôt que de modifier la fonction directement, j'aimerais inclure un fichier personnalisé que je pourrais utiliser pour simplement redéfinir la fonction selon mes besoins.

6 votes

Il existe de nombreux cas où l'on peut vouloir modifier une fonction déjà existante. Par exemple lors de l'écriture de doubles de test (ou mocks) ; ou de bibliothèques de singe Parcheando à l'exécution (sans avoir à modifier le code source réel de la bibliothèque). En fait, je trouve que cette limitation est l'une des plus frustrantes de PHP, contrairement à des langages de programmation plus dynamiques comme Ruby ou JavaScript, où cela est non seulement possible, mais aussi souvent fait.

23voto

Annika Backstrom Points 8138

Non, il y a une erreur :

Fatal error: Cannot redeclare foo()

Le runkit fournit des options, notamment runkit_function_rename() y runkit_function_redefine() .

0 votes

Note : runkit n'est pas encore mis à jour pour PHP 7.0. Voir github.com/zenovich/runkit/issues/87

1 votes

Runkit pour PHP 7 peut maintenant être trouvé ici : github.com/runkit7/runkit7

22voto

Gordon Points 156415

Si vous voulez parler de surcharge au sens de Java, alors la réponse est non, ce n'est pas possible.

En citant le Manuel PHP sur les fonctions :

PHP ne supporte pas la surcharge de fonctions, et il n'est pas possible d'annuler ou de redéfinir des fonctions précédemment déclarées.

Vous pourriez utiliser le runkit mais l'utilisation de runkit dans des scénarios de production est généralement considérée comme une pratique douteuse. Si vous souhaitez échanger des algorithmes au moment de l'exécution, jetez un coup d'oeil à la version Modèle de stratégie o Fonctions anonymes à la place.

Si par redéfinir vous voulez dire ajouter à une fonction userland existante, remanier, substituer ou réécrire, alors oui : c'est aussi simple que vous l'avez montré. Il suffit d'ajouter le code supplémentaire à la fonction, mais assurez-vous de définir une valeur par défaut pour la rétrocompatibilité.

Une autre option serait d'utiliser http://antecedent.github.io/patchwork

Patchwork est une bibliothèque PHP qui permet de redéfinir les fonctions et les méthodes définies par l'utilisateur au moment de l'exécution, en reproduisant approximativement les fonctionnalités de ces fonctions. runkit_function_redefine dans du code PHP 5.3 pur, ce qui vous permet, entre autres, de remplacer les méthodes statiques et privées par des doubles de test.

0 votes

Désolé, j'ai mal lu votre réponse. Je pensais que vous aviez dit le contraire. Les deux autres votes négatifs semblent indiquer que je ne suis pas la seule personne à avoir fait cette erreur.

0 votes

@Casebash merci d'avoir pris le temps de relire la réponse. J'apprécie.

0 votes

Gordon, ces runkit Les extensions fonctionnent très bien. En quoi est-ce "une pratique généralement considérée comme douteuse" ?

10voto

rustyx Points 2722

Il est impossible de redéfinir ou d'annuler une fonction en PHP (sans recourir à des modules tiers). Cependant, vous pouvez définir une fonction de manière conditionnelle.

Donc, si vous connaissez la fonction A peut être défini ailleurs, mais pas toujours, vous pouvez l'envelopper comme ceci :

if (!function_exists('A')) {
    function A() {
        // default A implementation
    }
}

Il vous suffit alors de vous assurer que l'implémentation que vous souhaitez est rencontrée en premier :

function A() {
    // another A implementation
}

0 votes

Avec le nouveau avertissement que les appels arrivent après définitions . (PHP récent ne se soucie pas de l'ordre call/define pour les fonctions définies inconditionnellement).

1voto

Cuse70 Points 61

J'ai une bibliothèque de fonctions qui, parfois, ne doivent pas être invoquées pendant les tests (généralement des mises à jour de bases de données). Si j'ai, par exemple, quelques fonctions différentes de mise à jour de la base de données qui sont partout dans le code, au lieu de commenter le code, je crée simplement une classe spéciale (par exemple, class foo {}). Définir une variable globale (par exemple, $DEBUG) et une fonction fictive (par exemple, function dummy {}). A l'intérieur de foo, définissez toutes les fonctions (publiques et statiques) que vous devez imiter en tant que

$fn = isset($DEBUG) ? 'dummy' : 'real function' ; return call_user_func_array($fn,func_get_args()) ;

De plus, vous avez l'avantage de pouvoir faire d'autres choses, comme enregistrer les appels et les paramètres.

Ensuite, remplacez simplement tous vos appels à real_function(...) par foo::real_function(...). En général, il suffit d'une simple recherche/remplacement (ou de le laisser là ; selon ce qui se passe dans la fonction et la fréquence à laquelle elle est appelée, l'overhead peut ne pas être pertinent).

0voto

googletorp Points 22395

Vous ne pouvez pas avoir les deux fonctions déclarées en même temps, cela donnera une erreur.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X