web-dev-qa-db-ja.com

なぜクローズタグを省略するのでしょうか。

私は読み続けていますが、ファイルの終わりにPHP closeタグ?>を使うのは悪い習慣です。ヘッダの問題は次の文脈では無関係のようです(そしてこれがこれまでのところ唯一の良い議論です):

近代的なバージョンのPHPは、php.iniでoutput_bufferingフラグを設定します。出力バッファリングが有効になっている場合は、HTMLを出力した後でHTTPヘッダーとcookieを設定できます。

すべてのグッドプラクティスブックとウィキはこの「ルール」で始まりますが、誰も正当な理由を提供しません。 最後のPHPタグをスキップするもう1つの良い理由はありますか?

354
danidacar

通常のコースよりも早くヘッダーを送信すると、大きな影響を与える可能性があります。以下は、たまたま私の頭に浮かんだそれらのほんの一部です。

  1. 現在のPHPリリースでは出力バッファリングがオンになっている場合がありますが、コードをデプロイする実際の実稼働サーバーははるかに重要です開発マシンまたはテストマシン。そして、彼らは常に最新のPHPトレンドにすぐに従う傾向があるわけではありません。

  2. 不可解な機能の損失に頭痛の種があるかもしれません。ある種の支払いゲートウェイを実装し、支払いプロセッサによる確認が成功した後にユーザーを特定のURLにリダイレクトするとします。何らかのPHPエラー、警告、または過剰な行末が発生した場合、支払いは未処理のままであり、ユーザーはまだ請求されていないように見える場合があります。これは、不必要なリダイレクトが悪である理由の1つでもあり、リダイレクトを使用する場合は注意して使用する必要があります。

  3. Internet Explorerでは、最新バージョンであっても「ページ読み込みがキャンセルされました」タイプのエラーが発生する場合があります。これは、AJAXresponse/json includeに含まれてはならないものが含まれているためです。一部のPHPファイル。数日前に出会ったのと同じです。

  4. アプリにファイルのダウンロードがある場合は、これが原因で壊れることもあります。また、ダウンロードの特定の破壊的な習慣はサーバー、ブラウザ、ファイルの種類とコンテンツに依存するため(そしておそらく私が退屈したくない他のいくつかの要因) 。

  5. 最後に、 SymfonyZend 、およびPHPを含む多くのLaravelフレームワーク( コーディングガイドライン しかし、それはスーツに従います) PSR-2標準 (項目2.2)は、終了タグの省略を要求します。 PHPマニュアル自体( 12 )、 WordpressDrupal およびその他多くのPHPソフトウェアと思います。そうすることをお勧めします。単に標準に従う習慣を作る(そして、コードに PHP-CS-Fixer を設定する)だけで、問題を忘れることができます。それ以外の場合は、常に問題を念頭に置く必要があります。

ボーナス:これらの2つのキャラクターに関連するいくつかの落とし穴(実際には現在1つ):

  1. よく知られているライブラリでも、?>の後に余分な行末が含まれている場合があります。例としてSmartyがあり、2。*および3. *ブランチの最新バージョンでもこれがあります。したがって、いつものように、サードパーティのコードを監視します。ボーナスのボーナス:不要なPHPの末尾を削除するための正規表現:PHPコードを含むすべてのファイルの(\s*\?>\s*)$を空のテキストに置き換えます。
314
Halil Özgür

Php終了タグ(?>)を省略しなければならないのは、プログラマが誤って余分な改行文字を送らないようにするためです。

Phpの終了タグを省略してはいけない理由は、phpタグのバランスが崩れるためです。また、頭が半ばのプログラマは、余分な空白を追加しないことを忘れないでください。

だからあなたの質問のために:

終了phpタグをスキップするもう1つの正当な理由はありますか?

いいえ、終わりのphpタグをスキップする正当な理由はありませんanother

終了タグに煩わされないためのいくつかの引数で終わります。

  1. たとえどれほど頭が良くても、人々は常に間違いを犯すことができます。起こり得る間違いの数を減らす練習に従うことは(私見)良い考えです。

  2. PHPはXMLではありません。 PHPは、適切に記述され機能するためにXMLの厳密な標準に従う必要はありません。終了タグが見つからないと煩わしい場合は、終了タグを使用することが許可されていますが、それはどちらにせよ、定石のルールではありません。

