I tried to make the update statement to be safety againts sql injection but its give me this erro Fatal error: Call to a member function bind_param() on a non-object on line 39
$pid = $_POST['pid'];
$pagetitle = $_POST['pagetitle'];
$linklabel = $_POST['linklabel'];
$keyword = $_POST['keyword'];
$descriere = $_POST['descriere'];
$data = $_POST['data'];
$pagebody = $_POST['pagebody'];
// Filter Function -------------------------------------------------------------------
function filterFunction ($var) {
$var = nl2br(htmlspecialchars($var));
$var = str_replace("/", "\\\\", $var);
$var = preg_replace("~/~", "\\\\", $var);
return $var;
}
$pagetitle = filterFunction($pagetitle);
$linklabel = filterFunction($linklabel);
$keyword = filterFunction($keyword);
$descriere = filterFunction($descriere);
$data = filterFunction($data);
$pagebody = filterFunction($pagebody);
// End Filter Function --------------------------------------------------------------
include_once "../conx.php";
// Add the updated info into the database table
$stmt = $con->prepare("UPDATE pages SET (pagetitle, linklabel, keywords, description, pagebody, lastmodified) VALUES (?, ?, ?, ?, ?, ?) WHERE id = ?");
// TODO check that $stmt creation succeeded
// "s" means the database expects a string
$stmt->bind_param("sssssss", $pagetitle, $linklabel, $keyword, $descriere, $pagebody, $data, $pid);
$stmt->execute();
$stmt->close();
line 39 is $stmt->bind_param("sssssss", $pagetitle, $linklabel, $keyword, $descriere, $pagebody, $data, $pid);
it is necessary to make this or i can revert to how it was before
$query = mysqli_query($con, "UPDATE pages SET pagetitle='$pagetitle', linklabel='$linklabel', pagebody='$pagebody', lastmodified='now()' WHERE id='$pid'") or die (mysqli_error($con));
Didn't this produce an error?
$con->prepare("UPDATE pages SET (pagetitle, linklabel, keywords, description, pagebody, lastmodified) VALUES (?, ?, ?, ?, ?, ?) WHERE id = ?");
this should be
$con->prepare("UPDATE pages SET pagetitle=?, linklabel=?, keywords=?, description=?, pagebody=?, lastmodified=? WHERE id = ?");
Refer: http://dev.mysql.com/doc/refman/5.7/en/update.html
now you can proceed to bind parameters
$stmt->bind_param("sssssss", $pagetitle, $linklabel, $keyword, $descriere, $pagebody, $data, $pid);
Related
I have an app that is written using procedural PHP. I've created an insert page where I take a buck of addresses and pass them as an array and insert them in the database. There I have the id of the row and then an orderId, the address type, and the address. Now I want to be able to update a specific one. Until now I've come up with the following:
// update new supplier order
function updateSupplierOrder($conn, $orderDate, $datePickup, $dateDelivery, $timePickup, $timeDelivery, $car, $carType, $goodsDescription, $paletChange, $paletNo, $supplier, $orderObservation, $paymentDate, $value, $addressPickup, $addressDelivery, $userid, $orderID) {
$sql1 = "UPDATE suppliersOrders SET supplierId = ?, date = ?, datePickup = ?, timePickup = ?, goodsDescription = ?, dateDelivery = ?, timeDelivery = ?, carType = ?, carNo = ?, paletChange = ?, paletNo = ?, value = ?, invoice = ?, observations = ?, operator = ? WHERE id = ?;";
$stmt1 = mysqli_stmt_init($conn);
if (!mysqli_stmt_prepare($stmt1, $sql1)) {
header ("location: ../suppliersOrders?error=failedupdateorder");
exit();
}
mysqli_stmt_bind_param($stmt1, "isssssssisisssii", $supplier, $orderDate, $datePickup, $timePickup, $goodsDescription, $dateDelivery, $timeDelivery, $carType, $car, $paletChange, $paletNo, $value, $paymentDate, $orderObservation, $userid, $orderID);
mysqli_stmt_execute($stmt1);
mysqli_stmt_close($stmt1);
for ($i=0; $i<count($addressPickup); $i++) {
$address = $addressPickup[$i];
$type = '1';
$sql2 = "UPDATE suppliersOrdersAddress SET address = ?, operator = ? WHERE orderId = ? AND addressType = ?;";
$stmt2 = mysqli_stmt_init($conn);
if (!mysqli_stmt_prepare($stmt2, $sql2)) {
header ("location: ../suppliersOrders?error=failedupdateaddress");
exit();
}
mysqli_stmt_bind_param($stmt2, "siii", $address, $userid, $orderID, $type);
mysqli_stmt_execute($stmt2);
mysqli_stmt_close($stmt2);
}
for ($i=0; $i<count($addressDelivery); $i++) {
$address = $addressDelivery[$i];
$type = '2';
$sql2 = "UPDATE suppliersOrdersAddress SET address = ?, operator = ? WHERE orderId = ? AND addressType = ?;";
$stmt2 = mysqli_stmt_init($conn);
if (!mysqli_stmt_prepare($stmt2, $sql2)) {
header ("location: ../suppliersOrders?error=failedupdateaddress");
exit();
}
mysqli_stmt_bind_param($stmt2, "siii", $address, $userid, $orderID, $type);
mysqli_stmt_execute($stmt2);
mysqli_stmt_close($stmt2);
}
header("location: ../suppliersOrders-edit.php?id=$orderID");
}
But this will update all the addresses of an order and a type. How can I update based on the id from the table, this will make sure that the right address is updated.
Help would be appreciated.
I found a solution to the issues. The simplest way to be able to update the row that I needed was to add the id value from the row in an array and do the update based on the WHERE clause that had the id value. This way I was able to update just the needed value/row.
I would like to have data inserted in one table, and data updated in another through prepared statements in mysqli. Trying the following only executes the INSERT command:
EDITED:
if($stmt=$mysqli->prepare("SELECT bids_id, bid, fruit_volume FROM basket ORDER BY bid DESC")) {
$stmt->execute();
$stmt->store_result();
$stmt->bind_result($bids_id, $bid, $fruit_volume);
while($stmt->fetch()) {
$stack = array($bids_id, $bid, $fruit_volume);
array_push($all_fruits, $stack);
}
$stmt->free_result();
}
foreach ($all_fruits as $fruits) {
if ($_POST["offer"] == $fruits[1] && $volume < $fruits[2]) {
$stmt2 = $mysqli->prepare("INSERT INTO oranges (username, price, volume, date) VALUES (?, ?, ?, ?)");
$stmt2->bind_param('sdis', $user, $price, $volume, $today);
$stmt2->execute();
$stmt3 = $mysqli->prepare("UPDATE basket SET fruit_volume = ? WHERE bids_id = ?");
$stmt3->bind_param('ii', 800, 1);
$stmt3->execute();
}
}
$mysqli->close();
bind_param passes by reference not by value,so you need to have those values in variables before they can be referenced
$a=800;
$b=1;
foreach ($all_fruits as $fruits) {
if ($_POST["offer"] == $fruits[1] && $volume < $fruits[2]) {
$stmt2 = $mysqli->prepare("INSERT INTO oranges (username, price, volume, date) VALUES (?, ?, ?, ?)");
$stmt2->bind_param('sdis', $user, $price, $volume, $today);
$stmt2->execute();
$stmt3 = $mysqli->prepare("UPDATE basket SET fruit_volume = ? WHERE bids_id = ?");
$stmt3->bind_param('ii',$a, $b);
$stmt3->execute();
}
}
Try this instead
foreach ($all_fruits as $fruits) {
if ($_POST["offer"] == $fruits[1] && $volume < $fruits[2]) {
$stmt2 = $mysqli->prepare("INSERT INTO oranges (username, price, volume, date) VALUES (?, ?, ?, ?)");
$stmt2->bind_param('sdis', $user, $price, $volume, $today);
$stmt2->execute();
$stmt3 = $mysqli->prepare("UPDATE basket SET fruit_volume = ? WHERE bids_id = ?");
$stmt3->bind_param('ii', 800, 1);
$stmt3->execute();
}
}
$mysqli->close();
I am converting from mysqli to PDO and very much a beginner with this. Here is my update statement for my database 'users'
public function pdo_update_test() {
$sql = "UPDATE users SET visible_password = ?, hashed_password = ?, ";
$sql .="temp_hashed_password = ?, email = ?, first_name= ?, last_name = ?, ";
$sql .="position = ?, location = ?, city = ?, country = ?, institution = ? ";
$sql .="interests = ?, profile_comment = ? WHERE id =" . $this->id;
$query = $handler->prepare($sql);
$result = array($visible_password, $hashed_password, $temp_hashed_password, $email,
$first_name, $last_name, $position, $location, $city, $country, $institution,
$interests, $profile_comment);
$query->execute($result);
if (($query = $handler->prepare($sql)) === false) {
print_r($handler->errorInfo());
}
if ($query->execute($result) === false) {
print_r($query->errorInfo());
}
}
I am using ? rather than nameholders because once I have this working I am going to try to make it abstract so I can use it in all the classes in my site and I have found it easier with ? than nameholders. When I run the following it fails to work. I am sure an obvious error on my part but I can't seem to see the issue....
$user = new User();
$user->id= 256;
$visible_password = "Bob";
$user->pdo_update_test();
I have found a solution to make the whole thing dynamic. I won't presume that its going to be helpful for others (as I am the beginner) but i though I would post it anyway....
If you see problems or have criticisms please let me know
public function pdo_update_test(){
$attributes = $this->attributes();
$attribute_pairs = array();
foreach($attributes as $key => $value) {
if(isset($value))
$attribute_pairs[] = "{$key}='{$value}'";
}
$sql = "UPDATE ".self::$table_name." SET ";
$sql .= join(", ", $attribute_pairs);
$sql .= " WHERE id=". $this->id;
$query = $handler->prepare($sql);
$query->execute(array());
}
What you need is to create SET statement for the query dynamically. To make it contain only actual fields you have values for.
So, for the code given, it should produce a query
UPDATE users SET visible_password = ? WHERE id = ?
-- but not one you wrote above with all the fields listed
and it is not PDO related problem - it's rather just basic string manipulation, every PHP user is supposed to be able to write. If you can't, you can refer to PDO tag wiki for the code to adopt.
To make it work your code have to be like this
$user = new User();
$user->id= 256;
$data = array('visible_password' => "Bob");
$user->pdo_update_test($data);
where pdo_update_test will create the above SQL query out of $data array
I'm starting with mysql prepared statements and I can't advance due to an error that I don't understand. Here's my function to update de db:
public function updateUserData($user_label,$user_alliance, $score, $rank, $timestamp, $user_id, $db_object){
$sql='UPDATE users SET label = ?, alliance = ?, points = ?, position = ?, modified = ?, WHERE user_id = ?';
$label = $user_label;
$alliance = $user_alliance;
$points = $score;
$position = $rank;
$modified = $timestamp;
$user_id_q = $user_id;
$stmt = $db_object->prepare($sql);
if($stmt === false) {
trigger_error('Wrong SQL: ' . $sql . ' Error: ' . $db_object->error, E_USER_ERROR);
}
$stmt->bind_param('ssiiii',$label,$alliance,$points,$position,$modified,$user_id_q);
/* Execute statement */
$stmt->execute();
echo $stmt->affected_rows;
$stmt->close();
}
Here's how I use it:
//Get user Data
$user = new user();
$page_clasif = $user->getPagClasif($ch,$url_clasif);
$user_label = $user->findPlayerName($page_clasif);
$user_alliance = $user->findAllianceName($page_clasif);
$rank = $user->findRank($page_clasif);
$score = $user->findScore($page_clasif);
$user_id = $user->findPlayerId($page_clasif);
$version = $user->findVersion($page_clasif);
$user_universe = $user->findUniverse($page_clasif);
//Get install date as timestamp
$core = new core();
$timestamp = $core->dateAsTimestamp();
//Update User
$user->updateUserData($user_label,$user_alliance,$score,$rank,$timestamp,$user_id,$conn);
Here's the error:
PHP Fatal error: Wrong SQL: UPDATE users SET label = ?, alliance = ?, points = ?, position = ?, modified = ?, WHERE user_id = ? Error: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'WHERE user_id = ?'
Any ideas?
Thanks in advance.
You have a superfluous comma before the WHERE keyword:
$sql='UPDATE users SET label = ?, alliance = ?, points = ?, position = ?, modified = ?, WHERE user_id = ?';
// remove this comma --^
Based on : http://www.raywenderlich.com/2941/how-to-write-a-simple-phpmysql-web-service-for-an-ios-app
My database looks like this : id | rw_promo_code_id | email_id | device_id | redeemed_time
I try this in the index.php:
// Check for required parameters
if (isset($_POST["rw_app_id"]) && isset($_POST["code"]) && isset($_POST["email_id"]) && isset($_POST["device_id"]) ) {
...........
// Add tracking of redemption
$stmt = $this->db->prepare("INSERT INTO rw_promo_code_redeemed (rw_promo_code_id, email_id, device_id) VALUES (?, ?, ?)");
$stmt->bind_param("is", $id, $email_id, device_id);
$stmt->execute();
$stmt->close();
IF I REMOVE && isset($_POST["device_id"]) and make this line
$stmt = $this->db->prepare("INSERT INTO rw_promo_code_redeemed
(rw_promo_code_id, email_id, device_id) VALUES (?, ?, ?)");
to
$stmt = $this->db->prepare("INSERT INTO rw_promo_code_redeemed
(rw_promo_code_id, email_id) VALUES (?, ?)");
I GET THE EMAIL CORRECTLY IN THE DATABASE OF COURSE, BUT NOT THE DEVICE ID
How can I get the the both values (device_id and email_id) to display in the database and not only one ?
I use this in the app (there is no problem with this)
NSString *emailadrress = email.text;
NSURL *url = [NSURL URLWithString:#"http://localhost:8888/"];
ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:url];
[request setPostValue:#"1" forKey:#"rw_app_id"];
[request setPostValue:code forKey:#"code"];
[request setPostValue:emailadrress forKey:#"email_id"];
[request setPostValue:#"23131" forKey:#"device_id"];
[request setDelegate:self];
[request startAsynchronous];
EDIT : HERE IS THE ORGINAL FUNCTION:
function redeem() {
// Check for required parameters
if (isset($_POST["rw_app_id"]) && isset($_POST["code"]) && isset($_POST["device_id"])) {
// Put parameters into local variables
$rw_app_id = $_POST["rw_app_id"];
$code = $_POST["code"];
$device_id = $_POST["device_id"];
// Look up code in database
$user_id = 0;
$stmt = $this->db->prepare('SELECT id, unlock_code, uses_remaining FROM rw_promo_code WHERE rw_app_id=? AND code=?');
$stmt->bind_param("is", $rw_app_id, $code);
$stmt->execute();
$stmt->bind_result($id, $unlock_code, $uses_remaining);
while ($stmt->fetch()) {
break;
}
$stmt->close();
// Bail if code doesn't exist
if ($id <= 0) {
sendResponse(400, 'Invalid code');
return false;
}
// Bail if code already used
if ($uses_remaining <= 0) {
sendResponse(403, 'Code already used');
return false;
}
// Check to see if this device already redeemed
$stmt = $this->db->prepare('SELECT id FROM rw_promo_code_redeemed WHERE device_id=? AND rw_promo_code_id=?');
$stmt->bind_param("si", $device_id, $id);
$stmt->execute();
$stmt->bind_result($redeemed_id);
while ($stmt->fetch()) {
break;
}
$stmt->close();
// Bail if code already redeemed
if ($redeemed_id > 0) {
sendResponse(403, 'Code already used');
return false;
}
// Add tracking of redemption
$stmt = $this->db->prepare("INSERT INTO rw_promo_code_redeemed (rw_promo_code_id, device_id) VALUES (?, ?)");
$stmt->bind_param("is", $id, $device_id);
$stmt->execute();
$stmt->close();
// Decrement use of code
$this->db->query("UPDATE rw_promo_code SET uses_remaining=uses_remaining-1 WHERE id=$id");
$this->db->commit();
// Return unlock code, encoded with JSON
$result = array(
"unlock_code" => $unlock_code,
);
sendResponse(200, json_encode($result));
return true;
}
sendResponse(400, 'Invalid request');
return false;
}
EDIT: The error
PHP Warning: mysqli_stmt::bind_param() [<a
href='mysqli-stmt.bind-param'>mysqli-stmt.bind-param]:
Number of elements in type definition
string doesn't match number of bind
variables in
/Applications/MAMP/htdocs/index.php on
line 134
which is :
$stmt = $this->db->prepare("INSERT
INTO rw_promo_code_redeemed
(rw_promo_code_id, device_id,
email_id) VALUES (?, ?, ?)");
$stmt->bind_param("is", $id,
$device_id, $email_id);
got you...
you are missing value type for third variable.
$stmt = $this->db->prepare("INSERT INTO rw_promo_code_redeemed (rw_promo_code_id, device_id, email_id) VALUES (?, ?, ?)"); $stmt->bind_param("iss", $id, $device_id, $email_id);
change "is" to "iss" or "iis" any one required. you can get further info about bind_param on
http://www.php.net/manual/en/mysqli-stmt.bind-param.php