Detaillierte Erklärung, wie PHP Objekte durchquert

藏色散人
Freigeben: 2023-04-09 18:14:01
nach vorne
3621 Leute haben es durchsucht

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
Nach dem Login kopieren

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:
Nach dem Login kopieren

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 List 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
Nach dem Login kopieren

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!

Verwandte Etiketten:
php
Quelle:segmentfault.com
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage