Invalid argument supplied to foreach using php - php

$numofOfficer = sizeof($_POST['officer']); // = 2
for ($cntr = 0; 0 < $numOfficer; $cntr++)
{
foreach ($_POST['officer'][$cntr] as $index => $value)
{
// DO SOMETHING HERE...
}
}
Please help. I don't how to fix this warning.
The argument of foreach is an array having 2 length and 2 dimension. BUT, the other codes same with this went well, same length and length dimension of array argument. I just cant figure what is difference of the code above to the other.

There is no need to use for and foreach doing the same. You can omit the for and reduce you code to:
if (is_array($_POST['officer']))
{
foreach ($_POST['officer'] as $officer)
{
foreach ($officer as $index => $value)
{
// DO SOMETHING HERE...
}
}
}

Related

Use one foreach loop instead of two

I have one array
$array = array(0=>array('id'=>1 ,'va'=>2),1=>array('id'=>3,'va'=>4));
With the help of two foreach() loop i can use it.
foreach($array as $temp)
{
foreach($temp as $key=>$val)
{
echo $key.'=>'.$val;
}
}
As array has more than 5 lacs record. this solution is not feasible for me.
Keys are dynamic so i can not put keys as static inside first for each loop.
I tried following code but till now did not get any solution.
function myfunction($value,$key)
{
foreach($value as $k=>$a)
{
echo $k.'=>'.$a;
}
}
$array = array(0=>array('id'=>1,'va'=>2),1=>array('id'=>2,'va'=>2));
array_walk($array,"myfunction");
And this one also
$keys = Array_keys($array['0']);
for($i=0;$<=count($array);$i++)
{
for($j=0;$j<count($keys);$j++)
{
echo $keys[$j].'=>'.$array[$i][$keys];
}
}
I want to make this code as optmize as possible.

Finding a string by looping through an array php

