PHPはどのように相手を遍歴しますか?

5115 ワード

phpにとってforeachは非常に使いやすい文法であり、ほとんどのPHPerにとって日常的な接触が最も多い要求の一つである.では、オブジェクトはforeachで遍歴できますか?
答えは肯定的ですが、オブジェクトの遍歴は共通の属性しか得られないという条件があります.
//     
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

メソッドも保護されている変数もプライベート変数も遍歴できません.共通の属性だけが遍歴されます.実は、私たちが前に設計モードを話したときに話した反復器モードはオブジェクトの遍歴に特化しており、PHPはすでに関連するインタフェースを用意してくれており、このインタフェースを実現するだけで反復器モードの作成を完了することができます.具体的には、以前のデザインモデルシリーズの記事:PHP設計モードの反復器モードを参照してください.
//        
class B implements Iterator
{
    private $var = [];

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

    public function rewind()
    {
        echo "rewinding
"; reset($this->var); } public function current() { $var = current($this->var); echo "current: $var
"; return $var; } public function key() { $var = key($this->var); echo "key: $var
"; return $var; } public function next() { $var = next($this->var); echo "next: $var
"; return $var; } public function valid() { $var = $this->current() !== false; echo "valid: {$var}
"; 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:

もし今日の文章が前に話した反復器のモードだけを話していたら、それはつまらないので、もっと面白い応用を勉強しなければなりません.それは,オブジェクトを配列のように操作できるようにすることである.これもPHPを使ってすでに用意されているインタフェースです.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: 

このインタフェースには4つの方法が必要です.
  • offsetSet($offset,$value)オフセット量設定値
  • offsetExists($offset)は、オフセット量に基づいてコンテンツ
  • が存在するか否かを決定する.
  • offsetUnset($offset)は、オフセット量に応じてコンテンツ
  • を削除する.
  • offsetGet($offset)は、希薄量からコンテンツ
  • を取得する.
    ここのオフセット量は私たちがよく言う下付きです.この4つの方法を実装することで,配列を操作するようなオブジェクトを操作することができる.もちろん,日常開発では反復器を含むこれらのオブジェクトを遍歴する能力をあまり使わないかもしれない.通常、オブジェクトを配列(array)objに直接変換して次の操作を行います.ただし、javaでは、特にJavaBeanではクラスの内部にリストが自分のオブジェクトとして自分の集合状態を表すことがよくあります.比較することにより,PHPもこのような能力を完全に実現でき,反復器とArrayAccessインタフェースを用いて同様の能力をより容易に実現できることが分かった.これはとても役に立つ知識の拡張で、次のプロジェクトでこれらの能力を運用できるかもしれません.
    テストコード: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.php
    参照ドキュメント:
    https://www.php.net/manual/zh/language.oop5.iterations.php
    各メディアプラットフォームで検索可能【ハードコアプロジェクトマネージャ】