2010-11-15 12 views
6

Pourquoi PHP autoriserait-il les fonctions d'imbrication?Imbrication des fonctions PHP: dans quel but?

<?php 
function foo() { 
    function bar() { 
     return "bar"; 
    } 
    return "foo"; 
} 
print foo(); 
print bar(); 

.. est valide PHP.

Mais:

  1. Pourquoi faudrait-il jamais de nidification?
  2. Et même si oui, pourquoi puis-je appeler la barre de n'importe où (et non, par exemple seulement avec foo(), ou par foo.bar() ou tel).

Je suis tombé sur ceci aujourd'hui, parce que j'ai oublié un support de fermeture quelque part, et j'en ai eu un de trop plus bas. Le code était valide et aucune erreur n'a été levée; mais tout a commencé à agir vraiment bizarre. Les fonctions ne sont pas déclarées, les rappels deviennent berserk et ainsi de suite. Est-ce une caractéristique, et si oui, dans quel but? Ou une certaine idiosyncrasie?

RÉPONSE: commentor souligne que c'est un doublon de What are php nested functions for.

+1

Lovely. Comme si PHP avait besoin d'une autre raison pour attirer la haine ... –

+1

A déjà été très bien couvert: duplication possible de [Quelles sont les fonctions imbibées php?] (Http://stackoverflow.com/questions/415969/what-are- php-imbriqué-fonctions-pour) – meagar

+3

Aussi, juste parce que vous ne comprenez pas quelque chose ne fait pas "idiocracy", qui n'est pas un mot d'ailleurs. – meagar

Répondre

7

Notez que la commande est importante ici; vous ne pouvez pas appeler bar() avant d'appeler foo() dans votre exemple. La logique ici semble être que l'exécution de foo() définit bar() et le met dans une portée globale, mais il n'est pas défini avant l'exécution de foo(), à cause de la portée.

L'utilisation ici serait une forme primitive de surcharge de fonction; vous pouvez avoir votre fonction bar() effectuer différentes opérations en fonction de la version de foo() qui la déclare, en supposant bien sûr que chaque version différente de foo() définit en effet une fonction bar().

+2

Je me demande ce qu'il se passe quand 'foo()' est appelé deuxième fois. On pourrait penser qu'une erreur serait lancée parce que 'bar()' est déjà défini. – dnagirl

+2

@dnagirl: c'est le cas: Erreur fatale: func.Déjà défini. – berkes

6

En PHP, vous pouvez définir des fonctions, des constantes d'exécution et même des classes de manière conditionnelle. Cela vous permet de définir différentes fonctions/constantes/classes selon les circonstances.

Exemple simple: Définissez la fonction String\Length selon que la prise en charge multi-octets est activée ou désactivée dans votre application.

namespace String; 

if (\MULTIBYTE_MODE) { 
    function Length($string) { 
     return strlen($string); 
    } 
} else { 
    function Length($string) { 
     return mb_strlen($string); 
    } 
} 

Les fonctions imbriquées sont uniquement un cas particulier de définition de fonction conditionnelle.