A loop (while/foreach) with "offset" wrapping and - php

After applying what wrapping objects using math operator, I just tought it will be over. But no. By far.
<?php
$faces= array(
1 => '<div class="block">happy</div>',
2 => '<div class="block">sad</div>',
(sic)
21 => '<div class="block">angry</div>'
);
$i = 1;
foreach ($faces as $face) {
echo $face;
if ($i == 3) echo '<div class="block">This is and ad</div>';
if ($i % 3 == 0) {
echo "<br />"; // or some other wrapping thing
}
$i++;
}
?>
In the code I have to put and ad after the second one, becoming by that the third object. And then wrap the three all in a <div class="row"> (a br after won't work out by design reasons). I thought I will going back to applying a switch, but if somebody put more elements in the array that the switch can properly wrap, the last two remaining elements are wrapped openly.
Can i add the "ad" to the array in the third position? That would make things simplier, only leaving me with guessing how to wrap the first and the third, the fourth and the sixth, an so on.

First, insert the ad:
array_splice($faces, 2, 0, array('<div class="block">this is an ad</div>'));
Then, apply the wrapping:
foreach (array_chunk($faces, 3) as $chunk) {
foreach ($chunk as $face) {
echo $face;
}
echo '<br />';
}

You could just split the array in two, insert your ad and then append the rest:
// Figure out what your ad looks like:
$yourAd = '<div class="block">This is and ad</div>';
// Get the first two:
$before = array_slice($faces, 0, 2);
// Get everything else:
$after = array_slice($faces, 2);
// Combine them with the ad. Note that we're casting the ad string to an array.
$withAds = array_merge($before, (array)$yourAd, $after);
I think nickb's note about using the comparison operator rather than assignment will help get your wrapping figured out.

Related

Variable in URL

I'm making a website with wordpress for my company and i have a question for you
I have an url like this
http://mysuperwebsite/?_sft_category=cx+ms+lol
And i would like to grab the argument of this, so i tried
$motsclefs = $_GET['_sft_category'] ;
and a basic echo
echo'<div>'.$motsclefs.'</div>';
This is cool but now this return me something like this in a single div
cx ms lol
My desire is to cut those words, to have as much div as my words
To be more specific i would like to have something like this
<div class="1">cx</div>
<div class="2">ms</div>
<div class="3">lol</div>
So, i understood that i have to consider those "+" in the url to separate my words ?
Thanks ;)
You can try this.
$tempArr=explode(' ',$motsclefs);
for($i=0;$i < count($tempArr);$i++)
{
echo '<div>'.$tempArr[$i].'</div>';
}
As mentioned by Jon Stirling use explode and foreach.
<?php
$motsclefs = 'cx ms lol';
$divs = '';
foreach(explode(' ', $motsclefs) as $key => $element) {
$divs .= sprintf ('<div class="%s">%s</div>' . PHP_EOL, $key + 1, $element);
}
You can split the string by a space, if $motsclefs is a string with spaces separating the arguments, which is how it looks from your question:
$arguments = explode(" ", $motsclefs);
Then iterate through them:
foreach ($arguments as $argument) {
echo "<div>$argument</div>";
}
For different classes;
$i = 1;
foreach ($arguments as $argument) {
echo "<div class='class$i'>$argument</div>";
$i++;
}
$i increases for each loop round which will give you a new number with every iteration.

How to remove an all the elements in an array through iteration

