如何在创建包含重复键的数组时出错?
问题描述:
我最近在调试中丢失了40分钟,因为同事在重复行和PHP时没有触发任何错误。
原线类似于
$files = [
'identifier1' => '/path/to/file1'
];
拟行重复
$files = [
'identifier1' => '/path/to/file1',
'identifier2' => '/path/to/file2',
'identifier3' => '/path/to/file3'
];
怎么行真的是
$files = [
'identifier1' => '/path/to/file1',
'identifier1' => '/path/to/file2',
'identifier1' => '/path/to/file3'
];
这是一样的
$files = [
'identifier1' => '/path/to/file3'
];
后
当你错误地尝试定义一个带有重复键的数组时,有没有办法让php触发一个错误(即使它只是一个警告)?
我们希望全局启用该选项,并且error_reporting(E_ALL)不会失败。
答
这不被认为是PHP中的错误。它只是覆盖键/值对。
检查此项的唯一方法是检查count()
的$files
,然后再对其进行定义,以验证它是否有您认为应该包含的项目。然后,您可以抛出一个Exception
或记录一个错误,如果计数太低。
答
如果您提供源作为预建阵列:
$list = [
'one' => 1,
'two' => 2,
'one' => 3,
];
然后,它根本不可能为检测与运行时检查重复键,因为好像是这个代码被编译:
$list = [
'two' => 2,
'one' => 3,
];
即重复键基本上你的代码运行之前就消失了,你写任何代码就永远不会看到的第一个条目。如果您将代码编写为单独的行:
$list['one'] = 1;
$list['two'] = 2;
$list['one'] = 3;
然后您有几个选项。您可以创建一个实现ArrayAccess
的类,然后编写offsetSet()
方法来检查写入新偏移量时是否已存在给定偏移量。无论数组在哪里,该类基本上都可以使用。
class UniqueArray implements ArrayAccess
{
protected $data = [];
public function offsetExists($key)
{
return array_key_exists($key, $this->data);
}
public function offsetGet($key)
{
return $this->data[$key];
}
public function offsetSet($key, $value)
{
if ($this->offsetExists($key)) {
throw new Exception("key '$key' already exists");
}
$this->data[$key] = $value;
}
public function offsetUnset($key)
{
unset($this->data[$key]);
}
}
$list = new UniqueArray();
$list['one'] = 1;
$list['one'] = 2; // throws an exception
我想这可能比它的价值更麻烦。
你唯一真正的选择是静态代码分析。您可能会为PHPCS编写自己的嗅探,尝试在实际的源代码中查找这些重复的密钥实例。请注意,这需要在源代码上运行分析工具来检测问题。
相同的键会自动覆盖。所以你至少不会在数组中获得相同的密钥两次。所以基本上'$ files ='identifier1'=>'/ path/to/file1', 'identifier2'=>'/ path/to/file2', 'identifier3'=>'/ path/to/file3 ' ];'不可能在php中实现。现在你的问题是什么? –
@WOUNDEDStevenJones他展示了相同的密钥,所以他们被覆盖。他不是在谈论价值。 –
@AlivetoDie你说得对。我会建议还包括http://php.net/manual/en/function.array-keys.php来检查密钥,但事实证明,无论如何,因为'计数($文件)'无论如何返回1而不是3。 – WOUNDEDStevenJones