PHP 解析/語法錯誤;以及如何解決它們
P粉633075725
2023-08-23 16:16:57
<p>每個人都會遇到文法錯誤。即使是經驗豐富的程式設計師也會犯錯。對新人來說,這只是學習過程的一部分。但是,通常很容易解釋錯誤訊息,例如:</p>
<blockquote>
<p>PHP 解析錯誤:語法錯誤,index.php 第 20 行出現意外的「{」</p>
</blockquote>
<p>意外的符號並不總是真正的罪魁禍首。但行號給出了從哪裡開始查找的粗略資訊。 </p>
<blockquote>
<p>總是查看<strong>程式碼上下文</strong>。語法錯誤通常隱藏在<strong>前面的程式碼行</strong>中提到的<em>或</em>中。將您的程式碼與手冊中的語法範例進行比較。 </p>
</blockquote>
<p>雖然並非所有情況都互相匹配。然而,有一些<strong>解決語法錯誤</strong>的通用步驟。這本參考文獻總結了常見的陷阱:</p>
<ul>
<li><p>意外的 T_STRING</p>
</li>
<li><p>意外的 T_VARIABLE </p><p> 意外的「$varname」(T_VARIABLE)</p>
</li>
<li><p>意外的 T_CONSTANT_ENCAPSED_STRING </p><p>意外的 T_ENCAPSED_AND_WHITESPACE</p>
</li>
<li><p>意外的 $end</p>
</li>
<li><p>意外的 T_FUNCTION...</p>
</li>
<li><p>意外的<code>{</code></p><p>意外的<code>}</code></p>意外的<code>}</code></p><p>意外的<code>(</code></p><p>意外的<code>)</code></p>
</li>
<li><p>意外的<code>[</code></p><p>意外的<code>]</code></p>意外的<code>]</code></p>
</li>
<li><p>意外的T_IF </p><p> 意外的T_FOREACH </p><p> 意外的T_FOR </p><p> 意外的T_WHILE </lt;/p><p> 意外的T_WHILE </lt; p><p> 意外的T_DO </p><p> 意外的T_PRINT </p><p> 意外的T_ECHO</p>
</li>
<li><p>意外的 T_LNUMBER</p>
</li>
<li><p>意外?</p>
</li>
<li><p>意外繼續 (T_CONTINUE)</p><p>意外繼續 (T_BREAK)</p><p>意外繼續 (T_RETURN)</p>
</li>
<li><p>意外的「=」</p>
</li>
<li><p>意外的 T_INLINE_HTML…</p>
</li>
<li><p>意外的T_THIS_IS_THE_THING...</p>
</li>
<li><p>意外的 T_OBJECT_OPERATOR...</p>
</li>
<li><p>意外的 T_DOUBLE_ARROW...</p>
</li>
<li><p>意外的 T_SL...</p>
</li>
<li><p>意外的 T_BOOLEAN_OR…
</p><p>
意外的T_BOOLEAN_AND…</p>
</li>
<li><p>意外的 T_IS_EQUAL </p><p>
意外 T_IS_GREATER_OR_EQUAL </p><p>
意外的 T_IS_IDENTICAL </p><p>
意外的 T_IS_NOT_EQUAL </p><p>
意外的 T_IS_NOT_IDENTICAL </p><p>
意外 T_IS_SMALLER_OR_EQUAL </p><p>
意外的 <code><</code> </p><p>
意外的 <code>></code></p>
</li>
<li><p>意外的 T_NS_SEPARATOR...</p>
</li>
<li><p>輸入中存在意外字元:「<code></code>」(ASCII=92) state=1</p>
</li>
<li><p>意外的「公共」(T_PUBLIC) </p><p>意外的「私人」(T_PRIVATE) </p><p>意外的「受保護」(T_PROTECTEDTEDTEDTEDTEDTEDTEDTEDTED」 ) </p><p>意外的「最終'(T_FINAL)...</p>
</li>
<li><p>意外的 T_STATIC...</p>
</li>
<li><p>意外的 T_CLASS…</p>
</li>
<li><p>意外「使用」(T_USE)</p>
</li>
<li><p>意外的 T_DNUMBER</p>
</li>
<li><p>意外的 <code>,</code> <em>(逗號)</em></p>
</li>
<li><p>意外<code>。</code> <em>(句點)</em></p>
</li>
<li><p>意外的 <code>;</code> <em>(分號)</em></p>
</li>
<li><p>意外的<code>*</code><em>(星號)</em></p>
</li>
<li><p>意外的<code>:</code><em>(冒號)</em></p>
</li>
<li><p>意外的「:」、預期的「,」或「)」</p>
</li>
<li><p>意外的<code>&</code>(調用時按引用傳遞)</p>
</li>
<li><p>意外的<code>。 </code></p>
</li>
</ul>
<p>密切相關的參考文獻:</p>
<ul>
<li>這個錯誤在 PHP 中代表什麼? (運行時錯誤)
<ul>
<li>解析錯誤:語法錯誤,意外 T_XXX</li>
<li>解析錯誤:語法錯誤,意外 T_ENCAPSED_AND_WHITESPACE</li>
<li>解析錯誤:語法錯誤,意外的 T_VARIABLE</li>
</ul>
</li>
<li>這個符號在 PHP 中代表什麼? (語言標記)</li>
<li>那些<code>“”</code>智能<code>''</code>引號對PHP來說毫無意義</li>
</ul>
<p>還有:</p>
<ul>
<li>php.net 上的 PHP 手冊及其各種語言標記</li>
<li>或維基百科關於 PHP 的語法介紹。 </li>
<li>最後當然是我們的 <strong>php</strong> 標籤維基。 </li>
</ul>
<p>雖然 Stack Overflow 也歡迎新手程式設計師,但它主要針對專業程式設計問題。 </p>
<ul>
<li>回答每個人的編碼錯誤和狹隘的拼字錯誤大多被認為是偏離主題的。 </li>
<li>因此,在發布語法修復請求之前,請花一些時間遵循基本步驟。 </li>
<li>如果您仍然需要這樣做,請展示您自己的解決方案、嘗試的修復以及您對看似錯誤或可能錯誤的思考過程。</li>
</ul>
<p>如果您的<em>瀏覽器</em>顯示錯誤訊息,例如“SyntaxError:非法字元”,那麼它實際上不是與 php 相關,而是一個 javascript 語法錯誤。 </p>
<hr />
<p><strong>供應商程式碼引發的語法錯誤:</strong>最後,請考慮,如果語法錯誤不是透過編輯程式碼庫引發的,而是在外部供應商軟體包安裝或升級後引發的,則可能是由於PHP 版本造成的不相容,因此請根據您的平台設定檢查供應商的要求。 </p>
我認為這個主題完全討論過度/過於複雜。使用 IDE 是完全避免任何語法錯誤的方法。我甚至會說,在沒有 IDE 的情況下工作是一種不專業的行為。為什麼?因為現代 IDE 在您鍵入每個字元後都會檢查您的語法。當您編碼並且整行變成紅色,並且一個大警告通知顯示語法錯誤的確切類型和確切位置時,那麼絕對不需要搜尋其他解決方案。
使用語法檢查 IDE 意味著:
您將(有效地)再也不會遇到語法錯誤,因為您在鍵入時就可以正確地看到它們。說真的。
具有語法檢查功能的優秀 IDE(所有這些都適用於 Linux、Windows 和 Mac):
什麼是語法錯誤?
PHP 屬於 C 風格 和 命令式程式語言。它具有嚴格的語法規則,當遇到放錯位置的符號或識別碼時無法恢復。它無法猜測您的編碼意圖。
最重要的提示
您可以隨時採取一些基本的預防措施:
使用正確的程式碼縮排,或採用任何進階的程式碼樣式。 可讀性可防止違規行為。
使用IDE或編輯器對於 PHP,具有語法突出顯示。 這也有助於括號/括號平衡。
#閱讀手冊中的語言參考和範例。 兩次,就熟練了。
如何解釋解析器錯誤
典型的語法錯誤訊息如下:
其中列出了可能語法錯誤的位置。請參閱提到的檔名和行號。
諸如
T_STRING
之類的名字解釋了解析器/標記器無法解析的符號最後處理。然而,這不一定是語法錯誤的原因。查看以前的程式碼行也很重要。通常,語法錯誤只是之前發生的意外。錯誤行號正是解析器最終放棄處理所有內容的位置。
解決語法錯誤
有很多方法可以縮小範圍並修復語法問題。
開啟提到的來源檔案。查看提到的程式碼行。
對於失控的字串和錯位的運算符,這通常是您找到罪魁禍首的地方。
從左到右閱讀該行並想像每個符號的作用。
您還需要更頻繁地查看前面的行。
特別是,上一行結尾/語句處缺少
;
分號。 (至少從風格的角度來看。)#如果
{
程式碼區塊}
未正確關閉或嵌套,您可能需要進一步調查原始程式碼。使用適當的程式碼縮排簡化。看看語法著色!
字串、變數和常數都應該有不同的顏色。
運算子
-*/.
也應該著色不同。否則他們可能處於錯誤的環境。如果您發現字串著色延伸得太遠或太短,則表示您發現了未轉義或遺失的結束
"
或'
字串標記。兩個相鄰的相同顏色的標點符號也可能意味著麻煩。通常,如果運算子後面不是
、
--
或括號,則運算子是單獨的。在大多數情況下,兩個直接相連的字串/識別碼是不正確的。空白是你的朋友。 遵循任何編碼風格。
暫時打破長隊。
您可以在運算子或常數和字串之間自由新增換行符號。然後解析器將具體化解析錯誤的行號。您可以隔離遺失或放錯位置的語法符號,而不是查看非常冗長的程式碼。
將複雜的
if
語句拆分為不同的或嵌套的if
條件。不要使用冗長的數學公式或邏輯鏈,而是使用臨時變數來簡化程式碼。 (更具可讀性=更少的錯誤。)
在以下位置之間新增換行符號:
對長程式碼區塊進行分區確實有助於定位語法錯誤的根源。
註解掉違規程式碼。
如果無法隔離問題根源,請開始註解掉(從而暫時刪除)程式碼區塊。
一旦解決了解析錯誤,您就找到了問題根源。仔細看看那裡。
有時您想要暫時刪除完整的函數/方法區塊。 (如果出現不匹配的大括號和錯誤縮排的程式碼。)
#當您無法解決語法問題時,請嘗試從頭開始重寫註解掉的部分。
作為新手,請避免一些令人困惑的語法結構。
三元
? :
條件運算子可以壓縮程式碼並且確實很有用。但它並不能在所有情況下提高可讀性。在不熟悉的情況下喜歡簡單的if
語句。PHP 的替代語法(
if:
/elseif:
/endif;
) 對於模板來說很常見,但可以說不太容易遵循正常的{
程式碼}
區塊。新手最常見的錯誤是:
缺少用於終止語句/行的分號
;
。"
或'
的字串引號不匹配,且其中未轉義引號。被遺忘的運算符,特別是字串
.
連接。不平衡
(
括號)
。在報告的行中對它們進行計數。它們的數量相等嗎?不要忘記解決一個語法問題可以發現下一個語法問題。
如果您解決了一個問題,但下面的某些程式碼中出現了其他問題,那麼您基本上就走在正確的道路上了。
如果編輯後同一行出現新的語法錯誤,那麼您嘗試的變更可能會失敗。 (但並非總是如此。)
如果無法修復,請恢復先前工作程式碼的備份。
差異
。這可能有助於了解語法問題是什麼。看不見的雜散Unicode 字元:在某些情況下,您需要在原始程式碼上使用十六進位編輯器或其他編輯器/查看器。有些問題僅僅透過查看程式碼是無法發現的。
嘗試
grep --color -P -n "\[\x80-\xFF\]" file.php
作為尋找非ASCII 符號的第一個措施。特別是 BOM、零寬度空格或不間斷空格以及智慧引號通常會出現在原始碼中。
注意檔案中儲存的換行符號類型。
PHP 僅支援 \n 換行符,而不支援 \r 回車符。
對於 MacOS 使用者來說,這有時會是一個問題(即使是在 OS X 上,編輯器設定錯誤也是如此)。
通常只有在使用單行
//
或# 註解時才會出現問題。當忽略換行符號時,多行
/*...*/
註解很少會幹擾解析器。如果您的語法錯誤未透過網路傳輸: 您的機器上碰巧有語法錯誤。但在線發布相同的文件不再顯示它。這只能意味著以下兩件事之一:
您正在查看錯誤的檔案!
或您的程式碼包含不可見的雜散 Unicode(請參閱上文)。 您可以輕鬆發現:只需將程式碼從網頁表單複製回文字編輯器即可。
檢查您的PHP 版本。並非所有語法結構在每個伺服器上都可用。
php -v
用於命令列解釋器用於透過網頁伺服器呼叫。
這些不一定相同。特別是在使用框架時,您需要將它們匹配起來。
不要使用PHP 的保留關鍵字作為函數/方法、類別的識別碼或常數。
反覆試驗是最後的手段。
如果所有其他方法都失敗,您可以隨時google您的錯誤訊息。語法符號不太容易搜尋(儘管 Stack Overflow 本身是透過 SymbolHound 進行索引的)。因此,您可能需要再瀏覽幾頁才能找到相關內容。
更多指南:
白屏死機
如果您的網站只是空白,那麼通常是語法錯誤造成的。 啟用其顯示:
error_reporting = E_ALL
display_errors = 1
在您的
php.ini
一般來說,或透過 mod_php 的.htaccess
, 甚至.user.ini
使用 FastCGI 設定。在損壞的腳本中啟用它為時已晚,因為 PHP 甚至無法解釋/運行第一行。一個快速的解決方法是製作一個包裝腳本,例如
test.php
:然後透過存取此包裝器腳本來呼叫失敗的程式碼。
它還有助於啟用 PHP 的
error_log
並查看您的網頁伺服器的error.log
當腳本因 HTTP 500 回應而崩潰時。