web-dev-qa-db-ja.com

PHPで演算子をオーバーロードすることは可能ですか?

具体的には、Arrayクラスを作成し、[]演算子をオーバーロードしたいと思います。

62
chadgh

PHP5を使用している(使用する必要がある)場合は、 SPL ArrayObject クラスをご覧ください。ドキュメントはあまり良いものではありませんが、ArrayObjectを拡張すると、「偽の」配列になると思います。

編集:ここに私の簡単な例を示します。私はしかし、貴重なユースケースを持っていないのではないか:

class a extends ArrayObject {
    public function offsetSet($i, $v) {
        echo 'appending ' . $v;
        parent::offsetSet($i, $v);
    }
}

$a = new a;
$a[] = 1;
53
cbeer

実際、最適な解決策は、ArrayAccessインターフェイスの4つのメソッドを実装することです。 http://php.net/manual/en/class.arrayaccess.php

「foreach」のコンテキストでオブジェクトを使用する場合は、「Iterator」インターフェイスを実装する必要があります。 http://www.php.net/manual/en/class.iterator .php

26
panicz

PHPのオーバーロードと演算子の概念( オーバーロード および 配列演算子 を参照)は、C++の概念とは異なります。 +、-、[]などの演算子をオーバーロードできるとは思わない.

可能な解決策

21
grammar31

PHP 5.0+のシンプルでクリーンなソリューションの場合、 ArrayAccess interface を実装し、関数offsetGet、offsetSet、offsetExists、offsetUnsetをオーバーライドする必要があります。これで、オブジェクトを配列のように使用できます。

例:

<?php
class A implements ArrayAccess {
    private $data = array();

    public function offsetGet($offset) {
        return isset($this->data[$offset]) ? $this->data[$offset] : null;
    }

    public function offsetSet($offset, $value) {
        if ($offset === null) {
            $this->data[] = $value;
        } else {
            $this->data[$offset] = $value;
        }
    }

    public function offsetExists($offset) {
        return isset($this->data[$offset]);
    }

    public function offsetUnset($offset) {
        unset($this->data[$offset]);
    }
}

$obj = new A;
$obj[] = 'a';
$obj['k'] = 'b';
echo $obj[0], $obj['k']; // print "ab"
8
Fabien Sa

これは言語の機能ではないようです。これを参照してください bug 。ただし、何らかのオーバーロードを行うことができる package があるようです。

2
Benson

簡単に言えば、いいえ。また、C++スタイルのオーバーロードが必要だと思われる場合は、問題の解決策を考え直す必要があるかもしれません。または、PHPを使用しないことを検討してください。

Jamie Zawinskiを言い換えると、「問題があり、「わかっています!演算子のオーバーロードを使用します!」今、2つの問題があります。」

0
dirtside