Domanda
Problema:
ArrayObject funziona come previsto quando i valori sono impostati o leggere manualmente, ma quando si utilizza una funzione (foreach per esempio) per scorrere su di esso, le cose diventa malvagio.
E non chiamare l'offset metodi * che ho definito, ma invece utilizza i metodi ArrayIterator.
Codice:
La Classe:
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) );
}
}
Utilizzo Esempio:
$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;
Output:
test: Value
2: 1
Key: dGVzdA== Value:VmFsdWU=
Key: Mg== Value:MQ==
Soluzione
guardo al ArrayObject __construct
metodo documentazione e trovato il terzo argomento correlato al mio problema:
iterator_class:
specificare la classe che verrà utilizzata per l'iterazione di l'oggetto ArrayObject. ArrayIterator è la classe predefinita utilizzata.
Ora ho potuto esteso un ArrayIterator
con i miei metodi offset*
e passarlo al mio costruttore di ArrayObject
, così ho guardato in ArrayIterator
ed era quasi identica alla ArrayObject
tranne che non stava usando un iteratore esterna, ovviamente. Quindi tutto quello che dovevo fare era di estendere ArrayIterator
invece. e ha dovuto eseguire l'override del metodo di current
e key
pure.
In modo che ho:
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());
}
}
e funziona perfettamente come previsto.
e
$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;
ho ottenuto:
test: Value 2: 1 Key: test Value:Value Key: 2 Value:1
Altri suggerimenti
Ti consigliamo di implementare Iterator o IteratorAggregate . Hai più controllo sul primo, ma quest'ultimo è più semplice da implementare (probabilmente con più testa):
class People implements IteratorAggregate {
protected $children;
// ...
public function getIterator() {
return new ArrayIterator( $this->children );
}
}
Iterator per i metodi boilerplate per tale interfaccia.
A mio parere funziona come previsto il codice, se si vuole fare in modo che i valori gestite correttamente utilizzare metodi corretti:
$a = new obsecureArray();
$a->offsetSet('test', 'Value');
$a->offsetSet(2, '1');
anche al posto di
define('BR','
');
v'è predefinito proprietà PHP_EOL
php
Sarà necessario impostare una classe iteratore personalizzato:
<?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());
}
}