web-dev-qa-db-fra.com

Redéfinition PHP une fonction?

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;
}
34
Michael

Non, ça jette une erreur:

Fatal error: Cannot redeclare foo()

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

21
Annika Backstrom

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

Citant le manuel PHP sur les fonctions :

PHP ne supporte pas la surcharge de fonctions, il n'est pas non plus possible d'indéfinir ou de redéfinir les fonctions déclarées précédemment. 

Vous pouvez utiliser l'extension 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'œil au Modèle de stratégie ou Fonctions anonymes à la place.

Si par redéfinition, vous entendez ajouter à une fonction utilisateur existante, refactoriser, remplacer ou réécrire, alors oui: c’est aussi simple que vous l’avez montré. Ajoutez simplement le code supplémentaire à la fonction, mais assurez-vous de définir une valeur par défaut pour la compatibilité en amont.

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 méthodes définies par l'utilisateur au moment de l'exécution, en répliquant de manière lâche la fonctionnalité runkit_function_redefine en code pur PHP 5.3, qui permet notamment de remplacer et méthodes privées avec doubles tests.

22
Gordon

Vous ne pouvez pas redéfinir ou "annuler la définition" d'une fonction dans PHP (sans recourir à des modules tiers). Cependant, vous pouvez définir une fonction de manière conditionnelle.

Donc, si vous connaissez la fonctionApeut être définie ailleurs, mais pas toujours, vous pouvez l'envelopper comme ceci:

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

Ensuite, il vous suffit de vous assurer que l'implémentation souhaitée est rencontrée en premier:

function A() {
    // another A implementation
}
10
rustyx

J'ai une bibliothèque de fonctions que parfois je ne veux pas simplement invoquer pendant mes tests (généralement des mises à jour de base de données). Si j’ai, par exemple, quelques fonctions différentes de mise à jour de la base de données sur tout le code. au lieu de commenter le code, je crée simplement une classe spéciale (par exemple, classe foo {}). Définissez une variable globale (par exemple, $ DEBUG) et une fonction factice (par exemple, fonction factice {}) . À l'intérieur de foo, définissez toutes les fonctions (statiques publiques) que vous devez imiter

$ fn = isset ($ DEBUG)? 'dummy': 'fonction réelle'; return call_user_func_array ($ fn, func_get_args ());

De plus, vous avez les avantages de faire d’autres tâches, telles que la consignation des appels et des paramètres.

Ensuite, remplacez simplement tous vos appels sur real_function (...) par foo :: real_function (...). Habituellement, une simple recherche/remplacement (ou laissez-le là; selon ce qui se passe dans la fonction et la fréquence à laquelle on l'appelle, les frais généraux peuvent ne pas être pertinents). 

1
Cuse70

J'ai de bonnes et de mauvaises nouvelles.

La bonne nouvelle
C'est possible (lien (s) ci-dessous).

Les nadnews
Il y a 2 mauvaises nouvelles:

Par défaut, seules les fonctions de l'espace utilisateur peuvent être supprimées, renommées ou modifiées. Afin de remplacer les fonctions internes, vous devez activer le paramètre runkit.internal_override dans le fichier php.ini.

Et la deuxième mauvaise nouvelle: Vous devez sacrifier la lisibilité du code .

Exemple:

<?php
function this($a){
   return $a;
}

echo this(0);

$f_name = 'this';
$f_args = '$a';
$f_code = 'return $a*$b;';
runkit_function_redefine($f_name, f_args, f_code);

echo this(1,3);

Oh, et encore une chose, utiliser this comme nom d'une fonction peut créer de la confusion, car les méthodes d'un objet d'une classe peuvent utiliser this.something pour afficher la variable something qui est dans la méthode et qui porte le même nom. comme variable something à partir de l'objet lui-même. Voici un exemple

<?php
class theclass{
  $a = 'a';
  function a($a){
    echo $a;
    $a = this.$a;
  }
}
theclass $object = new theclass();
$object -> a('b'); // will echo: ab
0
SapioiT

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

0
googletorp

Vous ne pouvez pas le redéclarer. Si votre question concerne simplement la surcharge de cet exemple, que diriez-vous:

function this($a, $b=1)
{
    return $a * $b;
}
0
Tom

Définir une valeur par défaut appropriée pour tous les nouveaux arguments que vous ajoutez peut aider à la compatibilité en amont, c'est-à-dire:

function this($a, $b=1){  //New this function with a sane default.
    return $a * $b;
}

Je recommande également, par souci de clarté, d’éviter généralement d’utiliser this pour les noms de fonction/variable.

0
Kzqai