Php 使用数字字符串键篡改数组

Php 使用数字字符串键篡改数组,php,arrays,Php,Arrays,要理解我为什么问这个问题,请阅读下面的评论。考虑下面的代码: $obj = new stdClass; $obj->{10} = 'Thing'; $objArray = (array) $obj; var_dump($objArray); 产生: array(1) { ["10"]=> string(5) "Thing" } 现在,我无法通过$objArray['10']访问它,因为PHP将数字字符串键转换为整数键。在将数组强制转换为对象时,手册明确声明“整数属性不可

要理解我为什么问这个问题,请阅读下面的评论。考虑下面的代码:

$obj = new stdClass;
$obj->{10} = 'Thing';

$objArray = (array) $obj;
var_dump($objArray);
产生:

array(1) {
  ["10"]=>
  string(5) "Thing"
}
现在,我无法通过
$objArray['10']
访问它,因为PHP将数字字符串键转换为整数键。在将数组强制转换为对象时,手册明确声明“整数属性不可访问”。还是他们

为了证明文档是错误的,我创建了一个类:

class strKey implements ArrayAccess
{
    private $arr;
    public function __construct(&$array)
    {
        $this->arr = &$array;
    }

    public function offsetExists($offset)
    {
        foreach ($this->arr as $key => $value)
        {
            if ($key == $offset)
            {
                return true;
            }
        }
        return false;
    }

    public function offsetGet($offset)
    {
        foreach ($this->arr as $key => $value)
        {
            if ($key == $offset)
            {
                return $value;
            }
        }
        return null;
    }

    public function offsetSet($offset, $value)
    {
        foreach($this->arr as $key => &$thevalue)
        {
            if ($key == $offset)
            {
                $thevalue = $value;
                return;
            }
        }

        // if $offset is *not* present...
        if ($offset === null)
        {
            $this->arr[] = $value;
        }
        else
        {
            // this won't work with string keys
            $this->arr[$offset] = $value;
        }
    }

    // can't implement this
    public function offsetUnset($offset)
    {
        foreach ($this->arr as $key => &$value)
        {
            if ($key == $offset)
            {
                //$value = null;
            }
        }
    }
}
现在,我可以做:

最后一个难题是,如何取消设置键为数字字符串的元素?我尝试使用
ArrayIterator
key()
next()
,等等,但它不起作用。我找不到办法解开那些


任何解决方案都应该使用原始数组,而不是创建副本并替换原始数组。

如果您知道它的偏移量(
foreach(…){$offset++;…}
),可以尝试使用
array_splice()
将其删除,但将数据存储在这样的数组中确实不是一个好主意。应使用foreach将这些对象转换为数组:

foreach ( $obj as $key => $value )
    $array[$key] = $value;

按照pozs的建议,下面是结果
offsetUnset()
。我还添加了一个新的
offsetSet()
,它支持添加数字键

public function offsetUnset($offset)
{
    $off = 0;

    foreach ($this->arr as $key => $value)
    {
        if ($key === $offset)
        {
            array_splice($this->arr, $off, 1);
            return;
        }
        $off++;
    }       
}

public function offsetSet($offset, $value)
{
    foreach($this->arr as $key => &$thevalue)
    {
        if ($key === $offset)
        {
            $thevalue = $value;
            return;
        }
    }

    // if $offset is *not* present...
    if ($offset === null)
    {
        $this->arr[] = $value;
    }
    // it's a numeric string key, now we have to hack it
    else if (strval(intval($offset)) === $offset)
    {
        // create new array via loophole:
        $tempObj = new stdClass;
        $tempObj->{$offset} = $value;

        // append to old array (+= doesn't create copies)
        $this->arr += (array) $tempObj;
        unset($tempObj);
    }
    // we are dealing with a normal key
    else
    {
        $this->arr[$offset] = $value;
    }
}
我正式击败了PHP。耶

public function offsetUnset($offset)
{
    $off = 0;

    foreach ($this->arr as $key => $value)
    {
        if ($key === $offset)
        {
            array_splice($this->arr, $off, 1);
            return;
        }
        $off++;
    }       
}

public function offsetSet($offset, $value)
{
    foreach($this->arr as $key => &$thevalue)
    {
        if ($key === $offset)
        {
            $thevalue = $value;
            return;
        }
    }

    // if $offset is *not* present...
    if ($offset === null)
    {
        $this->arr[] = $value;
    }
    // it's a numeric string key, now we have to hack it
    else if (strval(intval($offset)) === $offset)
    {
        // create new array via loophole:
        $tempObj = new stdClass;
        $tempObj->{$offset} = $value;

        // append to old array (+= doesn't create copies)
        $this->arr += (array) $tempObj;
        unset($tempObj);
    }
    // we are dealing with a normal key
    else
    {
        $this->arr[$offset] = $value;
    }
}