每个人都会遇到语法错误。 即使是经验丰富的程序员也会出现错别字。 对于新人来说,这只是学习过程的一部分。 但是,通常很容易解释错误消息,例如:
PHP分析错误:语法错误,index.PHP中第20行出现意外的“{”
意外的符号并不总是真正的罪魁祸首。 但是行号给出了从哪里开始查找的粗略概念。
始终查看代码上下文。 语法错误通常隐藏在前面提到的代码行中或前面的代码行中。 将您的代码与手册中的语法示例进行比较。
但并不是每个案子都是一样的。 然而,有一些解决语法错误的一般步骤。 本文概述了常见的陷阱:
>
意外的T_STRING
意外的T_VARIABLE
意外的“$VARNAME”(T_VARIABLE)
意外的T_CONSTANT_ENCAPSED_STRING
意外的T_ENCAPSED_AND_WHITESPACE
意外的$END
意外的t_函数…
意外的{
意外的}
意外的(
意外的)
意外的[
意外的]
意外的T_IF
意外的T_FOREACH
意外的T_FOR
意外的T_WHILE
意外的T_DO
意外的T_PRINT
意外的T_ECHO
意外的T_LNUMBER
出乎意料?
意外的继续(T_CONTINUE)
意外的继续(T_BREAK)
意外的继续(T_RETURN)
意外的“=”
意外的T_INLINE_HTML…
意外T_PAAMAYIM_NEKUDOTAYIM…
意外的t_object_运算符…
意外的t_double_箭头…
意外的T_SL…
意外的T_Boolean_或…
意外的T_Boolean_和…
意外的T_IS_EQUAL
意外的T_IS_GREATER_OR_EQUAL
意外的T_IS_NOT_EQUAL
意外的T_IS_NOT_EQUAL
意外的T_IS_NOT_EQUAL
意外的<
意外的>
意外的T_NS_分隔符…
输入中出现意外字符:“\
”(ASCII=92)状态=1
意外的“public”(T_PUBLIC)
意外的“private”(T_PRIVATE)
意外的“protected”(T_PROTECTED)
意外的“final”(T_FINAL)…
意外的t_static…
意外的T类…
意外的T_DNUMBER
意外的,
(逗号)
未执行的。
(句点)
意外的;
(分号)
意外的*
(星号)
意外的:
(冒号)
意外的&
(调用时间通过引用传递)
意外的。
密切相关的参考文献:
和:
虽然Stack Overflow也欢迎新手程序员,但它主要针对专业编程问题。
如果您的浏览器显示错误消息,例如“syntaxerror:非法字符”,那么它实际上不是PHP相关的,而是一个JavaScript语法错误。
供应商代码上出现的语法错误:最后,请考虑如果语法错误不是在编辑代码库时出现的,而是在外部供应商软件包安装或升级后出现的,那么这可能是由于PHP版本不兼容造成的,因此请对照您的平台设置检查供应商的要求。
PHP属于C风格的命令式编程语言。 它有僵硬的语法规则,当遇到放错位置的符号或标识符时,它无法从这些规则中恢复。 它无法猜测您的编码意图。
有几个基本的预防措施你总是可以采取的:
>
使用适当的代码缩进,或采用任何崇高的编码风格。 可读性可防止不规则性。
使用带有语法突出显示的IDE或PHP编辑器。 这也有助于括号/括号的平衡。
阅读手册中的语言参考和示例。 两次,变得有些熟练。
典型的语法错误消息如下:
分析错误:语法错误,意外的T_STRING,file.php中的第217行应为“;
”
其中列出了语法错误的可能位置。 请参阅提到的文件名和行号。
诸如T_string
之类的名字可以解释解析器/标记器最终无法处理的符号。 然而,这并不一定是语法错误的原因。
同样重要的是查看前面的代码行。 通常语法错误只是早先发生的错误。 错误行号正是解析器最终放弃处理所有错误的地方。
有许多方法可以缩小和修复语法问题。
>
打开提到的源文件。 请查看提到的代码行。
>
对于失控的字符串和放错位置的运算符,这通常是您找到罪魁祸首的地方。
从左到右读这一行,想象每个符号的作用。
您还需要更经常地查看前面的行。
>
特别是缺少;
分号,在前面的行尾/语句。 (至少从文体的角度来看。)
如果{
代码块}
不正确地关闭或嵌套,您可能需要进一步研究源代码。 使用适当的代码缩进来简化这一点。
看看语法着色!
>
字符串,变量和常量都应该有不同的颜色。
运算符+-*/.
的颜色也应该是不同的。 否则他们可能是在错误的上下文中。
如果您看到字符串颜色化扩展得太远或太短,则说明您发现了未转义或缺少的结束“
或'
字符串标记。
两个颜色相同的标点符号紧挨着也可能意味着麻烦。 通常,如果运算符后面没有++
,--
或括号,则运算符是单独的。 两个字符串/标识符直接跟在对方后面,在大多数上下文中是不正确的。
空格是你的朋友。 遵循任何编码风格。
暂时打散长队。
>
您可以自由地在运算符或常量与字符串之间添加换行符。 解析器然后将解析错误的行号具体化。 不需要查看非常冗长的代码,您可以隔离丢失或放错位置的语法符号。
将复杂的if
语句拆分为不同的或嵌套的if
条件。
使用临时变量来简化代码,而不是冗长的数学公式或逻辑链。 (可读性更强=错误更少。)
在以下之间添加换行:
对长代码块进行分区确实有助于定位语法错误的根源。
注释掉违规代码。
>
如果无法隔离问题源,请开始注释掉(从而临时删除)代码块。
您一摆脱解析错误,就找到了问题源。 仔细看那里。
有时您希望暂时移除完整的函数/方法块。 (如果出现不匹配的花括号和错误缩进的代码。)
当您无法解决语法问题时,尝试从头重写注释掉的部分。
作为一个新手,请避免一些令人困惑的语法结构。
>
三元<代码>? :条件运算符可以压缩代码,非常有用。 但并不是在所有情况下都有助于可读性。 在未验证时,首选纯if
语句。
PHP的替代语法(if:
/elseif:
/endif;
)对于模板是常见的,但可以说不如普通的{
code}
块容易遵循。
最常见的新人错误是:
>
缺少分号;
用于终止语句/行。
“
或'
的字符串引号不匹配,且内有未转义引号。
忘记运算符,特别是字符串.
级联的运算符。
不平衡的(
括号)
。 在报告行中计数。 他们的人数相等吗?
不要忘记,解决一个语法问题可以发现下一个语法问题。
>
如果您解决了一个问题,但在下面的一些代码中又出现了其他问题,那么您基本上是在正确的道路上。
如果在编辑完一个新的语法错误出现在同一行中,那么您尝试的更改可能是失败的。 (但并非总是如此。)
如果无法修复,则还原以前工作代码的备份。
diff
。 这可能对语法问题是什么有启发意义。 不可见的杂散Unicode字符:在某些情况下,您需要在源代码上使用hexeditor或不同的编辑器/查看器。 有些问题不能仅仅从查看您的代码中发现。
>
尝试grep--color-p-n“\[\x80-\xff\]”file.php
作为查找非ASCII符号的第一个度量。
特别是BOM,零宽度空格或非断行空格,以及智能引号通常会出现在源代码中。
注意保存在文件中的换行符类型。
>
PHP只接受\n换行,而不接受\r回车。
这对于MacOS用户来说偶尔是个问题(即使在OS ;X上,编辑器配置错误也是如此)。
它通常只在使用单行//
或#
注释时才会出现问题。 当换行符被忽略时,多行/*...*/
注释很少干扰解析器。
如果您的语法错误没有通过Web传输:那么您的机器上就会出现语法错误。 但是将同样的文件发布到网上就不再显示它了。 这只能意味着两件事中的一件:
>
您正在查看错误的文件!
或者您的代码包含不可见的杂散Unicode(见上文)。 您可以很容易地发现:只需将您的代码从web表单复制回您的文本编辑器。
检查您的PHP版本。 并非所有的语法结构都在每台服务器上可用。
> 用于命令行解释器的
php-v
,通过Web服务器调用。
它们不一定相同。 尤其是在使用框架时,您将使它们匹配。
不要使用PHP的保留关键字作为函数/方法,类或常量的标识符。
试错是你最后的手段。
如果所有其他方法都失败了,你总是可以谷歌你的错误信息。 语法符号不那么容易搜索(堆栈溢出本身由SymbolHound索引)。 因此,在你找到相关的东西之前,可能需要多看几页。
进一步指南:
如果你的网站是空白的,那么典型的语法错误是原因。 启用显示:
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
,并在脚本崩溃时查看Web服务器的error.log
。
我认为这个话题完全被讨论过度了/过于复杂了。 使用IDE是完全避免任何语法错误的方法。 我甚至会说,在没有IDE的情况下工作是不专业的。 为什么? 因为现代IDE会在您键入的每个字符之后检查您的语法。 当您编写代码时,整个行变成红色,并且一个巨大的警告通知显示语法错误的确切类型和确切位置,那么就完全不需要搜索其他解决方案。
您(实际上)再也不会遇到语法错误了,这仅仅是因为您在键入时看到了正确的语法错误。 说真的。
具有语法检查的优秀IDE(所有IDE都适用于Linux,Windows和Mac):
现在,在过期的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版本,也可以使用预处理器和PHP 5.4语法下变频器。
意外[
语法错误的其他原因
如果不是PHP版本不匹配,那么它通常是一个简单的打字错误或新来者语法错误:
>
您不能在类中使用数组属性声明/表达式,甚至在PHP ;7中也是如此。
protected $var["x"] = "Nope";
⇑
将[
与开头的花括号{
或圆括号(
混淆是一种常见的疏忽。
foreach [$a as $b)
⇑
或者甚至:
function foobar[$a, $b, $c] {
⇑
或者尝试将常量(在PHP 5.6之前)作为数组取消引用:
$var = const[123];
⇑
至少PHP将const
解释为常量名称。
如果您打算访问数组变量(这是这里的典型原因),那么添加前导的$
符号-这样它就变成了$varname
。
您正在尝试对关联数组的成员使用global
关键字。 这是无效的语法:
global $var['key'];
这种情况比较少见,但终止数组]
括号也存在语法事故。
>
再次与)
括号或}
花括号不匹配是常见的:
function foobar($a, $b, $c] {
⇑
或者试图在没有数组的地方结束数组:
$var = 2];
这通常出现在多行和嵌套数组声明中。
$array = [1,[2,3],4,[5,6[7,[8],[9,10]],11],12]],15];
⇑
如果是这样,请使用您的IDE进行括号匹配以查找任何过早的]
数组闭包。至少使用更多的间距和换行来缩小它的范围。