I have an array $scripts_stack = []; that holds arrays:
$array_item = array('script' => $file_parts, 'handle' => $file_name, 'src' => $url);
array_push($scripts_stack, $array_item);
<?php
for ($i = 0; $i < sizeof($scripts_stack); $i++) {
$child_array = $scripts_stack[$i];
if (is_array($child_array)) {
// Do things with $child_array,
// then remove the child array from $scripts_stack when done with (BELOW)
unset($scripts_stack[$i]);
}
}
echo "Array Size : " . (sizeof($scripts_stack)); // AT THE END
However, my attemts only remove half the elements. No matter what I try, it's only half the items that get removed. sizeof($scripts_stack) is always half the size of what it was at the start.
I'm expecting that it would be empty // AT THE END
Why is it that I only get half the elements in the array removed?
Thank you all in advance.
As mentioned in other answers, $i increments but the sizeof() the array shrinks. foreach() is probably the most flexible looping for arrays as it exposes the actual key (instead of hoping it starts at 0 and increments by 1) and the value:
foreach ($scripts_stack as $key => $child_array) {
if (is_array($child_array)) {
// Do things with $child_array,
// then remove the child array from $scripts_stack when done with (BELOW)
unset($scripts_stack[$key]);
}
}
Just FYI, the way you're doing it with for almost works. You just need to establish the count before the loop definition, rather than recounting in the continuation condition.
$count = sizeof($scripts_stack);
for ($i = 0; $i < $count; $i++) { // ...
Still, I think it would be better to just use a different type of loop as shown in the other answers. I'd personally go for foreach since it should always iterate every element even if some indexes aren't present. (With the way you're building the array, it looks like the indexes should always be sequential, though.)
Another possibility is to shift elements off of the array rather than explicitly unsetting them.
while ($child_array = array_shift($scripts_stack)) {
// Do things with $child_array,
}
This will definitely remove every element from the array, though. It looks like $child_array should always be an array, so the is_array($child_array) may not be necessary, but if there's more to it that we're not seeing here, and there are some non-array elements that you need to keep, then this won't work.
You advanced $i while the array is getting shrinked, but in the same time you jump over items in your array.
The first loop is where $i == 0, and then when you removed item 0 in your array, the item that was in the second place has moved to the first place, and your $i == (so you will not remove the item in the current first place, and so on.
What you can do is use while instead of for loop:
<?php
$i = 0;
while ($i < sizeof($scripts_stack)) {
$child_array = $scripts_stack[$i];
if (is_array($child_array)) {
// Do things with $child_array,
// then remove the child array from $scripts_stack when done with (BELOW)
unset($scripts_stack[$i]);
} else {
$i++;
}
}
echo "Array Size : " . (sizeof($scripts_stack)); // AT THE END
May be you can use this script.It's not tested.
foreach($array as $key => $value ) {
unset($array[$key]);
echo $value." element is deleted from your array</br>";
}
I hope , it will help you.
The problem root is in comparing $i with sizeof($scripts_stack). Every step further sizeof($scripts_stack) becomes lower (it calculates at every step) and $i becomes higher.
The workaround may look like this:
<?php
$scripts_stack = [];
$array_item = array('script' => 1, 'handle' => 2, 'src' => 3);
array_push($scripts_stack, $array_item);
array_push($scripts_stack, $array_item);
array_push($scripts_stack, $array_item);
array_push($scripts_stack, $array_item);
array_push($scripts_stack, $array_item);
while (sizeof($scripts_stack) > 0) {
$child_array = array_shift($scripts_stack);
if (is_array($child_array)) {
// Do things with $child_array,
// then remove the child array from $scripts_stack when done with (BELOW)
}
}
echo "Array Size : " . (sizeof($scripts_stack)); // AT THE END
https://3v4l.org/N2p3v

PHP: Echo something for each 2 results

I have a simple foreach loop that outputs the information I want.
However, I want to wrap it with a div for every two results.
I tried the modulus operator with no success (the result applied for every result).
So, my code:
foreach ($result->data as $info) {
// A open div to wrap two results
echo 'something';
// An closing div to wrap the previous two results
}
This will do it!
foreach ($result->data as $i=>$info) {
if ($i % 2 == 0) echo '<div>';
echo $info;
if ($i % 2 == 1) echo '</div>';
}
if (count($result->data) % 2 == 1) echo '</div>';
exactly what you asked ;)
Most simple way: Iterate in steps of 2.
for ($cc = 0; $cc<count($result->data); $cc += 2) {
// here >> start div container for both
echo $result->data[$cc];
if (defined($result->data[$cc+1]))
echo $result->data[$cc+1];
// here >> end div container for both
}
HTML omitted for clearness.
You can also add an else branch to output a placeholder if the result contains an odd number of items.
add an index count then check that its divisible by two in the code.
IN THIS CASE the if block needs to be at the top of the foreach loop, since I started $i at 0. Please stop editing that portion :)
$i = 0;
// Create first new div before loop, here.
echo '<div>'; //first div
foreach ($result->data as $info) {
// An closing div to wrap the previous two results
if ($i % 2){
// Code here would occur after each two iterations
// IE: close div then open new one. something like this
echo '</div><div>';
}
// A open div to wrap two results
echo 'something';
$i++;
}
// close final div after loop, here.
echo '</div>';
For outputting every two results from array you can also use
<?php
$array = range( 1, 20 );
foreach( array_chunk( $array, 2 ) as $pair ) {
echo '<div>' , implode( ' ', $pair ) , '</div>';
}
// <div>1 2</div>
// <div>3 4</div>
// etc
?>
set 2 variables, string and int
save the value in string variable if the value of the int variable is not even
when the second variable is an even number
wrap in div
//just simply
<?php
foreach($result->data as $i=>$info){
if($i<5){
echo $info
}
}
?>

PHP: Count items in array, split total by two, create two UL lists with equal number of elements containing items from array

I have an array containing data (ID numbers and data associated with them).
The number of items in the array is always variable and not known.
I want to split this array in two equal parts IF there's more than 2 items in the original array (not the slice).
Then I want to create two indipendent UL lists containing the resulting array slices items. If the total number of items in the original array is odd, the first list should carry one more item.
I came up with this, but I'm sure I'm doing it wrong... the content shown in the output is almost the same for each UL list, just reordered, plus in my case the number is odd (if I echo $items it comes up with 3.5).
$panels = get_field('related_content');
$items = count($panels);
if ($items > 2) {
$split = $items / 2;
$firsthalf = array_slice($panels, $plit );
$secondhalf = array_slice($panels, 0, $plit);
echo '<div class="related-carousel"><ul>';
foreach($firsthalf as $post_object) :
printf('<li><a target="_blank" title="'.get_the_title($post_object->ID).'" href="'.get_permalink($post_object->ID).'"><span class="thumb">'.get_the_post_thumbnail($post_object->ID, 'smallest').'</span><span class="thumb-title"><h6>'.get_the_title($post_object->ID).'</h6></span></a><span>'.sg_get_the_excerpt().'</span></li>');
endforeach;
echo'</ul></div>';
echo '<div class="related-carousel"><ul>';
foreach($secondhalf as $post_object) :
printf('<li><a target="_blank" title="'.get_the_title($post_object->ID).'" href="'.get_permalink($post_object->ID).'"><span class="thumb">'.get_the_post_thumbnail($post_object->ID, 'smallest').'</span><span class="thumb-title"><h6>'.get_the_title($post_object->ID).'</h6></span></a><span>'.sg_get_the_excerpt().'</span></li>');
endforeach;
echo'</ul></div>';
}
else {
echo '<div class="related-carousel"><ul>';
foreach($panels as $post_object) :
printf('<li><a target="_blank" title="'.get_the_title($post_object->ID).'" href="'.get_permalink($post_object->ID).'"><span class="thumb">'.get_the_post_thumbnail($post_object->ID, 'smallest').'</span><span class="thumb-title"><h6>'.get_the_title($post_object->ID).'</h6></span></a><span>'.sg_get_the_excerpt().'</span></li>');
endforeach;
echo'</ul></div>';
}
You need to change the argument $plit of array_slice into $split! It's always useful to turn on error reporting which helps with such errors: error_reporting(E_ALL).
Could be you need to change your $split variable, e.g. by using ceil(), edit: look at AndVla answer
Think you can solve the problem like that:
$split = ($items+1) / 2;
or
$split = ceil($items / 2);
tim is right, however you also probably want the firsthalf to be the first half of the array, not vise-versa like you have it now. This is because slice arguments are: $output = array_slice($input, $offset, $length);. So you'll want to set your variables like this
$firsthalf = array_slice($panels, 0, $split);
$secondhalf = array_slice($panels, $split, $items);
Cheers

PHP in_array() can't even match a single character. Strict is set to true

I've seen a million of these threads here already, and read through every single one. That, plus some serious Googling.
UPDATE: I am rewriting this post to include complete code and explanation, so everyone understands what is going on and what I am trying to do.
I am developing using CodeIgniter, so some syntax may look weird if you are not familiar with it.
I have an link bar with letters A-Z. The idea is to find only "active" letters that have content in a particular column (mysql LIKE $letter%). With this information I would be able to "dim" certain "empty" letters if there are any, using CSS.
This function here queries mysql and gets each unique first letter of entries in a column. The result should be anywhere from 0 to 26 matches/array items.
//From am_model.php
function getFirstLetter($domainId)
{
$q = $this->db->query("SELECT DISTINCT LEFT(alias_name, 1)
AS letter
FROM am_aliases
WHERE domain_id = '" . $domainId . "'
ORDER BY alias_name;");
if($q->num_rows > 0):
foreach($q->result() as $row)
{
$result[] = $row;
}
//print_r($result); <-- prints out correct result.
return $result;
endif;
}
After that, I call this function from a controller:
$foundLetters = $this->am_model->getFirstLetter($domainId);
then define an $alphabet array.
$alphabet = range('a','z');
foreach($alphabet as $letter)
{
if(in_array($letter, $foundLetters, TRUE)):
echo $letter . ' found<br />';
else:
echo $letter . ' not found<br />';
endif;
}
Nothing complicated. All I have to do is check if a single character in a loop matches my alphabet array.
As Col. Shrapnel suggested below, I did some debugging, and dump() of letters from $alphabet and $foundLetters arrays produce different results, so I guess it does point
to possible encoding issues, which I am trying to figure out now...
Does anyone have any idea what the hell is going on here??
function dump(&$str) {
$i=0;
while (isset($str[$i])) echo strtoupper(dechex(ord($str[$i++])));
}
Here is the result from dump():
a: $alphabet->61 613C6272202F3E<-$foundLetters
b: $alphabet->62 613C6272202F3E<-$foundLetters
c: $alphabet->63 683C6272202F3E<-$foundLetters
d: $alphabet->64 613C6272202F3E<-$foundLetters
and these:
print_r($alphabet); // all 26 letters
Array (
[0] => a
[1] => b
[2] => c
...
[23] => x
[24] => y
[25] => z
)
print_r($foundLetters); // dynamic array.
Array (
[0] => b
[1] => s
)
got your letters from the file, eh? :)
use var_dump instead or print_r and trim in comparison :)
Edit
Use this code to see what is going on
foreach ($alphabet as $letter) {
foreach ($empty_letters as $empty) {
dump($letter);
echo " ";
dump($empty);
echo "<br>";
if ($letter == $empty) {
echo "$letter was found in \$empty_letters<br>\n";
break;
}
}
}
function dump(&$str) {
$i=0;
while (isset($str[$i])) echo strtoupper(dechex(ord($str[$i++])));
}
Works for me
The only thing in your sample that is strange is the : that comes after the foreach - followed by curly braces will cause a syntax error. Is that the problem, or does your program just not output anything?
I got the expected results as well. But I think your example array is different from what you are actually passing through. Give this a try...
foreach(array_values($alphabet) as $letter){
echo $letter . '<br />'; // Correctly prints out every letter from $alphabet.
if(in_array($letter, $emptyLetters)) { // $strict is set
// do something
echo 'found';
}
}

Categories