Heim  >  Artikel  >  Backend-Entwicklung  >  Detaillierte Erklärung, wie PHP Objekte durchquert

Detaillierte Erklärung, wie PHP Objekte durchquert

藏色散人
藏色散人nach vorne
2021-02-07 11:54:393624Durchsuche

Für PHP ist foreach eine sehr praktische und benutzerfreundliche Syntax. Für fast jeden PHPer ist es eine der häufigsten Anfragen im täglichen Leben. Kann das Objekt also durch foreach durchlaufen werden?

Die Antwort lautet „Ja“, aber es gibt eine Bedingung: Durch das Durchlaufen eines Objekts können nur seine öffentlichen Eigenschaften abgerufen werden.

// 普通遍历
class A
{
    public $a1 = '1';
    public $a2 = '2';
    public $a3 = '3';

    private $a4 = '4';
    protected $a5 = '5';

    public $a6 = '6';

    public function test()
    {
        echo 'test';
    }
}
$a = new A();
foreach ($a as $k => $v) {
    echo $k, '===', $v, PHP_EOL;
}

// a1===1
// a2===2
// a3===3
// a6===6

Egal ob es sich um eine Methode oder eine geschützte oder private Variable handelt, sie kann nicht durchlaufen werden. Es können nur öffentliche Attribute durchlaufen werden. Tatsächlich wird das „Iterator-Muster“, über das wir zuvor gesprochen haben, speziell für die Objektdurchquerung verwendet, und PHP hat die relevanten Schnittstellen für uns vorbereitet. Wir müssen diese Schnittstelle nur implementieren, um den Iterator zu vervollständigen. Das Muster wird erstellt . Spezifische Inhalte finden Sie in der vorherigen Artikelreihe zu Designmustern: PHP Design Patterns Iterator Pattern (empfohlen: „PHP Video Tutorial“)

// 实现迭代器接口
class B implements Iterator
{
    private $var = [];

    public function __construct($array)
    {
        if (is_array($array)) {
            $this->var = $array;
        }
    }

    public function rewind()
    {
        echo "rewinding\n";
        reset($this->var);
    }

    public function current()
    {
        $var = current($this->var);
        echo "current: $var\n";
        return $var;
    }

    public function key()
    {
        $var = key($this->var);
        echo "key: $var\n";
        return $var;
    }

    public function next()
    {
        $var = next($this->var);
        echo "next: $var\n";
        return $var;
    }

    public function valid()
    {
        $var = $this->current() !== false;
        echo "valid: {$var}\n";
        return $var;
    }
}

$b = new B([1, 2, 3, 4]);

foreach ($b as $k => $v) {
    echo $k, '===', $v, PHP_EOL;
}

// rewinding
// current: 1
// valid: 1
// current: 1
// key: 0
// 0===1
// next: 2
// current: 2
// valid: 1
// current: 2
// key: 1
// 1===2
// next: 3
// current: 3
// valid: 1
// current: 3
// key: 2
// 2===3
// next: 4
// current: 4
// valid: 1
// current: 4
// key: 3
// 3===4
// next:
// current:
// valid:
Wenn der heutige Artikel nur über das zuvor erwähnte Iteratormuster spricht, dann wäre es so Zu viel. Es ist langweilig, also müssen wir eine interessantere Anwendung lernen. Dadurch können Objekte wie Arrays manipuliert werden. Dabei wird tatsächlich eine Schnittstelle verwendet, die PHP bereits für uns vorbereitet hat: ArrayAccess.

// 让类可以像数组一样操作
class C implements ArrayAccess, IteratorAggregate
{
    private $container = [];
    public function __construct()
    {
        $this->container = [
            "one" => 1,
            "two" => 2,
            "three" => 3,
        ];
    }
    public function offsetSet($offset, $value)
    {
        if (is_null($offset)) {
            $this->container[] = $value;
        } else {
            $this->container[$offset] = $value;
        }
    }
    public function offsetExists($offset)
    {
        return isset($this->container[$offset]);
    }
    public function offsetUnset($offset)
    {
        unset($this->container[$offset]);
    }
    public function offsetGet($offset)
    {
        return isset($this->container[$offset]) ? $this->container[$offset] : null;
    }

    public function getIterator() {
        return new B($this->container);
    }
}

$c = new C();
var_dump($c);

$c['four'] = 4;
var_dump($c);

$c[] = 5;
$c[] = 6;
var_dump($c);

foreach($c as $k=>$v){
    echo $k, '===', $v, PHP_EOL;
}

// rewinding
// current: 1
// valid: 1
// current: 1
// key: one
// one===1
// next: 2
// current: 2
// valid: 1
// current: 2
// key: two
// two===2
// next: 3
// current: 3
// valid: 1
// current: 3
// key: three
// three===3
// next: 4
// current: 4
// valid: 1
// current: 4
// key: four
// four===4
// next: 5
// current: 5
// valid: 1
// current: 5
// key: 0
// 0===5
// next: 6
// current: 6
// valid: 1
// current: 6
// key: 1
// 1===6
// next: 
// current: 
// valid:

Diese Schnittstelle erfordert die Implementierung von vier Methoden:

offsetSet($offset, $value), legt den Wert basierend auf dem Offset fest
  • offsetExists($offset) und bestimmt, ob Inhalt basierend auf dem Offset vorhanden ist
  • offsetUnset(( $offset), lösche den Inhalt basierend auf dem Offset
  • offsetGet($offset), erhalte den Inhalt basierend auf dem Offset
  • Der Offset wird hier oft als Index bezeichnet. Durch die Implementierung dieser vier Methoden können wir Objekte wie Arrays bedienen. Natürlich nutzen wir in der täglichen Entwicklung die Möglichkeit, diese Objekte, einschließlich Iteratoren, zu durchlaufen, möglicherweise nicht sehr oft. Normalerweise konvertieren wir das Objekt im nächsten Schritt direkt in ein Array (Array) obj. In Java, insbesondere in JavaBean, gibt es jedoch häufig eine List8742468051c85b06f0a0af9e3e506b5c innerhalb der Klasse als eigenes Objekt, um ihren eigenen Sammlungsstatus darzustellen. Durch einen Vergleich haben wir herausgefunden, dass PHP solche Funktionen vollständig implementieren kann und es bequemer ist, Iteratoren und die ArrayAccess-Schnittstelle zu verwenden, um ähnliche Funktionen zu erreichen. Dies ist eine sehr nützliche Wissenserweiterung. Vielleicht können Sie diese Fähigkeiten in Ihrem nächsten Projekt nutzen!
测试代码:
https://github.com/zhangyue0503/dev-blog/blob/master/php/201912/source/PHP%E6%80%8E%E4%B9%88%E9%81%8D%E5%8E%86%E5%AF%B9%E8%B1%A1%EF%BC%9F.ph

Das obige ist der detaillierte Inhalt vonDetaillierte Erklärung, wie PHP Objekte durchquert. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:segmentfault.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen