David
David

Reputation: 4007

PHP @ foreach warning

I have a PHP foreach from an array, the array is given to me by my DB provider via a soap web service so I cannot change the array I get. When there are no elements to return, I get an empty array, this results in

Warning: Invalid argument supplied for foreach()

the loop looks like

foreach (($point1['return']) as $val) 

Where can I put an @ to stop this warning, and if I cant, what I do I do to turn off php warnings.

Upvotes: 7

Views: 5897

Answers (8)

Alex Finger
Alex Finger

Reputation: 31

Paste this into your function file:

set_error_handler(function($errno, $errstr){
     if(stristr($errstr,'Invalid argument supplied for foreach()')){
        return true;
    }
        return false;
});

Upvotes: 0

kapa
kapa

Reputation: 78691

Hiding the warning is not the right way. You should check whether it exists and is an array.

if (is_array($point1['return'])) {
    foreach ($point1['return'] as $val)  {
         ...
    }
}

PHP is_array()

Actually, turning off warnings or using the @ operator is not the right way to go 99% of the time.

Solve the problem instead of hiding it.

Upvotes: 20

Maxim Krizhanovsky
Maxim Krizhanovsky

Reputation: 26699

You can also explicitly cast the argument to array:

foreach ((array) $point1['return'] as $val)  {

Note: this still will issue undefined index, if there is no 'return' key in $point1

Upvotes: 3

VolkerK
VolkerK

Reputation: 96159

foreach() can handle not only arrays but also objects by either using the the default "all visible properties" implementation or a custom implementation via the traversable/iterator interface.
And a "DB provider via a soap web service" is something where I'd keep an eye on the possibility of (suddenly) having an object/iterator instead of a plain array.
So, if you're going to test the existence and data type before passing the variable to foreach, you should consider not only testing for is_array() but also for instanceof Traversable.

<?php
class Foo implements Iterator {
    protected $v = 0;
    public function current() { return $this->v; }
    public function key() { return $this->v; }
    public function next() { ++$this->v; }
    public function rewind() { $this->v=0; }
    public function valid() { return 10>$this->v; }
}

//$a = array(1,2,3,4);
$a = new Foo;


if( is_array($a) || $a instanceof Traversable ) {
    foreach($a as $e) {
        echo $e, "\n";
    }
}

Upvotes: 7

Mob
Mob

Reputation: 11098

Check whether that is actually an array. with is_array(); !! There's no need to suppress the warning. As a matter of fact, It's not possible to suppress that invalid argument warning.

Upvotes: 1

Dave Child
Dave Child

Reputation: 7881

Better to let errors display but check that the input is an array first. So you could wrap the foreach in an if, like this:

if ((is_array($point1)) && (is_array($point1['return']))) {
    foreach (($point1['return']) as $val) 
    ...
}

Upvotes: 4

Vikk
Vikk

Reputation: 3363

Check first for an array:

if(is_array($point1['return']))
{
...
}

Upvotes: 3

Wesley van Opdorp
Wesley van Opdorp

Reputation: 14941

An empty array does not cause that error, the problem is that you are trying to iterate trough something that is not an array. You could add a check using is_array function.

Upvotes: 6

Related Questions