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==

CodePad esempio.

È stato utile?

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

CodePad esempio

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());
    }
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top