118
zzzzBov

これは初心者用コーディングスタイルの推奨、善意、そして助言 マニュアルによる です。

  • ただし、?>を省略すると、よくあるトリクル共通の ヘッダーはすでに送信されている (未加工の出力、 BOM 、注意事項など)とその解決方法だけが解決されます。フォローアップの問題.

  • PHPには、実際には?>終了トークンの後に単一の改行を食うための魔法が含まれています。にもかかわらず 歴史的な問題 を持っていますが、新参者はまだ荒削りな編集者の影響を受けやすく、?>の後の他の空白文字を無意識にシャッフルしています。

  • 文体的には、<?php?>をSGMLタグ/ XML処理命令として見るほうを好む開発者もいます。これは末尾のクローズトークンのバランスの一貫性を意味します。 (ところで、依存関係を結合するクラスでは、非効率的なファイルごとの自動ロードを避けるために、が便利ですが含まれます。)

  • 開始<?phpがPHPShebang(および binfmt_misc で完全に実行可能)として特徴付けられるため、対応する終了タグの冗長性が検証されます。

  • 古典的なPHP構文ガイド 必須の?>\nともっと多くの 最近のもの(PSR-2) の間には明らかな矛盾があります。
    (記録については、Zend Frameworkが他のものよりも高いと主張することは、その本質的な優位性を意味するものではありません。専門家が扱いにくいAPIの視聴者に引き寄せられているという誤解です)。

  • SCM そして最近のIDE 組み込みの解決策を提供します ほとんどの場合、タグの詳細な管理を緩和します。

?> closeタグの使用を中止することは、まれな問題を避けるために基本的なPHP処理の振る舞いと言語の意味論の説明を遅らせるだけです。参加者の熟練度が異なるため、共同ソフトウェア開発には実用的です。

タグのバリエーションを閉じる

  • 通常 ?> closeタグは T_CLOSE_TAG 、つまり "close token"とも呼ばれます。

  • PHPの魔法のおかげで、もう少し具体化されていますnewline eating

    ?>\n (Unixラインフィード)

    ?>\r (キャリッジリターン、クラシックMAC)

    ?>\r\n (CR/LF、DOS/Winの場合)

    PHPはUnicodeコンボ改行をサポートしていません NEL (U + 0085)ただし。

    初期のPHPバージョンでは、プラットフォームアグノスティックス主義をある程度制限するIIRCコンパイルインがありました(FIでさえ>をクローズマーカーとして使用しただけです)。これはクローズタグ回避の歴史的起源と考えられます。

  • 見過ごされがちですが、 PHP7ではそれらが削除されます までは、通常の <?php 開始トークンは、まれに使用されるものと有効にペアにすることができます </script> as 奇数終了トークン

  • "hard close tag"は一つではありません - たとえその用語を類推のために作り上げました。概念的にそして用法的には __halt_compiler はクローズトークンとして認識されるべきです。

    __HALT_COMPILER();
    ?>
    

    これにより、トークナイザは基本的にその後のコードまたはプレーンなHTMLセクションを破棄します。特にPHARスタブはそれを利用するか、または図のように?>との冗長な組み合わせを利用します。

  • 同様にvoid return;はインクルードスクリプトの中ではめったに置き換えず、末尾の空白を含む?>を無効にします。

  • それからいろいろな種類のsoft/faux近いタグのバリエーションがあります。あまり知られておらず、めったに使われませんが、通常はコメントアウトされたトークンごとに:

    • 単純な間隔 // ? > PHPのトークナイザによる検出を回避するため。

    • あるいは派手なUnicodeの代替物 // ﹖﹥ 正規表現が把握できる(U + FE56小質問マーク、U + FE65小角度ブラケット)。

    両方ともはPHPには意味がありませんが、PHPに対応していない、または準認識している外部ツールキットには実用的な用途があります。やはりcatnameと結合されたスクリプトが頭に浮かぶことになり、結果としての// ? > <?phpの連結は前のファイルセクションをインラインに保持します。

そのため、必須のクローズタグの省略には、コンテキストに依存しますが実用的な方法があります。

