なぜGOTOはPHP 5に含まれていたのですか?[閉まっている]


8

GOTOコントロールキーワードがPHP 5.3.0で導入されたことを少し前に発見しました。

http://php.net/manual/en/control-structures.goto.php

なぜそれが起こったのですか?

この背後にある言語設計の目標は何ですか?

PHP開発者コミュニティはそれを求めましたか?


10
gotoには問題はありません。私は本当にしません。それでも、コードを単純化するような場合でもほとんど使われることはありませんが、人々はそれを嫌っています。はい、それはあなたがgotoソースを読むことに慣れているかどうかに関係なく、良い使い方があります。それらが慣用的なコードで頻繁に見られるかどうかは別の問題です。しかし、後藤は害を引き起こしません。
zxcdw

7
有限ステートマシンは、コード化が少し簡単ですgoto
yannis 2012

回答:


22

責任者は、このブログ投稿にそれを追加する理由を示します。

[T]私が取り組んでいた(いつか戻ってくるかもしれない)プロジェクトは、プログラミング言語を知らなくても動的なWebサイトを作成するためのワークフローベースのサイトビルダー[…]でした。サイトの実行方法に関するすべてのメタ情報を作成し、次にサイトビルダーがそれを実際のサーバーで実行されるPHPコードに「コンパイル」します。

GOTOがなくても実行できますが、特に複雑なビジネスロジックの結果のロジックは、それを使用することではるかに簡単になります。

PHPの防御では、限定されたスコープ内のラベルにジャンプすることしかできません。これにより、実行できる害が制限されます。

(また、PHPがこれまでに発明されたすべてのプログラミング言語からのすべての構造を明らかに吸収している方法を考えると、追加gotoは単に避けられなかったと主張するかもしれません)


19
それで、彼がもう取り組んでいないプロジェクトのために行われました... Sweet。
Robert Harvey

アイキャプテン!every construct from every programming language ever invented!...無限の彼方へ!(そして、彼らがPerl 5についてこれまで言っていたものだと思うと... PHPと呼ばれるナンセンスのこの増え続ける小さな塊をとても誇りに思っています)
ZJR

13

下位レベルのPHPではgoto、PHP 4以降に使用されていました。PHP4では、インタープリターがやり直され、Zend Engineが導入されました。これには、低レベルの「オペコード」にコンパイルされ、エグゼキューターに渡されます。

そのレベルでは、ジャンプ操作がall ifswitchまたは任意のループステートメントに使用されます。PHP 5.3ではgoto、長い議論の後、という名前でエクスポートすることが決定されました。

主な理由は次のとおりです。

  • 費用をかけずに実行できます(とにかく内部的に既に使用しています)
  • コードジェネレータを書くときに役立ちます
  • エラー処理コードをクリーンアップすると役立つ場合があります。

最初の2つの項目は説明を必要としない場合があり、3番目の部分は次のような状況に関するものです。

 function do() {
     $lock = $acquire_lock...)
     if (!do_something()) {
         goto cleanup
     }
     if (!do_more()) {
          goto cleanup;
     }
  cleanup:
  free_lock($lock);

もちろん、PHPにはそのような状況はほとんどありません。PHPには参照カウントガベージコレクションシステムがあり、そのような変数と関連リソースを予測どおりに解放します。それにもかかわらず、開発者がクリーンアップコードを複数回複製したり、エミュレーションとしてd do { } while (0);を悪用したりするような状況が存在breakgotoます。

誤用を防ぐために、ループにジャンプできないように実装が制限されていました。したがって、有名なDuff's Deviceの邪魔をすることはできません。

結局のところ、PHPは問題を解決するために開発されています。自分の足で撃つことから完全に保護するわけではありませんgoto。この制限よりも悪い方法で多くの機能を悪用することができます。したがって、結論は、それが有用で問題を解決できるエッジケースがあるということでした。


2
goto cleanup?マジ?実際のtry-finally構成を実装しないのはなぜですか?(PHPには1つありますか?)
Mason Wheeler

3
@MasonWheeler PHPはfinallyかなり最近になり、その後になりましたgoto
yannis

3
えーと、例外は嫌いで後藤が好きな人がいます。それは自由な世界です;-)
ヨハネス'19

7
そして、ところで。PHP 5.3のリリースマスターである私は、この決定について全責任を負います:-)
johannes

5

どんな言語でも悪いコードを書くことができます。goto言語を使用しているからといって、言語が悪いというわけではありません。

さまざまな言語で既存の構造を考える- ブレークcontinuenext最後にthrow。でも、switch これらは、スコープの同じまたはより高いレベルへのスコープの1つのレベルからその行くに計算され、外出先のすべての形態です。

gotoの問題は、それがより深いレベルのスコープに入るとき、またはスタックフレームをジャンプするときです。

質問からリンクされたドキュメントの例3に注意してください。

<?php
goto loop;
for($i=0,$j=50; $i<100; $i++) {
  while($j--) {
    loop:
  }
}
echo "$i = $i";
?>

gotoはより深いレベルのスコープにジャンプしようとしているため、これは機能しません。

さまざまな形式の制限付きgotoには何の問題もありません。gotoという名前のキーワードや他の分岐名があります。代替案(forループの醜い条件文)は、多くの場合より悪い場合があります。そのまま、gotoを使用すると、

個人的には、例1の例が気に入らない

<?php
goto a;
echo 'Foo';

a:
echo 'Bar';
?>

ただし、これは、このようなコードを意図的に作成する開発者に何らかの体型学習経験を適用する必要があること以外は、言語に問題を引き起こしません。


4
+1:特に「言語にgotoがあることは、言語が悪いことを意味するわけではありません」
Deco
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.