web-dev-qa-db-ja.com

PHP そしてそれをどれのように解決しますか?解析/構文エラー。

誰もが構文エラーに遭遇します。経験豊富なプログラマーでもタイプミスをします。初心者にとっては、学習プロセスの一部にすぎません。ただし、次のようなエラーメッセージは簡単に解釈できます。

PHP解析エラー:構文エラー、行20のindex.phpに予期しない '{'があります

予想外のシンボルが常に本当の原因とは限りません。しかし、行番号はどこから見ればいいのか大体の考えを与えます。

常に コードコンテキスト を見てください。構文の間違いは、 前のコード行 の中のorを隠してしまうことがよくあります。コードをマニュアルの構文例と比較してください。

すべてのケースが他と一致するわけではありませんが。まだいくつかあります 構文の誤りを解決するための一般的なステップ 。これは、よくある落とし穴をまとめたものです。

密接に関連した参考文献:

そして:

Stack Overflowはルーキーコーダーも歓迎しますが、それは主にプロのプログラミングに関する質問を対象としています。

  • すべての人のコーディングミスや狭いタイプミスに答えるのは、ほとんど話題外と考えられています。
  • そのため、構文修正要求を投稿する前に、 基本的な手順 に従うようにしてください。
  • それでもやらなければならない場合は、あなた自身の解決のイニシアチブ、試みた修正、そして何が見えているか、あるいは間違っているかもしれないかについてのあなたの思考プロセスを見せてください。

あなたのbrowserが "SyntaxError:illegal character"のようなエラーメッセージを表示するなら、それは実際には php 関連ではありません - しかし javascript - syntax error .


ベンダコードで発生した構文エラー: 最後に、コードベースを編集しても構文エラーが発生しなかったが、外部ベンダパッケージのインストールまたはアップグレード後にPHPが原因であると考えます。 _バージョンの非互換性なので、プラットフォームの設定に対してベンダーの要件を確認してください。

580
mario

構文エラーとは何ですか?

PHPは C-style および imperative プログラミング言語に属します。これには厳格な文法規則があり、シンボルや識別子の置き場所が間違っていると回復できません。コーディングの意図を推測することはできません。

Function definition syntax abstract

最も重要なヒント

あなたが常に取ることができるいくつかの基本的な予防措置があります:

  • 適切なコードインデントを使用するか、高尚なコーディングスタイルを採用します。可読性は不規則性を防ぎます。

  • IDEまたはPHPのエディター を使用し、構文強調表示を使用します。括弧/ブラケットのバランス調整にも役立ちます。

    Expected: semicolon

  • 言語リファレンス とマニュアルの例をお読みください。二度、ある程度熟練する。

パーサーエラーの解釈方法

典型的な構文エラーメッセージは次のとおりです。

解析エラー:構文エラー、予期しないT_STRING';'が必要ですinfile.phponline217

構文ミスのpossibleロケーションをリストします。前述のファイル名および行番号を参照してください。

moniker などT_STRINGは、パーサー/トークン化プログラムが最終的に処理できなかったシンボルを説明します。ただし、これは必ずしも構文エラーの原因ではありません。

前のコード行も調べることが重要です。多くの場合、構文エラーは以前に発生した単なる事故です。エラー行番号は、パーサーがすべてを処理するために最終的に断念した場所です。

構文エラーの解決