?>クローズタグの手動ベビーシッターは、どちらにしても現代的ではありません。そのための自動化ツールは常にありました(たとえsed/awkやregex-onelinersであっても)。特に:

phptags tag tidier

https://Fossil.include-once.org/phptags/

これは一般的に第三者のコードのためのphpタグを--uncloseするために使われるかもしれません、あるいはむしろ実際のホワイトスペース/ BOM問題を(そしてすべての)修正するだけです:

  • phptags --warn --whitespace *.php

ランタイム/設定の互換性のために--longタグ変換なども処理します。

54
mario

タグではありません…

あなたがそれを持っている場合しかし、あなたはそれの後に空白を持つ危険があります。

それを文書の先頭にインクルードとして使用すると、HTTPヘッダーを送信する前に空白(コンテンツ)を挿入することになります。これは許可されていません。

21
Quentin

最後の?>を入れないようにするのはとても便利です。

このファイルはPHP(構文エラーではありません)に対して有効であり、@ David Dorwardが?>の後に空白やブレークライン(ヘッダーをブラウザに送ることができるもの)を避けることを可能にします。

例えば、

<?
    header("Content-type: image/png");
    $img = imagecreatetruecolor ( 10, 10);
    imagepng ( $img);
?>
[space here]
[break line here]

有効ではありません。

しかし

<?
    header("Content-type: image/png");
    $img = imagecreatetruecolor ( 10, 10 );
    imagepng ( $img );

意志。

とりあえず、あなたは怠惰でなければならない安全な

15
Shikiryu

the docs によると、次のような理由でファイルの末尾にある場合は終了タグを省略することをお勧めします。

ファイルが純粋なPHPコードの場合は、ファイルの末尾のPHP終了タグを省略することをお勧めします。 PHP終了タグの後に誤って空白や新しい行が追加されるのを防ぎます。これは、プログラマが出力を送信する意図がない場合にPHPが出力バッファリングを開始するために望ましくない結果を招く可能性があります。スクリプトのその時点で。

PHPマニュアル>言語リファレンス>基本的な構文> PHP tags

13
Asaph

それを見るには2つの方法があります。

  1. PHPコードは、一連の XML処理命令 に過ぎません。したがって、拡張子.phpを持つファイルはXMLファイルに過ぎず、PHPを解析します。コード。
  2. PHPはまさにそのオープンタグとクローズタグのXML処理命令フォーマットを共有します。それに基づいて、.php拡張子を持つファイルは有効なXMLファイルであるかもしれませんが、そうである必要はありません。

最初の方法を信じるなら、すべてのPHPファイルは終了タグを閉じる必要があります。それらを省略すると、無効なXMLファイルが作成されます。繰り返しますが、<?xml version="1.0" charset="latin-1" ?>宣言を開くことなくしても、有効なXMLファイルは作成されません。したがって、これは大きな問題ではありません...

2番目の方法を信じるなら、それは2種類の.phpファイルへの扉を開きます。

  • コードのみを含むファイル(たとえばライブラリファイル)
  • ネイティブXMLとコードも含むファイル(例えばテンプレートファイル)

それに基づいて、コードのみのファイルは?>タグを閉じることなく終了しても問題ありません。しかし、XMLコードファイルはXMLを無効にするため、?>を閉じずに終了しても問題ありません。

しかし、私はあなたが何を考えているのか知っています。何が問題なのかを考えているのですが、PHPファイルを直接レンダリングすることは絶対にありません。テンプレートをデザインするのであれば、それは問題ではありません。有効なXML/HTMLであれば、通常のブラウザはPHPコードを単に表示しません(コメントのように扱われます)。そのため、PHPコードを実行しなくてもテンプレートを模擬できます。

これが重要だとは言っていません。それは私があまり頻繁に表現していないような単なる見解です。

個人的には、ライブラリファイルのタグは閉じませんが、テンプレートファイルのタグは閉じます。それは個人的な好み(およびコーディングガイドライン)であり、何よりも難しいことです。

9
ircmaxell

その理由はわかっていますが、それを示すことはできません。

PHPコードのみを含むファイルの場合、終了タグ(?>)は許可されません。 PHPでは必須ではありません。省略すると、応答に末尾の空白が誤って挿入されるのを防ぐことができます。

