3

アプリケーション構成を保存するために ArrayObject クラスを実装する方法を探していましたが、この実装を php マニュアル (コメントの 1 つ) で見つけました。

<?php
 use \ArrayObject;


/**
 *  Singleton With Configuration Info
 */
class Config extends ArrayObject
{
    /**
     *
     * Overwrites the ArrayObject Constructor for
     * Iteration throught the "Array". When the item
     * is an array, it creates another static() instead of an array
     */
    public function __construct(Array $array)
    {
        $this->setFlags(ArrayObject::ARRAY_AS_PROPS);
        foreach($array as $key => $value)
        {
            if(is_array($value))
            {
                $value = new static($value);
            }
            $this->offsetSet($key, $value);
        }
    }

    public function __get($key)
    {
        return $this->offsetGet($key);
    }

    public function __set($key, $value)
    {
        $this->offsetSet($key, $value);
    }
    /**
     * Returns Array when printed (like "echo array();")
     * Instead of an Error
     */
    public function __ToString()
    {
        return 'Array';
    }
}

使用法:

$config = new Config\Config($settings);
$config->uri = 'localhost'; // works
$config->url->uri = 'localhost'; // doesn't work
print_r($config);

このクラスに __get と __set を追加しようとしましたが、単純な配列では問題なく機能しますが、多次元配列に関しては... 事情が異なります。インデックスが定義されていないというエラーが表示されます。誰かが私を助けてくれませんか.

このクラスの問題を解決しました。後で、完全に機能する例をここに投稿します。おそらく誰かがそれを必要とするでしょう。時間を割いてこのスレッドを読んでくれてありがとう

更新:では、皆さんはどう思いますか?どのような改善...変更を加える必要がありますか?

    public function __construct(Array $properties)
    {
        $this->populateArray($properties);
    }

    private function populateArray(Array $array)
    {
        if(is_array($array))
        {
            foreach($array as $key => $value)
            {
                $this->createProperty($key, $value);
            }
        }
        unset($this->properties);
    }

    private function createProperty($key, $value)
    {
        is_array($value) ? 
            $this->offsetSet($key, $this->createComplexProperty($value))
            : $this->offsetSet($key, $value);
    }

    private function createComplexProperty(Array $array)
    {
        return new Config($array);
    }

    private function createPropertyIfNone($key)
    {
        if($this->offsetExists($key))
            return;

        $this->createProperty($name, array()); 
    }

    public function __get($key)
    {
        $this->createPropertyIfNone($key);
        return $this->offsetGet($key);
    }

    public function __set($key, $value)
    {
        $this->createProperty($key, $value);
    }

    public function __ToString()
    {
        return (string) $value;
    }
}
4

1 に答える 1

2

存在しないキーが配列であると想定したい場合は、これでうまくいくはずです。

public function __get($key)
{
    if(!$this->offsetExists($key))
    {
         $this->offsetSet($key,new Array());
    }
    return &$this->offsetGet($key);
}

使用法:

$config = new Config\Config($settings);
$config->url['uri'] = 'localhost';
print_r($config);

編集:

これが機能するために参照を返す必要があるかどうかはわかりません。

    return &$this->offsetGet($key);

またはこれ

    return $this->offsetGet($key);
于 2013-06-05T16:04:27.683 に答える