具体的には、配列クラスを作成し、[]演算子をオーバーロードしたいと思います。
6 に答える
PHP5を使用している場合(そして使用する必要がある場合)は、SPLArrayObjectクラスを確認してください。ドキュメントはあまり良くありませんが、ArrayObjectを拡張すると、「偽の」配列が作成されると思います。
編集:これが私の簡単な例です。ただし、貴重なユースケースはありません。
class a extends ArrayObject {
public function offsetSet($i, $v) {
echo 'appending ' . $v;
parent::offsetSet($i, $v);
}
}
$a = new a;
$a[] = 1;
実際、最適なソリューションは、ArrayAccessインターフェイスの4つのメソッドを実装することです。http: //php.net/manual/en/class.arrayaccess.php
'foreach'のコンテキストでもオブジェクトを使用する場合は、'Iterator'インターフェイスを実装する必要があります: http ://www.php.net/manual/en/class.iterator.php
PHPのオーバーロードと演算子の概念(オーバーロードと配列演算子を参照)は、C++の概念とは異なります。+、-、[]などの演算子をオーバーロードすることはできないと思います。
可能な解決策
- SPL ArrayObjectを実装します(cbeerで説明されています)。
- Iteratorを実装します(
ArrayObject
遅すぎる場合)。 - PECLオペレーター拡張機能を使用します( Bensonが述べたように)。
PHP 5.0以降のシンプルでクリーンなソリューションの場合、ArrayAccess
インターフェースを実装し、関数offsetGet、offsetSet、offsetExists、offsetUnsetをオーバーライドする必要があります。これで、オブジェクトを配列のように使用できます。
例(PHP7 +の場合):
<?php
class A implements ArrayAccess {
private $data = [];
public function offsetGet($offset) {
return $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"
この言語の機能ではないようです。このバグを参照してください。ただし、ある種のオーバーロードを実行できるパッケージがあるようです。
簡単に言えば、いいえ。また、C ++スタイルのオーバーロードが必要だと思われる場合は、問題の解決策を再考する必要があるかもしれません。または、PHPを使用しないことを検討してください。
ジェイミー・ザウィンスキーを言い換えると、「あなたには問題があり、 『わかっている!演算子のオーバーロードを使用する!』と思う。」今、2つの問題があります。」