Problem with array - php

I am running into issues with the following code:
$ids = '"' . implode('", "', $crumbs) . '"';
$motd = array();
$dober = $db->query("SELECT id, name, msg, datetime FROM tbl_depts td INNER JOIN tbl_motd tm ON td.id = tm.deptid WHERE td.id IN (" . $ids . ")");
while ($row = $dober->fetch_array()) {
$motd[] = $row;
}
A print_r reveals this:
Array
(
[0] => Array
(
[0] => 1
[id] => 1
[1] => Management
[name] => Management
[2] => New Management Rule!
[msg] => New Management Rule!
[3] =>
[datetime] =>
)
[1] => Array
(
[0] => 2
[id] => 2
[1] => Human Resources
[name] => Human Resources
[2] => DPS
[msg] => DPS
[3] =>
[datetime] =>
)
)
As such, I cannot use this code to generate things:
foreach ($motd[] as &$value) {
if ($motd['msg'] != "") {
if ($i == 0) {
?>
<li><a href="#" title="content_<?php echo $value['id']; ?>"
class="tab active"><?php echo $value['name']; ?></a></li>
<?
} elseif ($i == $len - 1) {
?>
<li><a href="#" title="content_<?php echo $value['id']; ?>"
class="tab"><?php echo $value['name']; ?></a></li>
<?php } else { ?>
<li><a href="#" title="content_<?php echo $value['id']; ?>"
class="tab"><?php echo $value['name']; ?></a></li>
<?
}
$i++;
}
}
Any ideas on what I'm doing wrong here?
EDIT: you might find it easier to understand if you read this first: Optimize this SQL query

First - your code will not work because of this two lines:
foreach ($motd[] as &$value) {
if ($motd['msg'] != "") {
You should use $motd, not $motd[] in foreach and check $value['msg'], not $motd['msg']
Second, try to use mysql_fetch_assoc instead of mysql_fetch_array
Third - there is no initial value for $i.

1.) You might have an issue with foreach ($motd[] as &$value) {
perhaps it should be foreach ($motd as &$value) {
2.) I would rather use a for() loop instead of a foreach.
for($a=0, $cnt=count($motd)-1; $a<=$cnt; $a++ )
{
if($motd[$a]["msg"] != "" )
{
#do something here
}
}

I have rewritten your code a bit. No need to define the whole HTML several times only because there is a small change in it (I only spotted active).
$i=0;
foreach ($motd as $value) {
if ($value['msg'] != "") {
$active = $i == 0 ? ' active' : ''; //based on the value of `$i`
?>
<li>
<a href="#"
title="content_<?php echo $value['id']; ?>"
class="tab<?php echo $active?>"><?php echo $value['name']; ?></a></li>
<?php
$i++;
}
}
As I noted in the comments earlier:
In foreach you have to specify the array itself, you do not need [].
Always initialize your $i.
You do not need &$value, you only need that reference if you want to modify your array in the foreach.

Related

Created alphabetical list in php [duplicate]

I have an array that already contains all it's values in alphabetical order:
Alligator
Alpha
Bear
Bees
Banana
Cat
Cougar
Now I just want to list the first letter each starts with above it like so:
A
---
Alligator
Alpha
B
---
Bear
Bees
Banana
C
---
Cat
Cougar
etc...
How can this be done?
The solution is to keep in a variable the first letter of the previously printed word, like:
$previous = null;
foreach($array as $value) {
$firstLetter = substr($value, 0, 1);
if($previous !== $firstLetter) echo "\n".$firstLetter."\n---\n\n";
$previous = $firstLetter;
echo $value."\n";
}
NB: if some entries start with a lower-case letter and others with upper-case letters, use the strcasecmp function in the test instead of !==.
here is another simple solution:-
$result = array();
foreach ($list as $item) {
$firstLetter = substr($item, 0, 1);
$result[$firstLetter][] = $item;
}
echo "<pre>"; print_r($result);
Output :-
Array (
[A] => Array
(
[0] => Alligator
[1] => Alpha
)
[B] => Array
(
[0] => Bear
[1] => Bees
[2] => Banana
)
[C] => Array
(
[0] => Cat
[1] => Cougar
)
)
Well i have three solutions.
1) Make another array containing all alphabets. Then use foreach to iterate through this array. And in nested foreach check for occurance of that letter through strpos method of php.
Here is rough code.
<?php
$alphabets = array ("A","B","C"....); //for all alphabtes
foreach($alphabets as $alphabet)
{
echo $alphabet;
foreach($myArray as $arr)
{
$pos = strpos($arr, $alphabet);
if($pos===flase)
{
//do nothing
}
else
{
echo $arr;
}
}
?>
2) second method have same logic as above. But here you dont need to make array for alphabets. You can get all alphabets this way.
<?php
foreach(range('a', 'z') as $letter) {
echo $letter;
}
?>
Php range method
3) Third solution also have same logic as above two. Here you can get alphabets by another way :)
for ($i=65; $i< =90; $i++) {
$x = chr($i);
print $x;
}
For HTML output:
<h3>A</h3>
<ol>
<li>
<em>tag count</em>
Animal
</li>
<li>
<em>tag count</em>
Aqua
</li>
<li>
<em>tag count</em>
Arthur
</li>
</ol>
<!-- if B not EXIST not show B -->
<h3>C</h3>
<ol>
<li>
<em>tag count</em>
Camel
</li>
<li>
<em>tag count</em>
Crazy
</li>
</ol>
<!-- etc -->
I change Artefact2 code and share for you
<?php $previous = null;
foreach ($dataProvider as $key => $tag) {
$firstLetter = strtoupper(substr($tag['name'], 0, 1));
if($previous !== $firstLetter) {
if($key != 0) {
echo '</ol>';
}?>
<h3 class="alpha">
<span><?php echo $firstLetter;?></span>
</h3>
<ol class="tags main">
<?php } ?>
<li class="tag">
<em><?php echo $tag['TagsCount']; ?></em>
<a href="<?php echo $tag['slug']; ?>">
<strong><?php echo ucfirst($tag['name']); ?></strong>
</a>
<span class="perc" style="width: 90px;"></span>
</li>
<?php if($key == count($dataProvider)-1) {
echo '</ol>';
}
$previous = $firstLetter;
}
?>
Best Regards www.Forum.iSYSTEMS.am
Iterate through the array and check if the current item starts with another letter than the previous one. If that's the case print your "A ---".
$currentLetter = '';
foreach ($list as $item) {
$firstLetter = substr($item, 0, 1);
if ($firstLetter !== $currentLetter) {
echo $firstLetter . "\n---\n";
$currentLetter = $firstLetter;
}
echo $item . "\n";
}
As Shivansh said above in his answer, I think that is correct way
$result = array();
foreach ($list as $item) {
$firstLetter = substr($item, 0, 1);
$result[$firstLetter][] = $item;
}
echo "<pre>"; print_r($result);
To Display the array generated by this code use
foreach ( $list as $key => $value ) {
//Do some thing with $key (A,B,C)
foreach ($value as $var){
//Do some thing with $var (Array of A, B ,C)
}
}

