Related
I am trying out prepared statements, but the below code is not working. I am getting the error:
Fatal error: Call to a member function execute() on a non-object in
/var/www/prepared.php on line 12
<?php
$mysqli = new mysqli("localhost", "root", "root", "test");
if ($mysqli->connect_errno) {
echo "Failed to connect to MySQL: " . $mysqli->connect_error;
}
$stmt = $mysqli->prepare("INSERT INTO users (name, age) VALUES (?,?)");
// insert one row
$stmt->execute(array('one',1));
// insert another row with different values
$stmt->execute(array('two',1));
?>
Also, do I need to use mysqli for prepared statements? Can anyone point me to a complete example on prepared statements from connection to insertion to selection with error handling?
From the mysqli::prepare docs:
The parameter markers must be bound to application variables using mysqli_stmt_bind_param() and/or mysqli_stmt_bind_result() before executing the statement or fetching rows.
bind_param docs.
i.e.:
$name = 'one';
$age = 1;
$stmt = $mysqli->prepare("INSERT INTO users (name, age) VALUES (?,?)");
// bind parameters. I'm guessing 'string' & 'integer', but read documentation.
$stmt->bind_param('si', $name, $age);
// *now* we can execute
$stmt->execute();
Also do I need to use mysqli for prepared statement. Can anyone point me to a complete example on prepared statement from connection to insertion to selection with error handling
You can also use PDO which I much prefer. In fact, it looks like you're confusing PDO and Mysqli in your code example.
$db = new PDO($dsn, $user, $pass);
$stmt = $db->prepare("INSERT INTO users (name, age) VALUES (?,?)");
$stmt->execute(array($name1, $age1));
$stmt->execute(array($name2, $age2));
Unlike with mysqli you don't have to call a separate binding function, although that feature is available if you prefer/want/need to use it.
Another fun thing about PDO is named placeholders which can be much less confusing in complex queries:
$db = new PDO($dsn, $user, $pass);
$stmt = $db->prepare("INSERT INTO users (name, age) VALUES (:name,:age)");
$stmt->execute(array(':name' => $name1, ':age' => $age1));
$stmt->execute(array(':name' => $name2, ':age' => $age2));
Connection
The importance of mysqli connection is often overlooked, being diminished to a single line. Whereas a correct connection code can solve a multitude of problems, from security to usability.
Given your code is the usual procedural PHP, here is a simple mysqli connection code to be included in your scripts:
$host = '127.0.0.1';
$db = 'test';
$user = 'root';
$pass = '';
$charset = 'utf8mb4';
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
try {
$mysqli = new mysqli($host, $user, $pass, $db);
$mysqli->set_charset($charset);
} catch (\mysqli_sql_exception $e) {
throw new \mysqli_sql_exception($e->getMessage(), $e->getCode());
}
unset($host, $db, $user, $pass, $charset); // we don't need them anymore
The full explanation can be found in my article How to connect properly using mysqli (as well as many useful hints), but just a small citation to highlight most important parts:
setting the proper character set for the connection will eliminate the whole class of errors, such as weird characters/question marks instead of your data, empty json_encode() output, problems with storing emojis, etc.
setting the proper error reporting mode will eliminate the cryptic error messages like mysqli_fetch_assoc() expects parameter... / Call to a member function bind_param()..., giving you the actual error message from MySQL instead.
security is not a laughing matter, there should be not a chance to leak your database details to the outside
Insertion
Insert query is relatively simple, and it is already covered in the other answer.
All you need is to replace all variables (along with surrounding quotes!) in the query with question marks, then prepare the query, then shove all variables with their types into bind_param() and finally execute the query.
Only a quick tip: MySQL will gladly accept all variables as strings, so don't go nuts finding the correct type for a certain variable, simply using "s" for any.
So basically inserting would be like this
$sql = "INSERT INTO users (name, email, password) VALUES (?,?,?)";
$stmt= $conn->prepare($sql);
$stmt->bind_param("sss", $name, $email, $password_hash);
$stmt->execute();
The same principle should be used for all other query types, such as UPDATE or DELETE.
Selection
Running a select query is almost the same, but with one small trick. For some unknown reason you cannot use familiar fetch functions right off the prepared statement. So you need to get the mysqli_result first, and then you'll be able to use fetch_assoc(), fetch_obj() etc:
$sql = "SELECT * FROM users WHERE id=?"; // SQL with parameters
$stmt = $conn->prepare($sql);
$stmt->bind_param("s", $id);
$stmt->execute();
$result = $stmt->get_result(); // get the mysqli result
$user = $result->fetch_assoc(); // fetch data
Tip: there is absolutely no need for the familiar mysqli_num_rows() function. If you think of it, you can always use the data itself, to see whether your query returned any rows:
$user = $result->fetch_assoc();
if ($user) {
// found!
}
the same goes for the multiple rows, thanks to
another tip: there is a handy function fetch_all() that can get you an array of all selected rows in one go. For example, if a query returns multiple rows, you can get them into array by changing the last line to
$users = $result->fetch_all(MYSQLI_ASSOC); // fetch data
Error handling
Error handling is the most important yet somewhat surprising part. Despite what numerous articles and examples say, as a rule, you shouldn't write any error handling code at all. It sounds absolutely crazy but that's exactly how things must be done. Most of time all you need to do is just report the error. And mysqli/PHP already can do it for you, no help required. Therefore, you shouldn't write any code that verifies the query execution result - in case of error mysqli will report it automatically, thanks to the mysqli_report() function call mentioned in the #Connection part. Again, the full explanation of this principle can be found in another article, dedicated to general PHP error reporting.
On a rare occasion when you really need to handle the error, that is to perform some action in case of error instead of just reporting it, then wrap your query(es) in a try..catch.
I am trying out prepared statements, but the below code is not working. I am getting the error:
Fatal error: Call to a member function execute() on a non-object in
/var/www/prepared.php on line 12
<?php
$mysqli = new mysqli("localhost", "root", "root", "test");
if ($mysqli->connect_errno) {
echo "Failed to connect to MySQL: " . $mysqli->connect_error;
}
$stmt = $mysqli->prepare("INSERT INTO users (name, age) VALUES (?,?)");
// insert one row
$stmt->execute(array('one',1));
// insert another row with different values
$stmt->execute(array('two',1));
?>
Also, do I need to use mysqli for prepared statements? Can anyone point me to a complete example on prepared statements from connection to insertion to selection with error handling?
From the mysqli::prepare docs:
The parameter markers must be bound to application variables using mysqli_stmt_bind_param() and/or mysqli_stmt_bind_result() before executing the statement or fetching rows.
bind_param docs.
i.e.:
$name = 'one';
$age = 1;
$stmt = $mysqli->prepare("INSERT INTO users (name, age) VALUES (?,?)");
// bind parameters. I'm guessing 'string' & 'integer', but read documentation.
$stmt->bind_param('si', $name, $age);
// *now* we can execute
$stmt->execute();
Also do I need to use mysqli for prepared statement. Can anyone point me to a complete example on prepared statement from connection to insertion to selection with error handling
You can also use PDO which I much prefer. In fact, it looks like you're confusing PDO and Mysqli in your code example.
$db = new PDO($dsn, $user, $pass);
$stmt = $db->prepare("INSERT INTO users (name, age) VALUES (?,?)");
$stmt->execute(array($name1, $age1));
$stmt->execute(array($name2, $age2));
Unlike with mysqli you don't have to call a separate binding function, although that feature is available if you prefer/want/need to use it.
Another fun thing about PDO is named placeholders which can be much less confusing in complex queries:
$db = new PDO($dsn, $user, $pass);
$stmt = $db->prepare("INSERT INTO users (name, age) VALUES (:name,:age)");
$stmt->execute(array(':name' => $name1, ':age' => $age1));
$stmt->execute(array(':name' => $name2, ':age' => $age2));
Connection
The importance of mysqli connection is often overlooked, being diminished to a single line. Whereas a correct connection code can solve a multitude of problems, from security to usability.
Given your code is the usual procedural PHP, here is a simple mysqli connection code to be included in your scripts:
$host = '127.0.0.1';
$db = 'test';
$user = 'root';
$pass = '';
$charset = 'utf8mb4';
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
try {
$mysqli = new mysqli($host, $user, $pass, $db);
$mysqli->set_charset($charset);
} catch (\mysqli_sql_exception $e) {
throw new \mysqli_sql_exception($e->getMessage(), $e->getCode());
}
unset($host, $db, $user, $pass, $charset); // we don't need them anymore
The full explanation can be found in my article How to connect properly using mysqli (as well as many useful hints), but just a small citation to highlight most important parts:
setting the proper character set for the connection will eliminate the whole class of errors, such as weird characters/question marks instead of your data, empty json_encode() output, problems with storing emojis, etc.
setting the proper error reporting mode will eliminate the cryptic error messages like mysqli_fetch_assoc() expects parameter... / Call to a member function bind_param()..., giving you the actual error message from MySQL instead.
security is not a laughing matter, there should be not a chance to leak your database details to the outside
Insertion
Insert query is relatively simple, and it is already covered in the other answer.
All you need is to replace all variables (along with surrounding quotes!) in the query with question marks, then prepare the query, then shove all variables with their types into bind_param() and finally execute the query.
Only a quick tip: MySQL will gladly accept all variables as strings, so don't go nuts finding the correct type for a certain variable, simply using "s" for any.
So basically inserting would be like this
$sql = "INSERT INTO users (name, email, password) VALUES (?,?,?)";
$stmt= $conn->prepare($sql);
$stmt->bind_param("sss", $name, $email, $password_hash);
$stmt->execute();
The same principle should be used for all other query types, such as UPDATE or DELETE.
Selection
Running a select query is almost the same, but with one small trick. For some unknown reason you cannot use familiar fetch functions right off the prepared statement. So you need to get the mysqli_result first, and then you'll be able to use fetch_assoc(), fetch_obj() etc:
$sql = "SELECT * FROM users WHERE id=?"; // SQL with parameters
$stmt = $conn->prepare($sql);
$stmt->bind_param("s", $id);
$stmt->execute();
$result = $stmt->get_result(); // get the mysqli result
$user = $result->fetch_assoc(); // fetch data
Tip: there is absolutely no need for the familiar mysqli_num_rows() function. If you think of it, you can always use the data itself, to see whether your query returned any rows:
$user = $result->fetch_assoc();
if ($user) {
// found!
}
the same goes for the multiple rows, thanks to
another tip: there is a handy function fetch_all() that can get you an array of all selected rows in one go. For example, if a query returns multiple rows, you can get them into array by changing the last line to
$users = $result->fetch_all(MYSQLI_ASSOC); // fetch data
Error handling
Error handling is the most important yet somewhat surprising part. Despite what numerous articles and examples say, as a rule, you shouldn't write any error handling code at all. It sounds absolutely crazy but that's exactly how things must be done. Most of time all you need to do is just report the error. And mysqli/PHP already can do it for you, no help required. Therefore, you shouldn't write any code that verifies the query execution result - in case of error mysqli will report it automatically, thanks to the mysqli_report() function call mentioned in the #Connection part. Again, the full explanation of this principle can be found in another article, dedicated to general PHP error reporting.
On a rare occasion when you really need to handle the error, that is to perform some action in case of error instead of just reporting it, then wrap your query(es) in a try..catch.
I am trying out prepared statements, but the below code is not working. I am getting the error:
Fatal error: Call to a member function execute() on a non-object in
/var/www/prepared.php on line 12
<?php
$mysqli = new mysqli("localhost", "root", "root", "test");
if ($mysqli->connect_errno) {
echo "Failed to connect to MySQL: " . $mysqli->connect_error;
}
$stmt = $mysqli->prepare("INSERT INTO users (name, age) VALUES (?,?)");
// insert one row
$stmt->execute(array('one',1));
// insert another row with different values
$stmt->execute(array('two',1));
?>
Also, do I need to use mysqli for prepared statements? Can anyone point me to a complete example on prepared statements from connection to insertion to selection with error handling?
From the mysqli::prepare docs:
The parameter markers must be bound to application variables using mysqli_stmt_bind_param() and/or mysqli_stmt_bind_result() before executing the statement or fetching rows.
bind_param docs.
i.e.:
$name = 'one';
$age = 1;
$stmt = $mysqli->prepare("INSERT INTO users (name, age) VALUES (?,?)");
// bind parameters. I'm guessing 'string' & 'integer', but read documentation.
$stmt->bind_param('si', $name, $age);
// *now* we can execute
$stmt->execute();
Also do I need to use mysqli for prepared statement. Can anyone point me to a complete example on prepared statement from connection to insertion to selection with error handling
You can also use PDO which I much prefer. In fact, it looks like you're confusing PDO and Mysqli in your code example.
$db = new PDO($dsn, $user, $pass);
$stmt = $db->prepare("INSERT INTO users (name, age) VALUES (?,?)");
$stmt->execute(array($name1, $age1));
$stmt->execute(array($name2, $age2));
Unlike with mysqli you don't have to call a separate binding function, although that feature is available if you prefer/want/need to use it.
Another fun thing about PDO is named placeholders which can be much less confusing in complex queries:
$db = new PDO($dsn, $user, $pass);
$stmt = $db->prepare("INSERT INTO users (name, age) VALUES (:name,:age)");
$stmt->execute(array(':name' => $name1, ':age' => $age1));
$stmt->execute(array(':name' => $name2, ':age' => $age2));
Connection
The importance of mysqli connection is often overlooked, being diminished to a single line. Whereas a correct connection code can solve a multitude of problems, from security to usability.
Given your code is the usual procedural PHP, here is a simple mysqli connection code to be included in your scripts:
$host = '127.0.0.1';
$db = 'test';
$user = 'root';
$pass = '';
$charset = 'utf8mb4';
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
try {
$mysqli = new mysqli($host, $user, $pass, $db);
$mysqli->set_charset($charset);
} catch (\mysqli_sql_exception $e) {
throw new \mysqli_sql_exception($e->getMessage(), $e->getCode());
}
unset($host, $db, $user, $pass, $charset); // we don't need them anymore
The full explanation can be found in my article How to connect properly using mysqli (as well as many useful hints), but just a small citation to highlight most important parts:
setting the proper character set for the connection will eliminate the whole class of errors, such as weird characters/question marks instead of your data, empty json_encode() output, problems with storing emojis, etc.
setting the proper error reporting mode will eliminate the cryptic error messages like mysqli_fetch_assoc() expects parameter... / Call to a member function bind_param()..., giving you the actual error message from MySQL instead.
security is not a laughing matter, there should be not a chance to leak your database details to the outside
Insertion
Insert query is relatively simple, and it is already covered in the other answer.
All you need is to replace all variables (along with surrounding quotes!) in the query with question marks, then prepare the query, then shove all variables with their types into bind_param() and finally execute the query.
Only a quick tip: MySQL will gladly accept all variables as strings, so don't go nuts finding the correct type for a certain variable, simply using "s" for any.
So basically inserting would be like this
$sql = "INSERT INTO users (name, email, password) VALUES (?,?,?)";
$stmt= $conn->prepare($sql);
$stmt->bind_param("sss", $name, $email, $password_hash);
$stmt->execute();
The same principle should be used for all other query types, such as UPDATE or DELETE.
Selection
Running a select query is almost the same, but with one small trick. For some unknown reason you cannot use familiar fetch functions right off the prepared statement. So you need to get the mysqli_result first, and then you'll be able to use fetch_assoc(), fetch_obj() etc:
$sql = "SELECT * FROM users WHERE id=?"; // SQL with parameters
$stmt = $conn->prepare($sql);
$stmt->bind_param("s", $id);
$stmt->execute();
$result = $stmt->get_result(); // get the mysqli result
$user = $result->fetch_assoc(); // fetch data
Tip: there is absolutely no need for the familiar mysqli_num_rows() function. If you think of it, you can always use the data itself, to see whether your query returned any rows:
$user = $result->fetch_assoc();
if ($user) {
// found!
}
the same goes for the multiple rows, thanks to
another tip: there is a handy function fetch_all() that can get you an array of all selected rows in one go. For example, if a query returns multiple rows, you can get them into array by changing the last line to
$users = $result->fetch_all(MYSQLI_ASSOC); // fetch data
Error handling
Error handling is the most important yet somewhat surprising part. Despite what numerous articles and examples say, as a rule, you shouldn't write any error handling code at all. It sounds absolutely crazy but that's exactly how things must be done. Most of time all you need to do is just report the error. And mysqli/PHP already can do it for you, no help required. Therefore, you shouldn't write any code that verifies the query execution result - in case of error mysqli will report it automatically, thanks to the mysqli_report() function call mentioned in the #Connection part. Again, the full explanation of this principle can be found in another article, dedicated to general PHP error reporting.
On a rare occasion when you really need to handle the error, that is to perform some action in case of error instead of just reporting it, then wrap your query(es) in a try..catch.
Building a tool that first pulls a sim number, then marks it as taken. The first part is working great and is being served to my page with ajax. The second part doesn't seem to want to work.
include_once 'inc/db_connect.php';
$stmt = $db->query('SELECT sim FROM p2p WHERE taken = 0 ORDER by id ASC LIMIT 1');
while($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
$result = $row['sim'];
}
echo json_encode($result);
$stmt = $db->prepare("UPDATE p2p SET taken = 1 WHERE sim = ?");
$stmt->bind_param('i', $result);
$stmt->execute();
Any ideas!
It's because of this bind_param() that is MySQLi_* syntax and you're using PDO.
fetch(PDO::FETCH_ASSOC)
Use PDO's bindParam() function
Those two APIs do not mix.
If that doesn't work, use bindValue()
Add $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); right after the connection is opened. That will signal the error.
An insight
I've noticed in a previous question you posted, that you are using mysqli_* functions to connect to your database with.
$result = mysqli_query($conn, $query);
If that is still the case, then you cannot mix PDO with mysqli_ in any way, shape or form.
Those MySQL APIs do not intermix with each other.
Consult: http://php.net/manual/en/mysqlinfo.api.choosing.php
Generally I connect and retrieve data using the standard way (error checking removed for simplicity):
$db = mysql_select_db("dbname", mysql_connect("host","username","passord"));
$items = mysql_query("SELECT * FROM $db");
while($item = mysql_fetch_array($items)) {
my_function($item[rowname]);
}
Where my_function does some useful things witht that particular row.
What is the equivalent code using objects?
Since version 5.1, PHP is shipped with the PDO driver, which gives a class for prepared statements.
$dbh = new PDO("mysql:host=$hostname;dbname=$db", $username, $password); //connect to the database
//each :keyword represents a parameter or value to be bound later
$query= $dbh->prepare('SELECT * FROM users WHERE id = :id AND password = :pass');
# Variables are set here.
$query->bindParam(':id', $id); // this is a pass by reference
$query->bindValue(':pass', $pass); // this is a pass by value
$query->execute(); // query is run
// to get all the data at once
$res = $query->fetchall();
print_r($res);
see PDO driver at php.net
Note that this way (with prepared statements) will automatically escape all that needs to be and is one of the safest ways to execute mysql queries, as long as you use binbParam or bindValue.
There is also the mysqli extension to do a similar task, but I personally find PDO to be cleaner.
What going this whole way around and using all these steps gives you is possibly a better solution than anything else when it comes to PHP.
You can then use $query->fetchobject to retrieve your data as an object.
You can use the mysql_fetch_object()
http://is2.php.net/manual/en/function.mysql-fetch-object.php