I have this array $filelist
Array ( [0] => . [1] => .. [2] => .DS_Store [3] => 11-96.eml [4] => 11-97.eml )
Which is a list of all files in a particular directory... Sometimes there is no .DS_Store file, sometimes there is, sometimes there are 2 eml files, sometimes there are as many as 6. I'm trying to loop through and find the first array position a .eml file exists so that I can work out how many file are eml and where to start referencing the array.. I have tried...
function firstFileInList($filelist) {
$x = 0;
foreach ($filelist as $value) {
if(strpos($filelist, ".eml") == false) {
$x = $x + 1;
//break;
}
}
return $x;
}
This returns 5, if I include the break it returns 1 and I was expecting to get 4.
Please could somebody point me in the right direction or even if there is a completely better way to do this then I would be more than grateful to see that...
Thanks Paul,
break exists every PHP loop directly when it is called, even if there are other elements. Use continue to get to the next element.
Based on your question
I'm trying to loop through and find the first array position a .eml file exists
function firstFileInList($filelist) {
foreach($filelist as $k => $v)
if(strpos($v, ".eml") !== false)
return $k;
return false;
}
The best way to grab a key from an array in a foreach is to define the key before it starts. Try updating your code with this:
function firstFileInList($filelist) {
$x = false;
foreach ($filelist as $key => $value) {
if(strpos($value, ".eml") == false) {
$x = $key;
break;
}
}
return $x;
}
What this does is set $x to the actual key instead of a number that you increment like you would in a for() loop. $key will always be the array key, so in this example 0, 1, 2, 3, 4.
function firstFileInList($filelist) {
$key=false;
foreach ($filelist as $key=>$value) {
if(strpos($value, ".eml") !==false){
break;
}
}
return $key;
}
In case there is no match you get false.
The problem lies here:
foreach ($filelist as $value) {
if(strpos($filelist, ".eml") == false) {
Note that, for the foreach loop as you have written, it takes each element of the $filelist array, and puts it into the $value variable. Maybe you don't have warnings turned on in PHP, but when I tried your code, I got the following:
Warning: strpos() expects parameter 1 to be string, array given in test/a.php on line 6
What you want is
foreach ($filelist as $value) {
if(strpos($value, ".eml") == false) {
$x = $x + 1;
}
}
Note $value in the second line.

PHP Array structure

I am trying to generate an MS Excel spread sheet using PHPExcel 1.7.6 . I am having trouble determining the structure of the array expected.
The code that builds up the columns and rows is as follows:
function _headers() {
$i=0;
foreach ($this->data[0] as $field => $value) {
if (!in_array($field,$this->blacklist)) {
$columnName = Inflector::humanize($field);
$this->sheet->setCellValueByColumnAndRow($i++, 4, $columnName);
}
}
$this->sheet->getStyle('A4')->getFont()->setBold(true);
$this->sheet->getStyle('A4')->getFill()->setFillType(PHPExcel_Style_Fill::FILL_SOLID);
$this->sheet->getStyle('A4')->getFill()->getStartColor()->setRGB('969696');
$this->sheet->duplicateStyle( $this->sheet->getStyle('A4'), 'B4:'.$this->sheet->getHighestColumn().'4');
for ($j=1; $j<$i; $j++) {
$this->sheet->getColumnDimension(PHPExcel_Cell::stringFromColumnIndex($j))->setAutoSize(true);
}
}
function _rows() {
$i=5;
foreach ($this->data as $row) {
$j=0;
foreach ($row as $field => $value) {
if(!in_array($field,$this->blacklist)) {
$this->sheet->setCellValueByColumnAndRow($j++,$i, $value);
}
}
$i++;
}
}
I'm currently getting an 'Invalid argument supplied for foreach()' error.
I would appreciate it if somebody can outline the correct array structure required.
As IsisCode said, it sounds like you're looking in the wrong direction by associating the problem with PHPExcel. That error is generally just saying that the first argument supplied to foreach() isn't an array.
I don't see anything indicating that the problem is explicitly with the initial foreach in the _headers() method though. If there's a non array element in $this->data then your _rows() method could produce the error as well.
Given:
$this->data = Array(
Array('foo' => 'bar'),
'baz'
)
That would cause the second foreach in _rows() to fail, as an example. Your error message should be able to point you to which foreach() is failing, but ultimately it sounds like you've got a non-array element in $this->data where you don't expect it. If that can't be helped, then consider verifying you're dealing with an array before calling foreach:
function _rows() {
$i=5;
foreach ($this->data as $row) {
$j=0;
if(!is_array($row)) { continue; } // Ignore non-array elements
foreach ($row as $field => $value) {
if(!in_array($field,$this->blacklist)) {
$this->sheet->setCellValueByColumnAndRow($j++,$i, $value);
}
}
$i++;
}
Verifying the type of a variable before handing it to a type-specific function is never a bad idea and can save a lot of headache in general.

iterate through array, number of keys is variable, the first value being processed differently

Hi I have a PHP array with a variable number of keys (keys are 0,1,2,3,4.. etc)
I want to process the first value differently, and then the rest of the values the same.
What's the best way to do this?
$first = array_shift($array);
// do something with $first
foreach ($array as $key => $value) {
// do something with $key and $value
}
I would do this:
$firstDone = FALSE;
foreach ($array as $value) {
if (!$firstDone) {
// Process first value here
$firstDone = TRUE;
} else {
// Process other values here
}
}
...but whether that is the best way is debatable. I would use foreach over any other method, because then it does not matter what the keys are.
Here is one way:
$first = true;
foreach($array as $key => $value) {
if ($first) {
// something different
$first = false;
}
else {
// regular logic
}
}
$i = 0;
foreach($ur_array as $key => $val) {
if($i == 0) {
//first index
}
else {
//do something else
}
$i++;
}
I would do it like this if you're sure the array contains at least one entry:
processFirst($myArray[0]);
for ($i=1; $i<count($myArray); $1++)
{
processRest($myArray[$i]);
}
Otherwise you'll need to test this before processing the first element
I've made you a function!
function arrayCallback(&$array) {
$callbacks = func_get_args(); // get all arguments
array_shift($callbacks); // remove first element, we only want the callbacks
$callbackindex = 0;
foreach($array as $value) {
// call callback
$callbacks[$callbackindex]($value);
// make sure it keeps using last callback in case the array is bigger than the amount of callbacks
if(count($callbacks) > $callbackindex + 1) {
$callbackindex++;
}
}
}
If you call this function, it accepts an array and infinite callback arguments. When the array is bigger than the amount of supplied functions, it stays at the last function.
You can simply call it like this:
arrayCallback($array, function($value) {
print 'callback one: ' . $value;
}, function($value) {
print 'callback two: ' . $value;
});
EDIT
If you wish to avoid using a function like this, feel free to pick any of the other correct answers. It's just what you prefer really. If you're repeatedly are planning to loop through one or multiple arrays with different callbacks I suggest to use a function to re-use code. (I'm an optimisation freak)

Knowning at which point we are in a foreach

I have an array:
$array=array('key1'=>'value1','key2'=>'value2','value3');
and a foreach:
foreach($array as $v){
//do something
}
Is there a way to know in the foreach which element we are parsing?
(without doing something like:)
$count=0;
foreach($array as $v){
$count++;
// do something
}
thanks
EDIT1:
Sorry maybe I was not clear:
I don't want know the key, but I need to know how many elements are left in the foreach. (that's why I did the example with $count)
You could use a class that extends ArrayIterator:
class FooArrayIterator extends ArrayIterator {
private $offset = 0;
public function next() {
$this->offset++;
return parent::next();
}
public function rewind() {
$this->offset = 0;
parent::rewind();
}
public function seek($offset) {
if ($offset >= 0 && $offset < $this->count()) {
$this->offset = $offset;
}
parent::seek($offset);
}
public function offset() {
return $this->offset;
}
}
Example:
$array = array('value1','value2','value3');
$iter = new FooArrayIterator($array);
foreach ($iter as $v) {
echo ($iter->count() - $iter->offset() - 1).' more';
}
You can get the actual index:
foreach ($array as $index => $value) {
}
If you are working with an associative array there is no way to tell the current position of the internal array pointer. There is only an indirect way: you search for the current key in the keys of the array with:
foreach ($array as $index => $value) {
$position = array_search ($index, array_keys ($array));
echo ($position);
}
... but I guess count++ is a much more resource-friendly way.
You can:
$count = count($array);
foreach($array as $key => $value) {
$count--;
//$count elements are left
}
Yes, sort of.
foreach($array as $key=>$value)
// code
}
$key will be the array key, although if you want an actual integer count of iterations, and the keys are not numbered sequentially, or are strings, you will have to use a counter like in your original post.
Edit: to handle the last element without implementing a counter, you can use (if keys are int)
$foo = ($key == count($array)-1) ? "last element" : "any other element";
(janked from the manual comments - http://php.net/manual/en/control-structures.foreach.php)
Edit: if your keys are not integers, you can create a counter like you have in your code above, and substitute $key with your counter variable.
You're being a bit too picky :)
By the way the trick is to transform an associative array to an indexed array:
foreach ( array_values($array) as $key=>$value ){
echo $key; //yes, it will be an INT
echo ( count($array) - $key );
}
Without some pre-processing, such as your count() version, there isn't any way to know where you are in an associative array. At most you can check if you're at the end with end(), but there's no guarantee as to what order foreach() will retrieve the individual elements. Generally it's the same order they got added to the array, but not guarantees.
Another pre-processing option would be
$keys = array_keys($array);
$cnt = count($keys)
for ($i = 0; $i < $cnt; $i++) {
$element = $array[$keys[$i]];
}
and $i would tell you exactly how far through you've gone.

Categories