Having difficulties with php foreach and passing by reference - php

I'm pulling some data from a database (with a function I have called query), and I want to add another key/value pair to each result, i.e.:
$items = query("SELECT * FROM items");
foreach($items as &$item) {
$item['fixedname'] = str_replace(' ','_',$item['name']);
}
Now I want to put these on an html view, i.e.:
<?php foreach($items as $item): ?>
<div id="<?= $item['fixedname'] ?>" ><?= $item['name'] ?></div>
<?php endforeach; ?>
However, this doesn't output correctly. For instance, when the query returns two items, the loop in the php outputs the same thing twice. If there are three: it outputs the first one, then two of the second one. What's the problem here?

When modifying using foreach() I've had weird results on occasion. I use
foreach ($items as $key=>$value) {
$items[$key] = modified($value);
}
Or, why not do it in the SQL SELECT your, fields, here, REPLACE(name, ' ', '-') AS fixedname

The data returned on the right side of the foreach is a copy of the data, it can't be modified directly. Instead you need to fetch both the $key (the ID of the item in the array) and the $item. By letting PHP telling you the $key you don't need to worry about whether the array is normal (e.g. having indexes of 0,1,2,...) and associative.
This example would walk the $items array and add 'fixedname' into it.
foreach($items as $key => $item) {
$items[$key]['fixedname'] = str_replace(' ','_',$item['name']);
}

You could do a normal for loop
<?php
for($i=0; $i < count($items); $i++){
$items[$i]['fixedname'] = str_replace(' ','_',$items[$i]['name']);
}
?>
Then everything will be ready when you go to your next foreach.

