如何在创建包含重复键的数组时出错?

问题描述:

阅读器,如何在创建包含重复键的数组时出错?

我最近在调试中丢失了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)不会失败。

+0

相同的键会自动覆盖。所以你至少不会在数组中获得相同的密钥两次。所以基本上'$ files ='identifier1'=>'/ path/to/file1', 'identifier2'=>'/ path/to/file2', 'identifier3'=>'/ path/to/file3 ' ];'不可能在php中实现。现在你的问题是什么? –

+0

@WOUNDEDStevenJones他展示了相同的密钥,所以他们被覆盖。他不是在谈论价值。 –

+0

@AlivetoDie你说得对。我会建议还包括http://php.net/manual/en/function.array-keys.php来检查密钥,但事实证明,无论如何,因为'计数($文件)'无论如何返回1而不是3。 – WOUNDEDStevenJones

这不被认为是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编写自己的嗅探,尝试在实际的源代码中查找这些重复的密钥实例。请注意,这需要在源代码上运行分析工具来检测问题。