PHP Strict standards:Declaration of … should be compatible with that of…

文章详细解析了在将老旧PHP代码导入PaaS平台时遇到的Strict标准错误问题,并揭示了其根本原因。通过提供具体解决方法,文章帮助开发者避免了此类错误,提升了代码移植效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

    今天把原来一份很老的PHP代码导入到了PaaS上,出现了许多Strict standards:Declaration of … should be compatible with that of…这样的错误,字面意思好像是说函数不匹配,看了下出错的函数,都是子类重写的基类函数。

      上网搜索了一下,发现许多帖子基本都抄的一样,说什么这是由于 php5.3版本后,要求继承类必须在父类之后定义,如果父类定义在前,继承类在后,就不会出现这个错误。

          我看了下自己的代码,虽然确实也用到了autoload,但是都是显式的先导入了几个基类,并不存在这样的情况,而且将上面的正反例子试了一下,都会出现E_STRICT的警告。

真正原因:

其实如果子类重写方法的参数和基类不一样,只要给参数个默认值,使得编译器认为参数可以为空,保持重写方法与基类方法的函数签名相同就可以了。

经常用JAVA的同学肯定知道,在JAVA或者C++中,重写方法的函数签名本应该就和基类函数是一致的,我认为这也是符合自然规律的,因为override本来就是覆盖的意思嘛,既然覆盖了,那么就应该和原函数一致,不然怎么能“盖”的住呢~并且方法的重写多用在重写虚函数或者更明白的说就是重写接口的函数,如果重写的时候函数签名都不一致了,还要接口干嘛呢。。。

所以PHP的新版本中,我觉得定义这个E_STRICT的警告错误是很有用处的,要提醒程序员自己的重写方法到底对不对。

最后还是鄙视一下上面那些抄来抄去的帖子,如果某个语言连基类和子类定义的顺序都不能打乱,说明这个编译器非常有问题了,显然是bug。。。

