0
foreach ($pElements as $pElement) { var_dump($pElement); } 

If I execute the above, I notice it dumps each value in the 'nodes' array even though $pElement is an object. Can anyone explain this behavior?

At first I thought running foreach on an object automatically searches for a member array, but the first listed array namespaces seems to be ignored.

Here is the full object $pElements:

/var/www/html/phpTestArea/index.php:35: object(Symfony\Component\DomCrawler\Crawler)[38] protected 'uri' => null private 'defaultNamespacePrefix' => string 'default' (length=7) private 'namespaces' => array (size=0) empty private 'baseHref' => null private 'document' => object(DOMDocument)[2] public 'doctype' => string '(object value omitted)' (length=22) public 'implementation' => string '(object value omitted)' (length=22) <public properties removed> private 'nodes' => array (size=2) 0 => object(DOMElement)[36] <public properties removed> 1 => object(DOMElement)[35] <public properties removed> private 'isHtml' => boolean true 
2
  • 3
    What does the first sentence mean exactly? What do you expect and what is the actual output exactly? Commented Apr 8, 2019 at 21:17
  • I'm new to PHP but I thought every object member would be iterated over. The actual output is the nodes array. Commented Apr 8, 2019 at 21:45

1 Answer 1

1

If you take a look at the source code of that class here, you can see that it implements two interfaces, defined as follow:

Countable: this define how the instances of the class should behave when passed to the native php count function. The counting depends on the implementation.

interface Countable { abstract public count(void): int } 

IteratorAggregate: this is the one that return an iterator (which extends Traversable) that defines how and what should be traversed.

interface IteratorAggregate extends Traversable { abstract public getIterator(void): Traversable } 

So if you look closely into the source code for these two functions, you will see how these are implemented:

/** * @return int */ public function count() { return \count($this->nodes); } /** * @return \ArrayIterator|\DOMElement[] */ public function getIterator() { return new \ArrayIterator($this->nodes); } 

So if you call count($pElements), the object's internal count function will be executed, therefore you would get the count of the nodes property.

In the same way, if you iterate with a foreach over $pElements, you are iterating over the nodes property, as this is the behaviour defined by getIterator().

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.