Looping into a multidimensional array with PHP

I've got this array:
Array
(
[0] => Array
(
[name] => System
[order] => 1
[icon] => stats.svg
[0] => Array
(
[title] => Multilingual
)
[1] => Array
(
[title] => Coloring
)
[2] => Array
(
[title] => Team work
)
[3] => Array
(
[title] => Tutorials
)
)
)
I want to loop into this to show the section name and after all the features containing in the following array.
So, this is what I made:
foreach ($features as $feature => $info) {
echo '
'.$info['name'].'
<ul class="menu-vertical bullets">
';
foreach (array_values($info) as $i => $key) {
echo '
<li>'.$key['title'].'</li>
';
}
echo '
</ul>
';
}
It works except for the first third <li> where I have the first char of name, order and icon value.
Do you know why ?
Thanks.
array_values return value of array so for info values is name, order, icon, 0, 1, ...
Your values foreach is wrong if you just want print title you can use:
foreach ($features as $feature => $info) {
echo '
'.$info['name'].'
<ul class="menu-vertical bullets">
';
//Remove some keys from info array
$removeKeys = array('name', 'order', 'icon');
$arr = $info;
foreach($removeKeys as $key) {
unset($arr[$key]);
}
foreach (array_values($arr) as $i => $key) {
echo '
<li>'.$key['title'].'</li>
';
}
echo '
</ul>
';
}
In php, array_values means all the values of the array. So array_values($info) is array($info['name'], $info['order'], $info['icon'], $info[0], $info[1], $info[2], $info[3])
in your example, you can skip the non-integer keys of the $info to get your titles:
<?php
$features = array();
$info = array();
$info['name'] = 'System';
$info['order'] = 1;
$info['icon'] = 'stats.svg';
$info[] = array('title'=>'Multilingual');
$info[] = array('title'=>'Coloring');
$features[] = $info;
foreach ($features as $feature => $info) {
echo $info['name'] . PHP_EOL;
echo '<ul class="menu-vertical bullets">' . PHP_EOL;
foreach ($info as $k => $item) {
if(!is_int($k)) continue;
echo '<li>' . $item['title'] . '</li>' . PHP_EOL;
}
echo '</ul>' . PHP_EOL;
}
BUT, your original data structure is not well designed and hard to use. For a better design, you can consider the following code, move your items to a sub array of $info:
<?php
$features = array();
$info = array();
$info['name'] = 'System';
$info['order'] = 1;
$info['icon'] = 'stats.svg';
$info['items'] = array();
$info['items'][] = array('title'=>'Multilingual');
$info['items'][] = array('title'=>'Coloring');
$features[] = $info;
foreach ($features as $feature => $info) {
echo $info['name'] . PHP_EOL;
echo '<ul class="menu-vertical bullets">' . PHP_EOL;
foreach ($info['items'] as $item) {
echo '<li>' . $item['title'] . '</li>' . PHP_EOL;
}
echo '</ul>' . PHP_EOL;
}
Sample output of the two demos:
System
<ul class="menu-vertical bullets">
<li>Multilingual</li>
<li>Coloring</li>
</ul>
It works except for the first third li where I have the first char of name, order and icon value. Do you know why ?
Why you see first chars of the values of 'name', 'order', 'icon'? Let see how PHP works.
Take the first loop as an example: foreach (array_values($info) as $i => $key)
Then $i == 0, $key == 'System'
We know that $key[0] == 'S', $key[1] == 'y', $key[2] == 's', etc.
Then you try to access $key['title'], but the string 'title' is not valid as a string offset, so it is converted to an integer by PHP: intval('title') == 0.
Then $key['title'] == $key[intval('title')] == 'S'
That's what you see.
array_value() returns the values of the array, here you will get the value of the array $info and what I understand is that is not what you need. See details for array_value().
You can check if the key for the $info is an integer. if yes, echo the title. Give this a try.
foreach ($features as $feature => $info) {
echo $info['name'].'<ul class="menu-vertical bullets">';
foreach ($info as $key => $value) {
if (is_int($key)) {
echo '<li>'.$key['title'].'</li>';
}
}
echo '</ul>';
}

