提问者:小点点

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


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

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

    意外的(逗号)

    未执行的(句点)

    意外的(分号)

    意外的*(星号)

    意外的:(冒号)

    意外的&(调用时间通过引用传递)

    意外的

    密切相关的参考文献:

    • 这个错误在PHP中是什么意思? (运行时错误)
      • 分析错误:语法错误,意外的T_XXX
      • 分析错误:语法错误,意外的t_encapsed_and_whitespace
      • 分析错误:语法错误,意外的t_variable

      和:

        关于PHP.NET及其各种语言标记的PHP手册
      • 或维基百科关于PHP的语法介绍。
      • 最后是我们的php标记--当然是wiki.

      虽然Stack Overflow也欢迎新手程序员,但它主要针对专业编程问题。

      • 回答每个人的编码错误和狭义的错别字被认为大部分离题。
      • 因此,在发布语法修复请求之前,请花时间遵循基本步骤。
      • 如果您仍然必须这样做,请显示您自己解决问题的主动性,尝试的修复方法,以及您对看起来或可能出错的问题的思考过程。

      如果您的浏览器显示错误消息,例如“syntaxerror:非法字符”,那么它实际上不是PHP相关的,而是一个JavaScript语法错误。

      供应商代码上出现的语法错误:最后,请考虑如果语法错误不是在编辑代码库时出现的,而是在外部供应商软件包安装或升级后出现的,那么这可能是由于PHP版本不兼容造成的,因此请对照您的平台设置检查供应商的要求。


  • 共3个答案

    匿名用户

    PHP属于C风格的命令式编程语言。 它有僵硬的语法规则,当遇到放错位置的符号或标识符时,它无法从这些规则中恢复。 它无法猜测您的编码意图。

    有几个基本的预防措施你总是可以采取的:

    >

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

    使用带有语法突出显示的IDE或PHP编辑器。 这也有助于括号/括号的平衡。

    阅读手册中的语言参考和示例。 两次,变得有些熟练。

    典型的语法错误消息如下:

    分析错误:语法错误,意外的T_STRING,file.php中的第217行应为“

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

    诸如T_string之类的名字可以解释解析器/标记器最终无法处理的符号。 然而,这并不一定是语法错误的原因。

    同样重要的是查看前面的代码行。 通常语法错误只是早先发生的错误。 错误行号正是解析器最终放弃处理所有错误的地方。

    有许多方法可以缩小和修复语法问题。

    >

  • 打开提到的源文件。 请查看提到的代码行。

    >

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

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

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

    >

  • 特别是缺少分号,在前面的行尾/语句。 (至少从文体的角度来看。)

    如果{代码块}不正确地关闭或嵌套,您可能需要进一步研究源代码。 使用适当的代码缩进来简化这一点。

    看看语法着色!

    >

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

    运算符+-*/.的颜色也应该是不同的。 否则他们可能是在错误的上下文中。

    如果您看到字符串颜色化扩展得太远或太短,则说明您发现了未转义或缺少的结束'字符串标记。

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

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

    暂时打散长队。

    >

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

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

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

    在以下之间添加换行:

    1. 您可以轻松识别为正确的代码,
    2. 您不确定的部分,
    3. 和解析器抱怨的行。

    对长代码块进行分区确实有助于定位语法错误的根源。

    注释掉违规代码。

    >

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

    您一摆脱解析错误,就找到了问题源。 仔细看那里。

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

    当您无法解决语法问题时,尝试从头重写注释掉的部分。

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

    >

  • 三元<代码>? :条件运算符可以压缩代码,非常有用。 但并不是在所有情况下都有助于可读性。 在未验证时,首选纯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索引)。 因此,在你找到相关的东西之前,可能需要多看几页。

    进一步指南:

    • PHP调试基础知识
    • ,作者:David Sklar
    • Jason McCreary
    • 修复PHP错误
    • PHP错误-10个常见错误,Mario Lurig著
    • 常见PHP错误和解决方案
    • 如何排除和修复WordPress网站的故障
    • 设计人员PHP错误消息指南-粉碎杂志

    如果你的网站是空白的,那么典型的语法错误是原因。 启用显示:

    • 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):

    1. NetBeans[免费]
    2. phpstorm[199美元]
    3. 带PHP插件的Eclipse[免费]
    4. Sublime[$80美元](主要是一个文本编辑器,但可通过插件扩展,如PHP语法解析器)

    匿名用户

    现在,在过期的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语法错误,意外的“[”
    • 数组的速记:是否存在像{}或[]这样的文字语法?
    • PHP 5.3.10 vs PHP 5.5.3语法错误意外的“[”
    • array()和[]
    • 之间的PHP差异
    • PHP数组语法分析错误左方括号“[”

    顺便说一句,如果您真的喜欢使用更老更慢的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进行括号匹配以查找任何过早的]数组闭包。至少使用更多的间距和换行来缩小它的范围。