【问题标题】:How to get an error when creating an array with duplicate keys?创建具有重复键的数组时如何出错?
【发布时间】:2018-02-15 07:24:52
【问题描述】:

读者,

我最近在调试中浪费了 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) 无法正常工作。

【问题讨论】:

  • 同一个键会自动覆盖。因此,您将永远不会在数组中至少两次获得相同的密钥。所以基本上$files = [ 'identifier1' => '/path/to/file1', 'identifier2' => '/path/to/file2', 'identifier3' => '/path/to/file3' ]; 无法在 php 中实现。现在你的问题是什么?
  • @WOUNDEDStevenJones 他展示了相同的键,所以它们被覆盖了。他不是在谈论价值观。
  • @AlivetoDie 你是对的。我本来建议还包括php.net/manual/en/function.array-keys.php 来检查密钥,但事实证明这无论如何都不起作用,因为count($files) 无论如何都会返回 1 而不是 3。

标签: php arrays hashmap syntax-error


【解决方案1】:

这在 PHP 中不被视为错误。它只是覆盖一个键/值对。

检查这一点的唯一方法是在定义它之后检查$filescount(),以验证它有多少你认为应该有的项目。然后,如果计数太低,您可以抛出 Exception 或记录错误。

【讨论】:

    【解决方案2】:

    如果您以预构建数组的形式提供源代码:

    $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 编写自己的嗅探器,以尝试在实际源代码中找到这些重复的键实例。请注意,这将需要在源代码上运行分析工具来检测问题。

    【讨论】:

      猜你喜欢
      • 2020-11-15
      • 1970-01-01
      • 1970-01-01
      • 2020-08-11
      • 2021-02-21
      • 2010-11-11
      • 1970-01-01
      • 2019-04-08
      • 2016-07-13
      相关资源
      最近更新 更多