how to add html element for every three result in foreach using php?

I would like to add ul li html element for every 3 results in foreach using php. I have tried with the following method. but i am not getting the exact results. please advise on this
Array ( [0] => stdClass Object ( [category_name] => Architect )
[1] => stdClass Object ( [category_name] => Doors & Windows )
[2] => stdClass Object ( [category_name] => Garage Doors )
[3] => stdClass Object ( [category_name] => Home Inspection ) )
<?php
$i=0;
//$arrays = array_chunk($get_business_cat_details, 3);
foreach($get_business_cat_details as $key=> $cat_name){
//echo " <ul style='margin-top: 20px;'><li><a href='#'>".ucwords($cat_name->category_name) ."</a></li>";
if($i%3==0){
echo "<ul><li><a href='#'>".ucwords($cat_name->category_name) ."</a></li></ul>";
}else{
echo "<ul><li><a href='#'>".ucwords($cat_name->category_name) ."</a></li></ul>";
}
$i++;
}
?>
Output:
Power -- Wash -- Cleaning Paint
East Valley -- Central/South Phx -- West Valley
Please try below code.
<?php
$i = 0;
//$arrays = array_chunk($get_business_cat_details, 3);
foreach ($get_business_cat_details as $key => $cat_name) {
//echo " <ul style='margin-top: 20px;'><li><a href='#'>".ucwords($cat_name->category_name) ."</a></li>";
if($i==0) {
$get_style="style='margin-top: 20px;'";
} else {
$get_style="";
}
if ($i % 3 == 0) {
echo "<ul ".$get_style." >";
}
echo "<li><a href='#'>" . ucwords($cat_name->category_name) . "</a></li>";
$i++;
if ($i % 3 == 0 && $i != 0) {
echo "</ul>";
}
}
?>
I think this may be what your looking for. Since your initial tag is in your loop every result would essentially be a complete list. By removing the from the loop you can close the tag and open a new one dynamically in the loop.
<? php
$i = 0;
echo "<ul>";
foreach($get_business_cat_details as $key => $cat_name) {
if ($i % 3 == 0) {
echo "</ul><ul>";
}
echo "<li><a href='#'>".ucwords($cat_name - > category_name).
"</a></li>";
$i++;
}
echo "</ul>";
?>

match two arrays and return count of how much values matched php

