当我将空值视为这样的数组时,为啥 PHP 不会抱怨?
Posted
技术标签:
【中文标题】当我将空值视为这样的数组时,为啥 PHP 不会抱怨?【英文标题】:Why does PHP not complain when I treat a null value as an array like this?当我将空值视为这样的数组时,为什么 PHP 不会抱怨? 【发布时间】:2014-06-24 07:35:45 【问题描述】:在 php 中,我将 error_reporting
设置为报告包括通知在内的所有内容。
为什么以下内容不会引发任何通知、错误或其他任何内容?
$myarray = null;
$myvalue = $myarray['banana'];
故障排除步骤:
$myarray = array();
$myvalue = $myarray['banana'];
// throws a notice, as expected ✔
$myarray = (array)null;
$myvalue = $myarray['banana'];
// throws a notice, as expected ✔
$myarray = null;
$myvalue = $myarray['banana'];
// no notice or warning thrown, $myvalue is now NULL. ✘ Why?
这可能是 PHP 中的一个错误,或者我只是不了解它的工作原理。
【问题讨论】:
就数据类型而言,PHP 并不是真正最合乎逻辑的语言:me.veekun.com/blog/2012/04/09/php-a-fractal-of-bad-design 我同意@Blender 的观点:它通常会做最有意义的事情,尽其所能。这通常非常方便,不会因为小错误而打扰任何人。 哇 - 我已经使用 PHP 多年了,不知何故直到今天才被这种疯狂所困扰。快速测试表明,这种疯狂的设计决定在 PHP 7 中保持不变。:( 您甚至可以这样做:<?php null['banana'];
,这不是错误。我想这与使用包含空值的变量相同,但它看起来非常奇怪。和 Mark 一样,我在使用 PHP 几年后才遇到这种情况,我很惊讶。
【参考方案1】:
在以下三种类型中使用数组解除引用语法可能是有效的:
数组 字符串(访问给定位置的字符) 对象(实现 ArrayAccess 接口的对象)对于所有其他类型,PHP 只返回 未定义变量。
数组取消引用由FETCH_DIM_R opcode 处理,它使用zend_fetch_dimension_address_read() 来获取元素。
如您所见,NULL 有一种特殊情况,还有一种默认情况,它们都返回未定义变量。
【讨论】:
这是正确的答案,$myarray['banana']
的评估没有类型杂耍。【参考方案2】:
通常,当您尝试像使用另一种类型一样使用一种类型的值时,会引发错误或警告,或者发生“类型杂耍”。例如,如果您尝试用.
连接两个数字,它们都会被强制转换为字符串并连接起来。
但是,正如 the manual page about type juggling 中所解释的,当将非数组视为数组时,情况并非如此:
当前未定义自动转换为数组的行为。
实际上,正如您所观察到的,当通过取消引用非数组触发此“未定义行为”时发生的行为是 null
被返回。这不仅会影响空值 - 如果您尝试取消引用数字或资源,您还将获得 null
。
【讨论】:
谢谢 Narf,之前错过了 Type Juggling 页面的那部分。但是,如果遇到“未定义”的行为,您会认为发出警告或通知对他们来说是一个有用的设计选择。 嗯,我希望 PHP 也更严格一些,但是……这是一种独特的功能,我认为他们不会愿意随时弃用很快。 我不希望他们弃用任何东西,只需发出通知或警告,以便与您访问不存在的数组索引的其他时间保持一致,并警告开发人员注意潜在的错误。$myarray['banana']
的评估中没有类型杂耍(通过引用文档在此答案中正确公开)。 PHP 源代码就是证明。解释和链接由this answer提供。【参考方案3】:
从 2006 年开始有一个活跃的bug report。
在文档中,String 部分对此进行了通知。
【讨论】:
太好了。据我所知,当我写这篇文章时,它不在文档中(或者我可能因为它在字符串部分而错过了它),所以感谢添加/提交它的人。 对于 PHP 7.4,现在会抛出通知:wiki.php.net/rfc/notice-for-non-valid-array-container以上是关于当我将空值视为这样的数组时,为啥 PHP 不会抱怨?的主要内容,如果未能解决你的问题,请参考以下文章
当我将 print_r() 应用于 PHP 中的数组时,为啥会得到“资源 id #4”? [复制]
使用比较对 Kendo Grid JQuery 进行排序 - 排序时将空值放在最后