構文のしゃっくりを絞り込んで修正するには、多くのアプローチがあります。

  • 上記のソースファイルを開きます。上記のコード行を見てください。

    • 暴走文字列と置き忘れた演算子の場合、これは通常、犯人を見つける場所です。

    • 行を左から右に読み、各シンボルが何をするか想像してください。

  • より定期的に、の前の行も調べる必要があります。

    • 特に、欠落している;セミコロンは、前の行の終了/ステートメントにありません。 (少なくとも文体的な観点から。)

    • {コードブロック}が誤って閉じられたり、ネストされている場合は、ソースコードをさらに調査する必要があります。適切なコードインデントを使用して、それを簡素化します。

  • 構文の色分け!を見てください。

    • 文字列、変数、定数はすべて異なる色にする必要があります。

    • 演算子+-*/.も同様に区別する必要があります。そうでない場合は、間違ったコンテキストにある可能性があります。

    • 文字列の色付けが長すぎたり短すぎたりする場合は、エスケープされていないか、閉じている"または'文字列マーカーが見つかりません。

    • 同じ色の句読点文字が2つ並んでいると、問題が発生することもあります。通常、++--、または演算子に続く括弧でない場合、演算子は孤立しています。互いに直接続く2つの文字列/識別子は、ほとんどのコンテキストで正しくありません。

  • 空白はあなたの友達ですanyコーディングスタイルに従います。

  • 長い行を一時的に分割します。

    • 演算子または定数と文字列の間に自由に改行を追加できます。パーサーは、解析エラーの行番号を具体化します。非常に長いコードを調べる代わりに、欠落している構文シンボルや置き忘れた構文シンボルを分離できます。

    • 複雑なifステートメントを個別のまたはネストされたif条件に分割します。

    • 長い数式やロジックチェーンの代わりに、一時変数を使用してコードを簡素化します。 (読みやすい=エラーが少ない。)

    • 次の間に改行を追加します。

      1. 正しいものとして簡単に識別できるコード、
      2. よくわからない部分、
      3. そして、パーサーが文句を言う行。

      長いコードブロックのパーティション分割reallyは、構文エラーの原因の特定に役立ちます。

  • コメントアウト問題のあるコード。

    • 問題の原因を特定できない場合は、コードのブロックをコメントアウトします(したがって、一時的に削除します)。

    • 解析エラーを取り除くとすぐに、問題の原因が見つかりました。よく見てください。

    • 機能/メソッドブロック全体を一時的に削除したい場合があります。 (一致しない中括弧と誤ってインデントされたコードの場合。)

    • 構文の問題を解決できない場合は、rewriteコメントアウトされたセクションを最初からにしてください。

  • 初心者の方は、混乱を招く構文構造の一部を避けてください。

    • 三項の? :条件演算子はコードを圧縮でき、実際に役立ちます。しかし、すべての場合に読みやすさを支援するわけではありません。単純なifステートメントを優先します。

    • PHPの代替構文(if:/elseif:/endif;)はテンプレートでは一般的ですが、通常の{コード}ブロックよりも簡単にたどることは間違いありません。

  • 最も一般的な新人の間違いは次のとおりです。

    • ステートメント/行を終了するためのセミコロン;がありません。

    • "または'の文字列引用符の不一致、およびその中のエスケープされていない引用符。

    • 忘れられた演算子、特に文字列.の連結。

    • アンバランスな(括弧)。報告された行でそれらを数えます。それらの数は同じですか?

  • ある構文問題を解くことで次の問題を発見できることを忘れないでください。

    • 1つの問題を解消しても、以下のコードで他の問題が発生する場合は、ほとんど正しい道を進んでいます。

    • 編集後に新しい構文エラーが同じ行で発生する場合、変更しようとして失敗した可能性があります。 (常にではありません。)

  • 修正できない場合は、以前に動作していたコードのバックアップを復元します。

    • ソースコードのバージョン管理システムを採用します。壊れた最後の作業バージョンのdiffをいつでも表示できます。これは構文の問題が何であるかについて啓発的かもしれません。
  • 目に見えない浮遊Unicode文字:場合によっては、ソースで hexeditorを使用 または別のエディター/ビューアーが必要です。一部の問題は、コードを見ただけでは見つけることができません。

    • 非ASCII記号を見つける最初の手段として grep --color -P -n "\[\x80-\xFF\]" file.php を試してください。

    • 特に、BOM、幅がゼロのスペース、または改行しないスペース、およびスマートクォートは、ソースコードへの道を定期的に見つけることができます。

  • どのタイプの改行がファイルに保存されるかに注意してください。

    • PHPはただ光栄です \n 改行ではなく \r キャリッジリターン。

    • これは、MacOSユーザーにとっては時折問題になります(OS Xでエディターの構成が正しくない場合でも)。

    • 多くの場合、単一行の//または#コメントが使用されている場合にのみ問題として浮上します。複数行の/*...*/コメントは、改行が無視されるときにパーサーをめったに妨害しません。

  • 構文エラーがWeb経由で送信されない場合:マシンで構文エラーが発生していることがあります。ただし、まったく同じファイルをオンラインで投稿しても、それは表示されなくなります。これは、次の2つのうちの1つのみを意味します。

    • 間違ったファイルを見ています!

    • または、コードに目に見えない浮遊Unicodeが含まれていました(上記を参照)。簡単に見つけることができます:Webフォームからテキストエディターにコードをコピーするだけです。

  • PHPバージョンを確認してください。すべての構文構成がすべてのサーバーで利用できるわけではありません。

    • コマンドラインインタープリターの場合はphp -v

    • <?php phpinfo();は、Webサーバーを介して呼び出されます。


    これらは必ずしも同じではありません。特にフレームワークを使用する場合は、それらを一致させます。

  • PHPの予約キーワード を関数/メソッド、クラス、または定数の識別子として使用しないでください。

  • 試行錯誤が最後の手段です。

他のすべてが失敗した場合は、いつでもgoogleエラーメッセージを送信できます。構文記号の検索は簡単ではありません(スタックオーバーフロー自体は SymbolHound でインデックス化されます)。したがって、関連性のあるものを見つける前に、さらに数ページを調べる必要があります。

その他のガイド:

死の白い画面

Webサイトが空白の場合、通常は構文エラーが原因です。ディスプレイを有効にする:

  • error_reporting = E_ALL
  • display_errors = 1

php.ini 一般的に、または .htaccess を介してmod_php、または .user.ini でFastCGIセットアップを使用します。

PHPは最初の行を解釈/実行すらできないため、壊れたスクリプト内で有効にするのは遅すぎます。簡単な回避策は、ラッパースクリプトを作成することです(test.phpなど)。

<?php
   error_reporting(E_ALL);
   ini_set("display_errors", 1);
   include("./broken-script.php");

次に、このラッパースクリプトにアクセスして、失敗したコードを呼び出します。

また、PHPのerror_logを有効にし、スクリプトがHTTP 500応答でクラッシュしたときに webserverのerror.log を調べるのにも役立ちます。

273
mario

私はこのトピックは完全に議論され過ぎて/複雑過ぎると思います。 IDEを使用するのは、構文エラーを完全に回避するための方法です。 IDEを使わずに作業することは、非専門的な作業であるとも言えます。どうして?現代のIDEは、入力したすべての文字の後に構文をチェックするためです。コーディングして行全体が赤くなり、大きな警告通知が構文エラーの正確なタイプと正確な位置を示している場合は、別の解決策を探す必要はまったくありません。

構文チェックIDEを使用すると、次のようになります。

入力したとおりに正しく表示されるというだけの理由で、(事実上)構文エラーが発生することは決してありません。真剣に。

構文チェック付きの優れたIDE(すべてLinux、Windows、Mac用):

  1. NetBeans [無料]
  2. PHPStorm [$ 199 USD]
  3. Eclipse with PHPプラグイン [free]
  4. Sublime [$ 80 USD](主にテキストエディタですが、 PHP Syntax Parser のようにプラグインで拡張できます)
99
Sliq