转自: http://levi.cg.am/?p=2896
<think>我们正在讨论PHP中出现的"StrictStandards:Onlyvariablesshouldbepassedbyreference"错误。这个错误通常发生在你试图将一个非变量的值(比如一个函数的返回值)作为引用参数传递给一个函数时。在PHP中,引用传递要求传递的是一个变量,而不是一个表达式或字面量。回顾引用[1]的内容,它展示了一个使用SQL替换模板字符串的例子,但与当前PHP错误关系不大。因此,我们将主要关注PHP问题的解决。在PHP中,常见的引发此错误的场景是使用内置函数时,如array_pop()、end()等,它们要求参数是通过引用传递的变量。例如:$last=array_pop(array_slice($array,-1));//错误:array_slice返回的是数组,不是变量$last=end(array_keys($array));//错误:array_keys返回的是数组,不是变量解决方案:1.将表达式的结果先赋值给一个临时变量,然后传递这个临时变量。2.修改代码,避免在引用参数的位置使用非变量。下面针对常见的几种情况给出示例:情况一:使用array_pop()获取数组最后一个元素错误写法:$last=array_pop(array_slice($array,-1));正确写法:$slice=array_slice($array,-1);$last=array_pop($slice);情况二:使用end()获取数组最后一个元素的值错误写法:$last=end(array_keys($array));正确写法:$keys=array_keys($array);$last=end($keys);情况三:在函数调用中,将一个函数的返回值作为引用参数传递例如,函数定义如下:functionfoo(&$param){...}调用时:foo(bar());//错误,bar()的返回值不是变量应该改为:$temp=bar();foo($temp);在您的具体情况中,错误出现在cls_template.php文件中。您需要定位到错误发生的行号,然后按照上述方法进行修改。如果您使用的是模板引擎,可能是在调用某些模板引擎的方法时出现了这个问题。请检查在传递参数时是否使用了直接的函数调用或表达式,而不是变量。例如,在Smarty模板引擎中,可能这样写:$smarty->assign('variable',$object->getMethod());//这通常不会出错,因为不是引用传递但如果是在其他模板引擎中,可能有不同的使用方式。由于您提到是cls_template.php,可能是自定义的模板类。请查找类似下面的代码:$this->assign('var',&$this->getVar());//错误示例,而且PHP5.3以后不推荐使用&作为调用时传递引用但实际上,在PHP5.3及以上版本中,调用时传递引用(在函数调用前加&)已经被废弃。所以您应该避免使用&。更可能的情况是,在某个函数内部,您对参数进行了引用传递的要求,而在调用该函数时传递了一个非变量。因此,解决步骤:1.打开cls_template.php文件,找到错误指定的行号。2.查看该行是否有函数调用,并且该函数的某个参数是引用传递(在函数定义中使用&)。3.确保在调用该函数时,该参数位置传递的是一个变量,而不是表达式或函数返回值。4.如果传递的是表达式,将其赋值给一个临时变量,然后传递该变量。另外,建议检查您的PHP版本,因为从PHP5.4开始,调用时传递引用已被移除,所以您可能还需要修改函数定义本身,去掉不必要的引用传递,或者调整调用方式。最后,如果您无法修改代码(比如是第三方代码),您可以选择降低错误报告级别(例如,将error_reporting设置为不显示严格标准错误),但这不是推荐的解决方案,因为它可能隐藏其他问题。示例:在index.php中设置error_reporting(E_ALL&~E_STRICT);但是,最好的方式是修复代码。下面我们生成相关问题以深入探讨。</think> ### 解决"Strict Standards: Only variables should be passed by reference"错误 此错误发生在将**非变量值**作为引用参数传递给PHP函数时。引用参数(`&$var`)要求必须是**具名变量**,不能是常量、表达式或函数返回值。以下是解决方案和常见场景: --- ### 错误重现示例 ```php // 错误示例:直接将函数结果作为引用传递 $last = end(array_keys($arr)); // 触发错误 ``` --- ### ✅ 解决方案 #### 方法1:创建临时变量(最常用) ```php $keys = array_keys($arr); // 先赋值给变量 $last = end($keys); // 传递变量引用 ``` #### 方法2:修改函数参数定义(需访问源码) ```php // 在 cls_template.php 中找到函数定义,移除引用符号 & function process($param) { ... } // 原 function process(&$param) ``` #### 方法3:处理特定函数 常见引发错误的函数及修复: | 函数 | 错误用法 | 正确用法 | |------|----------|----------| | `end()` | `end(array_slice($arr,-1))` | `$tmp=array_slice($arr,-1); end($tmp);` | | `array_pop()` | `array_pop(explode('.', $str))` | `$tmp=explode('.',$str); array_pop($tmp);` | | `next()` | `next($arr['nested'])` | `$tmp=$arr['nested']; next($tmp);` | --- ### 🔧 修复步骤 1. **定位错误行** 在错误消息中找到文件名和行号(如 `cls_template.php line 158`) 2. **检查引用传递** 在指定行找到类似结构: `function_name( non_variable_value )` 3. **插入临时变量** ```diff + $temp = some_function_call(); - function_name(some_function_call()); + function_name($temp); ``` --- ### 📌 常见触发场景 1. **直接传递函数结果** ```php reset(array_filter($data)); // 错误 ``` 2. **链式方法调用** ```php $obj->getData()->process(); // 当process()参数要求引用时 ``` 3. **数组元素直接传递** ```php modifyItem($arr[0]); // $arr[0]不被视为独立变量 ``` --- ### ⚙️ 相关配置 在 `php.ini` 中调整错误级别(临时方案): ```ini ; 关闭严格错误报告 error_reporting = E_ALL & ~E_STRICT ``` > 不推荐长期使用,可能掩盖其他问题 --- ### ❓ 相关问题 1. PHP引用传递(`&$var`)和值传递的区别是什么? 2. 如何避免PHP严格标准(Strict Standards)错误? 3. 除了引用传递错误,还有哪些常见的PHP严格标准警告? 4. 如何在框架(如Laravel/Symfony)中定位引用传递错误? [^1]: 引用示例展示代码替换逻辑,但PHP错误需关注参数传递机制差异
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值