I hope someone can help. Basically I'm fairly OK with PHP and MySQL,
however, I need some advice on how to complete this task.
As my system is to complex to explain, I've condensed it down so it's clearer.
Basically, I have an simple PHP Form that asks the user for their:
Name,Item Ordered, Item Quantity. The OrderID is autogenerated and is a random
4 number. So at the moment I do it with this:
$sql="INSERT INTO system_orders
(orderid,name,itemordered,itemquantity) VALUES
('$randomgeneratednumber', '$_POST[name]','$_POST[itemordered]','$_POST[itemquantity]')"; and
run $sql
Now what I want is if they put the quantity as "2", I want it to create an additional row and append
the randomgeneratednumber. For example, if the randomgeneratednumber was 9876 and the quantity was 2, it would create an additional new row, with the $randomgeneratednumber-2, in this example 9876-2
Would anyone know how to achieve this?
I have temporarily used an if statement (which I know is really bad programming practice)
to append the -2 manually, but there must be a function out there to detect if $quantity = 2
then create additional row with the appended -2 and so on for 3,4,5,6,7,8...
Use a loop:
if ($quantity > 1) {
for ($q = 2; $q <= $quantity; $q++) {
$sql = "INSERT INTO system_orders
(orderid,name,itemordered,itemquantity) VALUES
('$randomgeneratednumber-$q', '$_POST[name]', '$_POST[itemordered]', '$_POST[itemquantity]')";
// run $sql
}
}
You also should switch to a database API that supports parametrized queries, or escape the user-supplied inputs.
$sql="INSERT INTO system_orders
(orderid,name,itemordered,itemquantity) VALUES
('$randomgeneratednumber', '$_POST[name]','$_POST[itemordered]','$_POST[itemquantity]')"; and
run $sql
if ($_POST['itemquantity']>1) {
$multipleorderid = $randomgeneratednumber."-".$POST['itemquantity'];
$sql="INSERT INTO system_orders
(orderid,name,itemordered,itemquantity) VALUES
('$multipleorderid', '$_POST[name]','$_POST[itemordered]','$_POST[itemquantity]')"; and
run $sql
}
Related
I have been tasked to update the price list on our website. Currently, we have to do this one item at a time inside the Admin Panel.
However, we have over 3000 items, and tiered pricing for each item (up to 5 tiers)
Problem is, in the sell_prices table, the prices are structured like so:
10.50:9.50:8.50;7.50;6.50 in one cell.
I am attempting to write a script that will update each sell_price by 10%
UPDATE inv_items
SET sell_prices = sell_prices * 1.10
WHERE id = xxxxxx
I have also tried:
UPDATE inv_items
SET sell_prices = sell_prices * 1.10; sell_prices = sell_prices * 1.10
WHERE id = xxxxxx
But naturally received an error.
This works great but only updates one record, and leaves the rest blank.
Currently, I am working through PhpMyAdmin but I will write a new Price Increase script once I can figure this out.
I have backed up the database.
If I understand you correctly then you have 5? prices in one field, colon separated?
That is a really bizarre way of doing it. There may be a nifty way of doing it with mySQL parsing, but from PHP you're going to need to pull the values out, explode them into an array, apply the price increase to each element, implode it back with the colons and write it back to the database. It's as clunky as all get-out but faster than doing it by hand. Just.
Going forward if you can you really need to look at refactoring that; that's just going to keep biting you.
You'll need to do something like:
select sell_prices from inv_items
(get the values into php)
(split the values by delimiter ':')
(update each value)
(rebuild the line of values with ':' in between)
update inv_items set sell_prices = (value string you just created)
EDIT with mysqli function as suggested:
$qry = 'SELECT id, sell_prices FROM `tablename`';
if($result = $mysqli->query($qry)) {
while ($row = $result->fetch_assoc()) {
$temp = explode(';', $row['sell_prices']);
foreach ($temp as &$price) {
$price = (float)$price*1.1;
}
$prices[$row['id']] = implode(';', $temp);
}
foreach ($prices as $id => $pricesStr) {
$stmt = $mysqli->prepare("UPDATE `tablename` SET sell_prices = ? WHERE id = ?");
$stmt->bind_param('si', $pricesStr, $id);
$stmt->execute();
$stmt->close();
}
}
Please note that I wrote this on the fly without testing, i may overlooked something :)
I have a bunch of photos on a page and using jQuery UI's Sortable plugin, to allow for them to be reordered.
When my sortable function fires, it writes a new order sequence:
1030:0,1031:1,1032:2,1040:3,1033:4
Each item of the comma delimited string, consists of the photo ID and the order position, separated by a colon. When the user has completely finished their reordering, I'm posting this order sequence to a PHP page via AJAX, to store the changes in the database. Here's where I get into trouble.
I have no problem getting my script to work, but I'm pretty sure it's the incorrect way to achieve what I want, and will suffer hugely in performance and resources - I'm hoping somebody could advise me as to what would be the best approach.
This is my PHP script that deals with the sequence:
if ($sorted_order) {
$exploded_order = explode(',',$sorted_order);
foreach ($exploded_order as $order_part) {
$exploded_part = explode(':',$order_part);
$part_count = 0;
foreach ($exploded_part as $part) {
$part_count++;
if ($part_count == 1) {
$photo_id = $part;
} elseif ($part_count == 2) {
$order = $part;
}
$SQL = "UPDATE article_photos ";
$SQL .= "SET order_pos = :order_pos ";
$SQL .= "WHERE photo_id = :photo_id;";
... rest of PDO stuff ...
}
}
}
My concerns arise from the nested foreach functions and also running so many database updates. If a given sequence contained 150 items, would this script cry for help? If it will, how could I improve it?
** This is for an admin page, so it won't be heavily abused **
you can use one update, with some cleaver code like so:
create the array $data['order'] in the loop then:
$q = "UPDATE article_photos SET order_pos = (CASE photo_id ";
foreach($data['order'] as $sort => $id){
$q .= " WHEN {$id} THEN {$sort}";
}
$q .= " END ) WHERE photo_id IN (".implode(",",$data['order']).")";
a little clearer perhaps
UPDATE article_photos SET order_pos = (CASE photo_id
WHEN id = 1 THEN 999
WHEN id = 2 THEN 1000
WHEN id = 3 THEN 1001
END)
WHERE photo_id IN (1,2,3)
i use this approach for exactly what your doing, updating sort orders
No need for the second foreach: you know it's going to be two parts if your data passes validation (I'm assuming you validated this. If not: you should =) so just do:
if (count($exploded_part) == 2) {
$id = $exploded_part[0];
$seq = $exploded_part[1];
/* rest of code */
} else {
/* error - data does not conform despite validation */
}
As for update hammering: do your DB updates in a transaction. Your db will queue the ops, but not commit them to the main DB until you commit the transaction, at which point it'll happily do the update "for real" at lightning speed.
I suggest making your script even simplier and changing names of the variables, so the code would be way more readable.
$parts = explode(',',$sorted_order);
foreach ($parts as $part) {
list($id, $position) = explode(':',$order_part);
//Now you can work with $id and $position ;
}
More info about list: http://php.net/manual/en/function.list.php
Also, about performance and your data structure:
The way you store your data is not perfect. But that way you will not suffer any performance issues, that way you need to send less data, less overhead overall.
However the drawback of your data structure is that most probably you will be unable to establish relationships between tables and make joins or alter table structure in a correct way.
I populate a web form with rows of data. Some of the fields I need to be updatable so I put the value into a text field. MySQL query is:
SELECT * FROM results WHERE EventID = %s AND CompNo = %s", GetSQLValueString($colname_rsResults, "int"),GetSQLValueString($colname2_rsResults, "int"));
EventID and CompNo are passed in the URL.
Let's say the result is 50 rows. I want to be able to update the Name field (eg, make correction to the spelling), click a button and have the code update the database with any new values. It doesn't matter that most of the values will not change as this is a very infrequent operation.
I used to be able to do this in ASP but I can't seem to do in PHP.
This is the code I am using and I think it is completely wrong!!
if ((isset($_POST["JM_update"])) && ($_POST["JM_update"] == "form1")) {
$i = 0;
$j = $totalRows_rsResults;
while($i < $j)
$resultID=$_GET['ResultID'];
$vDelete=$_GET['Del'];
if ($vDelete == 1) {
$delSQL = sprintf("DELETE FROM Results WHERE ResultID=$resultID");
mysql_query($delSQL,$connFeisResults);
} else {
$name=$_GET['Name'];
$qual=$_GET['Qual'];
$updateSQL = sprintf("UPDATE results SET Name = ".$name{$i}.", Qual = ".$qual[$i]." WHERE ResultID=$resultID");
mysql_query($updateSQL, $connFeisResults);
$i++;
}
}
There is also a checkbox at the end of each row to check if I need that record deleted. That doesn't work either!!
I am using Dreamweaver CS6 and trying to adapt the update behaviours etc.
Any thoughts? Many thanks in advance.
It looks like you're missing an opening brace after your while statement.
--UPDATED
Also, check your sprintf statements -- they look wrong, and they look like they're writing the raw '$resultID' to the SQL String, instead of the value within it.
See how to do it here: http://www.talkphp.com/general/1062-securing-your-mysql-queries-sprintf.html
I found a PHP-based recipe and meal plan script, that I'd like to edit.
There's a MealPlan Class that allows all users to create their own daily menus/mealplans, by selecting from a list of all recipes found in the database.
I want to switch the table/column names used in the insert statement, based on the level of the user.
The original insert method is:
// Insert Meal Plan
function insert($date, $meal, $recipe, $servings, $owner) {
global $DB_LINK, $db_table_mealplans, $LangUI;
$date = $DB_LINK->addq($date, get_magic_quotes_gpc());
$meal = $DB_LINK->addq($meal, get_magic_quotes_gpc());
$recipe = $DB_LINK->addq($recipe, get_magic_quotes_gpc());
$servings = $DB_LINK->addq($servings, get_magic_quotes_gpc());
$owner = $DB_LINK->addq($owner, get_magic_quotes_gpc());
$sql = "INSERT INTO $db_table_mealplans (
mplan_date,
mplan_meal,
mplan_recipe,
mplan_servings,
mplan_owner)
VALUES (
'$date',
$meal,
$recipe,
$servings,
'$owner')";
$rc = $DB_LINK->Execute($sql);
DBUtils::checkResult($rc, NULL, $LangUI->_('Recipe already added on:'.$date), $sql);
}
My idea was to change:
mplan_date,
mplan_meal,
mplan_recipe,
mplan_servings,
mplan_owner
to:
$mplan_date,
$mplan_meal,
$mplan_recipe,
$mplan_servings,
$mplan_owner
and use a switch statement to change the table/column names. But I've been told that this sort of thing is frowned upon in OOP. What's the best way to go about this?
(NOTE: I can post the whole class if need be, but figured this would be enough info)
I don't have any code for you, but I've done something similar to this recently. Basically I dynamically made the SQL string by concating the string depending on what the user input. Bear with me as I try to type something on the fly.
$columnsArray = array();
$sqlCmd = "INSERT INTO";
If (someCondition) {
array_push($columnsArray, "mplan_date");
}//Could try turning this into a loop and just push all
//applicable columns into the array
$counter = 0;
Foreach ($columnsArray as $columnName) {
$sqlCmd .= " $columnName";
$counter++
If ($counter < count($columnsArray)){
$sqlCmd .= ",";
}//This will put a comma after each column with the
//exception of the last one.
}
So I did something like this only with a user defined select statement to retrieve data. Basiclly keep going with the logic until you’ve built a custom string that will be the user defined SQL statement, and then execute it. This includes doing something similar to the above script to concat the values into the string.
Hope this gives you some ideas.
Please forgive my ignorance, I am still very much a beginner, and I don't even know if this is possible.
I need to insert into the database a price list in one currency based on another (based on EUR, output in USD).
I have the form to take the input for the conversion multiplier value and to put the values into an array should be relatively simple (even for me!)
<?php
// Make a MySQL Connection
$query = "SELECT price FROM table";
$result = mysql_query($query) or die(mysql_error());
while($row = mysql_fetch_array($result)){
echo $row[euros].
//here is where I need to perform the calculation with the result going into $row[dollars](euros * ex.rate = dollars)
UPDATE table SET dollars=INT($row[dollars]);
}
?>
Unfortunately, I need to fiddle with this some more as it doesn't work.
What I can't figure out is how to multiply the form input against each euro value and write the result into the appropriate dollars cell as an integer.
What I would do is write a single SQL query for this:
UPDATE `table` SET dollars=euros*1.23 WHERE 1
You can, of course, do this in PHP:
<?php
// first, prevent anyone from tampering with the query!
$factor = floatval($user_input);
// then the query itself
$result = mysql_query("UPDATE `table` SET dollars=euros*{$factor} WHERE 1");
?>
While I'm writing, when using associative arrays, you should use single quotes, e.g. not $row[dollars] but $row['dollars']. Enclose these inside curlies:
echo "dollars: {$row['dollars']}";