質問
問題:
ArrayObjectは、値が手動で設定または読み取られると予想どおりに機能しますが、機能を使用してそれを反復する場合、物事は邪悪になります。
私が定義したオフセット*メソッドを呼び出すのではなく、代わりにアレイテレーターメソッドを使用します。
コード:
クラス:
class obsecureArray extends ArrayObject {
public function offsetSet($name, $value) {
call_user_func_array(array('parent', __FUNCTION__), array(base64_encode($name), base64_encode($value)) );
}
public function offsetGet($name) {
return base64_decode( call_user_func_array(array('parent', __FUNCTION__), (array) base64_encode($name) ) );
}
public function offsetExists($name) {
return call_user_func_array(array('parent', __FUNCTION__), (array) base64_encode($name) );
}
public function offsetUnset($name) {
return call_user_func_array(array('parent', __FUNCTION__), (array) base64_encode($name) );
}
}
使用例:
$a = new obsecureArray();
$a['test'] = 'Value';
$a[2] = '1';
define('BR','<br />');
echo 'test: ',$a['test'],BR,'2: ',$a[2],BR;
foreach($a as $key => $value)
echo 'Key: ',$key,' Value:',$value,BR;
出力:
test: Value
2: 1
Key: dGVzdA== Value:VmFsdWU=
Key: Mg== Value:MQ==
解決
私はを調べます arrayObject __construct
方法 ドキュメンテーション そして、私の問題に関連する3番目の議論を見つけました:
iterator_class:
ArrayObjectオブジェクトの反復に使用されるクラスを指定します。 Arrayiteratorは、使用されるデフォルトのクラスです。
今、私は拡張することができました ArrayIterator
私自身で offset*
方法とそれを私のコンストラクターに渡します ArrayObject
, 、だから私は調べた ArrayIterator
そして、それはほとんど同じでした ArrayObject
明らかに外部イテレーターを使用していなかったことを除いて。だから私がしなければならなかったのは拡張することだけでした ArrayIterator
代わりは。そして、それを無効にしなければなりませんでした current
と key
メソッドも同様です。
私が持っていること:
class obsecureArray extends ArrayIterator {
public function offsetSet($name, $value) {
call_user_func_array(array('parent', __FUNCTION__), array(base64_encode($name), base64_encode($value)));
}
public function offsetGet($name) {
return base64_decode(call_user_func_array(array('parent', __FUNCTION__), (array) base64_encode($name)));
}
public function offsetExists($name) {
return call_user_func_array(array('parent', __FUNCTION__), (array) base64_encode($name));
}
public function offsetUnset($name) {
return call_user_func_array(array('parent', __FUNCTION__), (array) base64_encode($name));
}
public function key() {
return base64_decode(parent::key());
}
public function current() {
return base64_decode(parent::current());
}
}
そして、それは予想通りに完全に機能します。
と:
$a = new obsecureArray();
$a['test'] = 'Value';
$a[2] = '1';
define('BR','<br />');
echo 'test: ',$a['test'],BR,'2: ',$a[2],BR;
foreach($a as $key => $value)
echo 'Key: ',$key,' Value:',$value,BR;
手に入れた:
test: Value 2: 1 Key: test Value:Value Key: 2 Value:1
他のヒント
実装したいと思うでしょう イテレーター また IteratorAggregate. 。前者をより多く制御できますが、後者は実装がより簡単です(おそらくより多くのオーバーヘッドで):
class People implements IteratorAggregate {
protected $children;
// ...
public function getIterator() {
return new ArrayIterator( $this->children );
}
}
を参照してください イテレーター そのインターフェイスのボイラープレートメソッド用。
私の意見では、あなたのコードが予想どおりに機能します。あなたの値が適切に正しい方法を使用していることを確認する場合:
$a = new obsecureArray();
$a->offsetSet('test', 'Value');
$a->offsetSet(2, '1');
代わりに
define('BR','
');
事前定義されたPHPプロパティがあります PHP_EOL
カスタムイテレータークラスを設定する必要があります。
<?php
class SecureArray extends ArrayObject {
public function __construct($array = array()) {
parent::__construct($array);
$this->setIteratorClass('SecureIterator');
}
public function offsetSet($name, $value) {
parent::offsetSet( base64_encode($name), base64_encode($value) );
}
public function offsetGet($name) {
return base64_decode( parent::offsetGet( base64_encode($name) ) );
}
public function offsetExists($name) {
return parent::offsetExists( base64_encode($name) );
}
public function offsetUnset($name) {
return parent::offsetUnset( base64_encode($name) );
}
}
class SecureIterator extends ArrayIterator {
function current() {
return base64_decode(parent::current());
}
function key() {
return base64_decode(parent::key());
}
}