I have done some searching on Stackoverflow already on this topic, however as far as I can tell, I am not treating an array as a string ?
The message I am getting is :
Array to string conversion in X on line 42
Line 42 of my code is the opening of a foreach
loop :
foreach ($collection as $element) {
Variable $collection
is a caching iterator that is based on database output:
$collection=new \CachingIterator(new \ArrayIterator($this->dbData));
If I print_r()
on $this->dbData
, I certainly get an array:
Array
(
[0] => Array
(
[c_id] => A
)
[1] => Array
(
[c_id] => B
)
So, in summary:
ArrayIterator()
expects an array
as argumentCachingIterator()
expects an Iterator
as argumentforeach()
can loop over an Iterator
TL;DR I am really not sure what I am treating as string here ?
EDIT TO ADD....
Even if I greatly simplify my code, I can still reproduce:
<?php
error_reporting (E_ALL | E_STRICT);
ini_set ('display_errors', 1);
$arrX=array(array("c_id"=>"A"),array("c_id"=>"B"));
$collection=new \CachingIterator(new \ArrayIterator($arrX));
foreach($collection as $element) {
echo $element["c_id"].PHP_EOL;
}
Notice: Array to string conversion in /Users/bp/tmp/test.php on line 6
A
Notice: Array to string conversion in /Users/bp/tmp/test.php on line 6
B
The short answer is, you're inadvertently asking the CachingIterator
to convert the sub-arrays to strings during iteration. To not do this, don't use the CachingIterator::CALL_TOSTRING
or CachingIterator::TOSTRING_USE_INNER
flags.
You can set no flags, by using 0
as the value for the $flags
parameter, or use a different flag: this can be done in the constructor, or after initialisation by using CachingIterator::setFlags()
.
For example:
$array = [["c_id" => "A"], ["c_id" => "B"]];
$collection = new CachingIterator(new ArrayIterator($array), 0);
foreach ($collection as $element) {
// no E_NOTICE messages, yay!
}
And a few words by way of explanation...
By default, the CachingIterator
class sets the CachingIterator::CALL_TOSTRING
flag as noted in the PHP manual page on CachingIterator
.
public __construct ( Iterator $iterator [, int $flags = self::CALL_TOSTRING ] )
When this flag (or the CachingIterator::TOSTRING_USE_INNER
flag) is set, and the CachingIterator::next()
method is called (i.e. during iteration) the current value (in this case each sub-array) or the inner iterator (in this case, the ArrayIterator
), respectively, is converted to a string and saved internally. This string value is what is returned from CachingIterator::__toString()
when one of those flags is used.
When using any of the other flags, the above is not done when calling CachingIterator::next()
.
You need CachingIterator::FULL_CACHE
per this PHP docs comment
<?php
$arrX = array(
array( "c_id" => "A" ),
array( "c_id" => "B" )
);
$collection = new \CachingIterator( new \ArrayIterator( $arrX ), CachingIterator::FULL_CACHE );
foreach( $collection as $element )
{
echo $element["c_id"].PHP_EOL;
}