I have one array with values: $array_metaValue
Array ( [0] => php [1] => ajax [2] => my [3] => profile [4] => java )
and second array contains: $search_res[$e]
php
ajax
But the problem is that the count value is always one which is wrong. It should be 2.
print_r( $array_metaValue);
for($e=0;$e<=count($search_res);$e++){
echo '<br>'.$search_res[$e].'<br>';
echo '<pre>';
$key = array_search($search_res[$e],$array_metaValue);
if(!$key==0)
{
$count=$count+1;
}
$count right now is saving 1.
Use
$count = count(array_intersect($array_metaValue, $search_res));
array_intersect returns an array containing the elements that are in both of the input arrays.
The problem with your code is that you need to test
if ($key !== false)
Try this
$arrInp = array('php','ajax','my','profile','java');
$arrSearch = array('php','ajax');
$count = 0;
foreach ($arrSearch as $key => $value) {
if(in_array(trim($value), $arrInp))
$count++;
}
echo $count;
<?php
$array_metaValue=array('php','ajax','profile','java');
$search_res=array('php','ajax');
print_r($array_metaValue);
$count=0;
for($e=0;$e<count($search_res);$e++){
echo '<br>'.$search_res[$e].'<br>';
$key = array_search($search_res[$e],$array_metaValue);
echo 'Key value =>'.$key. " ";
if($key>=0)
{
$count=$count+1;
echo 'Count value =>'.$count;
}
}
?>

Foreach giving erroneous $value

This has me stumped. print_r displays the correct array indices and values, but the foreach construct retrieves erroneous values and even changes the value for the last index even though I'm not retrieving the values by reference (not using the ampersand).
<?php
require './includes/dbal.php';
require './includes/user.php';
require './includes/book.php';
session_start();
$title='My Shopping Cart';
include './template/header.php';
if(!isset($_SESSION['user']))
{
die('You are not logged in.');
}
if(!isset($_SESSION['cart']))
{
$_SESSION['cart'] = array();
}
if(isset($_POST['submit']) && strcmp($_GET['mode'], 'add') == 0)
{
if(filter_var($_POST['qty'], FILTER_VALIDATE_INT) == FALSE)
{
echo '<div style="color: red;">Invalid quantity specified. Please go back and use a valid quantity.</div>';
}
else
{
$_SESSION['cart'][$_POST['book_id']] = $_POST['qty'];
}
}
else if(isset($_POST['update']) && strcmp($_GET['mode'], 'update') == 0)
{
foreach($_SESSION['cart'] as $key => &$value)
{
if((int) $_POST["qty_$key"] === 0)
{
unset($_SESSION['cart']["$key"]);
}
else
{
$value = $_POST["qty_$key"];
}
}
}
echo '<h3>Your shopping cart</h3>';
$db = new DBal();
$total=0;
echo '<div id="cart-items"><ul><form action="./cart.php?mode=update" method="post">';
// echo 'Original array: '; print_r($_SESSION['cart']);
foreach($_SESSION['cart'] as $key => $value)
{
// echo '<br />$key => $value for this iteration: ' . "$key => $value<br />";
// print_r($_SESSION['cart']);
$b = new Book($key, $db);
$book = $b->get_book_details();
$total += $value * $book['book_nprice']
?>
<li>
<div><img src="./images/books/thumbs/book-<?php echo $book['book_id']; ?>.jpg" title="<?php echo $book['book_name']; ?>" /></div>
<span class="cart-price">Amount: Rs. <?php echo $value * $book['book_nprice']; ?></span>
<h3><?php echo $book['book_name']; ?> by <?php echo $book['book_author']; ?></h3>
Price: Rs. <?php echo $book['book_nprice']; ?><br /><br />
Qty: <input type="number" name="qty_<?php echo $book['book_id']; ?>" maxlength="3" size="6" min="1" max="100" value="<?php echo $value; ?>" /><br />
</li>
<?php } echo "<span class=\"cart-price\">Total amount: $total</span>" ?>
<br />
<input type="submit" name="update" value="Update Cart" />
</form></ul></div>
<?php include './template/footer.html'; ?>
Sample output after pressing the update button is like this :
Original array:
Array (
[9] => 6
[8] => 7
[3] => 8
)
$key => $value for this iteration: 9 => 6
Array (
[9] => 6
[8] => 7
[3] => 6
)
$key => $value for this iteration: 8 => 7
Array (
[9] => 6
[8] => 7
[3] => 7
)
$key => $value for this iteration: 3 => 7
Array (
[9] => 6
[8] => 7
[3] => 7
)
The value for the last index gets changes to the value of the current index in every iteration. This results in the last value output having the same value as the second-to-last index.
Help?
You were using &$value as reference before:
foreach($_SESSION['cart'] as $key => &$value)
The variable continues to exist as reference beyond the loop, using it again in a loop has expected but non-obvious side effects. This is even mentioned in a big red box in the manual. unset($value) after the first loop to avoid that.
You are using references here:
foreach($_SESSION['cart'] as $key => &$value)
Either don't use reference here or unset $value immediately after the loop.

Categories