2008-08-21 19 views
5

J'ai entendu des rumeurs selon lesquelles PHP prévoit d'introduire une commande "goto". Qu'est-ce que c'est censé faire?Commande GOTO en PHP?

J'ai essayé de chercher un peu, mais je n'ai rien trouvé d'horriblement descriptif. Je comprends que ce ne sera pas une commande "GOTO 10" ...

+1

Et en fait, il est en PHP5. Et ce qu'il fait est, "tout simplement goto". –

Répondre

9

Ils n'ajoutent pas de vrai GOTO, mais ils étendent le mot clé BREAK pour utiliser des étiquettes statiques. Fondamentalement, il va améliorer la capacité de sortir de basculer imbriqués si les instructions. Voici l'exemple de concept que je trouve:

<?php 
for ($i = 0; $i < 9; $i++) { 
    if (true) { 
     break blah; 
    } 
    echo "not shown"; 
    blah: 
    echo "iteration $i\n"; 
} 
?> 

Bien sûr, une fois que le GOTO « rumeur » était, il n'y avait rien pour arrêter le mal à certains gars propager une blague comefrom supplémentaire. Soyez sur vos orteils.

Voir aussi:

http://www.php.net/~derick/meeting-notes.html#adding-goto

+4

Je pense que c'est vraiment déroutant, car une rupture en elle-même sautera hors de la boucle for, pas seulement l'instruction if. – DisgruntledGoat

3

Accordé, je ne suis pas un programmeur PHP, et je ne sais pas ce que l'implémentation exacte de PHP de GOTO va ressembler, mais voici ma compréhension de GOTO:

GOTO est juste une déclaration de contrôle de flux plus explicite que n'importe quelle autre. Disons que vous avez des boucles imbriquées et que vous n'avez besoin que de trouver une chose. Vous pouvez mettre une instruction conditionnelle (ou plusieurs) et lorsque les conditions sont correctement remplies, vous pouvez utiliser une instruction GOTO pour sortir de toutes les boucles (au lieu d'avoir une instruction 'break' à chaque niveau d'imbrication avec une instruction conditionnelle . pour chaque et oui, je crois que la mise en œuvre traditionnelle est d'avoir nommé des étiquettes que l'instruction GOTO peut sauter par nom Vous pouvez faire quelque chose comme ceci:.

for(...) { 
    for (...) { 
     for (...) { 
     // some code 
     if (x) GOTO outside; 
     } 
    } 
} 
:outside 

Ceci est une mise en œuvre plus simple (et plus efficace) . que sans GOTO l'équivalent serait:

for(...) { 
    for (...) { 
     for (...) { 
      // some code 
      if (x) break; 
     } 
     if(x) break; 
    } 
    if(x) break; 
} 

Dans le second cas (ce qui est pratique courante) il y a thre Les instructions conditionnelles, ce qui est évidemment plus lent que de n'en avoir qu'une. Donc, pour des raisons d'optimisation/simplification, vous pouvez utiliser les instructions GOTO dans des boucles étroitement imbriquées.

+0

Vous n'avez pas besoin de GOTO pour cette raison. Voir ma réponse pour une manière plus structurée d'exprimer la rupture des boucles qui fonctionne toujours et introduit l'inefficacité zéro. Aller à cet effet est juste bête. (Ce n'est pas une réflexion sur vous.) –

0

Il est looks comme c'est actuellement en PHP 5.3, mais n'est pas encore entièrement documenté. De ce que je peux dire, il partage sa syntaxe goto avec C, donc il devrait être facile à prendre en main et à utiliser. Rappelez-vous juste warning de Dijkstra et utilisez-le seulement si nécessaire.

0

@ steveth45

Ma règle de base est que si vous avez le code imbriqué plus de 3 niveaux de profondeur, vous faites quelque chose de mal.

alors vous n'avez pas à vous soucier de l'utilisation d'instructions break multiples ou goto: D

+0

Je suis légèrement d'accord mais parfois plusieurs niveaux de boucles imbriquées sont inévitables et ne devraient pas être moqués. – Christian

0

Dans l'exemple donné par steveth45 vous pouvez utiliser une fonction à la place:

function findItem(...) { 
    for (...) { 
    for (...) { 
     for (...) { 
     if (x) { 
      return theItem; 
     } 
     } 
    } 
    } 
} 

// no need for label now 
theItem = findItem(a, b, c); 
5

Je suis toujours étonné à quel point les concepteurs PHP sont incroyablement stupides. Si le but d'utiliser GOTO est de faire sortir de imbriquées se multiplient des boucles plus efficaces, il y a une meilleure façon: les blocs de code marqués et casser des déclarations qui peuvent faire référence étiquettes:

a: for (...) { 
    b: for (...) { 
     c: for (...) { 
       ... 
       break a; 
      } 
     } 
    } 

maintenant est est clair que la boucle/bloquer pour quitter, et la sortie est structurée; vous ne pouvez pas obtenir le code spaghetti avec ce que vous pouvez avec de vrais gotos.

C'est une vieille, vieille, vieille idée. La conception de bonnes structures de gestion de flux de contrôle a été résolue depuis les années 70, et la littérature sur tout cela est depuis longtemps écrite. Le théorème de Bohm-Jacopini a montré que vous pouviez coder n'importe quoi avec l'appel de fonction, if-then-else, et while boucles. En pratique, pour sortir des blocs profondément imbriqués, le codage Bohm-Jacopini style nécessitait des drapeaux booléens supplémentaires ("mettre ce drapeau pour sortir de la boucle") qui était maladroit codage sage et inefficace (vous ne voulez pas un tel drapeaux dans votre boucle intérieure). Avec if-then-else, diverses boucles (tandis que, pour) et un bloc break-to-labelled, vous pouvez coder n'importe quel algorithme sans perte d'efficacité . Pourquoi les gens ne lisent-ils pas la littérature, à la place de copier ce que C a fait? Grrr.

+0

N'est-ce pas ce _break-to-labelled-block_ chose que vous avez mentionné exactement ce qui est mis en avant avec cette nouvelle fonctionnalité PHP? Pardonnez-moi si je me trompe –

+0

Quelle nouvelle fonctionnalité? ALLER À? GOTO vous amènera à une étiquette placée dans une partie aléatoire de votre code. Le break-to-label * only * permet de faire des pauses depuis l'intérieur d'un bloc jusqu'à la sortie du bloc. –

+0

Eh bien, je suppose que ce que vous avez mentionné _break-to-label_ est ** exactement ** ce qui est censé être introduit dans php6. Il ne fait pas revivre GOTO. –