group php foreach loop (Closed) [closed]
How can i group php foreach?i’v already tried 5 days,but still can’t get it work i don’t know php foreach how it works, but I’m learning it, Thanks to everyone’s advice original php:
leading) && count($this->leading)): ?> leading as $key=>$item): ?> item=$item; echo $this->loadTemplate(‘item’); ?> primary) && count($this->primary)): ?> primary as $key=>$item): ?> item=$item; echo $this->loadTemplate(‘item’); ?> secondary) && count($this->secondary)): ?> secondary as $key=>$item): ?> item=$item; echo $this->loadTemplate(‘item’); ?>
leading) && count($this->leading)) && (isset($this->primary) && count($this->primary)) && (isset($this->secondary) && count($this->secondary)): ?> leading, $this->primary, $this->secondary) as $key=>$item) ($this->leading as $key=>$item): ?> item=$item; echo $this->loadTemplate(‘item’); ?>
I dont understand why are you messing up the code with tag in every line when you can write all the code within single tag??php>
You really like having in every line of code, don’t you? But it’s really odd. Please reformat it — it’s hard to read.?php>
And what the hell are you trying to do ? Those 3 ´foreach´ seems to do differents stuff each, so I think they should all be kept.
3 Answers 3
do you mean something like this.
leading; $arr[] = $this->primary; $arr[] = $this->secondary; foreach($arr as $v) < if(is_array($v) && (count($v) >0)) < foreach($v as $item) < $this->item=$item; echo $this->loadTemplate('item'); > > > ?>
function foobar ($tmp) < if(isset($tmp) && count($tmp)) < foreach ($tmp as $key =>$item) < // Load category_item.php by default $this->item = $item; echo $this->loadTemplate('item'); > > >
and call it with your data:
foobar($this->leading); foobar($this->primary); foobar($this->secondary);
The simplest way to handle this is to first build a list containing all the items you need, and then use just one foreach to cycle through that list.
I’d also recommend some consistancy in whether the three variables (leading, primary, secondary) are defined. If you can guarantee that they’re set and are arrays — even if they’re empty arrays, it can make your code as simple as this:
leading, $this->primary, $this->secondary); foreach ($items as $Item) < $this->item = $item; $this->loadTemplate('item'); > ?>
If you really don’t know whether the variables are set, and you can’t refactor your code elsewhere to change this, you could do this instead:
leading)) $items = array_merge($items, $this->leading); if (isset($this->primary)) $items = array_merge($items, $this->primary); if (isset($this->secondary)) $items = array_merge($items, $this->secondary); foreach ($items as $Item) < $this->item = $item; $this->loadTemplate('item'); > ?>
Php if isset foreach
Beware of how works iterator in PHP if you come from Java!
In Java, iterator works like this :
interface Iterator < O > boolean hasNext ();
O next ();
void remove ();
>
?>
But in php, the interface is this (I kept the generics and type because it’s easier to understand)
interface Iterator < O > boolean valid ();
mixed key ();
O current ();
void next ();
void previous ();
void rewind ();
>
?>
1. valid() is more or less the equivalent of hasNext()
2. next() is not the equivalent of java next(). It returns nothing, while Java next() method return the next object, and move to next object in Collections. PHP’s next() method will simply move forward.
Here is a sample with an array, first in java, then in php :
class ArrayIterator < O >implements Iterator < O > private final O [] array;
private int index = 0 ;
public ArrayIterator ( O [] array) this .array = array;
>
public boolean hasNext () return index < array. length ;
>
public O next () if ( ! hasNext ())
throw new NoSuchElementException ( ‘at end of array’ );
return array[ index ++];
>
public void remove () throw new UnsupportedOperationException ( ‘remove() not supported in array’ );
>
>
?>
And here is the same in php (using the appropriate function) :
/**
* Since the array is not mutable, it should use an internal
* index over the number of elements for the previous/next
* validation.
*/
class ArrayIterator implements Iterator private $array ;
public function __construct ( $array ) if ( ! is_array ( $array ))
throw new IllegalArgumentException ( ‘argument 0 is not an array’ );
$this -> array = array;
$this -> rewind ();
>
public function valid () return current ( $this -> array ) !== false ;
// that’s the bad method (should use arrays_keys, + index)
>
public function key () return key ( $this -> array );
>
public function current () return current ( $this -> array );
>
public function next () if ( $this -> valid ())
throw new NoSuchElementException ( ‘at end of array’ );
next ( $this -> array );
>
public function previous () // fails if current() = first item of array
previous ( $this -> array );
>
public function rewind () reset ( $this -> array );
>
>
?>
The difference is notable : don’t expect next() to return something like in Java, instead use current(). This also means that you have to prefetch your collection to set the current() object. For instance, if you try to make a Directory iterator (like the one provided by PECL), rewind should invoke next() to set the first element and so on. (and the constructor should call rewind())
class ArrayIterable < O >implements Iterable < O > private final O [] array;
public ArrayIterable ( O [] array) this .array = array;
>
public Iterator < O >iterator () return new ArrayIterator (array);
>
>
?>
When using an Iterable, in Java 1.5, you may do such loops :
for ( String s : new ArrayIterable < String >(new String [] < "a" , "b" >)) .
>
?>
Which is the same as :
Iterator < String >it = new ArrayIterable < String >(new String [] < "a" , "b" >);
while ( it . hasNext ()) String s = it . next ();
.
>
?>
While in PHP it’s not the case :
foreach ( $iterator as $current ) .
>
?>
Is the same as :
for ( $iterator -> rewind (); $iterator -> valid (); $iterator -> next ()) $current = $iterator -> current ();
.
>
?>
(I think we may also use IteratorAggregate to do it like with Iterable).
Take that in mind if you come from Java.
I hope this explanation is not too long.
Show one message only for foreach loop
When looping through the foreach loop below I’ll get an echo output for each time the loop is performed. How can I reduce these messages to only one final message? I.e. if only «success messages» then echo «Success» , if an error occurs («fail» or «nothing saved» message) then echo «Fail» . The loop shall NOT be stopped once an error occurred but fully be proceeded. And in the end I just want to know if an error occurred or a result has not been saved.
if(!isset($_POST["submitbutton"])) < echo "Click this button to save your input."; >else < foreach($_POST['tipp_id'] as $key =>$tipp_id) < if($tipp_id >0) < $result=" //SQL query "; $query=mysqli_query($conn,$result); if($query) < echo "Success.
"; > else < echo "Fail.
"; > > else < echo "Nothing saved."; >> >
before the foreach , add a boolean variable such as $fail_happened = false; , defaulted to false , then when you encounter a failure in the loop, set it to true . Then at the end, check the value.
One thing that seems to be missing from your code and both answers so far is the fact that you want nothing to be saved in case of an error, which would require a transaction.
@JoseManuelAbarcaRodríguez Wouldn’t that end in interrupting the whole loop? I.e. stopping the loop from processing all steps? That would not be what I’m looking for: The loop shall be completed, then the messages shall be checked and if the messages contain a «fail» or «nothing saved» message I’d like the system to echo out «fail» — otherwise «success».
PHP: Check if variable exist but also if has a value equal to something
I have (or not) a variable $_GET[‘myvar’] coming from my query string and I want to check if this variable exists and also if the value corresponds to something inside my if statement: What I’m doing and think is not the best way to do: if(isset($_GET[‘myvar’]) && $_GET[‘myvar’] == ‘something’) : do something My question is, exist any way to do this without declare the variable twice? That is a simple case but imagine have to compare many of this $myvar variables.
PHP doesn’t have a solution for this, but it’s a programming language. You can (and ought to) always write a subprogram to shorten a repetitive code. Not to mention that in a good program every variable should be defined before use.
In PHP 7+, many of these cases can be done by Null coalescing operator . Check this link out for use cases:
14 Answers 14
Sadly that’s the only way to do it. But there are approaches for dealing with larger arrays. For instance something like this:
$required = array('myvar', 'foo', 'bar', 'baz'); $missing = array_diff($required, array_keys($_GET));
The variable $missing now contains a list of values that are required, but missing from the $_GET array. You can use the $missing array to display a message to the visitor.
Or you can use something like that:
$required = array('myvar', 'foo', 'bar', 'baz'); $missing = array_diff($required, array_keys($_GET)); foreach($missing as $m )
Now each required element at least has a default value. You can now use if($_GET[‘myvar’] == ‘something’) without worrying that the key isn’t set.
One other way to clean up the code would be using a function that checks if the value is set.
function getValue($key) < if (!isset($_GET[$key])) < return false; >return $_GET[$key]; > if (getValue('myvar') == 'something') < // Do something >
Test If A Foreach is Successful
I need a way to detect if the ‘foreach‘ is unsuccessful. If it is unsuccessful, then repeat the same error message that is in the current ‘else‘.
short as $shorts) < if($shorts->name == $_GET['r']) < header('Location: '.$shorts->url); break; > > > else < header("refresh:2;url=http://www.wlatw.co/"); echo 'Malformed URLRedirecting. '; > > ?>
What makes the foreach loop successful or unsuccessful? Do you mean if there are no $xml->short to iterate as a non-success?
2 Answers 2
Create a flag before starting the loop; Set it to unsuccesful when it fails.
short as $shorts) < if($shorts->name == $_GET['r']) < header('Location: '.$shorts->url); $success = true; break; > > if ($success) < // do what you want when not success ful. header("refresh:2;url=http://www.wlatw.co/"); echo 'Malformed URLRedirecting. '; > > else < header("refresh:2;url=http://www.wlatw.co/"); echo 'Malformed URLRedirecting. '; > > ?>
But looking at your code, you can just exit after setting the header:
foreach($xml->short as $shorts) < if($shorts->name == $_GET['r']) < header('Location: '.$shorts->url); exit; break; > >
Note: As @Sverri M. Olsen said, you should always stop your script after setting the Location header, either with die, exit or any other mechanism you have.