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;
}
}