am new to prepared statements and PDO. I have a script with two prepared statements, the insert statement works fine, yet the update does not. It returns no errors and displays the success message, yet it doesn't update the database.
Here is the code that doesn't work. Any help wouild be much appreciated. Thanks
$queryString="UPDATE team_directory SET team_name=':team_name',
aka=':aka',
website=':website',
main_contact=':main_contact',
phone=':phone',
email=':email',
other=':other',
np1=':np1',
np2=':np2',
np3=':np3',
np4=':np4',
np5=':np5',
np6=':np6',
np7=':np7',
np8=':np8',
np9=':np9',
np10=':np10',
np11=':np11',
np12=':np12'
where team_id=':team_id'";
$query=$database->prepare($queryString);
$query->execute(array(':team_name'=>$team_name,
':aka'=>$aka,
':website'=>$website,
':main_contact'=>$main_contact,
':phone'=>$phone,
':email'=>$email,
':other'=>$other,
':np1'=>$np1,
':np2'=>$np2,
':np3'=>$np3,
':np4'=>$np4,
':np5'=>$np5,
':np6'=>$np6,
':np7'=>$np7,
':np8'=>$np8,
':np9'=>$np9,
':np10'=>$np10,
':np11'=>$np11,
':np12'=>$np12,
':team_id'=>$team_id));
if ($query->errorCode()==0) {
echo "<p>Team amended successfully, Amend Another </p>
<p>Team Directory</p>
<p>Admin Homepage</p>";
}
else {
$errors=$query->errorInfo();
echo ($errors[2]);
}
Simply take the placeholders (your to-be-used prepared statement markers for variables) out of those evil quotes:
$queryString="UPDATE team_directory SET team_name = :team_name,
aka = :aka,
website = :website,
main_contact = :main_contact,
phone = :phone,
email = :email,
other = :other,
np1 = :np1,
np2 = :np2,
np3 = :np3,
np4 = :np4,
np5 = :np5,
np6 = :np6,
np7 = :np7,
np8 = :np8,
np9 = :np9,
np10 = :np10,
np11 = :np11,
np12 = :np12
where team_id = :team_id";
Related
This is my code I have to insert an array each value in the insert statement
if(isset($_POST['add'])){
$batch = $_POST['batch'];
$course = explode(':', $_POST['course']);
$cid = $course[0];
$rowCount = count($_POST['branch']);
$branch = implode(',', $_POST['branch']);
$semester = $_POST['sem'];
$day = $_POST['day'];
$hour = $_POST['hour'];
for($i=0;$i<$rowCount;$i++){
$description = $_POST['branch'][$i];
$sql. = "INSERT INTO batch (batch,bdescription,branch,course,semester,day,hour,user) VALUES ('$batch','$description',$i,'$cid','$semester','$day','$hour','$usnid');";
}
if($conn->query($sql)){
$_SESSION['success'] = 'batch added successfully';
}
else{
$_SESSION['error'] = $conn->error;
}
}
Please help thanks
You can't execute multiple queries with a single call to $conn->query().
Change your query so it's just a single INSERT statement with multiple lists of values after VALUES.
$sql = "INSERT INTO batch (batch,bdescription,branch,course,semester,day,hour,user) VALUES "
for($i=0;$i<$rowCount;$i++){
$description = $_POST['branch'][$i];
$sql. = "('$batch','$description',$i,'$cid','$semester','$day','$hour','$usnid'),";
}
$sql = substr($sql, 0, -1); // remove last comma
You should also use $conn->real_escape_string() to escape all the inputs, to protect against SQL injection (it would be even better to do that with a prepared statement, but it's difficult to make a prepared statement in mysqli with dynamic parameters).
Barmar is correct, you can't execute multiple SQL statements with query(). There's mysqli_multi_query(), but there's hardly ever a justification for using that. The former Engineering Director for MySQL once told me unequivocally, "there's no reason for multi-query to exist."
You should use parameters instead of copying $_POST variables directly into your SQL strings. It's not hard, in fact it makes code easier than fiddling with confusing quotes-within-quotes and mysqli_real_escape_string() and so on.
I wouldn't bother with trying to insert multiple tuples in a single INSERT statement. How many branches can possibly be in a single POST? A few dozen at most? Not enough to make it necessary to make the INSERT into a single statement. So just call execute() for a prepared INSERT, once for each row.
$sql = "INSERT INTO batch
SET batch=?, bdescription=?, branch=?, course=?, semester=?,
day=?, hour=?, user=?";
$stmt = $conn->prepare($sql) or die($conn->error);
$description = '';
$stmt->bind_param('ssssssss', $batch, $description, $i, $cid, $semester, $day, $hour, $usnid);
for($i=0;$i<$rowCount;$i++){
$description = $_POST['branch'][$i];
$stmt->execute() or die($stmt->error);
}
Read the manual for https://www.php.net/manual/en/mysqli-stmt.bind-param.php for more code examples.
This is how I Fixed My Code. I Used for loop
if(isset($_POST['addstd'])){
$rowCount = count($_POST['student']);
for($i=0;$i<$rowCount;$i++){
$stdid = $_POST['student'][$i];
$course = $_POST['course'][$i];
$batch = $_POST['batch'][$i];
$branch = $_POST['branch'][$i];
//insert students into attendance table
$sqlsel = "SELECT year,student_id, student_rollno,firstname,lastname, branch,active, nr FROM student WHERE student.student_id = '$stdid' AND student.branch = '$branch'";
$querysel = $conn->query($sqlsel) or die($conn->error);
$rowsel = $querysel->fetch_assoc();
if($rowsel !== null){
$year = $rowsel['year'];
$rollno = $rowsel['student_rollno'];
$active = $rowsel['active'];
$branch = $rowsel['branch'];
$name = $rowsel['firstname'].$rowsel['lastname'];
$sql = "INSERT IGNORE INTO class (year,regno, rollno,name, programme,coursecode,batch,user,active,count) VALUES ('$year','$stdid','$rollno','$name','$branch','$course','$batch','$usnid','$active','$i');";
if($conn->query($sql)){
$_SESSION['success'] = 'Students Added To Batch Successfully';
}
else{
$_SESSION['error'] = $conn->error;
}
}
else{
continue;
}
}
}
else{
$_SESSION['error'] = 'Fill up add form first';
}
why i always get error in hostgator when try to update this ga field in database, error happen when insert this code in textarea
_gaq.push(['_setCustomVar',1, 'Status', 'Logged In']);
_gaq.push(['_trackEvent', 'Custom', 'PageLoad', 'Setting Logged In State',0,true]);
<textarea name="ga"></textarea>
$name = $_POST['name'];
$ga = trim($_POST['ga']);
$req = "UPDATE `con` SET `name` = '".$name."', `ga` = '".$ga."'");
if (mysqli_query($con, $req)) {
echo "success"
}
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 '_setCustomVar',1, 'Status', 'Logged In']);
_gaq.push(['_trackEvent', 'Custom', ' at line 1
if i remove ga = '".$ga."' my database update but if add this code it give error i have hostgator and it work good in localhost
type of ga in database is text.
Prepared statements are the one stop solution for this. Your code is supposed to be:
$name = trim($_POST['name']);
$ga = trim($_POST['ga']);
$some_value = 'some_value'; //This is just the imaginary value for demonstration
$req = "UPDATE `con` SET `name` = ?, `ga` = ? WHERE column_name = ?";
$stmt = $mysqli->prepare($req);
$stmt->bind_param('sss', $name, $ga, $some_value);
$stmt->execute();
You always want to use WHERE with UPDATE query. If you don't use WHERE clause, the changes will be applied to all records. I suppose you are aware of SQL injection, the notorious attack!
An alternative which can be used to fix the issue with your code is mysqli_real_escape_string().
For example,
$name = mysqli_real_escape_string($con, trim($_POST['name']));
$ga = mysqli_real_escape_string($con, trim($_POST['ga']));
But always use prepared statements as I've shown above.
i have a simple code to input data to my database
using prepare and bind_param
there is no error but my data are not inputted into database
$stmt1 = $mysqli -> prepare ("INSERT INTO equipment(eqp_type, eqp_name, eqp_qty, eqp_usd, $eqp_idr) VALUES (?,?,?,?,?)");
$stmt1->bind_param('sssss',$eqp_type, $eqp_name, $eqp_qty, $eqp_usd, eqp_idr);
$eqp_type = 'BUC';
$eqp_name = 'BUC test';
$eqp_qty = '1';
$eqp_usd = '0';
$eqp_idr = '0';
$stmt1->execute();
is there any idea why there is no error but my data are not inputted into database ?
You might forget to execute it.
You can do it with following code:
$stmt1->execute();
So your code would look as follows:
$eqp_type = 'BUC';
$eqp_name = 'BUC test';
$eqp_qty = '1';
$eqp_usd = '0';
$eqp_idr = '0';
$stmt1 = $mysqli -> prepare ("INSERT INTO equipment(eqp_type, eqp_name, eqp_qty, eqp_usd, eqp_idr) VALUES (?,?,?,?,?)");
$stmt1->bind_param('sssss',$eqp_type, $eqp_name, $eqp_qty, $eqp_usd, $eqp_idr);
$stmt1->execute();
Manual
PHP: mysqli_stmt::bind_param
You have to execute your query using
$stmt1->execute();
Read here: http://php.net/manual/en/pdostatement.execute.php
You need to add $stmt1->execute() and you will get error as you also missed $ in eqp_idr
I'm here trying to update my DB rows without deleting/creating new ones all the time. Currently, my DB creates new entries everytime I run this block of code. Instead of spamming my DB, I just want to change some of the values.
<?php
try {
$conn = new PDO("mysql:host=localhost;port=3306;dbname=dbname", Username, password);
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
catch(PDOException $e){
echo "Connection failed: " . $e->getMessage();
}
if(isset($_POST['mUsername']))
{
$mUsername = urldecode($_POST['mUsername']);
$mEvent = urldecode($_POST['mEvent']);
$mChat = urldecode($_POST['mChat']);
$mlongitude = urldecode($_POST['mlongitude']);
$mlatitude = urldecode($_POST['mlatitude']);
$sqlUPDATE = "UPDATE users
SET lastEvent=:lastEvent, lastChat=:lastChat,
lastLong=:lastLong, lastLatt=:lastLatt
WHERE name=:name";
$stmt = $conn->prepare($sqlUPDATE);
$stmt->bindParam(':lastEvent', $mEvent);
$stmt->bindParam(':lastChat', $mChat);
$stmt->bindParam(':lastLong', $mlongitude);
$stmt->bindParam(':lastLatt', $mlatitude);
$stmt->bindParam(':name', $mUsername);
$stmt->execute();
}
echo "successfully updated";
?>
My assumption is my final line, the $results area. I believe it's just treating this an a new entry instead of an update. How do I go about just replacing values? some values will not change, like the username, and sometimes longitude/latitude won't need to be changed. Would that have to be a separate query, should I split this in to two scripts? Or could I just enter a blank, null value? Or would that end up overwriting the ACTUAL last coordinates, leaving me with null values? Looking for any help or guides or tutorials. Thank you all in advance.
lots of syntax error in your code. It is simple to use bindParam
$sqlUPDATE = "UPDATE users
SET lastEvent=:lastEvent, lastChat=:lastChat,
lastLong=:lastLong, lastLatt=:lastLatt
WHERE name=:name";// you forget to close statement in your code
$stmt = $conn->prepare($sqlUPDATE);
$stmt->bindParam(':lastEvent', $mEvent);
$stmt->bindParam(':lastChat', $mChat);
$stmt->bindParam(':lastLong', $mlongitude);
$stmt->bindParam(':lastLatt', $mlatitude);
$stmt->bindParam(':name', $mUsername);
$stmt->execute();
read http://php.net/manual/en/pdostatement.bindparam.php
When using prepared statements, you should also make a habbit of following the set rules. Use named parameters. Try this:
if(isset($_POST['mUsername']))
{
$mUsername = urldecode($_POST['mUsername']);
$mEvent = urldecode($_POST['mEvent']);
$mChat = urldecode($_POST['mChat']);
$mlongitude = urldecode($_POST['mlongitude']);
$mlatitude = urldecode($_POST['mlatitude']);
$sqlUPDATE = "UPDATE users SET lastEvent= :lastEvent, lastChat= :lastChat, lastLong= :lastLong, lastLatt= :lastLatt WHERE name= :name";
$q = $conn->prepare($sqlUPDATE);
$results = $q->execute(array(':name'=>$mUsername, ':lastEvent'=>$mEvent, ':lastChat'=>$mChat, ':lastLong'=>$mlongitude, ':lastLatt'=>$mlatitude));
}
I'm playing around with MySQLi at the moment, trying to figure out how it all works. In my current projects I always like to echo out a query string while coding, just to make sure that everything is correct, and to quickly debug my code. But... how can I do this with a prepared MySQLi statement?
Example:
$id = 1;
$baz = 'something';
if ($stmt = $mysqli->prepare("SELECT foo FROM bar WHERE id=? AND baz=?")) {
$stmt->bind_param('is',$id,$baz);
// how to preview this prepared query before acutally executing it?
// $stmt->execute();
}
I've been going through this list (http://www.php.net/mysqli) but without any luck.
EDIT
Well, if it's not possible from within MySQLi, maybe I'll stick with something like this:
function preparedQuery($sql,$params) {
for ($i=0; $i<count($params); $i++) {
$sql = preg_replace('/\?/',$params[$i],$sql,1);
}
return $sql;
}
$id = 1;
$baz = 'something';
$sql = "SELECT foo FROM bar WHERE id=? AND baz=?";
echo preparedQuery($sql,array($id,$baz));
// outputs: SELECT foo FROM bar WHERE id=1 AND baz=something
Far from perfect obviously, since it's still pretty redundant — something I wanted to prevent — and it also doesn't give me an idea as to what's being done with the data by MySQLi. But I guess this way I can quickly see if all the data is present and in the right place, and it'll save me some time compared to fitting in the variables manually into the query — that can be a pain with many vars.
I don't think you can - at least not in the way that you were hoping for. You would either have to build the query string yourself and execute it (ie without using a statement), or seek out or create a wrapper that supports that functionality. The one I use is Zend_Db, and this is how I would do it:
$id = 5;
$baz = 'shazam';
$select = $db->select()->from('bar','foo')
->where('id = ?', $id)
->where('baz = ?', $baz); // Zend_Db_Select will properly quote stuff for you
print_r($select->__toString()); // prints SELECT `bar`.`foo` FROM `bar` WHERE (id = 5) AND (baz = 'shazam')
I have struggled with this one in the past. So to get round it I wrote a little function to build the SQL for me based on the SQL, flags and variables.
//////////// Test Data //////////////
$_GET['filmID'] = 232;
$_GET['filmName'] = "Titanic";
$_GET['filmPrice'] = 10.99;
//////////// Helper Function //////////////
function debug_bind_param(){
$numargs = func_num_args();
$numVars = $numargs - 2;
$arg2 = func_get_arg(1);
$flagsAr = str_split($arg2);
$showAr = array();
for($i=0;$i<$numargs;$i++){
switch($flagsAr[$i]){
case 's' : $showAr[] = "'".func_get_arg($i+2)."'";
break;
case 'i' : $showAr[] = func_get_arg($i+2);
break;
case 'd' : $showAr[] = func_get_arg($i+2);
break;
case 'b' : $showAr[] = "'".func_get_arg($i+2)."'";
break;
}
}
$query = func_get_arg(0);
$querysAr = str_split($query);
$lengthQuery = count($querysAr);
$j = 0;
$display = "";
for($i=0;$i<$lengthQuery;$i++){
if($querysAr[$i] === '?'){
$display .= $showAr[$j];
$j++;
}else{
$display .= $querysAr[$i];
}
}
if($j != $numVars){
$display = "Mismatch on Variables to Placeholders (?)";
}
return $display;
}
//////////// Test and echo return //////////////
echo debug_bind_param("SELECT filmName FROM movies WHERE filmID = ? AND filmName = ? AND price = ?", "isd", $_GET['filmID'], $_GET['filmName'], $_GET['filmPrice']);
I have also build a little online tool to help.
Mysqli Prepare Statement Checker
I recently updated this project to include composer integration, unit testing and to better handle accepting arguments by reference (this requires updating to php 5.6).
In response to a request I received on a project I created to address this same issue using PDO, I created an extension to mysqli on github that seems like it addresses your issue:
https://github.com/noahheck/E_mysqli
This is a set of classes that extend the native mysqli and mysqli_stmt classes to allow you to view an example of the query to be executed on the db server by interpolating the bound parameters into the prepared query then giving you access to resultant query string as a new property on the stmt object:
$mysqli = new E_mysqli($dbHost, $dbUser, $dbPass, $dbName);
$query = "UPDATE registration SET name = ?, email = ? WHERE entryId = ?";
$stmt = $mysqli->prepare($query);
$stmt->bindParam("ssi", $_POST['name'], $_POST['email'], $_POST['entryId']);
$stmt->execute();
echo $stmt->fullQuery;
Will result in:
UPDATE registration SET name = 'Sue O\'reilly', email = 'sue.o#example.com' WHERE entryId = 5569
Note that the values in the fullQuery are escaped appropriately taking into account the character set on the db server, which should make this functionality suitable for e.g. log files, backups, etc.
There are a few caveats to using this, outlined in the ReadMe on the github project, but, especially for development, learning and testing, this should provide some helpful functionality.
As I've outlined in the github project, I don't have any practical experience using the mysqli extension, and this project was created at the request of users of it's sister project, so any feedback that can be provided from devs using this in production would be greatly appreciated.
Disclaimer - As I said, I made this extension.
Just set it to die and output the last executed query. The Error handling should give you meaningful information which you can use to fix up your query.
You can turn on log queries on mysql server.
Just execute command:
sql> SHOW VARIABLES LIKE "general_log%";
sql> SET GLOBAL general_log = 'ON';
And watch queries in the log file.
After testing turn log off:
sql> SET GLOBAL general_log = 'OFF';
I was able to use var_dump() to at least get a little more info on the mysqli_stmt:
$postmeta_sql = "INSERT INTO $db_new.wp_postmeta (post_id, meta_key, meta_value) VALUES (?, ?, ?)";
$stmt = $new_conn->prepare($postmeta_sql);
$stmt->bind_param("sss", $post_id, $meta_key, $meta_value);
echo var_dump($stmt);
$stmt->execute();
$stmt->close();