2009-02-10 3 views

Répondre

11

Ceci est un bit en retard, mais je tiens juste à souligner que depuis PHP 5.3, il est en fait possible de surcharger les fonctions internes sans utiliser d'extension PHP. L'astuce est que vous pouvez redéfinir une fonction PHP interne à l'intérieur d'un espace de noms. Il est basé sur la façon dont PHP nomme la résolution des fonctions:

À l'intérieur de l'espace de noms (disons A \ B), les appels aux fonctions non qualifiées sont résolus au moment de l'exécution. Voici comment un appel à la fonction foo() est résolu:

  1. Il recherche une fonction dans l'espace de noms actuel: A \ B \ foo().
  2. Il essaie de trouver et d'appeler la fonction globale foo()
+0

Nice, pourquoi cette réponse n'est-elle pas acceptée? – Pacerier

+1

Très probablement, parce qu'il a été posté près de quatre ans après la question, et la réponse acceptée était probablement la plus pertinente à l'époque. –

+0

Je suis toujours sur SO ... Accepté! –

9

Non, il est impossible de le faire comme on pouvait s'y attendre.

De l'manual:

PHP ne supporte pas la surcharge de fonctions, ni est-il possible ou la redéfinition de fonctions déjà déclarées.

Cependant, vous pouvez utiliser runkit_function_redefine et ses cousines, mais il est certainement pas très élégant ...

Vous pouvez également utiliser create_function faire quelque chose comme ceci:

<?php 
$func = create_function('$a,$b','return $a + $b;'); 
echo $func(3,5); // 8 
$func = create_function('$a,$b','return $a * $b;'); 
echo $func(3,5); // 15 
?> 

Comme runkit, ce n'est pas très élégant, mais ça donne le comportement que vous recherchez.

+0

Vous l'avez dit deux fois, mais pourquoi est-il "pas très élégant"? – Pacerier

+0

@Pacerier: Eh bien, pour les débutants, c'est un peu une odeur de code de vouloir faire cela pour commencer, et il va certainement rejeter toute personne qui vient derrière vous pour regarder votre code, mais si vous passez que vous devez taper le code de fonction comme un argument de chaîne dans les deux cas, ce qui est disgracieux pour tout sauf pour les fonctions les plus courtes. –

+0

Sûrement nous sommes au moins sur PHP 5.3, plus personne ne fait de chaîne, le code de fonction peut être fourni comme une fonction anonyme. – Pacerier

5

Je réalise que cette question est un peu ancienne, mais Patchwork est un projet PHP 5.3 récemment publié qui supporte la redéfinition des fonctions définies par l'utilisateur. Bien que, comme l'auteur mentionne, vous devrez recourir à runkit ou php-test-helpers aux fonctions de noyau/bibliothèque de singe-correctif.

+2

Très jolie petite lib. Merci pour le partage :) –

1

Comme jmikola mentionné, Patchwork est une bonne solution si vous souhaitez ajouter du code à une fonction.

est ici un article sur la façon dont cela fonctionne: http://phpmyweb.net/2012/04/26/write-an-awesome-plugin-system-in-php/

Il est livré avec un exemple de code. Je pense que la version de phpmyweb utilise un code légèrement meilleur, car il n'utilise pas le code eval() 'd, contrairement au patchwork. Vous pouvez mettre en cache les opcodes lorsque vous utilisez eval().

+0

pourquoi avez-vous besoin de vous soucier des caches d'opcode lorsque vous testez des unités? Ou quoi ... vous utilisez des correctifs de singe pour autre chose que des tests? Dans ce cas, vous avez plus de problèmes que 'eval()' à s'inquiéter. – Spudley

+1

@Spudley Évidemment, l'article que j'ai posté n'est pas destiné aux tests unitaires (d'où le titre "Write an awesome plugin system"). Il montre juste une autre façon de créer une architecture de plugin. Et il dit aussi qu'il veut juste montrer une autre façon de créer une telle architecture. Bien sûr, c'est à discuter si c'est un bon moyen. Bien que je ne vois aucun problème avec cela. --- De quels «problèmes» parlez-vous? Comme l'auteur l'a dit, la mise en cache des opcode ne devrait pas poser de problème puisque eval() n'est pas utilisé du tout (contrairement au patchwork). – Vivendi

+0

@Vivendi, Le patchwork utilise-t-il les fonctions du runkit en interne? – Pacerier

Questions connexes