予期しない[

最近、予期しない[配列ブラケットは、古いPHPバージョンでよく見られます。 短い配列構文 は、PHP> = 5.4以降で利用可能です。古いインストールではarray()のみがサポートされます。

$php53 = array(1, 2, 3);
$php54 = [1, 2, 3];
         ⇑

配列関数の結果の逆参照は、古いPHPバージョンでは同様に使用できません。

$result = get_whatever()["key"];
                      ⇑

参照-このエラーはPHPで何を意味しますか?-"構文エラー、予期しない\[" は、最も一般的で実用的な回避策を示しています。

ただし、PHPインストールをアップグレードするだけの方が良いでしょう。共有Webホスティングプランの場合、最初に調査します(例: SetHandler php56-fcgiを使用して、新しいランタイムを有効にすることができます。

こちらもご覧ください:

ところで、プリプロセッサと PHP 5.4シンタックスダウンコンバーター があります。古い+遅いPHPバージョンに本当に慣れている場合。

のその他の原因予期しない[構文エラー

それがPHPバージョンの不一致でない場合、それはしばしば単純なタイプミスまたは新しい構文の間違いです:

  • クラス内の配列プロパティ宣言/式 は使用できません。PHP7でも使用できません。

    protected $var["x"] = "Nope";
                  ⇑
    
  • [を開き中括弧{または括弧(と混同するのはよくある見落としです。

    foreach [$a as $b)
            ⇑
    

    あるいは:

    function foobar[$a, $b, $c] {
                   ⇑
    
  • または、配列として(PHP 5.6より前の)定数を逆参照しようとしています。

    $var = const[123];
           ⇑
    

    少なくともPHPはconstを定数名として解釈します。

    配列変数にアクセスする場合(ここでの一般的な原因)、先頭の$ sigilを追加して、$varnameになります。

  • 連想配列のメンバーでglobalキーワードを使用しようとしています。これは有効な構文ではありません:

    global $var['key'];
    


予期しない]closing角括弧

これはややまれですが、終端配列]ブラケットでの構文事故もあります。

  • ここでも、)括弧または}中括弧との不一致が一般的です。

    function foobar($a, $b, $c] {
                              ⇑
    
  • または、配列が存在しない場所で配列を終了しようとしています:

    $var = 2];
    

    これは、multi-lineおよびnested配列宣言でよく発生します。

    $array = [1,[2,3],4,[5,6[7,[8],[9,10]],11],12]],15];
                                                 ⇑
    

    その場合は、IDEを使用してブラケットの一致を検出し、早期の]配列クロージャーを見つけます。少なくとも、より多くのスペースと改行を使用して絞り込みます。

57
mario

予期しないT_VARIABLE

"予想外のT_VARIABLE"は、リテラルの$variable名があることを意味しますが、それは現在の式/ステートメントの構造には収まりません。

purposefully abstract/inexact operator+$variable diagram

  1. 行方不明のセミコロン

    最も一般的には セミコロンの欠落 が前の行にあります。文に続く変数の代入は、どこを見ればよいかを示す良い指標です。

           ⇓
    func1()
    $var = 1 + 2;     # parse error in line +2
    
  2. 文字列の連結

    よくある誤操作は 文字列の連結 忘れられた.演算子です。

                                   ⇓
    print "Here comes the value: "  $value;
    

    ところで、読みやすくするために、 文字列補間 (二重引用符で囲まれた基本変数)をお勧めします。これは、これらの構文の問題を回避します。

    文字列補間はスクリプト言語コア機能です。利用しても恥ずかしいことではありません。変数.の連結が速いであることに関するマイクロ最適化のアドバイスは無視してください。 違います。

  3. 式演算子がありません

    もちろん、算術演算など、他の式でも同じ問題が発生する可能性があります。

               ⇓
    print 4 + 7 $var;
    

    ここで変数を追加、減算、または比較する必要がある場合、PHPは推測できません。

  4. リスト

    パーサが期待されるカンマ,も示す配列母集団のように、構文リストでも同じです。

                                          ⇓
    $var = array("1" => $val, $val2, $val3 $val4);
    

    または関数パラメータリスト:

                                    ⇓
    function myfunc($param1, $param2 $param3, $param4)
    

    listまたはglobalステートメントで、またはforループ内に;セミコロンがない場合にも、これと同じことがわかります。

  5. クラス宣言

    このパーサエラーは クラス宣言内でも発生します 。式ではなく、静的定数のみを割り当てることができます。したがって、パーサーは割り当てられたデータとして変数について文句を言います:

    class xyz {      ⇓
        var $value = $_GET["input"];
    

    中括弧を閉じている}を比較しない場合、特にここに導くことができます。メソッドの終了が早すぎる場合(適切なインデントを使用してください)、外部変数は通常クラス宣言本体に誤って配置されます。

  6. 識別子の後の変数

    変数を識別子の後に続けることはできません 直接:

                 ⇓
    $this->myFunc$VAR();
    

    ところで、これは 変数変数 を使うことを意図した一般的な例です。この場合、たとえば$this->{"myFunc$VAR"}();を使用した可変プロパティ検索です。

    可変変数を使用することは例外であるべきであることに留意してください。配列がより単純でより適切である場合でも、初心者はあまりにも気軽にそれらを使用しようとすることがよくあります。

  7. 言語構成の後に欠けている括弧

    厄介なタイピングはifforforeachステートメントのための忘れられた左括弧を導くかもしれません:

           ⇓
    foreach $array as $key) {
    

    解決策:文と変数の間に欠けている開始(を追加してください。

  8. さもなければ条件を期待しません

         ⇓
    else ($var >= 0)
    

    解決策:elseから条件を削除するか、 elseif を使用してください。

  9. 閉鎖用ブラケットが必要

         ⇓
    function() uses $var {}
    

    解決策:$varの前後に角かっこを追加します。

  10. 目に見えない空白

    参照回答 "見えない野外のUnicode"( 改行なしのスペース など)で述べたように、このエラーは疑わないコードでも見られるかもしれません:

    <?php
                              ⇐
    $var = new PDO(...);
    

    ファイルの先頭やコピーアンドペーストされたコードではかなり普及しています。コードに構文上の問題が含まれているように見えない場合は、16進数エディタで確認してください。

また見なさい

42
mario

予期しないT_CONSTANT_ENCAPSED_STRING
予期しないT_ENCAPSED_AND_WHITESPACE

扱いにくい名前T_CONSTANT_ENCAPSED_STRINGおよびT_ENCAPSED_AND_WHITESPACEは、引用符付き"string"literalsを参照します。

それらは異なるコンテキストで使用されますが、構文の問題は非常に似ています。 T_ENCAPSED…警告は二重引用符付き文字列コンテキストで発生しますが、T_CONSTANT…文字列はしばしばPHP式またはステートメント。

  1. 誤った変数補間

    また、PHP変数の補間が正しくない場合に最も頻繁に発生します。

                              ⇓     ⇓
    echo "Here comes a $wrong['array'] access";
    

    PHPコンテキストでは、配列キーを引用する必要があります。しかし、二重引用符で囲まれた文字列(またはHEREDOC)では、これは間違いです。パーサーは、含まれる単一引用符で囲まれた'string'について文句を言います。これは、通常、そこにリテラルID /キーが必要だからです。

    より正確には、PHP2スタイル 二重引用符で囲まれた単純な構文 を配列参照に使用することが有効です。

    echo "This is only $valid[here] ...";
    

    ただし、ネストされた配列またはより深いオブジェクト参照には、 複雑なカーリー文字列式 構文が必要です。

    echo "Use {$array['as_usual']} with curly syntax.";
    

    よくわからない場合は、これを使用する方が一般的に安全です。多くの場合、さらに読みやすいと見なされます。そして、より優れたIDEは、実際には明確な構文の色付けを使用します。

  2. 連結の欠落

    文字列が式の後にあるが、連結または他の演算子がない場合、PHPが文字列リテラルについて文句を言うのがわかります。

                           ⇓
    print "Hello " . WORLD  " !";
    

    あなたと私には明らかですが、PHPは、文字列がそこに追加されることを意図していたguessできません。

  3. 紛らわしい文字列引用エンクロージャ

    複雑な文字列区切り文字 の場合、同じ構文エラーが発生します。単一の'または二重の"引用符で始まる文字列も同じで終わります。

                    ⇓
    print "<a href="' . $link . '">click here</a>";
          ⌞⎽⎽⎽⎽⎽⎽⎽⎽⌟⌞⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⌟⌞⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⌟
    

    その例は二重引用符で始まりました。しかし、二重引用符もHTML属性に向けられていました。ただし、内部の連結演算子は、単一引用符で囲まれた2番目の文字列の一部として解釈されるようになりました。

    Tip:単一引用符と二重引用符で囲まれた文字列にわずかに異なる色付けを使用するようにエディター/ IDEを設定します。 (また、テキスト出力には二重引用符で囲まれた文字列を、定数のような値には単一引用符で囲まれた文字列を好むようにアプリケーションロジックを支援します。)

    これは、最初に二重引用符から抜け出してはならない良い例です。代わりに、HTML属性の引用符に proper \" escapes を使用します。

    print "<a href=\"{$link}\">click here</a>";
    

    これは構文の混乱にもつながる可能性がありますが、すべての優れたIDE /エディターは、エスケープされた引用符の色を変えることで再び役立ちます。

  4. 引用符がありません

    同様に "/' quotesを開くのを忘れた パーサーエラーのレシピ:

                   ⇓
     make_url(login', 'open');
    

    ここでは、明らかにloginが文字列パラメータであることを意図していた場合、', 'はベアワードの後の文字列リテラルになります。

  5. 配列リスト

    配列作成ブロックで,コンマが欠落すると、パーサーは2つの連続した文字列を表示します。

    array(               ⇓
         "key" => "value"
         "next" => "....",
    );
    

    最後の行には常に余分なコンマが含まれることがありますが、その間の1つを見落とすことは許されないことに注意してください。構文を強調せずに発見することは困難です。

  6. 関数パラメーターリスト

    同じこと 関数呼び出しの場合

                             ⇓
    myfunc(123, "text", "and"  "more")
    
  7. 暴走ストリング

    一般的なバリエーションは、非常に単純に忘れられた文字列ターミネーターです。

                                    ⇓
    mysql_evil("SELECT * FROM stuffs);
    print "'ok'";
          ⇑
    

    ここで、PHPは、互いに直接続く2つの文字列リテラルについて文句を言います。しかし、本当の原因はもちろん、閉じられていない以前の文字列です。

こちらもご覧ください

32
mario

予期しないT_STRING

T_STRINGはちょっとした誤称です。引用符で囲まれた"string"を参照しません。生の識別子が検出されたことを意味します。これは、bare単語から残りのCONSTANTまたは関数名、忘れられた引用符で囲まれていない文字列、または任意のプレーンテキストにまで及びます。

  1. 引用符で囲まれていない文字列

    ただし、この構文エラーは、引用符で囲まれていない文字列値で最も一般的です。エスケープされていない"または'の引用は、無効な式を形成します。

                   ⇓                  ⇓
     echo "<a href="http://example.com">click here</a>";
    

    構文の強調表示は、そのような間違いを非常に明白にします。 \"の二重引用符または\'の単一引用符のエスケープには、 string Enclosure として使用されたものに応じて、バックスラッシュを使用することを忘れないでください。

    • 便宜上、二重引用符を含むプレーンHTMLを出力する場合は、外側の一重引用符を使用することをお勧めします。
    • 変数を補間する場合は二重引用符で囲まれた文字列を使用しますが、リテラルの"二重引用符のエスケープには注意してください。
    • より長い出力の場合は、複数のecho/print行をエスケープするのではなく、優先します。 HEREDOC セクションを検討してください。

    PHPでの単一引用符付き文字列と二重引用符付き文字列の違いは何ですか?も参照してください。

  2. 閉じられていない文字列

    "の終わりを忘れる の場合、通常は構文エラーが後で発生します。終了していない文字列は、次の目的の文字列値まで多くのコードを消費することがよくあります。

                                                           ⇓
    echo "Some text", $a_variable, "and some runaway string ;
    success("finished");
             ⇯
    

    パーサーが抗議するのは、リテラルのT_STRINGsだけではありません。別のよくあるバリエーションは、引用されていないリテラルHTMLの Unexpected '>' です。

  3. 非プログラミング文字列引用符

    コピーと貼り付けブログまたはWebサイトからのコードを使用すると、無効なコードで終わることがあります。 活版印刷の引用符はありません PHPが期待するもの:

    $text = ’Something something..’ + ”these ain't quotes”;
    

    活版印刷/スマート引用符はUnicode記号です。 PHPは、隣接する英数字テキストの一部としてそれらを扱います。たとえば、”theseは定数識別子として解釈されます。ただし、その後のテキストリテラルは、パーサーによってベアワード/ T_STRINGとして認識されます。

  4. 行方不明のセミコロン。再び

    前の行に終了していない式がある場合、次のステートメントまたは言語構造は生の識別子として認識されます。

           ⇓
    func1()
    function2();
    

    PHPは、2つの関数を次々に実行するつもりなのか、それらの結果を乗算、加算、比較するのか、1つの||のみを実行するのかを判断できません。

  5. PHPスクリプトの短いオープンタグと<?xmlヘッダー

    これはかなりまれです。ただし、short_open_tagsが有効になっている場合、PHPスクリプトを開始できません XML宣言を使用

          ⇓
    <?xml version="1.0"?>
    

    PHPは<?を認識し、それを自分で再利用します。迷いxmlの意味がわかりません。定数として解釈されます。ただし、versionは別のリテラル/定数と見なされます。そして、パーサーは、間に式演算子がなければ2つの後続のリテラル/値を理解できないため、パーサーは失敗します。

  6. 目に見えないユニコード文字

    構文エラーの最も恐ろしい原因は、 改行しないスペース などのUnicodeシンボルです。 PHPでは、Unicode文字を識別子名として使用できます。次のような完全に疑わしいコードについてT_STRINGパーサーの苦情を受け取った場合:

    <?php
        print 123;
    

    別のテキストエディターを作成する必要があります。または、hexeditorでさえ。ここではプレーンスペースと改行のように見えますが、目に見えない定数が含まれている場合があります。 JavaベースのIDEは、内部でマングルされたUTF-8 BOM、ゼロ幅のスペース、段落区切りなどを忘れることがあります。すべてを再編集し、空白を削除して、通常のスペースを追加し直してください。

    各行の先頭に冗長な;ステートメントセパレーターを追加することで絞り込むことができます:

    <?php
        ;print 123;
    

    ここでの余分な;セミコロンは、先行する不可視文字を未定義の定数参照(式としての式)に変換します。これにより、PHPが有用な通知を生成します。

  7. 変数名の前に「$」記号がありません

    PHPの変数 は、ドル記号と変数名で表されます。

    ドル記号($)は、識別子を変数の名前としてマークする sigil です。このシギルがなければ、識別子は 言語キーワード または 定数 になります。

    これは、PHPコードが 別の言語で記述されたコードから「翻訳」された (C、Java、JavaScriptなど)の場合の一般的なエラーです。そのような場合、変数型の宣言(元のコードが型付き変数を使用する言語で記述されている場合)もこっそりとこのエラーを生成する可能性があります。

  8. エスケープされた引用符

    文字列で\を使用する場合、特別な意味があります。これは「 エスケープ文字 」と呼ばれ、通常はパーサーに次の文字を文字どおりに取るように指示します。

    例:echo 'Jim said \'Hello\'';Jim said 'hello'を出力します

    文字列の閉じ引用符をエスケープすると、閉じ引用符は文字通りに解釈され、意図したとおりではありません。つまり、文字列を閉じずに、文字列の一部として印刷可能な引用符として解釈されます。これは、通常、次の文字列を開いた後、またはスクリプトの最後に解析エラーとして表示されます。

    Windowsでパスを指定するときの非常に一般的なエラー:"C:\xampp\htdocs\"が間違っています。 "C:\\xampp\\htdocs\\"が必要です。

24
mario

予期しない(

通常、開き括弧は、if/foreach/for/array/listなどの言語構造体に従うか、算術式を開始します。 "strings"、前の()、単独の$の後、およびいくつかの典型的な宣言コンテキストでは、構文が正しくありません。

  1. 関数宣言パラメーター

    このエラーのまれな発生は、 デフォルトの関数パラメーターとして式を使用しようとする です。これは、PHP7でもサポートされていません。

    function header_fallback($value, $expires = time() + 90000) {
    

    関数宣言のパラメーターは、リテラル値または定数式のみです。 whatever(1+something()*2)などを自由に使用できる関数呼び出しとは異なります。

  2. クラスプロパティのデフォルト

    クラスメンバーの宣言 でも同じです。式ではなく、リテラル/定数値のみが許可されます。

    class xyz {                   ⇓
        var $default = get_config("xyz_default");
    

    そのようなものをコンストラクタに入れてください。 なぜPHP属性は機能を許可しないのですか?

    ここでも、PHP 7ではvar $xy = 1 + 2 +3;定数式のみが許可されていることに注意してください。

  3. PHPのJavaScript構文

    JavaScriptまたは jQuery構文 を使用すると、明らかな理由でPHPで機能しません。

    <?php      ⇓
        print $(document).text();
    

    これが発生する場合、通常、終了していない先行文字列を示します。 PHPコードコンテキストに漏れるリテラル<script>セクション。

  4. isset(())、空、キー、次、現在

    isset()empty()は両方とも言語のビルトインであり、関数ではありません。 変数に直接アクセスする必要がある 。誤って括弧のペアを追加しすぎた場合は、式を作成します:

              ⇓
    if (isset(($_GET["id"]))) {
    

    同じことは、暗黙的な変数名アクセスを必要とする言語構成体にも当てはまります。これらのビルトインは言語文法の一部であるため、装飾的な余分な括弧を許可しません。

    変数参照を必要とするが、式の結果は渡されるユーザーレベルの関数は、代わりにランタイムエラーを引き起こします。


予期しない)

  1. 機能パラメータなし

    迷うことはできません コンマは関数呼び出しの最後 。 PHPはそこに値を期待しているため、早期終了)括弧について文句を言います。

                  ⇓
    callfunc(1, 2, );
    

    末尾のコンマは、array()またはlist()構造でのみ許可されます。

  2. 未完成の表現

    算術式で何かを忘れると、パーサーはあきらめます。なぜそれをどのように解釈する必要があるのか

                   ⇓
    $var = 2 * (1 + );
    

    )の終了を忘れてしまった場合は、代わりに予期しないセミコロンについて苦情を受け取ることになります。

  3. Foreach as constant

    制御ステートメントの忘れられた変数$プレフィックス の場合:

                       ↓    ⇓
    foreach ($array as wrong) {
    

    ここのPHPは、代わりに::を期待していることを示す場合があります。 class :: $ variableは予想される$ variable式を満たしている可能性があるためです。


予期しない{

中括弧{および}は、コードブロックを囲みます。そして、それらに関する構文エラーは、通常、ネストの誤りを示しています。

  1. ifの一致しない部分式

    最も一般的には、 アンバランス() が原因で、パーサーが開始中の{が早すぎると文句を言っています。簡単な例:

                                  ⇓
    if (($x == $y) && (2 == true) {
    

    括弧を数えるか、IDEを使用してください。また、スペースなしでコードを記述しないでください。読みやすさが重要です。

  2. 式コンテキスト内の{および}

    式に中括弧を使用することはできません。括弧とカーリーを混同すると、言語文法に準拠しなくなります。

               ⇓
    $var = 5 * {7 + $x};
    

    ローカルスコープ変数${references}など、識別子の構築にはいくつかの例外があります。

  3. 変数変数またはカーリーvar式

    これは非常にまれです。ただし、複雑な変数式に対して{および}パーサーの苦情を受け取ることもあります。

                          ⇓
    print "Hello {$world[2{]} !";
    

    ただし、このようなコンテキストでは、予期しない}の可能性が高くなります。


予期しない}

「予期しない}」エラーが発生した場合、ほとんどの場合、コードブロックを早めに閉じています。

  1. コードブロックの最後のステートメント

    これは、終了していない式で発生する可能性があります。

    関数/コードブロックの最後の行に末尾の;セミコロンがない場合:

    function whatever() {
        doStuff()
    }            ⇧
    

    ここで、パーサーは、+ 25;を関数の結果などに追加する必要があるかどうかを判断できません。

  2. 無効なブロックのネスト/忘れられた{

    コードブロックが}で閉じられた時期が早すぎる場合、または{の開始を忘れた場合でも、このパーサーエラーが表示されることがあります。

    function doStuff() {
        if (true)    ⇦
            print "yes";
        }
    }   ⇧
    

    上記のスニペットでは、ifには開始{中括弧がありませんでした。したがって、下の}の終了は冗長になりました。したがって、次の終了}は、関数用でしたが、元の開始{波括弧に関連付けられませんでした。

    このようなエラーは、適切なコードのインデントなしでは見つけるのがさらに困難です。 IDEとブラケットの一致を使用します。


予期しない{、予期する(

条件/宣言ヘッダーおよびコードブロックを必要とする言語構成体は、このエラーをトリガーします。

  1. パラメータリスト

    たとえば、 パラメータリストのない誤って宣言された関数 は許可されません。

                     ⇓
    function whatever {
    }
    
  2. 制御ステートメントの条件

    そして、同様に if条件なし を持つことはできません。

      ⇓
    if {
    }
    

    当然、これは意味をなしません。通常の容疑者と同じこと、for/foreachwhile/doなど.

    この特定のエラーが発生した場合は、いくつかの手動の例を確認する必要があります。

16
mario

予期しない$ end

PHPが "予想外の$end"について話すとき、それはあなたのコードが早まって終了したことを意味します。 (メッセージは文字通りに取られるとき少し紛らわしいです。それは時々初心者によって仮定されるように「$ end」と名付けられた変数についてではありません。それは「ファイルの終わり」を示します、 EOF。)

原因:コードブロックの{}のバランスが取れていません。

先行するコードブロックを閉じるための}の中括弧の欠如については、ほとんどの場合です

  • 繰り返しますが、このような問題を回避するために適切なインデントを使用してください。

  • }がどこに間違っているかを調べるには、IDEを大括弧で突き合わせて使用​​します。ほとんどのIDEとテキストエディタにはキーボードショートカットがあります。

    • NetBeans、PhpStorm、Komodo: Ctrl[ そして Ctrl]
    • Eclipse、Aptana: CtrlShiftP
    • 崇高なアトム: Ctrlm - Zendスタジオ CtrlM
    • Geany、Notepad ++: CtrlB - ジョー: CtrlG - Emacs: C-M-n - Vim: %

ほとんどのIDEはまた、中括弧、大括弧、および括弧の一致を強調表示します。これにより、それらの相関関係を調べるのがかなり簡単になります。

Bracket matching in an IDE

終了していない式

また、Unexpected $end構文/パーサーエラーは、終端されていない式やステートメントに対しても発生する可能性があります。

  • $var = func(1,?>EOF

それで、最初にスクリプトの終わりを見てください。末尾の;は、どのPHPスクリプトの最後の文でも冗長です。しかし、あなたは持っているべきです。その理由は、構文上の問題を絞り込むためです。

インデントHEREDOCマーカー

別の一般的な出現は、 HEREDOCまたはNOWDOC 文字列で表示されます。先頭のスペース、タブなどでは、終了マーカーは無視されます。

print <<< END
    Content...
    Content....
  END;
# ↑ terminator isn't exactly at the line start

そのため、パーサーはHEREDOC文字列をファイルの終わりまで続けます(したがって "Unexpected $ end")。ほとんどすべてのIDEおよび構文強調エディタは、これを明白にするか、またはそれについて警告します。

エスケープ引用符

文字列で\を使用する場合、それは特別な意味を持ちます。これは「 エスケープ文字 」と呼ばれ、通常は文字通り次の文字を受け取るようにパーサーに指示します。

例:echo 'Jim said \'Hello\'';Jim said 'hello'を印刷します

文字列の終わりの引用符をエスケープすると、終わりの引用符は意図したとおりにではなく文字列の一部としての印刷可能な引用符として解釈され、文字列を閉じません。これは、次の文字列を開いた後、またはスクリプトの最後に、一般に解析エラーとして表示されます。

Windowsでパスを指定するときの非常に一般的なエラー:"C:\xampp\htdocs\"は間違っています。 "C:\\xampp\\htdocs\\"が必要です。

代替構文

テンプレート内のステートメント/コードブロックに代替構文を使用した場合、この構文エラーが発生することはほとんどありません。例えばif:else:を使用し、不足しているendif;を使用します。

また見なさい:

14
mario

予期しないT_IF 
予期しないT_FOREACH 
予期しないT_FOR 
予期しないT_WHILE 
予期しないT_DO 
予期しないT_ECHO

ifname__、foreachname__、forname__、whilename__、listname__、globalname__、returnname__、doname__、printname__、echoname__などがあります。彼らは通常一人で並んでいる。

  1. セミコロン;どこにいるの? 

    パーサーが制御ステートメントについて文句を言うならば、かなり普遍的に セミコロンを逃しました 前の行で:

                 ⇓
    $x = myfunc()
    if (true) {
    

    解決策:前の行を見てください。セミコロンを追加します。

  2. クラス宣言 

    これが起こる別の場所は クラス宣言 です。クラスセクションでは、プロパティの初期化とメソッドセクションのみを一覧表示できます。そこにコードを置くことはできません。

    class xyz {
        if (true) {}
        foreach ($var) {}
    

    そのような構文エラーは一般的に間違ってネストされた{}を具体化します。特に、機能コードブロックが早すぎる時期にクローズされた場合。

  3. 式の文中の文 

    ほとんどの言語構成要素は ステートメントとしてのみ使用できます 。それらは他の表現の中に置かれることを意図していません:

                       ⇓
    $var = array(1, 2, foreach($else as $_), 5, 6);
    

    同様に、文字列、数式、その他の場所でifname__を使用することはできません。

                   ⇓
    print "Oh, " . if (true) { "you!" } . " won't work";
    // Use a ternary condition here instead, when versed enough.
    

    ifname __-like条件を具体的に式に埋め込むには、 ?:三項評価 を使用することがよくあります。

    同じことがforname__、whilename__、globalname__、echoname__およびそれより少ない拡張listname__にも当てはまります。

              ⇓
    echo 123, echo 567, "huh?";
    

    一方、print()は式の文脈で使用できる言語組み込みです。 (しかし、ほとんど意味がありません。)

  4. 識別子として予約されているキーワード 

    また、ユーザー定義関数またはクラス名にdoname__またはifname__などの言語構成要素を使用することはできません。 (おそらくPHP 7では。でもそれでもお勧めできません。)

11
mario

予期しないT_IS_EQUAL
予期しないT_IS_GREATER_OR_EQUAL
予期しないT_IS_IDENTICAL
予期しないT_IS_NOT_EQUAL
予期しないT_IS_NOT_IDENTICAL
予期しないT_IS_SMALLER_OR_EQUAL
予期しない<
予期しない>

==>====!=<>!==、および<=、または<および>などの比較演算子は、ほとんどの場合、if式などの式でのみ使用する必要があります。パーサーがそれらについて文句を言う場合、それはしばしば間違ったペアリングまたはそれらの周りの() parensの不一致を意味します。

  1. Parensのグループ化

    特に、複数の比較を含むifステートメントの場合は、 開き括弧と閉じ括弧 を正しくカウントするように注意する必要があります。

                            ⇓
    if (($foo < 7) && $bar) > 5 || $baz < 9) { ... }
                          ↑
    

    ここでif条件は)によって既に終了しています

    比較が十分に複雑になると、多くの場合、複数のネストされたif構成に分割するのに役立ちます。

  2. isset()を比較してマッシュ

    一般的な新参者は、pitfalが isset() または empty() と比較しようとしていることです:

                            ⇓
    if (empty($_POST["var"] == 1)) {
    

    あるいは:

                        ⇓
    if (isset($variable !== "value")) {
    

    issetemptyは変数名のみを受け入れる言語構成体であるため、これはPHPには意味がありません。出力はブール値のみであるため、結果を比較することも意味がありません。

  3. >=より大きいか等しい=>配列演算子と混同する

    どちらの演算子も多少似ているため、時々混乱することがあります。

             ⇓
    if ($var => 5) { ... }
    

    この比較演算子は「greater than」または「equal」それを正しくします。

    参照: PHPのIfステートメント構造

  4. 比較するものはありません

    同じ変数名に関する2つの比較を組み合わせることもできません。

                     ⇓
    if ($xyz > 5 and < 100)
    

    PHPは、初期変数を再度比較するつもりであると推測することはできません。通常、式は 演算子の優先順位 に従ってペアにされるため、<が表示されるまでには、元の変数からブール値の結果のみが残ります。

    参照: 予期しないT_IS_SMALLER_OR_EQUAL

  5. 比較チェーン

    演算子の行がある変数と比較することはできません。

                      ⇓
     $reult = (5 < $x < 10);
    

    これは、それぞれ$xに対する2つの比較に分割する必要があります。

    これは実際には、ブラックリストに登録された式の場合です(同等の演算子の結合性のため)。いくつかのCスタイル言語では構文的には有効ですが、PHPは期待される比較チェーンとしても解釈しません。

  6. 予期しない>
    予期しない<

    >より大きい演算子または<より小さい演算子には、カスタムT_XXXトークナイザー名がありません。そして、それらは他のすべてのものと同様に誤って配置される可能性がありますが、誤った引用符で囲まれた文字列とマッシュされたHTMLについて、パーサーが文句を言うことがよくあります。

                            ⇓
    print "<a href='z">Hello</a>";
                     ↑
    

    これは、文字列"<a href='z">とリテラル定数Helloと比較され、さらに別の<比較と比較されます。または、少なくともPHPの見方です。実際の原因と構文の間違いは、文字列の途中での"の終了です。

    PHP開始タグをネストすることもできません。

    <?php echo <?php my_func(); ?>
               ↑
    

こちらもご覧ください:

10
mario

予期しない「?」

PHP 7より前のバージョンのPHPでnull合体演算子??を使用しようとしている場合、このエラーが発生します。

<?= $a ?? 2; // works in PHP 7+
<?= (!empty($a)) ? $a : 2; // All versions of PHP

予期しない '?'、変数が必要です

次のように、null許容型についても同様のエラーが発生する可能性があります。

function add(?int $sum): ?int {

これは、古くなったPHPバージョンが使用されていることを示しています(CLIバージョンのphp -vまたはWebサーバーのバインド済みのphpinfo();)。

6
John Conde

予期しないT_LNUMBER

トークンT_LNUMBERは "long" /番号を表します。

  1. 無効な変数名

    PHPや他のほとんどのプログラミング言語では、 変数 は数字で始めることはできません。最初の文字は英字または下線でなければなりません。

    $1   // Bad
    $_1  // Good
    

    *

    • やってくる _ PHPコンテキストでpreg_replace-プレースホルダ"$1"を使うために:

      #                         ↓            ⇓  ↓
      preg_replace("/#(\w+)/e",  strtopupper($1) )
      

      コールバックが引用されるべきだったところ。 (今では/e regexフラグは推奨されなくなりました。しかしpreg_replace_callback関数ではまだ誤用されていることがあります。)

    • 同じ識別子制約が オブジェクトプロパティ 、btwにも適用されます。

             ↓
      $json->0->value
      
    • トークナイザ/パーサは変数名としてリテラル$1を許可しませんが、1つのcould${1}または${"1"}を使用します。これは、標準以外の識別子に対する構文上の回避策です。 (これをローカルスコープの検索と考えるのが最善です。ただし、一般的には、このような場合には単純な配列をお勧めします。)

    • 非常にお勧めですが、PHPのパーサーはUnicode識別子を許可します。 $➊が有効になるように。 (リテラル1とは異なります)。

  2. 浮遊配列エントリー

    配列宣言 - に,コンマが欠けていると、予期しない長さも発生する可能性があります。

    #            ↓ ↓
    $xy = array(1 2 3);
    

    あるいは、同様に関数呼び出しと宣言、そして他の構成要素:

    • func(1, 2 3);
    • function xy($z 2);
    • for ($i=2 3<$z)

    したがって、通常はリストや式を区切るための;または,のいずれかが欠けています。

  3. 誤って引用されたHTML

    繰り返しになりますが、 引用符で囲まれていない文字列 は、頻繁に発生する迷子数の原因です。

    #                 ↓ ↓          
    echo "<td colspan="3">something bad</td>";
    

    そのような場合は、 予期しないT_STRING エラーのように多かれ少なかれ扱われるべきです。

  4. その他の識別子

    関数、クラス、または 名前空間 のいずれも、数字で始まる名前を付けることはできません。

             ↓
    function 123shop() {
    

    変数名とほとんど同じです。

5
John Conde

予期しない '='

これは、変数名に無効な文字が含まれていることが原因である可能性があります。変数名 必ず /これらの規則に従う必要があります。

変数名はPHPの他のラベルと同じ規則に従います。有効な変数名は文字またはアンダースコアで始まり、その後に任意の数の文字、数字、またはアンダースコアが続きます。正規表現として、それは次のように表現されるでしょう。

2
John Conde

予期しない '続行'(T_CONTINUE)

continueは(forやifのような)文であり、独立していなければなりません。式の一部として使用することはできません。 continueは値を返さないが、式の中ではすべての部分式が何らかの値を返さなければならないため、式全体で値が返されるため、それが文と式の違いです。

つまり、continueは三項ステートメントや戻り値を必要とするステートメントでは使用できません。

予期しない 'break'(T_BREAK)

もちろんbreak;も同じです。式の文脈では使えませんが、厳密なステートメント(foreachifブロックと同じレベル)です。

予期しない 'return'(T_RETURN)

これはreturnにとってはもっと驚くべきことかもしれませんが、それは単なるブロックレベルの ステートメント でもあります。より高いスコープ/関数に値(またはNULL)を返しますが、式自体としては評価されません。 →つまり、return(return(false);;を実行しても意味がありません 

1
John Conde

予期しない「終わり」(T_ENDWHILE)

構文はコロンを使用しています - コロンがない場合は上記のエラーが発生します

<?php while($query->fetch()): ?>
 .... 
<?php endwhile; ?>

この構文の代わりに中括弧を使用することもできます。

<?php while($query->fetch()) { ?>
  ....
<?php } ?>

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

0
mplungjan

Parse error: syntax error, unexpected ':'で始まるエラーメッセージは、クラスの静的参照Class::$VariableClass:$Variableとして誤って記述したことが原因である可能性があります。

0
David Spector