23

配列のように動作し、取得と設定に通常の配列構文を使用する PHP クラスを作成できるようにしたいと考えています。

例 (Foo は私が作成した PHP クラスです):

$foo = new Foo();

$foo['fooKey'] = 'foo value';

echo $foo['fooKey'];

PHP には _get および _set マジック メソッドがあることは知っていますが、それらでは配列表記を使用して項目にアクセスできません。Python は __getitem__ と __setitem__ をオーバーロードすることでこれを処理します。

PHPでこれを行う方法はありますか?違いがある場合は、PHP 5.2 を実行しています。

4

2 に答える 2

35

拡張ArrayObjectまたは実装するArrayAccessと、必要なことを行うことができます。

于 2008-09-15T17:54:56.060 に答える
3

いいえ、キャストすると通常の PHP 配列が生成されるだけです。ArrayObject から派生したクラスが持っていた機能がすべて失われます。これをチェックしてください:

class CaseInsensitiveArray extends ArrayObject {
    public function __construct($input = array(), $flags = 0, $iterator_class =     'ArrayIterator') {
        if (isset($input) && is_array($input)) {
            $tmpargs = func_get_args();
            $tmpargs[0] = array_change_key_case($tmpargs[0], CASE_LOWER);
            return call_user_func_array(array('parent', __FUNCTION__), $tmp    args);
        }
        return call_user_func_array(array('parent', __FUNCTION__), func_get_args());
    }

    public function offsetExists($index) {
        if (is_string($index)) return parent::offsetExists(strtolower($index));
        return parent::offsetExists($index);
    }

    public function offsetGet($index) {
        if (is_string($index)) return parent::offsetGet(strtolower($index));
        return parent::offsetGet($index);
    }

    public function offsetSet($index, $value) {
        if (is_string($index)) return parent::offsetSet(strtolower($index, $value));
        return parent::offsetSet($index, $value);
    }

    public function offsetUnset($index) {
        if (is_string($index)) return parent::offsetUnset(strtolower($index));
        return parent::offsetUnset($index);
    }
}

$blah = new CaseInsensitiveArray(array(
    'A'=>'hello',
    'bcD'=>'goodbye',
    'efg'=>'Aloha',
));

echo "is array: ".is_array($blah)."\n";

print_r($blah);
print_r(array_keys($blah));

echo $blah['a']."\n";
echo $blah['BCD']."\n";
echo $blah['eFg']."\n";
echo $blah['A']."\n";

予想どおり、array_keys() 呼び出しは失敗します。さらに、is_array($blah) は false を返します。ただし、コンストラクタ行を次のように変更すると:

$blah = (array)new CaseInsensitiveArray(array(

次に、通常の PHP 配列を取得するだけです (is_array($blah) は true を返し、array_keys($blah) は機能します) が、ArrayObject 派生サブクラスのすべての機能が失われます (この場合、大文字と小文字を区別しないキーはもはや仕事)。上記のコードを両方の方法で実行してみてください。私の言いたいことがわかるでしょう。

PHP は、キーの大文字と小文字が区別されないネイティブ配列を提供するか、サブクラスが実装する機能を失うことなく ArrayObject を配列にキャストできるようにするか、すべての配列関数が ArrayObject インスタンスを受け入れるようにする必要があります。

于 2011-05-13T01:17:06.350 に答える