Foreach Loop With TWO or MORE Conditions - php

Here is my original which works (I'm using simple-html-dom)
foreach(($filtered->find('a')) as $element) {
// do stuff
}
Problem is that now I may need to use 2 conditions... something like:
foreach(($filtered->find('a')) as $element || ($filtered->find('img')) as $element) {
// do stuff
}
But it doesn't work. Neither does:
foreach(($filtered->find('a') || $filtered->find('img')) as $element) {
// do stuff
}
How does one go about implementing both conditions so it runs the "do stuff" whenever EITHER an 'a' element OR an 'img' element is found.
Thank you very much for any help you can give.

foreach(array_merge($filtered->find('a'),$filtered->find('img')) as $element) {
// do stuff
}
foreach takes no conditions at all.
foreach takes ALL values from ONE array.
So if you want to take ALL values from TWO arrays, you have to merge TWO arrays into ONE array, and foreach over that.

Try this instead:
foreach( $filtered->find('a, img') as $element ) { ... }
Using the comma, this will gets you all a and img nodes...
For more informations, please refer to PHP Simple HTML DOM Parser Manual

In PHP, || is a boolean operator and just returns true or false. If you want the first non-false value in a series of expressions, use ?::
foreach(($filtered->find('a') ?: $filtered->find('img')) as $element) {
// do stuff
}

Related

Correct way to check (with PHP) a variable before looping through?

Before looping through a variable (supposed to be an array)
I would make the following test:
if(
!empty($arrJobs) &&
is_array($arrJobs) &&
count($arrJobs)
){
foreach ($arrJobs as $item) {
//loop tasks
}
}
I've seen also using if(sizeof($arrJobs)>0) but in case $arrJobs isa integer (I can't trust the input) it would be through and I will try looping through a integer...weird.
Is there a more concise and comprehensive way to perform this test before looping through the array?
It is IMPORTANT to check if you're looping an ARRAY to FOREACH or else PHP will give you errors ... FOREACH expects parameter to be ARRAY..
You can use IS_ARRAY .. I believe that would be enough.
But checking it if empty would be VERY GOOD Practice... I'm using COUNT() to check if an ARRAY is empty.
You don't need to check anything but is_array: if it's empty, PHP simply won't loop.
Moreover a suggestion: if those if had sense (not that case, but is helpful for this explanation) you should split with "early exit" (as coding style because it improves readability)
if (empty($arrJobs)) {
return;
}
if (!is_array($arrJobs)) {
return;
}
if (count($arrJobs)) {
return;
}

PHP: If condition with explode within foreach loop

