PHP解析/语法错误;如何解决这些问题

PHP解析/语法错误;如何解决这些问题,php,javascript,parsing,debugging,syntax-error,Php,Javascript,Parsing,Debugging,Syntax Error,每个人都会遇到语法错误。即使是有经验的程序员也会打字。对于新手来说,这只是学习过程的一部分。但是,通常很容易解释错误消息,例如: PHP解析错误:语法错误,第20行index.PHP中出现意外的“{” 意外的符号并不总是真正的罪魁祸首。但是行号给出了从哪里开始寻找的粗略概念 始终查看代码上下文。语法错误通常隐藏在上述代码行或之前的代码行中。请将您的代码与手册中的语法示例进行比较 虽然不是每个案例都与另一个相匹配,但也有一些案例。 本参考文献总结了常见的陷阱: … 逗号 时期

每个人都会遇到语法错误。即使是有经验的程序员也会打字。对于新手来说,这只是学习过程的一部分。但是,通常很容易解释错误消息,例如:

PHP解析错误:语法错误,第20行index.PHP中出现意外的“{”

意外的符号并不总是真正的罪魁祸首。但是行号给出了从哪里开始寻找的粗略概念

始终查看代码上下文。语法错误通常隐藏在上述代码行或之前的代码行中。请将您的代码与手册中的语法示例进行比较

虽然不是每个案例都与另一个相匹配,但也有一些案例。 本参考文献总结了常见的陷阱:

逗号

时期

分号

星号

结肠

调用时间按引用传递

密切相关的参考文献:

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

世界及其各种 或者维基百科的。 最后当然是我们的。 虽然Stack Overflow也欢迎新手程序员,但它主要针对专业编程问题

回答每个人的编码错误和狭隘的打字错误通常被认为是离题的。 因此,在发布语法修复请求之前,请花时间遵循以下步骤。 如果您仍然必须这样做,请展示您自己的解决方案、尝试的修复,以及您对什么看起来或可能是错误的思考过程。 如果您的浏览器显示错误消息,如SyntaxError:非法字符,那么它实际上并不相关,而是一个-

供应商代码中出现的语法错误:最后,考虑到如果编辑代码库没有引起语法错误,但在外部供应商包安装或升级后,可能是由于PHP版本不兼容,所以检查供应商对平台设置的要求。

语法错误是什么? PHP属于语言和编程语言。它有严格的语法规则,当遇到错误放置的符号或标识符时无法恢复。它无法猜测您的编码意图

最重要的提示 您可以随时采取以下几项基本预防措施:

使用适当的代码缩进,或采用任何崇高的编码风格。 可读性可防止不规则

使用带有突出显示的语法。 这也有助于圆括号/支架的平衡

请阅读手册中的示例。 第二次,变得有点熟练

如何解释解析器错误 典型的语法错误消息如下:

分析错误:语法错误,意外的T_字符串,第217行的file.php中应为“;”

其中列出了语法错误的可能位置。请参阅所提到的文件名和行号

例如T_字符串解释了解析器/标记器最终无法处理的符号。然而,这不一定是语法错误的原因

查看前面的代码行也很重要。语法错误通常只是发生在前面的错误。错误行号正是解析器最终放弃处理它的地方

解决语法错误 有许多方法可以缩小和修复语法问题

打开上面提到的源文件。查看上面提到的代码行

对于失控的字符串和放错位置的运算符,这通常是找到罪魁祸首的地方

从左到右阅读这一行,想象每个符号的作用

您还需要更经常地查看前面几行

特别是,缺少;分号在前一行结尾/语句中缺少。至少从文体角度来看是这样

如果{code blocks}被错误地关闭或嵌套,您可能需要进一步研究源代码。使用适当的代码缩进来简化这一过程

看看语法着色

字符串、变量和常量都应该有不同的颜色

运算符+-*/。也应着色为不同的颜色。否则,它们可能位于错误的上下文中

如果您看到字符串着色扩展得太远或太短,那么您发现了一个未切换或缺少结束或“字符串”标记

两个相同颜色的标点符号相邻也可能意味着麻烦。通常,如果运算符后面不是++、-、或括号,则运算符是孤立的。在大多数上下文中,直接紧跟在后面的两个字符串/标识符是不正确的

空白是你的朋友。 遵循任何编码风格。

暂时打散长队

您可以在运算符或常量和字符串之间自由添加换行符。然后,解析器将具体化行号以分析错误。您可以隔离丢失或错位的语法符号,而不是查看非常长的代码

将复杂的if语句拆分为不同或嵌套的if条件

而不是冗长的数学公式或逻辑链 ,使用临时变量简化代码。可读性更强=错误更少

在以下各项之间添加换行符:

您可以轻松识别为正确的代码, 你不确定的部分, 以及解析器抱怨的行。 划分长代码块确实有助于找到语法错误的根源

注释掉有问题的代码

如果无法隔离问题源,请开始注释掉,从而临时删除代码块

一旦您消除了解析错误,您就找到了问题的根源。仔细看

有时您希望临时删除完整的函数/方法块。如果出现不匹配的大括号和错误缩进的代码

如果无法解决语法问题,请尝试从头重写注释掉的部分

作为新手,避免一些令人困惑的语法结构

三元条件运算符可以压缩代码,确实很有用。但它并不是在所有情况下都有助于可读性。在未设置参数时更喜欢纯if语句

PHP的替代语法if:/elseif:/endif;对于模板来说是很常见的,但可以说不如普通的{code}块容易遵循

最常见的新来者错误是:

缺少分号;用于终止语句/行

或“”的字符串引号不匹配,以及中的未替换引号不匹配

遗忘的运算符,尤其是字符串。串联

不平衡括号。在报告行中计算它们。他们的人数相等吗

不要忘记,解决一个语法问题可以揭示下一个语法问题

如果您消除了一个问题,但在下面的一些代码中出现了其他问题,那么您基本上走在了正确的道路上

如果在编辑同一行后出现新语法错误,则您尝试的更改可能失败。但并不总是这样

如果无法修复,请还原以前工作代码的备份

采用源代码版本控制系统。您始终可以查看损坏版本和上次工作版本的差异。这可能会对语法问题有所启发。 不可见的零散Unicode字符:在某些情况下,您需要在源代码上添加一个或多个不同的编辑器/查看器。有些问题仅仅通过查看代码是找不到的

尝试作为查找非ASCII符号的第一个度量

特别是bom、零宽度空格或不间断空格,以及智能引号可以定期进入源代码

注意保存在文件中的换行符类型

PHP只接受换行符,而不是回车符

对于MacOS用户来说,这有时也是一个问题,即使在OSX上,对于配置错误的编辑器也是如此

它通常只在使用单行//或注释时作为问题出现。当忽略换行符时,多行/*…*/注释很少会干扰解析器

如果您的语法错误没有通过web传输: 碰巧您的计算机上有语法错误。但是,在网上发布同样的文件不再显示它了。这只能意味着两件事中的一件:

您正在查看错误的文件

或者您的代码包含不可见的字符,请参见上文。 您可以很容易地找到:只需将您的代码从web表单复制回您的文本编辑器

检查您的PHP版本。并非所有的语法结构在每台服务器上都可用

用于命令行解释器的php-v

意外的T_变量 意外的T_变量意味着存在文本$VARIABLE name,它不适合当前表达式/语句结构

缺少分号 它通常在前一行中表示。语句后面的变量赋值是一个很好的指示器:

        ⇓
 func1()
 $var = 1 + 2;     # parse error in line +2
字符串串联 经常发生的不幸都会被遗忘。接线员:

                                ⇓
 print "Here comes the value: "  $value;
顺便说一句,只要有助于可读性,您应该更喜欢双引号中的基本变量。这样可以避免这些语法问题

字符串插值是脚本语言的核心功能。利用它并不羞耻。忽略任何关于变量的微观优化建议。连接速度更快。不是

缺少表达式运算符 当然,在其他表达式中也会出现同样的问题,例如算术运算:

            ⇓
 print 4 + 7 $var;
PHP在这里无法猜测是否应该添加、减去或比较变量等

列表 语法列表也是如此,如在数组填充中,解析器还指示预期的逗号,例如:

                                       ⇓
 $var = array("1" => $val, $val2, $val3 $val4);
或函数参数列表:

                                 ⇓
 function myfunc($param1, $param2 $param3, $param4)
同样地,您是否在列表或全局语句中看到了这一点,或者在缺少;for循环中的分号

类声明 此解析器错误也会发生。只能指定静态常量,不能指定表达式。因此,解析器将变量作为指定的数据进行投诉:

 class xyz {      ⇓
     var $value = $_GET["input"];
不匹配的}闭合大括号在这里特别重要。如果方法过早终止,请使用适当的缩进!,然后一个杂散变量是com 通常错误地放在类声明体中

标识符后的变量 您也不能直接:

              ⇓
 $this->myFunc$VAR();
顺便说一句,这是一个常见的例子,其目的可能是使用。在本例中,使用$this->{myFunc$VAR}进行变量属性查找;比如说

请记住,使用变量应该是例外。新来者经常试图过于随意地使用它们,即使数组更简单、更合适

语言构造后缺少括号 仓促键入可能会导致忘记开始或结束括号 对于if、for和foreach语句:

        ⇓
 foreach $array as $key) {
解决方案:在语句和变量之间添加缺少的开口

                       ⇓
 if ($var = pdo_query($sql) {
      $result = …
大括号不会打开代码块,除非先用右括号关闭if表达式

否则就不会有条件 解决方案:从else或use中删除条件

闭合需要括号吗 解决方案:在$var周围添加括号

不可见空白 正如在不可见的Unicode(如a)中提到的,您也可能会在不知情的代码中看到此错误,如:

<?php
                          ⇐
$var = new PDO(...);
<?php
    print 123;
这在文件开头以及复制和粘贴代码时非常普遍。如果代码在视觉上没有包含语法问题,请使用hexeditor进行检查

另见 意外的T_字符串 T_字符串有点用词不当。它不是指带引号的字符串。这意味着遇到了原始标识符。范围从裸字到剩余的常量或函数名、忘记的带引号的字符串或任何纯文本

错误引用的字符串 但是,对于错误引用的字符串值,此语法错误最为常见。任何未转义和错误的或引号将形成无效表达式:

               ⇓                  ⇓
 echo "<a href="http://example.com">click here</a>";
如果$text很大,有很多行,开发人员看不到整个PHP变量值,只关注代码片段而忘记了它的源代码,就会发生这种情况

另见

未闭合字符串 如果出现语法错误,通常会在以后出现。未终止的字符串通常会消耗一些代码,直到下一个预期的字符串值:

                                                       ⇓
echo "Some text", $a_variable, "and some runaway string ;
success("finished");
         ⇯
解析器可能会抗议的不仅仅是文本T_字符串。另一个常见的变体是对无引号的文本HTML的声明

非编程字符串引号 如果您从博客或网站复制并粘贴代码,有时会导致代码无效。PHP期望:

$text = ’Something something..’ + ”these ain't quotes”;
排版/智能引号是Unicode符号。PHP将它们视为相邻字母数字文本的一部分。例如,“它们被解释为常量标识符。但解析器随后将以下任何文本文本视为裸字/T_字符串

缺少的分号;再一次 如果前几行中有一个未终止的表达式,则以下任何语句或语言构造都将被视为原始标识符:

       ⇓
func1()
function2();
PHP就是不知道是要一个接一个地运行两个函数,还是要将它们的结果相乘、相加、比较,还是只运行一个或另一个

短的开放标记和意外的T_常量\u封装的\u字符串意外的T_封装的\u和\u空格 笨拙的名称T_CONSTANT_ENCAPSED_STRING和T_ENCAPSED_和_空格指的是带引号的字符串文字

它们在不同的上下文中使用,但语法问题非常相似。T_封装…警告出现在双引号字符串上下文中,而T_常量…字符串通常误入普通PHP表达式或语句中

不正确的变量插值 对于不正确的PHP变量插值,它最常出现:

                          ⇓     ⇓
echo "Here comes a $wrong['array'] access";
在PHP上下文中,引用数组键是必须的。但是在双引号字符串或herdeocs中,这是一个错误。解析器抱怨所包含的单引号“string”,因为它通常需要一个文本标识符/键

更准确地说,对数组引用使用PHP2样式是有效的:

echo "This is only $valid[here] ...";
但是,嵌套数组或更深层次的对象引用需要以下语法:

如果不确定,这通常更安全。它通常被认为更可读。更好的IDE实际上使用不同的语法着色

缺失串联 如果字符串跟在表达式后面,但缺少连接或其他运算符,则会看到PHP抱怨字符串文字:

                       ⇓
print "Hello " . WORLD  " !";
虽然这对您和我来说都很明显,但PHP无法猜测字符串是否要附加在那里

混乱的字符串引用附件 当.以单引号或双引号开头的字符串也以相同的结尾时,会发生相同的语法错误

                ⇓
print "<a href="' . $link . '">click here</a>";
      ⌞⎽⎽⎽⎽⎽⎽⎽⎽⌟⌞⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⌟⌞⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⎽⌟
虽然这也会导致语法混乱,但所有更好的IDE/编辑器都会通过对转义引号进行不同的着色来再次提供帮助

缺少开盘报价 同样地,语法分析器错误的配方是:

               ⇓
 make_url(login', 'open');
在这里,“,”将成为一个纯文字后面的字符串文字,而登录显然是一个字符串参数

数组列表 如果数组创建块中缺少逗号,解析器将看到两个连续字符串:

array(               ⇓
     "key" => "value"
     "next" => "....",
);
请注意,最后一行可能是 始终包含一个额外的逗号,但忽略其中一个是不可原谅的。如果没有语法突出显示,很难发现

函数参数列表 同样的事情:

失控的弦 一种常见的变体是被完全遗忘的字符串终止符:

                                ⇓
mysql_evil("SELECT * FROM stuffs);
print "'ok'";
      ⇑
这里,PHP抱怨两个字符串文字直接紧跟在一起。但真正的原因当然是之前未关闭的字符串

另见

想不到的 开括号通常跟随诸如if/foreach/for/array/list或start算术表达式之类的语言构造。在字符串、前一个、一个单独的$之后以及一些典型的声明上下文中,它们在语法上是不正确的

函数声明参数 此错误的罕见情况是。即使在PHP7中,这也不受支持:

function header_fallback($value, $expires = time() + 90000) {
函数声明中的参数只能是文字值或常量表达式。与函数调用不同,在函数调用中,您可以自由使用whatever1+something*2等

类属性默认值 对于仅允许文字/常量值,而不允许表达式的情况也一样:

class xyz {                   ⇓
    var $default = get_config("xyz_default");
                      ⇓
print "Hello {$world[2{]} !";
                   ⇓
$var = array(1, 2, foreach($else as $_), 5, 6);
把这些东西放到构造函数中。 另见

再次注意,PHP7只允许var$xy=1+2+3;这里有恒定的表达式

PHP中的JavaScript语法 由于明显的原因,使用JavaScript或PHP将不起作用:

<?php      ⇓
    print $(document).text();
这同样适用于任何需要隐式变量名访问的语言构造。这些内置函数是语言语法的一部分,因此不允许使用装饰性的附加括号

需要变量引用但得到传递的表达式结果的用户级函数会导致运行时错误

想不到的 缺失函数参数 你不可能迷路了。PHP期望在那里有一个值,并因此抱怨提前结束括号

              ⇓
callfunc(1, 2, );
只有在数组或列表构造中才允许使用尾随逗号

未完成的表达 如果您忘记了算术表达式中的某些内容,那么解析器就会放弃。因为它应该如何解释:

               ⇓
$var = 2 * (1 + );
如果你甚至忘记了结尾,那么你会收到关于意外分号的投诉

Foreach作为常数 因为你会看到:

                   ↓    ⇓
foreach ($array as wrong) {
这里的PHP有时会告诉您它需要的是::而不是。因为类::$variable可能已满足预期的$variable表达式

意料之外{ 大括号{和}将代码块括起来。关于它们的语法错误通常表示某些不正确的嵌套

if中不匹配的子表达式 如果解析器抱怨开头的卷曲出现得太早,最常见的原因是。一个简单的示例:

                              ⇓
if (($x == $y) && (2 == true) {
计算括号数或使用IDE,这有助于计算括号数。也不要编写没有空格的代码。可读性很重要

表达式上下文中的{和} 表达式中不能使用大括号。如果混淆括号和大括号,则不符合语言语法:

           ⇓
$var = 5 * {7 + $x};
标识符构造有一些例外情况,例如局部范围变量${references}

变量或卷曲变量表达式 这是非常罕见的。但对于复杂变量表达式,您可能还会收到{和}解析器投诉:

class xyz {                   ⇓
    var $default = get_config("xyz_default");
                      ⇓
print "Hello {$world[2{]} !";
                   ⇓
$var = array(1, 2, foreach($else as $_), 5, 6);
尽管在这种情况下发生意外}的可能性更高

意外} 当遇到意外的}错误时,您通常过早地关闭了代码块

代码块中的最后一条语句 任何未终止的表达式都可能发生这种情况

如果函数/代码块中的最后一行缺少尾随;分号:

function whatever() {
    doStuff()
}            ⇧
在这里,解析器无法判断您是否仍然想要添加+25;对于函数结果或其他东西

无效的块嵌套/遗忘{ 当代码块}关闭得太早,或者忘记打开{偶数:

在上面的代码片段中,if没有一个开头{大括号。因此下面的结尾}变得多余。因此,下一个结尾}是为函数准备的,与原始开头{大括号}不相关

如果没有适当的代码缩进,这样的错误更难发现。请使用IDE和括号匹配

意外的,期待的 需要条件/声明头和代码块的语言构造将触发此错误

<?= $a ?? 2; // works in PHP 7+
<?= (!empty($a)) ? $a : 2; // All versions of PHP
参数列表 例如,不允许:

                 ⇓
function whatever {
}
控制语句条件 你不可能有一个类似的

这显然是没有道理的。对于通常的嫌疑犯来说也是一样,比如for/foreach,while/do,等等

如果你有这个特殊的错误,你一定要查一些手册上的例子

意外的T_IF 意外事故 意外的 意外的 意想不到的事 意外的T_回声 控件构造(如if、foreach、for、while、list、global、return、do、print、echo)只能用作语句。它们通常单独驻留在一行上

分号;你在哪里? 美丽的你 通常情况下,如果解析器抱怨控制语句,您会在前一行中看到:

             ⇓
$x = myfunc()
if (true) {
                   ⇓
echo "<a href='" . if ($link == "example.org") { echo …
解决方案:查看前一行;添加分号

类声明 发生这种情况的另一个位置是。在类部分中,只能列出属性初始化和方法部分。没有代码可以驻留在那里

class xyz {
    if (true) {}
    foreach ($var) {}
这种语法错误通常在嵌套错误的{和}中具体化。特别是当函数代码块过早关闭时

表达式上下文中的语句 大多数语言结构都可以。它们不应放在其他表达式中:

class xyz {                   ⇓
    var $default = get_config("xyz_default");
                      ⇓
print "Hello {$world[2{]} !";
                   ⇓
$var = array(1, 2, foreach($else as $_), 5, 6);
同样,您不能在字符串、数学表达式或其他地方使用if:

               ⇓
print "Oh, " . if (true) { "you!" } . " won't work";
// Use a ternary condition here instead, when versed enough.
对于在表达式中嵌入if-like条件,通常需要使用

这同样适用于for、while、global、echo和较小的扩展列表

而print是一种内置的语言,可以在表达式上下文中使用。但很少有意义

保留关键字作为标识符 对于用户定义的函数或类名,也不能使用do或if和其他语言构造。也许在PHP7中。但即便如此,这也不可取

您的控制块后面有一个分号,而不是冒号:或花括号{ 控件结构通常用大括号括起来,但冒号可用于表示其作用域。如果意外使用分号,则会过早关闭该块,导致关闭语句抛出错误


我认为这个话题完全是讨论过度/过于复杂。使用IDE是完全避免语法错误的方法。我甚至会说,在没有IDE的情况下工作有点不专业。为什么?因为现代IDE会在你键入的每个字符后检查你的语法。当你编码时,你的整行代码都会变红,并且会发出一个很大的警告e向您显示语法错误的确切类型和确切位置,那么绝对不需要搜索其他解决方案

使用语法检查IDE意味着: 实际上,您永远不会再遇到语法错误,这仅仅是因为您在键入时正确地看到了语法错误

具有语法检查功能的优秀IDE所有IDE均适用于Linux、Windows和Mac:

[免费] [$199美元] 有[免费] [$80美元]主要是一个文本编辑器,但可以通过插件扩展,如 意外的$end 当PHP谈到意外的$end时,意味着您的代码过早结束。从字面上看,这条消息有点误导。它不是关于一个名为$end的变量,这有时是新来者假设的。它指的是文件的结尾,EOF

原因:代码块/和函数或类声明的{和}不平衡

$array = [1,[2,3],4,[5,6[7,[8],[9,10]],11],12]],15];
                                             ⇑
它几乎总是关于一个缺少的}大括号来关闭前面的代码块

同样,使用适当的缩进来避免此类问题

使用括号匹配的IDE,找出}的错误所在。 大多数IDE和文本编辑器中都有键盘快捷键:

NetBeans、PhpStorm、Komodo:Ctrl[和Ctrl] 日食,Aptana:CtrlShiftP 原子,崇高:Ctrlm-Zend Studio Ctrlm Geany,Notepad++:CtrlB-Joe:CtrlG-Emacs:C-M-n-Vim:% 大多数IDE还突出显示匹配的大括号、方括号和圆括号。 这样就很容易检查它们的相关性:

未终止表达式 对于未终止的表达式或语句,也可能发生意外的$end语法/解析器错误:

        ⇓
 foreach $array as $key) {
$var=func1, ?>EOF 所以,首先看一下脚本的结尾。尾随;对于任何PHP脚本中的最后一条语句,它通常是多余的。但是你应该有一个。正是因为它缩小了这种语法问题的范围

锯齿状遗传标记 另一种常见情况是字符串。终止标记会被前导空格、制表符等忽略:

print <<< END
    Content...
    Content....
  END;
# ↑ terminator isn't exactly at the line start
因此,解析器假定herdoc字符串持续到文件结尾,因此出现意外的$end。几乎所有的IDE和语法突出显示编辑器都会对此做出明确的说明或警告

转义引号 如果在字符串中使用\,则它具有特殊含义。这被称为,通常会告诉解析器按照字面意思提取下一个字符

示例:echo'吉姆说'你好';吉姆会说“你好”吗

如果对字符串的结束引号进行转义,则结束引号将按字面意思理解,而不是按预期,即作为字符串的一部分作为可打印引号,而不是结束字符串。这通常会在打开下一个字符串后或在脚本末尾显示为解析错误

在Windows中指定路径时出现非常常见的错误:C:\xampp\htdocs\错误。您需要C:\\xampp\\htdocs\\

替代语法 在模板中使用语句/代码块的替代语法时,您可能会看到这种语法错误。使用if:和else:以及缺少的endif;比如说

另见: 意料之外[ 如今,在过时的PHP版本中经常会出现意外的[array]括号 4.较旧的安装仅支持阵列

数组函数结果解引用同样不适用于较早的PHP版本:

$result = get_whatever()["key"];
                      ⇑
显示了最常见和最实用的解决方法

不过,升级PHP安装总是更好的选择。对于共享webhosting计划,首先研究是否可以使用SetHandler php56 fcgi来启用更新的运行时

另见:

顺便说一句,还有预处理器,如果你真的对旧的+较慢的PHP版本感兴趣的话

意外[语法错误]的其他原因

如果不是PHP版本不匹配,那么通常是一个简单的输入错误或新来者语法错误:

您不能使用,即使在PHP7中也不能

protected $var["x"] = "Nope";
              ⇑
将[与大括号{或圆括号]混淆是一个常见的疏忽

foreach [$a as $b)
        ⇑
甚至:

function foobar[$a, $b, $c] {
               ⇑
                    ⇓
if (isset($variable !== "value")) {
或者尝试将PHP 5.6之前的常量作为数组取消引用:

$var = const[123];
       ⇑
至少PHP将该常量解释为一个常量名

如果您想访问一个数组变量,这是这里的典型原因,那么添加前导$sigil,使其成为$varname

您试图对关联数组的成员使用全局关键字。这是无效语法:

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进行括号匹配,以找到任何过早的]数组闭包。至少使用更多的间距和换行来缩小范围

意外的T_等于 意外的T_大于或等于 意外的T_是相同的 意外的T_不相等 意外的T_不完全相同 意外的T_小于或等于 想不到的 比较运算符,如==、>=、==、!=、!=and=大于或等于with=>数组运算符 两个操作符看起来有些相似,因此有时会混淆:

         ⇓
if ($var => 5) { ... }
您只需记住,此比较运算符被称为大于或等于,以便正确使用

另见:

无可比拟 如果两个比较属于同一个变量名,则也不能将它们组合在一起:

                 ⇓
if ($xyz > 5 and < 100)
这相当于一个字符串 意外的T_IF 意料之外的 意外的其他 意外终止 条件控制块if、elseif和else遵循简单的结构。当您遇到语法错误时,很可能只是无效的块嵌套→ 缺少{大括号}或一个太多

由于缩进错误而缺少{或} 不匹配的代码大括号对于格式不太好的代码很常见,例如:

if((!($opt["uniQartz5.8"]!=$this->check58)) or (empty($_POST['poree']))) {if
($true) {echo"halp";} elseif((!$z)or%b){excSmthng(False,5.8)}elseif (False){
如果您的代码看起来像这样,请重新开始!否则,你或其他任何人都无法执行。在互联网上展示这一点来寻求帮助是没有意义的

只有在可视地遵循if/else条件及其{code blocks}的嵌套结构和关系的情况下,才能修复它。使用IDE查看它们是否都是成对的

if (true) {
     if (false) {
              …
     }
     elseif ($whatever) {
         if ($something2) {
             …
         } 
         else {
             …
         }
     }
     else {
         …
     }
     if (false) {    //   a second `if` tree
         …
     }
     else {
         …
     }
}
elseif (false) {
    …
}
任何double}都不仅仅关闭一个分支,而是关闭一个先前的条件结构。因此,坚持一种编码风格;不要在嵌套的if/else树中进行混合和匹配

除了这里的一致性之外,避免冗长的条件也很有帮助。使用临时变量或函数以避免不可读的if表达式

IF不能在表达式中使用 新来者经常犯的一个错误是试图在表达式中使用if语句,例如print语句:

             ⇓
$x = myfunc()
if (true) {
                   ⇓
echo "<a href='" . if ($link == "example.org") { echo …
为这种情况定义函数或方法通常也是有意义的

控制块不返回结果 现在这种情况不太常见,但一些程序员甚至尝试将if视为可以返回结果:

在结构上与在字符串连接/表达式中使用if相同

但是如果/foreach/while没有结果。 文本字符串true也只是一个void语句。 您必须在代码块中使用赋值:

或者,采用?:三元比较法

如果在如果中 您可以在以下条件中选择一种:

                    ⇓
if ($x == true and (if $y != false)) { ... }
这显然是多余的,因为and或or已经允许链接比较

被遗忘的;分号 再一次:每个控制块都需要是一条语句。如果前面的代码段没有以分号结尾,则这是一个保证语法错误:

                ⇓
$var = 1 + 2 + 3
if (true) { … }
if ($x) { x_is_true(); }; else { something_else(); };
顺便说一句,{…}代码块的最后一行也需要分号

分号太早 现在,指责一种特定的编码风格可能是错误的,因为这个陷阱太容易被忽视:

            ⇓
if ($x == 5);
{
    $y = 7;
}
else           ←
{
    $x = -1;    
}
这比你想象的要频繁

当您选择时,它将执行一个void语句。这个变成一个自己的空{}! 因此,{…}块与if分离,并将始终运行。 因此else不再与开放的if构造相关, 这就是为什么这会导致意外的T_ELSE语法 错误 这也解释了这个语法错误的一个同样微妙的变化:

                ⇓
$var = 1 + 2 + 3
if (true) { … }
if ($x) { x_is_true(); }; else { something_else(); };
在哪里;在代码块{…}之后,如果 构造,从语法上切断else分支

不使用代码块 在if/elseif/else分支中,语法上允许省略代码块的大括号{…}。不幸的是,这是一种语法风格,对于没有经验的程序员来说非常常见。在错误的假设下,这会更快地打字或阅读

但是,这很可能会导致语法错误。附加语句迟早会进入if/else分支:

if (true)
    $x = 5;
elseif (false)
    $x = 6;
    $y = 7;     ←
else
    $z = 0;
但要实际使用代码块,您必须将{…}代码块本身编写出来

即使是经验丰富的程序员也会避免这种无括号的语法,至少是这样 将其理解为该规则的例外情况

Else/Elseif顺序错误 当然,有一件事要提醒你自己的是

if ($a) { … }
else { … }
elseif ($b) { … }
↑
你想要多少就有多少,但是。事情就是这样

类声明 例如,在类声明中不能有控制语句:

class xyz {
    if (true) {
        function ($var) {}
    }
在这种情况下,您要么定义了一个,要么过早地关闭了一个

意外的其他/其他 混合使用PHP和HTML时,if/elseif的结尾}必须与下一个elseif/else位于同一PHP块中。这将生成一个错误,因为if的结束}需要是elseif的一部分:

两者都只能出现在{…}代码块中,而不能出现在控制结构标记之间

无论如何,这是没有道理的。当PHP在if和else分支之间跳转时,并不是存在一些未定义的状态。 您必须决定打印语句属于何处,或者是否需要在两个分支中重复它们。 也不能在不同的控制结构之间划分if/else:

foreach ($array as $i) {
    if ($i) { … }
}
else { … }
if和else之间没有任何区别。foreach词法作用域结束于},因此if结构没有继续的必要

特恩迪夫 如果投诉出现意外的T_ENDIF,则在以下情况下使用替代语法样式:⋯ 其他:⋯ 其他:⋯ endif;。你真的应该三思而后行

一个常见的陷阱让人莫名其妙地困惑。过早地用分号覆盖

由于缩进在模板文件中更难跟踪,因此在使用替代语法时,缩进越难跟踪-这似乎是你的endif;不匹配任何if:

使用 是一个双if终结者。

而意外的$end通常是一个被遗忘的}大括号的价格

分配与比较 因此,这不是语法错误,但在本文中值得一提:

       ⇓
if ($x = true) { }
else { do_false(); }
那不是一个好主意。这相当微妙,很容易导致一些用户无助地编辑整个条件块。当你遇到逻辑故障/错误时,首先要注意意外的任务

意外的T_LNUMBER 标记T_LNUMBER指的是长/长数字

无效的变量名 在PHP和大多数其他编程语言中,不能以数字开头。第一个字符必须是字母或下划线

$1   // Bad
$_1  // Good
在PHP上下文中使用preg_replace-placeholder$1的情况非常常见:

#                         ↓            ⇓  ↓
preg_replace("/#(\w+)/e",  strtopupper($1) )
回调应该被引用的地方。现在/e regex标志已被弃用。但它有时仍然被误用在preg_replace_回调函数中

顺便说一句,相同的标识符约束适用于

虽然标记器/解析器不允许文本$1作为变量名,但可以使用${1}或${1}。这是非标准标识符的语法解决方法。最好将其视为本地范围查找。但一般来说:在这种情况下更喜欢普通数组

有趣的是,PHPs解析器允许Unicode标识符,但不推荐使用;以致$➊ 这是有效的。与文字1不同

杂散阵列入口 也可能出现意外的长-如果缺少,则使用逗号:

或者类似地,函数调用和声明以及其他构造:

功能1,2,3; 函数xy$z2; 对于$i=23意外的“?” 如果您试图使用空合并运算符??在PHP7之前的PHP版本中,会出现此错误

<?= $a ?? 2; // works in PHP 7+
<?= (!empty($a)) ? $a : 2; // All versions of PHP
这再次表明,CLI版本PHP-v或Web服务器绑定版本phpinfo;正在使用过时的PHP版本

意外的“继续”T\u继续 continue是类似于for或if的语句,必须单独显示。它不能用作表达式的一部分。部分原因是continue不返回值,但在表达式中,每个子表达式都必须产生某个值,因此整个表达式产生一个值。这就是语句和表达式之间的区别

这意味着不能在三元语句或任何需要返回值的语句中使用continue

意外的“中断”T\u中断 休息也是如此;当然它在表达式上下文中也不可用,而是与foreach或if块处于同一级别的严格语句

意外的“返回”T\u返回 现在这对回归来说可能更令人惊讶,但这也只是一个障碍- 级别声明。它确实会向更高的作用域/函数返回值或NULL,但不会作为表达式本身进行计算。→ 那就是:做错误的事没有意义

意外的“=” 这可能是由于变量名中包含无效字符造成的。变量名称必须遵循以下规则:

变量名遵循与PHP中其他标签相同的规则。有效的变量名以字母或下划线开头,后跟任意数量的字母、数字或下划线。作为正则表达式,它可以这样表示:“[a-zA-Z\ux7F-\xff][a-zA-Z0-9\ux7F-\xff]*”

意外的“endwhile”T\u endwhile 语法使用冒号-如果没有冒号,则会出现上述错误

<?php while($query->fetch()): ?>
 ....
<?php endwhile; ?>
此语法的替代方法是使用花括号:

<?php while($query->fetch()) { ?>
  ....
<?php } ?>
意外的“ 如果您试图在不受支持的PHP版本中使用,可能会发生这种情况

。。。首次在PHP 5.6中提供,用于捕获函数的可变参数数:

function concatenate($transform, ...$strings) {
    $string = '';
    foreach($strings as $piece) {
        $string .= $piece;
    }
    return($transform($string));
}

echo concatenate("strtoupper", "I'd ", "like ", 4 + 2, " apples");
// This would print:
// I'D LIKE 6 APPLES
在PHP7.4中,您可以将其用于

意外: 1.PHP8命名参数语法 意外的“:”,应为“,”或

如果试图在PHP<8的版本中使用PHP 8的新命名参数功能,则会出现以下错误:

$table->string(column:'Name');
解决方案:

将您的PHP版本升级到PHP8.8.0或更高版本 不要使用命名参数按预期顺序传递参数 2.裁剪类::分隔符
开始解析错误的错误消息:语法错误,意外的“:”可能是由于错误地将类静态引用类::$Variable写入类:$Variable造成的。

出现这些错误的另一个原因是意外的空白,如代码中的类似字符,代码行似乎很完美,但是它们包含一些特定的字符,这些字符类似于换行符、空格或制表符,但是解析器无法解析它们。 当我试图通过简单的复制粘贴将一些代码从网页放到代码编辑器中时,我遇到了这个问题,我在数组定义中看到了这个错误。在数组定义中,一切看起来都是正确的。我无法找出正确的错误,最后我在一行中定义了这个数组,然后错误就消失了。然后,我再次尝试将该定义设置为多个,就像为每个数组元素手动添加breakEnter一样,并保存了该文件,这次编辑器没有解析错误,运行时也没有错误。 例如,我在一个博客上遇到了这个代码段的问题,实际上无法发布这些代码段,因为堆栈溢出已经知道代码的问题

然后在解决它之后,我的工作代码段是,它看起来与显示解析错误的代码段相似

语法错误,意外的auth T_常量_封装的_字符串,应为']'


对于VS代码的新手,如果看到语法错误,请检查是否已保存该文件。如果语法错误,请保存文件,然后在不再次保存的情况下修复语法,VS代码将继续显示错误。只有保存文件后,错误消息才会消失。

显然是这样。然而,在这里重新列出IDE,您能详细说明一下它们在语法帮助方面的不同之处吗?Sublime主要是一个编辑器,而不是IDE;但之后更漂亮、更活泼;它主要只是语法高亮,但在括号匹配方面也是名副其实的。它很容易发现T_常数_和_包裹的错误,例如,与PHPStorm不同;但是,它会为内联错误提供更多的曲线。NetBeans的语法提示过去比PHPs更神秘,甚至重新列出允许的构造。你能分享你的正反两方面的经验吗;你最喜欢的是Eclipse/PDT还是..?@mario我想你对这个话题非常深入,所以我真的不想在这里说错话,但是我和我的团队成员、编写代码的朋友、自由职业者合作伙伴在IDE中编写的所有代码都从来没有出现过语法错误。所以我认为至少Netbeans/PHPStorm的语法检查非常强大。但也许我误解了你的问题。给我几个小时;你的答案已经很准确了。符合我们99%的问题。然而,在这里的上下文中,我希望在IDE提供更为新手友好的工具提示这一点上进行权衡。这对我们来说可能是次要的,如果你足够精通的话,彩色和弯曲的线条就足够了。但我认为这些差异对初学者来说可能更为重要。有时IDE不是一个可行的选择。例如,快速编辑WordPress主题或插件。是的,我可以把所有的代码复制到一个IDE中,但是我必须打开它,把所有的代码都粘贴到IDE中,设置标题和所有其他浪费时间的废话,而我只是希望快速编辑。现在,如果您正在开发新功能或从头开始,那么,是的,在IDE中进行。你不会后悔在开始时花了那么多时间来设置它。我认为IDE是一个预告片,而不仅仅是一个工具箱。它可能无法修复,但可以帮助您查找并防止语法错误。这里的许多答案似乎是说,如果您保持代码干净,那么犯错误的机会就会减少
或者更容易被发现。自动缩进、代码提示、变量出现、自动收尾括号和自动格式化每天都能帮我省去许多打字错误,这也是我使用这种方法的主要优点。这并不包括问题调试器、数据库连接器、uml图表等范围之外的所有内容。IDE将节省您的时间,并将防止语法错误。这不足以作为答案,但您可以使用parsekit_compile_字符串编写分析器,并在其上给出更友好的答案。如果集成到您的IDE中,这可能是非常有用的。您为此投入了大量的工作。尊重这一点。对于教师来说,学会快速指出错误,或者对于那些创建IDE或实现快速修复的人来说,这可能是非常好的。然而,正如@Panique所建议的那样,ide已经可以有效地为您完成大部分工作。此外,在许多情况下,从头开始是一个好的选择。@Fred ii-我认为大多数原因与T_IF/T_FOREACH/…相似。。。块尽管我想为IF/ELSE/ELSEIF问题编写一个更自定义的摘要。你知道,我希望几年前学习PHP时有这个列表。非常有用,特别是对初学者。@β.εηοτ.βε好主意;最近有很多这样的问题。尽管可能的话,它需要涵盖三种常见情况:导入范围、特征、关闭;对于PHPSome的早期版本,比如NetBeans,IDEs不仅支持语法高亮显示,而且还支持代码格式化。如果您养成了正确格式化代码并要求IDE重新格式化的习惯,以防不时发现难以发现的问题,如不匹配的大括号。我在这篇文章中寻找我问题的答案,但我自己发现了一个问题的答案-出乎意料{,这就是为什么我想与大家分享我的答案-对我来说,问题是换行编码-不知何故,我的一些文件使用了macintosh换行符,但当我将它们改为windows换行符时-我的problemon localhostWAMP一切正常,但在linux Web服务器上没有解决。@EdgarsAivars感谢您的评论!特定于平台的换行符中断确实是一个不常见且棘手的问题。我可能在这里也会提到它。它只是在中提到的。我发现出人意料的}是因为我的一段代码使用了php短标记Good addition John。上面的链接“PHP5.4语法下变频器”被中断。函数foobar[$a,$b,$c]{我以为函数是像函数foobar$a、$b、$c一样声明的{???我觉得这已经被不可见的零散Unicode字符覆盖了。除了复制和粘贴编码器之外,它也没有那么普遍。如果是这样,就更有可能与意外的T_字符串情况配对。
if ($a) { … }
else { … }
elseif ($b) { … }
↑
class xyz {
    if (true) {
        function ($var) {}
    }
<?php if ($x) { ?>
    html
<?php } ?>
<?php elseif ($y) { ?>
    html
<?php } ?>
<?php if ($x) { ?>
    html
<?php } elseif ($y) { ?>
    html
<?php } ?>
if (true) {
}
echo "in between";    ←
elseif (false) {
}
?> text <?php      ←
else {
}
foreach ($array as $i) {
    if ($i) { … }
}
else { … }
       ⇓
if ($x = true) { }
else { do_false(); }
$1   // Bad
$_1  // Good
#                         ↓            ⇓  ↓
preg_replace("/#(\w+)/e",  strtopupper($1) )
       ↓
$json->0->value
#            ↓ ↓
$xy = array(1 2 3);
#                 ↓ ↓          
echo "<td colspan="3">something bad</td>";
         ↓
function 123shop() {
<?= $a ?? 2; // works in PHP 7+
<?= (!empty($a)) ? $a : 2; // All versions of PHP
function add(?int $sum): ?int {
<?php while($query->fetch()): ?>
 ....
<?php endwhile; ?>
<?php while($query->fetch()) { ?>
  ....
<?php } ?>
function concatenate($transform, ...$strings) {
    $string = '';
    foreach($strings as $piece) {
        $string .= $piece;
    }
    return($transform($string));
}

echo concatenate("strtoupper", "I'd ", "like ", 4 + 2, " apples");
// This would print:
// I'D LIKE 6 APPLES
$parts = ['apple', 'pear'];
$fruits = ['banana', 'orange', ...$parts, 'watermelon'];
// ['banana', 'orange', 'apple', 'pear', 'watermelon'];
$table->string(column:'Name');
    public $aliases = [
        'csrf'=> \CodeIgniter\Filters\CSRF::class,
        'toolbar'=> \CodeIgniter\Filters\DebugToolbar::class,
        'honeypot'=> \CodeIgniter\Filters\Honeypot::class,
        'auth' => \App\Filters\Auth::class,
];