1

これがデータイテレータの実装です

//Data Iterator 
    class DataIterator implements Iterator
    {
        public $data ;
        public function __construct(Data $obj)
        {
            $this->data = $obj;
        }
        public function rewind()
        {
            $this->properties = get_object_vars($this->data);                       
        }
        public function valid()
        {
            if (key($this->properties) === null )
            {
                return false;
            }   
            return true;
        }
        public function key()
        {
            return key($this->properties);
        }
        public function current()
        {
             return current($this->properties);
        }
        public function next()
        {
            next($this->properties);
        }

    }

これがデータクラスです

 /*Data Class*/
    class Data implements IteratorAggregate
    {
        public $name; 
        private $age;
        protected $address;
        public $country;
        public $state;

        public function __construct($name, $age, $address, $country = 'USA', $state = 'NH')
        {
            $this->name = $name;
            $this->age = $age;
            $this->address = $address;
            $this->country = $country;
            $this->state = $state;
        }
        function getIterator()
        {       
            return new DataIterator($this);
        }
    }

そしてここに呼び出し部分があります

$data = new Data('Joker', '27', 'California');

    foreach($data->getIterator() as $key => $value)
    {
        echo $key , ' ', $value, '<br>';
    }  

出力

name Joker
country USA
state NH

出力には、プライベートおよび保護されたプロパティ(年齢、住所)の出力が含まれていないことに注意してください。

それらも出力するようにIteratorに指示するにはどうすればよいですか?

4

3 に答える 3

1

public、private、protectedはアクセス修飾子です。これらは、クラス属性のアクセシビリティを制限するように設計されています。

  • パブリックとは、誰でもその属性にアクセスできることを意味します。したがって、誰かが必要に応じて、知らないうちに値を変更できます。
  • プライベートとは、属性がクラス内でのみアクセス可能であることを意味します。したがって、クラス外のこれらのプロパティをだれも「混乱」させることはできません。
  • ProtectedはPrivateと似ていますが、子クラス(そのクラスから継承するクラス)がアクセスできます。

あなたはプライベートで作成ageaddressているので、基本的に、これらの属性にアクセスすることは誰にも許可されていません。プライベート/保護された属性にアクセスする場合は、ゲッターとセッターを作成してこれらの関数を呼び出すか、属性をパブリックにする必要があります。

于 2013-02-14T13:04:33.653 に答える
1

これらのプロパティは外部からアクセスできないため(つまり、イテレータが出力するポイント)、イテレータに出力するように指示することはできませんget_object_vars($this->data)

これを行うには2つの方法があります。

  1. データオブジェクトに値をイテレータに渡させる。
  2. リフレクションAPIを使用して、それらを強制的に引き出します(冗長、遅い!)。

しかし、優先オプションとして#1を進める前に、少し立ち止まって自問してください。イテレータがデータオブジェクトの非公開メンバーを公開するのはなぜですか。

何かを作るということprivateは、「あなた方はこれについて本当に知る必要はありません。将来なくなるかもしれませんし、認識できないほど変わるかもしれません」という意味です。それが外の世界が気にかけているものであるなら、なぜそれはpublic(直接、または公のゲッターを通して公開されて)いないのですか?このイテレータの目的が何であるかを再考する必要があるかもしれません。

そうは言っても、これがあなたが#1をする方法です。

class DataIterator implements Iterator
{
    public $data;
    private $properties;
    public function __construct(Data $obj, array $propeties)
    {
        $this->data = $obj;
        $this->properties = $properties;
    }

    public function rewind()
    {
        // Arguably horrible trick to refresh the property map without
        // demanding that Data exposes a separate API just for this purpose
        $newIterator = $this->data->getIterator();
        $this->properties = $newIterator->properties;
    }
}

class Data implements IteratorAggregate
{
    function getIterator()
    {       
        return new DataIterator($this, get_object_vars($this));
    }
}
于 2013-02-14T13:17:15.490 に答える
0

get_class_varsを試してください

$this->properties = get_class_vars(get_class($this->data));

$ this->propertiesの代わりに=get_object_vars($ this-> data);

于 2013-02-14T12:48:31.993 に答える