Editing this question entirely, for future learners.
I initially asked if a single while function could replace the code below. I didn't realize while doesn't increment automatically like foreach, so no. Great answers below on better solutions using either array_slice() or the classic for loop.
foreach ($array as $key => $value) {
if ($key < 25) {
echo '<img src="'.$value.'/preview_image.jpg">';
}
}
You would still have to increment the key, plus the key would have to be uniform to work.
Foreach works on the set and is more resilient against gaps in the range. Iterating over a set with for example 1,2 and 4 as keys, works great with foreach.
Another method could be:
for ($i=0;$i<25;$i++) etc
This checks the end conditions straight away, but does not take gaps into account, which could lead to extra code in the for loop itself.
You can use simple for loop
like this
for($i = 0; $i < 25; $i++)
{
echo '<img src="'.$array[$i].'/preview_image.jpg">';
}
I like array_slice() solution.
Also you should use Alternative syntax for control structures for displaying HTML.
PHP: Alternative syntax for control structures - Manual
<?php
/* Logic Part */
$array = [...];
$array = array_slice($array, 0, 25);
// You MUST apply this function before echoing user inputs
// for the sake of security reasons.
function h($s)
{
return htmlspecialchars($s, ENT_QUOTES, 'UTF-8');
}
/* HTML Part */
?>
<!DOCTYPE html>
<meta charset="UTF-8">
<title>Example</title>
<div>
<?php foreach ($array as $value): ?>
<img src="<?=h($value)?>/preview_image.jpg">
<?php endforeach; ?>
</div>
You effectively want to retrieve the first 24 lines from a file.
There are many ways to do that.
This is one way:
$file = new SplFileObject($path);
$file->setFlags($file::DROP_NEW_LINE);
$head = new LimitIterator($file, 0, 24);
foreach ($head as $value) {
...
}
The benefit is that you get a plain variable to foreach over that provides the data you need. This works with the Decortator pattern and is pretty flexible.
If the file has less than 24 lines (records), the foreach will finish earlier.
Also this code would not read the whole file into memory only to provide the first 24 lines.
Related
From the two examples below, for and foreach have the capability to produce the same results for looping condition. I then search in other discussion about the benchmark and found that there is not much difference in performance between the two functions.
Thus, I want to know for web developers on how these two functions differ in handling programs.
When to use for? When to use foreach? Please provide me with some examples.
<html>
<body>
<?php
$array = array( 1, 2, 3, 4, 5);
foreach( $array as $value ) {
echo "Value is $value <br />";
}
?>
</body>
</html>
<html>
<body>
<?php
for( $i = 0; $i<5; $i++ ) {
echo("Value of i is $i <br />" );
}
?>
</body>
</html>
When we use for loop we need a condition after satisfying which the
loop will continue. For this reason we use some counters in our loop
which obviously occupies some memory.
But while using foreach loop we don't have to think about the
counter. In case of foreach loop there is no extra memory required
for the counters also. Because we don't have any counter in foreach
loop.
Both the techniques have advantages and disadvantages, the foreach
loop is used mainly in arrays and collections but for statement can
be used in any program.
foreach is specifically for iterating over elements of an array or object.
for is for doing something... anything... that has a defined start condition, stop condition, and iteration instructions.
So, for can be used for a much broader range of things. In fact, without the third expression - without the iteration instructions - a for becomes a while.
For each is used for iterating through arrays or object that use keys and values.
For example, if I had an array called 'User':
$User = array(
'name' => 'dinesh',
'email' => 'dinesh#xyz.com',
'age' => 25
);
I could iterate through that very easily and still make use of the keys:
foreach ($User as $key => $value) {
echo $key.' is '.$value.'<br />';
}
This would print out:
name is dinesh
email is dinesh#xyz.com
age is 25
With for loops, it's more difficult to retain the use of the keys.
When you're using object-oriented practice in PHP, you'll find that you'll be using foreach almost entirely, with for loops only for numerical or list-based things. foreach also prevents you from having to use count($array) to find the total number of elements in the array.
I have a foreach loop and that is doing some time consuming stuff:
$someHugeArray = [...]; // having beyond 300 to 1000 items
foreach ($someHugeArray as $item) {
$this->applyTimeConsumingMagic($item);
}
When debugging this I try to avoid iterating all of them items, so I am often writing escape code along the lines of:
foreach ($someHugeArray as $i => $item) {
$this->applyTimeConsumingMagic($item);
if ($i > 10) { break; } // #fixme: should not go live
}
And as the comment indicates, something like this did once go live making me feel like an amateur.
Is there some way to break the foreach loop from an XDebug session without writing var_dumpy code? As an IDE I use PhpStorm.
I did not find a way to break a foreach loop on the fly, yet the best next thing one can do is to decrease the array size on the fly.
Set a breakpoint after you set up your array, at best before the loop starts. (It does work inside the loop as well, yet could have weird behavior)
Select Evaluate expression phpstorm's debug window or use shortcut, default should be Alt + Shift + 8
run $someHugeArray = array_slice($someHugeArray, $offset = 0, $length = 10);
Besides array_slice one could also use array_filter if one wants to filter by more specific conditions using a closure.
Now you have a small array, enjoy fast execution time without having to worry to clean up after your debug session.
This will break the loop on the 10th run through - but obviously can be set to say 2 or 3 etc:
$myArray = $this->getHugeDataArray();
$i = 0; //here we set i to 0 so we can count to 10
foreach ($myArray as $key => $value)
{
$i++;
if ($i == 9) {break;}
//rest of actual code
}
I have a feeling I'm going to get scolded for this but here is the question.
$seq_numbers = range('1', '24');
foreach($seq_numbers as $seq_number)
{
Bullet <?php echo $seq_number;?>
// (this successfully creates - Bullet 1, Bullet 2, etc. -
below is the problem.
<?php echo $db_rs['bullet_($seqnumber)'];?>
} // this one doesn't work.
I've tried
with curly brackets {}
I basically have a few columns that are named same except for number at the end (bullet_1, bullet_2, bullet_3, etc.) and want to get the results using a loop.
Your problem is, that PHP doesn't replace variables inside strings enclosed with single quotes. You need to use $db_rs["bullet_{$seq_number}"] or one of those:
<?php
foreach ($seq_numbers as $seq_number) {
$key = 'bullet_' . $seq_number;
echo $db_rs[$key];
}
Even shorter, but a little less clear:
<?php
foreach ($seq_numbers as $seq_number) {
echo $db_rs['bullet_' . $seq_number];
}
An entirely different approach would be to loop over the result array. Then you don't even need $seq_numbers. Just as an afterthought.
<?php
foreach ($db_rs as $key => $value) {
if (substr($key, 0, 7) == 'bullet_') {
echo $value;
}
}
Oh...and watch out for how you spell your variables. You are using $seq_number and $seqnumber.
<?php echo $db_rs['bullet_'.$seqnumber];?>
why not:
$db_rs['bullet_'.$seqnumber]
If not, what are your fields, and what does a var_dump of $db_rs look like?
try this...
$seq_numbers = range('1', '24');
foreach($seq_numbers as $seq_number)
{
Bullet <?php echo $seq_number;?>
// (this successfully creates - Bullet 1, Bullet 2, etc. -
below is the problem.
<?php echo $db_rs["bullet_($seqnumber)"];?>
} // now it works.
If I have a foreach construct, like this one:
foreach ($items as $item) {
echo $item . "<br />";
}
I know I can keep track of how many times the construct loops by using a counter variable, like this:
$counter = 0;
$foreach ($items as $item) {
echo $item.' is item #'.$counter. "<br />";
$counter++;
}
But is it possible to do the above without using a "counter" variable?
That is, is it possible to know the iteration count within the foreach loop, without needing a "counter" variable?
Note: I'm totally okay with using counters in my loops, but I'm just curious to see if there is a provision for this built directly into PHP... It's like the awesome foreach construct that simplified certain operations which are clunkier when doing the same thing using a for construct.
No it's not possible unless your $items is an array having contiguous indexes (keys) starting with the 0 key.
If it have contiguous indexes do:
foreach ($items as $k => $v)
{
echo $k, ' = ', $v, '<br />', PHP_EOL;
}
But as others have stated, there is nothing wrong using a counter variable.
There's no easier way - that's kinda what count variables are for.
I'm assuming that you want to know the current count during the loop. If you just need to know it after, use count($items) as others have suggested.
You could tell how many time it WILL loop or SHOULD have looped by doing a
$loops = count($items);
However that will only work if your code does not skip an iteration in any way.
foreach loops N times, where N is just the size of the array. So you can use count($items) to know it.
EDIT
Of course, as noticed by Bulk, your loop should not break (or maybe continue, but I would count a continue as a loop, though shorter...)
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.)