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><p>意外的 <code>(</code></p><p>意外的<code>)</code></p>
</li>
<li><p>意外的<code>[</code></p><p>意外的<code>]</code></p>
</li>
<li><p>意外的 T_IF </p><p> 意外的 T_FOREACH </p><p> 意外的 T_FOR </p><p> 意外的 T_WHILE </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_PROTECTED) </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 响应而崩溃时。