出典: http://framework.zend.com/manual/en/coding-standard.php-file-formatting.html

8
tawfekov

すでに述べたことすべてに加えて、私はデバッグするのが私たちにとって大きな苦痛だったもう一つの理由を投げるつもりです。

Apache 2.4.6(PHP 5.4付き)は、最後のphpタグの後ろに空のスペースがあると、実際には私たちのプロダクションマシンのセグメンテーションエラーになります。 strace でバグを絞り込むまで、何時間も無駄にしました。

これはApacheが投げるエラーです:

[core:notice] [pid 7842] AH00052: child pid 10218 exit signal Segmentation fault (11)
7

「終了phpタグをスキップするもう1つの正当な理由(ヘッダーの問題以外)はありますか?」

バイナリ出力、 CSV data、またはその他のHTML以外の出力を生成するときに、余分な空白文字を誤って出力したくない場合があります。

6
user1238364

長所

短所

結論

私はタグを省略することを支持する議論がより強く見えると言うでしょう(header()で大きな頭痛を避けるのを助けます)+それはPHP/Zendの「推奨」です)。私はこれが私が今まで見た中で構文の一貫性の観点から見た最も「美しい」解決策ではないことを認めます、しかし何がより良いかもしれません?

5
Frosty Z

私の質問はこれと重複しているとマークされていたので、私はそれがO.Kであると思います。終了タグ?>を省略する理由NOTを投稿するには、いくつかの理由があります。

  • 完全な処理命令で構文(<?php ... ?>)PHP sourceは有効なSGML文書で、SGMLパーサーで問題なく構文解析し処理することができます。追加の制限がありますが、有効なXML/XHTMLでも構いません。

有効なXML/HTML/SGMLコードを書くことを妨げるものは何もありません。 PHPドキュメント はこれを知っています。抜粋:

注意:PHPをXMLまたはXHTMLに埋め込む場合は、標準に準拠するために<?php?>タグを使用する必要があります。

もちろん、PHP構文は厳密なSGML/XML/HTMLではないので、HTMLをXHTMLに変換してXMLに準拠するかどうかのように、SGML/XML/HTMLではない文書を作成します。

  • ある時点でソースを連結したいと思うかもしれません。 cat source1.php source2.phpタグを省略して矛盾が生じた場合、これは単に?>を実行するのと同じくらい簡単ではありません。

  • ?>がないと、ドキュメントがPHPエスケープモードまたはPHP無視モードのままになっているかどうかを判断するのが難しくなります(PIタグの<?phpが開かれているかどうか)。ドキュメントをPHP無視モードにしておくと、作業が楽になります。閉じられていないタグや入れ子になっていないタグがある文書と比較して、整形式のHTML文書を扱うのと同じようなものです。

  • Dreamweaverのようなエディターの中には、PIを開いたままにしておくと問題があるようです [1]

2
doc

私が質問を正しく理解したならば、それは出力バッファリングとこれが終了/終了タグに及ぼすかもしれない影響と関係がある。それが完全に有効な質問であるかどうかはわかりません。問題は、出力バッファがすべてのコンテンツがクライアントに送信される前にメモリに保持されることを意味するわけではないということです。内容の一部はそうです。

プログラマは意図的にバッファをフラッシュすることができますか、それともPHPの出力バッファオプションは本当に終了タグがコーディングに与える影響を変えるのでしょうか?そうではないと私は主張します。

そしてそれが、答えの大部分が個人的なスタイルと構文に戻った理由かもしれません。

0
Ruz

PHPコードには2つの用途があります。

  1. クラス定義や関数定義などのPHPコード
  2. テンプレート言語としてPHPを使用する(ビュー内など)

場合1。終了タグは全く役に立たない、また私はちょうど1(php)開始タグとNO(ゼロ)終了タグをそのような場合に見たいと思います。コードをクリーンにし、ロジックをプレゼンテーションから分離するので、これは良い習慣です。プレゼンテーションケース(2)では、PHPには実際には2つの別々のユースケースがあるため、すべてのタグ(PHPで処理されたものであっても)を閉じるのは当然のことです。混在させること:論理/微積分および提示

0