I am working on a simple order system.
the peice of code I am stuck on is the following:
if (isset($_GET['cart']))
{
$cart = array();
$total = 0;
foreach ($_SESSION['cart'] as $id)
{
foreach ($items as $product)
{
if ($product['id'] == $id)
{
$cart[] = $product;
$total += $product['price'];
break;
}
}
}
include 'cart.html.php';
exit();
}
This is the code is build on a preset array. I am working with a table with a few columns in mysql.
I have decided on the following:
if (isset($_GET['cart']))
{
$cart = array();
$total = 0;
foreach ($_SESSION['cart'] as $id)
{
while($row = mysql_fetch_assoc($productsSql)) {
foreach ($row as $product)
{
if ($product['id'] == $id)
{
$cart[] = $product;
$total += $product['price'];
break;
}
}
}
include 'cart.html.php';
exit();
}}
To display this "cart" I have decided on this:
foreach ($cart as $item) {
$pageContent .= '
<tr>
<td>'.$item['desc'].'</td>
<td>
R'.number_format($item['price'], 2).'
</td>
</tr>
';
}
All this seems to do is produce my cart in a fashion where when viewed it displays a list of only the items' id, e.g. where the description and price are supposed to be, I only get the items id in both fields... I also get a total price of 0.
Can anyone spot where I am going wrong here?
Or atleast try to give me some input so that I get going in the right direction!
Thanks!!
$productsQuery = 'SELECT `id`, `refCode`, `desc`, `pack`, `measure`, `quantity`, `deptCode`, `taxable`, `price1`, `price2`, `crdCode`, `cost1`, `cost2` FROM `products` ORDER BY `desc` ';
$productsSql = mysql_query($productsQuery) or die(mysql_error());
if (mysql_num_rows($productsSql) == 0) {
die('No results.');
} else {
$orderContent = '';
while($row = mysql_fetch_assoc($productsSql)) {
$prId = $row['id'];
$prRefCode = $row['refCode'];
$prDesc = $row['desc'];
$prPack = $row['pack'];
$prMeasure = $row['measure'];
$prQuantity = $row['quantity'];
$prDeptCode = $row['deptCode'];
$prTaxable = $row['taxable'];
$prPrice1 = $row['price1'];
$prPrice2 = $row['price2'];
$prCrdCode = $row['crdCode'];
$prCost1 = $row['cost1'];
$prCost2 = $row['cost2'];
$orderContent .= '
<tr>
<td>'.$prId.'</td>
<td>'.$prDesc.'</td>
<td>'.$prPack.'x'.$prSize.' '.$prMeasure.'</td>
<td>R'.$prPrice1.'</td>
<td>
<form action="" method="post">
<div>
<input type="text" size="3" name="quantity" />
</div>
</form>
</td>
<td>
<form action="" method="post">
<div>
<input type="hidden" name="id" value="'.$prId.'" />
<input type="submit" name="action" value="Order" />
</div>
</form>
</td>
</tr>
';
}}
Let's say that each of the rows in your database looks like this...
[product_id][product_name][product_description][product_price]
When you assign your query return to a variable passed through mysql_fetch_assoc() using a while loop, each pass will isolate a whole row. Of which you can piece apart manually by array key reference ($array['product_id']) or by using a foreach loop. I think the problem you're having is that you are mixing this up. Keeping the above example table layout in mind, you could do something like the following:
while ($tableRow = mysql_fetch_assoc($query)) { // Loops 3 times if there are 3 returned rows... etc
foreach ($tableRow as $key => $value) { // Loops 4 times because there are 4 columns
echo $value;
echo $tableRow[$key]; // Same output as previous line
}
echo $tableRow['product_id']; // Echos 3 times each row's product_id value
}
Look at this line in your code: if ($product['id'] == $id) { }
I think you probably mean if ($row['id'] == $id) { } instead.
Your middle code block makes no sense. You loop over session variables, and run a query each time... but it's the SAME query, and using an undefined variable to boot. Looping over a result row doesn't make much sense, as you'd be looping over the individual fields that your query returns for each row.
e.g. If your products table has just (id, name, description) as fields, then $row would be an array that looks like:
$row = array('id' => xxx, 'name' => yyy, 'description' => zzz);
When you foreach() on $row(), you'd not getting individual products, you'd be getting those fields in the row. $product would be xxx, then yyy, then zzz.
I don't know what your code is trying to accomplish - I'd guess you're trying to retrieve prices for products that a user is adding into their cart, but you're going about it in a very strange and highly inefficient manner.
Related
I have a search form with multiple "text" inputs currently functioning which I am trying to add checkboxes to.. After adding the checkboxes, I'm getting the following:
ERROR: Array to String Conversion
<form action='s-response.php method='get'>
<div class='cusname'><input type='text' name='cusname' class='EdtTxt' /></div>
<div class='street'><input type='text' name='street' class='EdtTxt' /></div>
Checkboxes
<?php while ($row=$query->fetch()){?>
<input type='checkbox' name='groupid[]' value='<?php echo $row['id'];?>'><?php echo $row['title'];?><?php }?>
RESPONSE PAGE
$wheres = array();
$params = array();
/* Find all Sent fields, If the field is Not Empty, add the field to the SQL query */
if (!empty($_GET['cosname'])) { $wheres[] = 'c.cname LIKE :cosname'; $params[':cosname'] = '%'.$_GET['cosname'].'%'; }
if (!empty($_GET['street'])) { $wheres[] = 'a.street LIKE :street'; $params[':street'] = '%'.$_GET['street'].'%'; }
Checkbox Part
if(!empty($_GET['groupid'])) {
foreach($_GET['groupid'] as $value){
$wheres[] = 'g.groupid = :groupid'; $params[':groupid'] = $_GET['groupid'];
}}
Query Part
/* Create the Start and End (static) parts of the query */
$q1="SELECT c.fname,a.street FROM customers c LEFT JOIN cus_address a ON c.id=a.custid WHERE c.act=1";
$q3=" GROUP BY c.id";
/* Create the Middle (dynamic) part of the query */
if (!empty($wheres)) { $q1 .= " AND " . implode(' AND ', $wheres); }
/* Combine into one query and execute */
$sql=$q1.$q3;
$query=$con->prepare($sql);
$query->execute($params);
Any idea what is causing the error?
Query Part
if(!empty($_GET['groupid'])) {
foreach($_GET['groupid'] as $i => $value){
$placeholder = sprintf(':groupid%d', $i+1);
$wheres[] = sprintf('g.groupid = %s', $placeholder);
$params[$placeholder] = $value;
}
}
In the foreach loop, you should be using $value, not $_GET['groupid'] - It's an array, remember? You're currently iterating over it.
I have edited my answer to show how to handle multiple group ids. The placeholder is unique, eg. :groupid1, :groupid2, :groupid3.
I was trying to update my table but I couldn't make it work.. I always end up with the error:
Invalid argument supplied for foreach()
Here is my Controller:
public function show_score($id)
{
$scores = Score::with(['lead','subject'])->where(['subject_id'=>$id])->get();
return view('markbook.show_score',compact('scores'));
}
public function update_score(Request $request)
{
$id = $request->input('id');
$scores = Score::find($id);
foreach ($scores as $datas) {
$datas->jan_ap=$request->input('jan_ap');
$datas->jan_hm=$request->input('jan_hm');
$datas->save();
}
}
route:
Route::get('markbook/scores/{id}', 'MarkbookController#show_score' );
Route::post('markbook/scores', 'MarkbookController#update_score');
Here is my table I'm trying to loop the updated score:
From chat discussion what found is that you want to update multiple scores, which is listed in tr, td. You can change it like this
Change in view
#foreach($scores as $score)
<tr>
<td>{{$score->lead->student_name}} <input type="hidden" name="scores[{{$loop->index}}][id]" value="{{$score->id}}"></td>
<td><input type="text" name="scores[{{$loop->index}}][jan_ap]" value="{{$score->jan_ap}}"></td>
<td><input type="text" name="scores[{{$loop->index}}][jan_hm]" value="{{$score->jan_hm}}"></td>
</tr>
#endforeach
Controller update score
public function update_score(Request $request)
{
$scores = $request->input('scores'); //here scores is the input array param
foreach($scores as $row){
$score = Score::find($row['id']);
$score->jan_ap = $row['jan_ap'];
$score->jan_hm = $row['jan_hm'];
$score->save();
}
}
Using Score::find($id) you're only ever going to return 1 result so there won't be anything to foreach over.
If you just want to update a single row in the table you don't need to foreach it.
You can simply run
$score = Score::find($request->input($id));
$score->jan_ap = $request->input('jan_ap');
$score->jan_hm = $request->input('jan_hm');
$score->save();
if you want to return multiple rows you need to change your find to a get()
so $scores = Score::where('something', $request->input('something))->get();
If you want to update every row in the table with the same information you'd do a:
$scores = Score::all();
That would return every row in the table.
i would like to ask for your help to solve my problem. Your help is kindly appreciated.
My question is i have two inputs type which are array ( <input type='text' name='cost[]'> and <input type='text' name='price[]'> ) in view. Both inputs type are within a foreach statement. Let's say foreach from a table of database that has 3 records. So, from the view of web browser it requires user to input 3 times on the cost and price fields for every record. In my controller, i want to compare user input as below
-price[1] cannot be more than cost[1]
-price[2] cannot be more than cost[2]
-price[3] cannot be more than cost[3]
by using if else statement. How am i going to code in my controller so that price[1] is only compared to cost[1], price[2] is only compared to cost[2] and price[3] is only compared to cost[3].Below is my code in my controller, but cannot work.
$cost = $this->input->post('cost');
$price = $this->input->post('price');
if ($price > $cost)
{
echo "Rejected";
}
else
{
echo "Accepted";
}
You will need to loop over all the values.
My Codeigniter is a little rusty but I believe $cost and $price should both be arrays. Some something simple like this;
foreach ($price as $key => $value) {
if ($value > $cost[$key] ) {
echo "Rejected";
} else {
echo "Accepted";
}
}
If you want all to be valid then you could just break on the first rejected value. Otherwise you loop through all and warn the user about the invalid ones?
Please try the code below.
For demo: Demo URL
<?php
//$cost = $this->input->post('cost');
//$price = $this->input->post('price');
//Suppose I have added dummy values in these variable as you received from view.
$cost = array(1,2,3);
$price = array(3,4,1);
//as you mentioned each one cost have price like $cost zero index compared with $price zero index.
$i = 0;
foreach($cost as $cos){
if ($price[$i] > $cos)
{
echo "Rejected";
}
else
{
echo "Accepted";
}
$i++;
}
?>
Hi guys I was wondering if they is a way to cross check select options getting posted to a different page with a database just to make sure that someone hasn't change anything using a inspect element or firebug or any developer tool.
database table product
my database looks something like this but they are over 400 data in it.
pid name size
1 grey 12 inch
2 blue 16 inch
database table category
pid category
1 vans
2 nike
database table itemised
pid price
1 30.00
2 50.00
item.php
in my item.php page I have a table. The size and category and SELECT OPTION then I have an input field for amount which uses jquery for validation.
in my cartpage.php
I Posting the pid, size and category then I am using all those to find the price(I AM NOT POSTING THE PRICE, I AM USING THE pid, size and category to find it.)
Now the problem is, if someone was to change the value for the size or category or both. They will still get posted but obviously the price wouldn't be find because the database can't find those value getting posted.
How I show my value category example *similar to how i show size too apart from I change the select statement*
<select id="Category" name="Category">
<?php
dbconnect();
$stmt = $conn->prepare("SELECT Name FROM Category WHERE pid=:id");
$stmt->bindParam('id',$id);
$stmt->execute();
$i = 0;
foreach ($stmt->fetchAll(PDO::FETCH_ASSOC) as $row ) {
if ($i == 0) {
echo '<option SELECTED value="'.$row['Name'].'">'.$row['Name'].'</option>
';
}
else {
echo '<option value="'.$row['Name'].'">'.$row['Name'].'</option>';
}
$i++;
}
?>
</select>
My question
Is they a way to find out that what is getting posted exist in the database and it is related to the pid? and if not that item shouldn't be added.
Edited to add how my cart page looks like Jim Martens I have added the code you show in your answer
//I have session start on top of this page.
<?php
*jim matens your code starts here*
if (isset($_GET['pid'])){
$id = $_GET['ProdID'];
$categoryID = (isset($_POST['Category']) ? intval($_POST['Category']) : 0);
dbconnect();
$stmt1 = $conn->prepare("SELECT CatID FROM Category WHERE pid=:id");
$stmt1->bindParam('id',$id);
$stmt1->execute();
$isValid = false;
$rows2 = $stmt1->fetchAll(PDO::FETCH_ASSOC);
foreach ($rows2 as $row1) {
if ($row1['CatID'] == $categoryID) {
$isValid = true;
break;
}
}
}
*My code starts here*
if(isset($_POST['pid']) && isset($_POST['length']) && isset($_POST['Qty']) && isset($_POST['Category'])){
$pid = $_POST['pid'];
$length = $_POST["length"];
$qty = $_POST['Qty'];
$Category = $_POST['Category'];
$wasFound = false;
$i = 0;
// If the cart session variable is not set or cart array is empty
if (!isset($_SESSION["cart_array"]) || count($_SESSION["cart_array"]) < 1) {
// RUN IF THE CART IS EMPTY OR NOT SET
$_SESSION["cart_array"] = array(0 => array("item_id" => $pid, "length" => $length, "Category" => $Category, "quantity" => $qty));
} else {
// RUN IF THE CART HAS AT LEAST ONE ITEM IN IT
foreach ($_SESSION["cart_array"]as $array_key=>$each_item) {
if ($each_item['item_id'] == $pid && $each_item['length'] == $length && $each_item['Category'] == $Category) {
$_SESSION["cart_array"][$array_key]['quantity']+=$qty;
$wasFound = true;
} // close if condition
} // close while loop
// close foreach loop
if ($wasFound == false) {
array_push($_SESSION["cart_array"], array("item_id" => $pid, "length" => $length, "Category" => $Category, "quantity" => $qty));
}
}
header('Location: '.fetchinline($bpages).$currentFile);
exit();
}
?>
I hope I have explain this clearly and if not please leave a comment and I will try and rephrase the question.
Thanks
JavaScript validation is a nice gimmick for spelling issues and the like. But it is neither foolproof nor able to actually verify if the data is semantically correct. Therefore you need to send the data to the PHP script.
That script now verifies it first for integrity (correct value type and the like). After this initial step you verify against the database in your case. If I understand you correctly, you want to make sure that the sent category is an existing category. There is one very simple way to achieve that.
First your form.
<select id="Category" name="Category">
<?php
dbconnect();
// select the ID of the category as well (should be there anyway)
$stmt = $conn->prepare("SELECT ID, Name FROM Category WHERE pid=:id");
$stmt->bindParam('id',$id);
$stmt->execute();
$i = 0;
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
foreach ($rows as $row) {
if ($i == 0) { ?>
<option selected="selected" value="<?php echo $row['ID']; ?>"><?php echo $row['Name']; ?></option>
<?php } else { ?>
<option value="<?php echo $row['ID']; ?>"><?php echo $row['Name']; ?></option>
<?php
}
$i++;
}
?>
</select>
For the actual processing of the input, you read all categoryIDs from database and check if the selected ID (should be made to integer by now) is among them. If yes, everything's fine, if not the user has given invalid input.
A quick example for that:
$categoryID = (isset($_POST['Category']) ? intval($_POST['Category']) : 0);
dbconnect();
$stmt = $conn->prepare("SELECT ID FROM Category WHERE pid=:id");
$stmt->bindParam('id',$id);
$stmt->execute();
$isValid = false;
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
foreach ($rows as $row) {
if ($row['ID'] == $categoryID) {
$isValid = true;
break;
}
}
ID stands here for the category ID (whatever that is in your case).
Of course your real code would continue before and after this, but it should give you the general direction.
I'm trying to load data from database and display it in table like here:
http://img196.imageshack.us/img196/1857/cijene.jpg
In database I have two tables:
cities (id, name)
prices (id, city1_id, city2_id, price)
For example, the printed table for 4 cities would look like this:
<table>
<tr>
<td>city1</td>
<td> </td>
<td> </td>
<td> </td>
</tr>
<tr>
<td> price_city1-city2</td>
<td>city2</td>
<td> </td>
<td> </td>
</tr>
<tr>
<td> price_city1-city3</td>
<td> price_city2-city3</td>
<td>city3</td>
<td> </td>
</tr>
<tr>
<td> price_city1-city4</td>
<td> price_city2-city4</td>
<td> price_city3-city4</td>
<td>city4</td>
</tr>
</table>
Does someone know what's the PHP statement to echo this kind of tables?
// This single query gets all required data
// NOTE: this query assumes that your price data is entered
// such that from_city always alphabetically precedes to_city!
$sql =
"SELECT a.name AS from_city, b.name AS to_city, price ".
"FROM prices ".
"INNER JOIN cities AS a ON a.id=prices.city1_id ".
"INNER JOIN cities AS b ON b.id=prices.city2_id";
// connect and do query
$conn = mysql_connect($host, $user, $pass);
mysql_select_db($db, $conn);
$q = mysql_query($sql, $conn);
// Stuff all data into an array for manipulation;
// keep list of all cities mentioned
$price = array();
$cities = array();
while (($res = mysql_fetch_assoc($q)) !== false) {
$from = $res['from_city'];
$cities[ $from ] = true;
$to = $res['to_city'];
$cities[ $to ] = true;
$price[$to][$from] = $res['price'];
}
// Invert to get alphabetical list of cities
$cities = array_keys($cities);
sort($cities);
$num = count($cities);
// some utility functions
function table($rows) {
return '<table>'.join($rows).'</table>';
}
function row($cells) {
return '<tr>'.join($cells).'</tr>';
}
function cell($text) {
$text = (string) $text;
if (strlen($text)==0)
$text = ' ';
return '<td>'.$text.'</td>';
}
// The data is now in the desired order;
// produce output as HTML table
$rows = array();
for ($to = 0; $to < $num; ++$to) {
$t = $cities[$to];
$cells = array();
for ($from = 0; $from < $to; ++$from) {
$f = $cities[$from];
if isset($price[$t]) && isset($price[$t][$f])
$text = $price[$t][$f];
else
$text = '';
$cells[]= cell($text);
}
$cells[]= cell($t); // add destination-label
for ($from = $to+1; $from < $num; ++$from) // pad to proper number of cells
$cells[]= cell('');
$rows[]= row($cells);
}
$html = table($rows);
// show results!
echo $html;
I've used a very simple approach to converting the results of a query to an HTML table.
I test that $query_result is true and fetch the results as an associative array...
$query_result = mysqli_query($db, $query);
if ($query_result) {
while ($columns = mysqli_fetch_assoc($query_result)) {
echo "<tr>\n";
foreach ($columns as $name => $column) {
echo "<td>";
printf("%s",$columns[$name]);
echo "</td>\n";
}
echo "</tr>\n";
}
}
EDIT: Now I've been able to look at your table, I can see that I haven't really answered your question. The query is obviously very important. Does the question become 'how do I create a query which returns results which can be turned into a table by my simple-minded approach?'
I hope someone else has a few ideas.
This is somewhat at the edge of practicality, but I'm approaching this problem more as an exercise in "doing it right."
I would do a simple select of each table and insert in to an array:
$query1 = "SELECT * FROM cities";
$query2 = "SELECT * FROM prices";
$results1 = mysql_query( $query1 );
$results2 = mysql_query( $query2 );
while( $rows = mysql_fetch_array( $results1 ) ) $cities[] = $row['name'];
while( $rows = mysql_fetch_array( $results2 ) ) $prices[] = array(
$row['city1_id'],
$row['city2_id'],
$row['name']
);
I would then use this to dynamically create two javascript lists:
$java_array1 = "var Cities = new Array;\n";
foreach( $cities as $key=>$city ) $java_array1 .= "Cities[$key] = \"$city\";\n";
$java_array2 = "var Prices = new Array;\n";
foreach( $cities as $key=>$price ) $java_array2 .= "Prices[$key] = new Array(
\"{$price[0]}\",
\"{$price[1]}\",
\"{$price[2]}\",
);\n";
I would next output a table with carefully crafted ids for each cell. I would use code very similar to that in the first answer, but I would give each cell a unique id of "cell-<row>-<col>".
The last thing I would do would be whip up some onload javascript which would populate the table using the appropriate pairings. My javascript is quite rusty, but it would look something like this (NOTE: pseudocode follows):
n = 1;
for( var i in cities )
{
// set city names on the diagonal
document.getElementById( 'cell-'&i&'-'&i ).innerHTML = names[i];
n = n + 1;
}
for( var j in prices )
{
// use the city IDs in the prices array (see earlier code initializing
// prices array) to place the prices
document.getElementById( 'cell-'&prices[1]&'-'&prices[2] ).innerHTML = prices[0];
}
I almost certainly messed up some of that javascript; use at your own risk.
This is a lot more complex than the simpler answer given above, but this is the only way I can think of doing it so that it makes "sense." Basically, with this method, you place everything where it should be, and you don't have to worry about odd tables and weird selects.