Pouvez-vous déclarer une fonction comme celle-ci ...
function ihatefooexamples(){
return "boo-foo!";
};
Et puis redeclare un peu comme ça ...
if ($_GET['foolevel'] == 10){
function ihatefooexamples(){
return "really boo-foo";
};
};
Est-il possible d'écraser une fonction de cette façon?
En tous cas?
Pour adresser des commentaires que cette réponse ne traite pas directement le question originale. Si vous venez d'une recherche Google, commencez ici
Il existe une fonction appelée override_function qui correspond réellement à la facture. Cependant, étant donné que cette fonction fait partie de Le débogueur PHP avancé extension, il est difficile de dire que override_function()
est destiné à une utilisation en production. Par conséquent, je dirais "Non", il n'est pas possible d'écraser une fonction avec l'intention que le questionneur initial avait en tête.
C'est là que vous devriez tirer parti de la POO, en particulier du polymorphisme.
interface Fooable
{
public function ihatefooexamples();
}
class Foo implements Fooable
{
public function ihatefooexamples()
{
return "boo-foo!";
}
}
class FooBar implements Fooable
{
public function ihatefooexamples()
{
return "really boo-foo";
}
}
$foo = new Foo();
if (10 == $_GET['foolevel']) {
$foo = new FooBar();
}
echo $foo->ihatefooexamples();
Le patch de singe est une méthode moins évasive que de modifier l’interprète.
La correction de singe est l'art de remplacer la mise en oeuvre réelle par un "correctif" similaire.
Avant de pouvoir utiliser les correctifs comme un Ninja PHP, nous devons d'abord comprendre les espaces de noms PHP.
Depuis PHP 5.3, nous avons été initiés aux espaces de noms que vous pourriez peut-être reconnaître à première vue comme équivalents à quelque chose comme les paquets Java, mais ce n'est pas tout à fait pareil. Les espaces de noms, en PHP, permettent d'encapsuler la portée en créant une hiérarchie de focus, en particulier pour les fonctions et les constantes. Comme ce sujet, repli sur des fonctions globales , vise à expliquer.
Si vous ne fournissez pas d'espace de nom lorsque vous appelez une fonction, PHP commence par rechercher dans l'espace de nom actuel, puis descend dans la hiérarchie jusqu'à ce qu'il trouve la première fonction déclarée dans cet espace de nom préfixé et l'exécute. Par exemple, si vous appelez print_r();
à partir de namespace My\Awesome\Namespace;
, ce que PHP fait, commence par rechercher une fonction appelée My\Awesome\Namespace\print_r();
puis My\Awesome\print_r();
puis My\print_r();
jusqu'à ce qu'il trouve la fonction intégrée PHP dans l'espace de noms global \print_r();
.
Vous ne pourrez pas définir une function print_r($object) {}
dans l'espace de noms global, car cela entraînera une collision de noms, car une fonction portant ce nom existe déjà.
Attendez-vous à une erreur fatale de la part de:
Fatal error: Cannot redeclare print_r()
Mais rien ne vous empêche cependant de faire cela dans le cadre d'un espace de noms.
Supposons que vous ayez un script utilisant plusieurs appels print_r();
.
<?php
print_r($some_object);
// do some stuff
print_r($another_object);
// do some other stuff
print_r($data_object);
// do more stuff
print_r($debug_object);
Mais vous changez d'avis par la suite et vous souhaitez plutôt que la sortie soit enveloppée dans des balises <pre></pre>
. Vous est-il déjà arrivé?
Avant que vous ne changiez chaque appel en print_r();
, pensez plutôt à appliquer des correctifs aux singes.
<?php
namespace MyNamespace {
function print_r($object)
{
echo "<pre>", \print_r($object, true), "</pre>";
}
print_r($some_object);
// do some stuff
print_r($another_object);
// do some other stuff
print_r($data_object);
// do more stuff
print_r($debug_object);
}
Votre script utilisera désormais MyNamespace\print_r();
au lieu de la fonction globale \print_r();
Fonctionne très bien pour se moquer des tests unitaires.
nonJoy!
Regardez override_function
pour remplacer les fonctions.
override_function - Remplace la fonction intégrée les fonctions
Exemple:
override_function('test', '$a,$b', 'echo "DOING TEST"; return $a * $b;');
la réponse courte est non, vous ne pouvez pas écraser une fonction une fois que cela se trouve dans la portée de la fonction PHP.
votre meilleur d'utiliser des fonctions anonymes comme si
$ihatefooexamples = function()
{
return "boo-foo!";
}
//...
unset($ihatefooexamples);
$ihatefooexamples = function()
{
return "really boo-foo";
}
Vous ne pouvez redéclarer aucune fonction en PHP. Vous pouvez cependant les remplacer. Vérifiez fonctions prioritaires ainsi que renommer des fonctions afin de sauvegarder la fonction que vous substituez si vous le souhaitez.
Donc, gardez à l'esprit que lorsque vous substituez une fonction, vous la perdez. Vous voudrez peut-être envisager de le garder, mais sous un nom différent. Je dis juste.
De plus, s'il s'agit de fonctions de classes que vous souhaitez remplacer, il vous suffira de créer une sous-classe et de redéclarer la fonction dans votre classe sans avoir à renommer_function et override_function.
Exemple:
rename_function('mysql_connect', 'original_mysql_connect' );
override_function('mysql_connect', '$a,$b', 'echo "DOING MY FUNCTION INSTEAD"; return $a * $b;');
J'inclurais toutes les fonctions d'un cas dans un fichier include
et les autres dans un autre include
.
Par exemple, simple.inc
contiendrait function boofoo() { simple }
et really.inc
contiendrait function boofoo() { really }
Cela facilite la lisibilité/la maintenance de votre programme, en ayant toutes les fonctions du même genre dans le même inc
.
Puis en haut de votre module principal
if ($_GET['foolevel'] == 10) {
include "really.inc";
}
else {
include "simple.inc";
}
Vous pouvez utiliser l'extension PECL
runkit_function_redefine
- Remplace une définition de fonction par une nouvelle implémentation mais c'est une mauvaise pratique à mon avis. Vous utilisez des fonctions, mais consultez le modèle de conception Decorator . Peut emprunter l'idée de base de celui-ci.
Non, ce sera un problème. PHP Fonctions de variable
Une solution pour le cas connexe où vous avez un fichier d'inclusion A que vous pouvez modifier et souhaitez remplacer certaines de ses fonctions dans un fichier d'inclusion B (ou le fichier principal):
Fichier principal:
<?php
$Override=true; // An argument used in A.php
include ("A.php");
include ("B.php");
F1();
?>
Inclure le fichier A:
<?php
if (!@$Override) {
function F1 () {echo "This is F1() in A";}
}
?>
Inclure le fichier B:
<?php
function F1 () {echo "This is F1() in B";}
?>
Parcourir le fichier principal affiche " Ceci est F1 () dans B ".
En fonction de la situation où vous en avez besoin, vous pouvez peut-être utiliser des fonctions anonymes telles que:
$greet = function($name)
{
echo('Hello ' . $name);
};
$greet('World');
... alors vous pouvez définir une nouvelle fonction pour la variable donnée à tout moment