ホームページ  >  記事  >  バックエンド開発  >  PHP がオブジェクトを走査する方法の詳細な説明

PHP がオブジェクトを走査する方法の詳細な説明

藏色散人
藏色散人転載
2021-02-07 11:54:393552ブラウズ

PHP にとって、foreach は非常に便利で使いやすい構文であり、ほぼすべての PHPer にとって、日常生活で最も一般的なリクエストの 1 つです。では、オブジェクトは 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

それがメソッドであっても、保護された変数やプライベート変数であっても、トラバースすることはできません。パブリック属性のみをトラバースできます。実際、デザイン パターンについて前に説明した Iterator パターン は、オブジェクト トラバーサルに特に使用されており、PHP は関連するインターフェイスを用意しています。このインターフェイスを実装するだけで済みます。イテレータパターンを完成させることができます。特定の内容については、デザイン パターンに関する以前の一連の記事を参照してください: PHP デザイン パターン イテレータ パターン (推奨: 「PHP ビデオ チュートリアル 」)

// 实现迭代器接口
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:

今日の記事で説明する内容だけであれば、以前にも言いましたが、イテレータ パターンは退屈すぎるので、もっと興味深いアプリケーションを学ばなければなりません。それは、オブジェクトを配列のように操作できるようにすることです。これは実際には、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 つのメソッドを実装することで、オブジェクトを配列のように操作することができます。もちろん、日常の開発では、イテレータを含むこれらのオブジェクトを走査する機能を頻繁に使用するわけではありません。通常、次のステップのためにオブジェクトを配列 (配列) obj に直接変換します。ただし、Java、特に JavaBean では、クラス内に独自のコレクション状態を表す独自のオブジェクトとして List が存在することがよくあります。比較を通じて、PHP でもそのような機能を実現でき、同様の機能を実現するにはイテレータと ArrayAccess インターフェイスを使用する方が便利であることがわかりました。これは非常に役立つ知識の拡張です。次のプロジェクトでこれらの能力を活用できるかもしれません。

えええええ

以上がPHP がオブジェクトを走査する方法の詳細な説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はsegmentfault.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。