1

なぜ私がこれを求めているのかを理解するには、これとその下のコメントを読んでください。次のコードを検討してください。

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

今、私は(デモ)を行うことができます:

$b = new strKey($objArray);

echo $b['10']; // Thing
$b['10'] = 'Something else';

// because the classes works with a reference to the original array,
// this will give us a modified array:
var_dump($objArray); 

パズルの最後のピースは、キーが数値文字列である要素の設定を解除するにはどうすればよいかということです。ArrayIteratorkey()、などを使用してみnext()ましたが、うまくいきません。それらの設定を解除する方法が見つかりません。

コピーを作成して元の配列を置き換えるのではなく、元の配列でどのソリューションも機能するはずです。

4

2 に答える 2

3

array_splice()オフセット ( ) がわかっている場合は、 で削除を試みることができますforeach (...) { $offset++; ... }が、このような配列にデータを格納することは、実際には良い考えではありません。これらのオブジェクトを foreach で配列に変換する必要があります。

foreach ( $obj as $key => $value )
    $array[$key] = $value;
于 2012-10-11T19:34:09.793 に答える
0

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を打ち負かしました。わーい!

于 2012-10-11T20:58:46.343 に答える