u have bunch of wrong things
1- dont use mysql , use PDO or mysqli instead
2- $items = query("SELECT * .... --->Call to undefined function query()
change it to
$items = mysql_query("SELECT * ....
3- Invalid argument supplied for foreach() ,
you missed to fetch your query
try this whole code
$items = mysql_query("SELECT * FROM items");
?>
<?php while ($row = mysql_fetch_array($items) ) {?>
<div id="<?php echo $row['fixedname'] ;?>" ><?php echo $row['name']; ?></div>
<?php } ?>

Related

Can't delete my first item in shopping basket

Currently doing my computing science assignment and I've chosen to make an online shop, I've used a tutorial to make the shopping basket and everything is working except I can only delete every item except the first one added to my cart. I'd really appreciate any help if possible.
This is where items in my cart are displayed (cart.php):
<?php
session_start();
require_once('db.php');
include('common.php');
?>
<?php getHeader(); ?>
<div class="container">
<div class="row">
<table class="table">
<?php
$items = $_SESSION['cart'];
$cartitems = explode(",", $items);
?>
<?php
$total = '';
$i=1;
foreach ($cartitems as $key=>$id) {
$sql = "SELECT * FROM products WHERE id = $id";
$res = mysqli_query($con, $sql);
$r = mysqli_fetch_assoc($res);
?>
<tr>
<td><?php echo $i; ?></td>
<td>Remove <?php echo $r['name']; ?></td>
<td>£<?php echo $r['price']; ?></td>
</tr>
<?php
$total = $total + $r['price'];
$i++;
}
?>
<tr>
<td><strong>Total Price</strong></td>
<td><strong>£<?php echo $total; ?></strong></td>
<td>Checkout</td>
</tr>
</table>
</div>
</div>
<?php getFooter(); ?>
This is my code that adds an item to my cart(addtocart.php):
<?php
session_start();
if(isset($_SESSION['cart']) & !empty($_SESSION['cart'])){
$items = $_SESSION['cart'];
$cartitems = explode(",", $items);
$items .= "," . $_GET['id'];
$_SESSION['cart'] = $items;
header('location: index.php?status=success');
}else{
$items = $_GET['id'];
$_SESSION['cart'] = $items;
header('location: index.php?status=success');
}
if(in_array($_GET['id'], $cartitems)){
header('location: index.php?status=incart');
}else{
$items .= "," . $_GET['id'];
$_SESSION['cart'] = $items;
header('location: index.php?status=success');
}
?>
This is my delete item code (delcart.php):
<?php
session_start();
$items = $_SESSION['cart'];
$cartitems = explode(",", $items);
if(($_GET['remove']) & !empty($_GET['remove'])){
$delitem = $_GET['remove'];
unset($cartitems[$delitem]);
$itemids = implode(",", $cartitems);
$_SESSION['cart'] = $itemids;
}
header('location:cart.php');
?>
The problem is this line:
if ($_GET['remove'] & !empty($_GET['remove']))
When you want to remove the first item, $_GET['remove'] is 0, which is falsey and also considered empty, so the code that's supposed to remove it doesn't run. Change it to:
if (isset($_GET['remove']) && is_numeric($_GET['remove']))
Also, throughout your scripts you're using & when you should be using &&. & is bit-wise AND, && is logical AND.
When you have only one item in your session,
$cartitems = explode(",", $items);
result is array with "0" index, so if you want to remove last value, $_GET['remove'] should be equal to "0" (example: www.site.loc/?remove=0)
I hope you show us only a sample (not production) code because it is very wrong written and dangerous example:
$sql = "SELECT * FROM products WHERE id = $id"; SHOULD NEVER BE USE!
There's a few things wrong with your code:
1) $_SESSION['cart'] appears to be a string of comma-separated ids, i.e. string(10) "1, 2, 3, 4"
Thus, $cartitems = explode(",", $items) would return an array of those ids, i.e. array(4)[ 1, 2, 3, 4 ]
2) Assuming that $_GET['remove'] is a string containing the item id, i.e. 3
Calling unset($cartitems[$delitem]) would remove the last element of my example array, 4, since arrays are zero-indexed.
To remove the value 3 you'd have to call:
$delitem = array_search($_GET['remove'], $cartitems);
unset($cartitems[$delitem]);
(see http://php.net/array_search)
3) May I please suggest using PDO? http://php.net/manual/en/book.pdo.php
Edit: since I can't comment, Barmar:
Given that OP's items are stored in a database, and id is likely a primary key, it's unlikely that he'd have an item with id of 0 so empty() should be perfectly suitable for his needs. To expound on that point, though, OP, Barmar is correct that in if there are in fact 0 based ids, you'd want to use isset($_GET['remove']) not !empty($_GET['remove'])
See http://php.net/isset and http://php.net/empty for differences.
Your loop and then usage of the variables is the problem:
foreach ($cartitems as $key=>$id) {
...
<td>Remove <?php echo $r['name']; ?></td>
...
}
The $key should be $id
When using foreach this way, the $key var is the array index and the $id is the value (which could be a string, array, object, int...).
http://php.net/manual/en/control-structures.foreach.php
But since you don't care about the array index here, you can simply omit it from the foreach declaration:
foreach ($cartitems as $id) {
and it will work identically.

php - why showing value of last item from array?

Ok, I have this code
<?php //getting values
$column1 = $params->get('param1','');
$column2 = $params->get('param2','');
$column3 = $params->get('param3','');
$column4 = $params->get('param4','');
$column5 = $params->get('param5','');
//setting array and filter the empty values
$getvalues = array($column1,$column2,$column3,$column4,$column5);
$values = array_filter($getvalues); ?>
then I am using these values inside a foreach
<?php foreach ( $values as $key=>$value ) : ?>
<div><?php echo $value; ?></div>
<?php endforeach; ?>
It does the job, but after the loop, it adds the last item's value. Why?
After a foeach loop the used $key and $value variables are still alive and holds their last values so i think you are using the $value somewhere else in you code whithout rewriting it's value.
Call unset($value) and unset($key) after the loop and watch the PHP errors i think you will face some if the error reportnig is set to the most strict mode.

Grabbing key value from a mysql query

I thought this was quite basic but for some reason I can't figure it out.
I have this query
$result = mysql_query("SELECT * FROM Users.Information LIMIT 0,1");
To grab the data (such as firstName, lastName), I use this snippet of code
<?php while ($row = mysql_fetch_assoc($result)): ?>
<?php foreach($row as $key=>$value) {
echo $value;
} ?>
<?php endwhile; ?>
which correctly prints everything I want.
Now in a separate table, I want to have it such that I will print the individual values separately. I thought this was quite simple like
first name:
however, this does not work. If I just do $value, of course this makes sense, but it prints the last value in the array.
How do I grab individual values? Do I just parse $value into different values, or is there an easier way?
Thank You.
$data = array() ; //Create a storage, so you can access it later.
<?php while ($row = mysql_fetch_assoc($result)): ?>
$data[] = $row ; //Add the value to storage.
<?php foreach($row as $key=>$value) {
echo $value;
} ?>
<?php endwhile; ?>
We are ready. We have $data array with all rows. Now you can manipulate it, access elements, pass somewhere.
$data[0] ; //Access the first element
echo $data[0]['FirstName'] ; //Print first name of the first row.

Subarray within foreach loop php

I have this code here:
<?php foreach($blog_posts['post_category'] as $category) { ?>
How can I get this to work?
Basically I have a database with all my blog posts within them, one of the columns is post_category I'm trying to make a list out of all these by a foreach statement that gets the results like so:
$data['blog_categories'] = $this->db->query("SELECT `post_category` FROM `blog_posts`");
This is codeigniter by the way... Then in my view I have the code:
<?php foreach($blog_posts['post_category'] as $category) { ?>
I need to display each category in an li...
You wanna use implode I think
$output = array();
forreach($blog_posts['post_category'] as $item){
$output[] = "<li>$item</li>";
}
echo "<ul>".implode('',$output)."</ul>";
Or if you were just after the list items and not list just replace the last line with
echo implode('',$output);
Pretty sure what you're looking for is
$data['blog_categories'] = $this->db->query("SELECT DISTINCT `post_category` FROM `blog_posts`");
foreach ($data['blog_categories'] as $category) {
echo "<li>$category</li>";
}
Me, I'd change $data['blog_categories'] to just $blog_categories or something, but I kept it as you had it so as not to confuse the issue.

How do I code a loop for my echo statement?

I get only one printed result in the foreach echo loop at the bottom of the page.
<?php
defined('_JEXEC') or die('Restricted access');
$db =& JFactory::getDBO();
$query0 = "SELECT * FROM `jos_ginfo` WHERE . . . LIMIT 30";
//echo $query0;
$db->setQuery($query0);
$ginfo = $db->loadObjectList();
//echo
//$ginfo[0];
foreach($ginfo as $ginfo[$i]):
{$i=0; $i++;}
endforeach;
echo $db->getErrorMsg();
if(empty($ginfo)){
echo "<center>No
game found, try a different entry.</center>";
}else{
$pgndata = array ( $ginfo[$i]->Id);
$i=0;
foreach($pgndata as $ginfo[$i]->Id):
//I am only getting one printed result!
{
echo "<a href='/index.php?option=com_publishpgn&tactical-game=".$ginfo[$i]->Id."&Itemid=78.html'>\n";
echo "".$ginfo[$i]->White." v. ".$ginfo[$i]->Black." (".$ginfo[$i]->Result.") ".$ginfo[$i]->EventDate." ECO:".$ginfo[$i]->ECO."</a><br>\n";
$i++;
}
endforeach;
//echo "</div>";
}
?>
A few errors in your code:
foreach($ginfo as $ginfo[$i]):
{$i=0; $i++;}
On the first iteration, $i is undefined, so the first value pulled from $ginfo for the foreach loop will be stored in $ginfo[null]. You then set $i to 0, increment it, and loop around, so now the next value gets stored in $ginfo[1], as will all further iterations. So you end up with only two values extracted from the $ginfo object, and stored in the 'null' and '1' keys.
Later, you do
$pgndata = array ( $ginfo[$i]->Id);
You're not doing this inside a loop, so $pgndata becomes an array with a single element taken from $ginfo[1]->Id. You then immediately do
foreach($pgndata as $ginfo[$i]->Id):
but $pgndata has only a single element in it, which explains why you only have one item output.
I don't know what your ->loadObjectList() at the top does. Is it returning an array? An object? If it's any array, what's the point of the first foreach loop? You're destroying all but the first two values present in it.
It's never ever a good idea to try and modify an array WHILE you're looping over it in a foreach loop. It's kinda like trying to change a tire and axle and transmission on your car while going down the highway at 100mph. You might get lucky once, the rest of the time you're going to be spread into a thin ketchup stain.
Also, why are you mixing the {} and : / end syntaxes? Choose one or the other, but don't use both. Braces are standard and universally understood. the :/end version is far less popular and unfamiliar to most people.
I suppose, you need this:
$ginfo = $db->loadObjectList();
foreach($ginfo as $value)
{
echo $value . '<br />';
}
Further, see foreach manual and other loops.
$query = mysql_query("select * from table");
while ($result = mysql_fetch_array($query))
{
echo "$result[id]";
echo "$result[firstname]";
}
This is a modified version of Sarfraz's code.
Try this..
// Array of multiple games
$ginfo = $db->loadObjectList();
// Loop through games array
foreach ($ginfo as $index => $singleGameInfo)
{
foreach($singleGameInfo as $elementName => $elementValue)
{
echo "[$elementName \"$elementValue\"]\n";
}
}
In place of...
echo "[Event \"".$ginfo[0]->Event."\"]\n";
echo "[Site \"".$ginfo[0]->Site."\"]\n";
echo "[Date \"".$ginfo[0]->Date."\"]\n";
echo "[Round \"".$ginfo[0]->Round."\"]\n";
echo "[White \"".$ginfo[0]->White."\"]\n";
echo "[Black \"".$ginfo[0]->Black."\"]\n";
echo "[Result \"".$ginfo[0]->Result."\"]\n";
echo "[ECO \"".$ginfo[0]->ECO."\"]\n";
echo "[WhiteElo \"".$ginfo[0]->WhiteElo."\"]\n";
echo "[BlackElo \"".$ginfo[0]->BlackElo."\"]\n";
echo "[Annotator \"".$ginfo[0]->Annotator."\"]\n";
echo "[SetUp \"".$ginfo[0]->SetUp."\"]\n";
Edit: Are you trying to loop through multiple games or the field-data of a single game?
Edit2: Updated to loop through games

Categories