I am trying to get multiple value from user input from text field and want to explode or keep adding into if condition statement
Here is my code
foreach ($list['post'] as $item) {
if( ($item['single']['catid'] != 8) AND ($item['single']['catid'] != 4) ){
$this->list_post($item);
}
}
Now what exactly I am looking for is in if( ($item['single']['catid'] != 8) AND ($item['single']['catid'] != 4) ) I want allow user to add multiple category ID and each ID will add AND and further id code AND ($item['single']['catid'] != 4)
I never done this before and don't know either this is proper way to do or any other possible better way.
Thanks a lot
You should have some kind of an array of the category IDs you want to check for, for example:
$categories = array(8, 4);
Then you could use something like the in_array(needle, haystack) built-in function of PHP.
Your if condition would become like that one: if (!in_array($item['single']['catid'], $categories)) {.
You should be using the above, but I am going to give you an idea of how it works, so you can understand the principle for more complex issues:
function exists($target, $array) {
foreach ($array as $element) { // Go through each element in the array
if ($element == $target) { // Check to see if any element there is what you are searching for
return true; // Return true, that it does exist, and stop there.
} else {
// Just ignore it...
}
}
return false; // If you get here, it means nothing returned true, so it does not exist...
}
To be used as if (exists($item['single']['catid'], $categories)) {.
It wouldn't work if it was "inside" the if statement because you have to do some processing before evaluating if it exists or not. So you either could have done that before the if statement, and store the result in a variable, or use a function (which PHP provides).
Hopefully the concept will help you fir more complex problems...
Note: this assumes your input is in the form of an array, which you can build via various ways, if not provided as is directly.
Update:
The input you get via the input field is sent through form, to which you specify either POST or GET as a method. Assuming it is POST that you are using, this is how you'd get the input as a string as it was entered in the text field:
$categories_string = $_POST['the_name_field_in_the_input_tag'];
After that you have to understand it as a list of items, let's say separated by commas: 1,3,5,8. Then this is simply separating by commas. You can use explode($delimiter, $string). Like that:
$categories_array = explode(',', $_POST['categories']);
But you cannot trust the input, so you could get something like 1, 2, 3,5,6. The spaces will mess it up, because you will have spaces all around. To remove them you can use trim for example.
$categories = array(); // Create the array in which the processed input will go
foreach ($categories_array as $c) { // Go through the unprocessed one
$categories[] = trim($c) * 1; // Process it, and fill the result. The times one is just so that you get numbers in the end and not strings...
}
Then you can use it as shown earlier, but keep in mind that this is just an example, and you might not even need all these steps, and there are much more efficient ways to process this input (regular expressions for example). But the concern here is not sanitizing input, but keep in mind you will need to do that eventually.
Hope it's clear enough :)
You might be better off with in_array() for checking a value against a variable number of possibilities.
I'm not sure I understand your problem. You want user to be able to input different values, e.g.:
$string = "5, 6, 7, 8, 10";
Afterwards, you want to check if 'catid' is not in that array and if it isn't you want to run $this->list_post($item);
If so, then you should use something like this:
$values = explode(", ", $string); //make array from values
foreach ($list['post'] as $item) {
if (!in_array($item['single']['catid'], $values)) { //check whether catid is in array
$this->list_post($item); // execute whatever you want
}
}
Hope it helps.

PHP what is the best way to handle a variable that may not be set?

I have a foreach loop, that will loop through an array, but the array may not exist depending on the logic of this particular application.
My question relates to I guess best practices, for example, is it ok to do this:
if (isset($array))
{
foreach($array as $something)
{
//do something
}
}
It seems messy to me, but in this instance if I dont do it, it errors on the foreach. should I pass an empty array?? I haven't posted specific code because its a general question about handling variables that may or may not be set.
Just to note: here is the 'safest' way.
if (isset($array) && is_array($array)) {
foreach ($array as $item) {
// ...
}
}
Try:
if(!empty($array))
{
foreach($array as $row)
{
// do something
}
}
That's not messy at all. In fact, it's best practice. If I had to point out anything messy it would be the use of Allman brace style, but that's personal preference. (I'm a 1TBS kind of guy) ;)
I'll usually do this in all of my class methods:
public function do_stuff ($param = NULL) {
if (!empty($param)) {
// do stuff
}
}
A word on empty(). There are cases where isset is preferable, but empty works if the variable is not set, OR if it contains an "empty" value like an empty string or the number 0.
If you pass an empty array to foreach then it is fine but if you pass a array variable that is not initialized then it will produce error.
It will work when array is empty or even not initialized.
if( !empty($array) && is_array($array) ) {
foreach(...)
}
I would say it is good practice to have a 'boolean' other value that is set as 0 (PHP's false) to start, and any time some function adds to this array, add +1 to the boolean, so you'll have a definite way to know if you should mess with the array or not?
That's the approach I would take in an object oriented language, in PHP it could be messier, but still I find it best to have a deliberate variable keeping track, rather than try to analyze the array itself. Ideally if this variable is always an array, set the first value as 0, and use it as the flag:
<?PHP
//somewhere in initialization
$myArray[0] = 0;
...
//somewhere inside an if statement that fills up the array
$myArray[0]++;
$myArray[1] = someValue;
//somewhere later in the game:
if($myArray[0] > 0){ //check if this array should be processed or not
foreach($myArray as $row){ //start up the for loop
if(! $skippedFirstRow){ //$skippedFirstRow will be false the first try
$skippedFirstRow++; //now $skippedFirstRow will be true
continue; //this will skip to the next iteration of the loop
}
//process remaining rows - nothing will happen here for that first placeholder row
}
}
?>

cleanest way to skip a foreach if array is empty [duplicate]

This question already has answers here:
Invalid argument supplied for foreach()
(20 answers)
Closed 7 years ago.
Not a major problem but I was wondering if there is a cleaner way to do this. It would be good to avoid nesting my code with an unnecessary if statement. If $items is empty php throws an error.
$items = array('a','b','c');
if(!empty($items)) { // <-Remove this if statement
foreach($items as $item) {
print $item;
}
}
I could probably just use the '#' error suppressor, but that would be a bit hacky.
There are a million ways to do this.
The first one would be to go ahead and run the array through foreach anyway, assuming you do have an array.
In other cases this is what you might need:
foreach ((array) $items as $item) {
print $item;
}
Note: to all the people complaining about typecast, please note that the OP asked cleanest way to skip a foreach if array is empty (emphasis is mine). A value of true, false, numbers or strings is not considered empty.
In addition, this would work with objects implementing \Traversable, whereas is_array wouldn't work.
The best way is to initialize every bloody variable before use.
It will not only solve this silly "problem" but also save you a ton of real headaches.
So, introducing $items as $items = array(); is what you really wanted.
$items = array('a','b','c');
if(is_array($items)) {
foreach($items as $item) {
print $item;
}
}
If variable you need could be boolean false - eg. when no records are returned from database or array - when records are returned, you can do following:
foreach (($result ? $result : array()) as $item)
echo $item;
Approach with cast((Array)$result) produces an array of count 1 when variable is boolean false which isn't what you probably want.
I wouldn't recommend suppressing the warning output. I would, however, recommend using is_array instead of !empty. If $items happens to be a nonzero scalar, then the foreach will still error out if you use !empty.
I think the best approach here is to plan your code so that $items is always an array. The easiest solution is to initialize it at the top of your code with $items=array(). This way it will represent empty array even if you don't assign any value to it.
All other solutions are quite dirty hacks to me.
foreach((array)$items as $item) {}
i've got the following function in my "standard library"
/// Convert argument to an array.
function a($a = null) {
if(is_null($a))
return array();
if(is_array($a))
return $a;
if(is_object($a))
return (array) $a;
return $_ = func_get_args();
}
Basically, this does nothing with arrays/objects and convert other types to arrays. This is extremely handy to use with foreach statements and array functions
foreach(a($whatever) as $item)....
$foo = array_map(a($array_or_string)....
etc
Ternary logic gets it down to one line with no errors. This solves the issue of improperly cast variables and undefined variables.
foreach (is_array($Items) || is_object($Items) ? $Items : array() as $Item) {
It is a bit of a pain to write, but is the safest way to handle it.
You can check whether $items is actually an array and whether it contains any items:
if(is_array($items) && count($items) > 0)
{
foreach($items as $item) { }
}
Best practice is to define variable as an array at the very top of your code.
foreach((array)$myArr as $oneItem) { .. }
will also work but you will duplicate this (array) conversion everytime you need to loop through the array.
since it's important not to duplicate even a word of your code, you do better to define it as an empty array at top.

What's the best way to verify that an element is ready for use in a foreach() loop in php?

example:
foreach($boxes as $box) {
echo "$box \n";
}
Used to be fairly easy, I could just wrap the foreach around a check like:
if(is_array($boxes) && count($boxes) > 0) {
//foreach loop here
}
Without having to worry about a warning getting thrown if for whatever reason bad input was passed to the $boxes array.
When Iterators, were added to the mix, this no longer works, as Iteratable objects are not arrays. So, I have a few solutions, but am wondering if there is a 'best practice' for this.
// 1:
if($boxes instanceof Traversable && count($boxes) > 0) {
//foreach loop here
}
// 2:
if($boxes && count($boxes) > 0) {
//foreach loops here
}
There are others, but these seem like the most obvious. Anyone have any suggestions. PHP docs seem to be silent.
You shouldn't have the count($array) > 0 part, because a) foreach works fine with empty arrays, b) objects can be Traversable yet not be Countable and c) the value returned by count() may even (for objects) be disconnected from the number of items the traversal will yield.
And #1 there is different from #2; since $boxes instanceOf Traversable is not the same as $boxes. Also note that internally arrays don't implement Traversable.
I would go with
if (is_array($boxes) || $boxes instanceof Traversable) {
foreach (...)
}
This still doesn't guarantee that the traversal will be successful; the iteration may throw an exception at any point. In particular, for some classes it may not make sense to traverse them more than once.
I think generally in these cases you would probably know that the variable is going to be iterable if it is not null or false etc., so I would be happy to just do:
if ($boxes) {
foreach ($boxes as $box) {}
}
Maybe that is naive though
One possibility depending on your php version is a cast:
<?php
$a = array('foo', array('bar'));
foreach ($a as $thing)
foreach ((array) $thing as $item) // <-- here
echo "$item\n";
?>
This test will give true for both arrays and array-like objects
if (is_array($obj) || $obj instanceof Traversable) {
foreach ($obj as $item) { /* foreach loop is safe here */
}
}
In PHP5 you can iterate over any array or object so..
if (is_array($my_var) || is_object($my_var)) {
// Do some foreachin'
}

Categories