I have come across a PHP foreach statement that I am having trouble finding any documentation on.
Here is the code I am having trouble understanding:
<?php foreach((array)$this->item->partno as $value): ?>
// do some stuff
<?php endforeach; ?>
What is the (array) doing and what is happening with this foreach?
You're casting (converting) whatever the type of $this->item->partno is, in an array.
More on this in the php docs here
This technique is useful when you have a function and you want it to take an argument that can be either a single value or an array. For example, you might normally do something like this:
function foo($items) {
if (!is_array($items)) {
$items = array($items);
}
foreach ($items as $item) {
// ...
}
}
By casting the variable to an array inline, you can avoid the explicit array check, and the code will work fine if you pass it either a single value or an array:
function foo($items) {
foreach ((array) $items as $item) {
// ...
}
}
foo(1);
foo([1, 2, 3]);
Related
There are numerous questions out there about the safety implications of manipulating an array when using foreach on it. I can't find any questions on doing this in a while loop, though.
So I wonder, is it safe to do this? Below is an example script in PHP and I'm not sure if this is alright.
while ($item = array_pop($array)) {
findMoreItems($item, $array);
}
function findMoreItems($item, &$array) {
// Returns null if no more items are found
$newItem = someFuncFromServer($item);
if ($newItem) {
array_push($array, $newItem);
}
}
By safe I mean: can I be sure that no items are skipped in the loop?
Your code is essentially equivalent to :
$item = array_pop($array);
while ($item) {
findMoreItems($item, $array);
$item = array_pop($array)
}
function findMoreItems($item, &$array) {
// Returns null if no more items are found
$newItem = someFuncFromServer($item);
if ($newItem) {
array_push($array, $newItem);
}
}
Now if you rewrite this in the above way it is obvious that the code will not do anything like copy references or array points or anything like that which is what foreach does. foreach does that because it relies on the internal array pointer which array_pop and array_push do not.
I have this case when I have array_push inside function and then I need to run it inside foreach filling the new array. Unfortunately I can't see why this does not work. Here is the code:
<?php
$mylist = array('house', 'apple', 'key', 'car');
$mailarray = array();
foreach ($mylist as $key) {
online($key, $mailarray);
}
function online($thekey, $mailarray) {
array_push($mailarray,$thekey);
}
print_r($mailarray);
?>
This is a sample function, it has more functionality and that´s why I need to maintain the idea.
Thank you.
PHP treats arrays as a sort of “value type” by default (copy on write). You can pass it by reference:
function online($thekey, &$mailarray) {
$mailarray[] = $thekey;
}
See also the signature of array_push.
You need to pass the array by reference.
function online($thekey, &$mailarray) {
Is it possible to have an AND in a foreach loop?
For Example,
foreach ($bookmarks_latest as $bookmark AND $tags_latest as $tags)
You can always use a loop counter to access the same index in the second array as you are accessing in the foreach loop (i hope that makes sense).
For example:-
$i = 0;
foreach($bookmarks_latest as $bookmark){
$result['bookmark'] = $bookmark;
$result['tag'] = $tags_latest[$i];
$i++;
}
That should achieve what you are trying to do, otherwise use the approach sugested by dark_charlie.
In PHP 5 >= 5.3 you can use MultipleIterator.
Short answer: no. You can always put the bookmarks and tags into one array and iterate over it.
Or you could also do this:
reset($bookmarks_latest);
reset($tags_latest);
while ((list(, $bookmark) = each($bookmarks_latest)) && (list(,$tag) = each($tags_latest)) {
// Your code here that uses $bookmark and $tag
}
EDIT:
The requested example for the one-array solution:
class BookmarkWithTag {
public var $bookmark;
public var $tag;
}
// Use the class, fill instances to the array $tagsAndBookmarks
foreach ($tagsAndBookmarks as $bookmarkWithTag) {
$tag = $bookmarkWithTag->tag;
$bookmark = $bookmarkWithTag->bookmark;
}
you can't do that.
but you can
<?php
foreach($keyval as $key => $val) {
// something with $key and $val
}
the above example works really well if you have a hash type array but if you have nested values in the array I recommend you:
or option 2
<?php
foreach ($keyval as $kv) {
list($val1, $val2, $valn) = $kv;
}
No, but there are many ways to do this, e.g:
reset($tags_latest);
foreach ($bookmarks_latest as $bookmark){
$tags = current($tags_latest); next($tags_latest);
// here you can use $bookmark and $tags
}
No. No, it is not.
You'll have to manually write out a loop that uses indexes or internal pointers to traverse both arrays at the same time.
Yes, for completeness:
foreach (array_combine($bookmarks_latest, $tags_latest) as $bookm=>$tag)
That would be the native way to get what you want. But it only works if both input arrays have the exact same length, obviously.
(Using a separate iteration key is the more common approach however.)
I looking for another samples of php foreach code that similar to the code as following:
foreach ($this->ask->post['books'] as $book) {
if ($book['qty']) {
$this->goto->add($book['book_id'], $book['qty'], (isset($book['opt'])) ? $book['opt'] : NULL);
}
}
I just want to save it as my collection, so, is there another samples of php foreach that You may know? let me know it. Thanks
Maybe this example can help you:
foreach($myArrayOfObject as $key=>$object) {
if($object->aPropertyOfMyObject) {
// do something...
}
}
You can also have a look to http://php.net/manual/en/control-structures.foreach.php
Do you specifically need foreach?
You can also use this:
<?php
$array = array(); // Imagine a filled array
array $max = count($array);
for($i=0;$i<$max;$i++) {
// Loop over the array
echo $array[$i]['name_of_key'];
}
?>
I have an array of URLs I'm running thru an included preg_replace_callback function, the idea being that each loop will yield a new result.
Problem is that it keeps outputting only the first result, as if it stalls after processing the first URL.
Here is the code:
if (!function_exists('name')) {
function name($match)
{
return($match[1]);
}
$foo = preg_replace_callback("#[regex]#", "name", $bar);
}
Any ideas how I can get this to work properly? Thanks.
You can also use T-Regx library:
pattern('[regex]')->replace($bar)->callback('name');
If you are applying the function preg_replace_callback() to all elements in an array, you might want to do this:
// put this on the top of the file
function name($match) {
return($match[1]);
}
Then, to iterate through elements of an array:
foreach ($array as $value) {
$foo = preg_replace_callback("#[regex]#", "name", $value);
// do stuff with $foo
}