Everything with it is fine. The name of the database and table, the name of the columns etc. $username is good and exists in the database. Yet, after this runs, if I "alert" $dbuid it comes up as 0 and $dbusername comes up as empty. MySQLi throws no errors. (That is why I did if(! .. ) echo error;, to see if it throws an error on anything, but it works perfectly fine.) Where am I going wrong ?
if(!$msmysqli = new mysqli("localhost","root","","ms")){
echo $msmysqli->connect_error;
}
if(!$stmt = $msmysqli->prepare("SELECT id,name,password FROM accounts WHERE name=?")){
echo $msmysqli->error;
}
if(!$stmt->bind_param("s",$username)){
echo $stmt->error;
}
if(!$stmt->execute()){
echo $stmt->error;
}
if(!$stmt->bind_result($dbuid,$dbusername,$dbpassword)){
echo $stmt->error;
}
$stmt->close();
You simply forgt to fetch your result to get the row... thats why your code wasn't working as expected! Another thing to bare in mind is that an object, at least in php, returns always its instance while being constructed! The statement $msmysqli = new mysqli(...) is never going to be false! thats why you should check your connection as shown!
$msmysqli = new mysqli("localhost","root","","ms");
if ( $msmysqli->connect_errno ) echo $msmysqli->connect_error;
if( $stmt = $msmysqli->prepare("SELECT id,name,password FROM accounts WHERE name=?") ) {
$stmt->bind_param("s",$username);
$stmt->execute();
$stmt->bind_result($dbuid,$dbusername,$dbpassword);
$stmt->fetch();
$stmt->close();
} else {
echo $msmysqli->error;
}
$msmysqli->close();
Related
I need to show website visitor that something went wrong should him making queries to my database fails technically.
Want to get the php code to echo "Sorry! Something went wrong!" if for some reason data fetching failed.
Following are some ways I am trying to accomplish this.
3 samples.
They result in neverending loops thus crashing my browser.
(NOTE the IFs on each sample. That is where the 3 samples differ).
I ranked them according to favourite ....
How to fix this to bare minimum to achieve my purpose ? Would appreciate codes samples. I know how to achieve this with mysqli_stmt_get_result() but need to learn with the mysqli_stmt_bind_result() in procedural style programming. Not into oop yet. Nor pdo.
1.
<?php
//LOOPS NEVERENDING
$server = 'localhost';
$user = 'root';
$password = '';
$database = 'brute';
$conn = mysqli_connect("$server","$user","$password","$database");
$keywords = 'keyword';
$query = 'SELECT id,domain from links WHERE keywords = ?';
$stmt = mysqli_stmt_init($conn);
if(mysqli_stmt_prepare($stmt,$query))
{
mysqli_stmt_bind_param($stmt,'s',$keywords);
if(mysqli_stmt_execute($stmt))
{
while($result = mysqli_stmt_bind_result($stmt,$id,$domain))
{
mysqli_stmt_fetch($stmt);
echo 'Id: ' .$id; echo '<br>';
echo 'Domain: ' .$domain; echo '<br>';
if(!$result)
{
echo 'Sorry! Something went wrong. Try again later.';
}
}
}
mysqli_stmt_close($stmt);
mysqli_close($conn);
}
?>
<?php
//LOOPS NEVERENDING
$server = 'localhost';
$user = 'root';
$password = '';
$database = 'brute';
$conn = mysqli_connect("$server","$user","$password","$database");
$keywords = 'keyword';
$query = 'SELECT id,domain from links WHERE keywords = ?';
$stmt = mysqli_stmt_init($conn);
if(mysqli_stmt_prepare($stmt,$query))
{
mysqli_stmt_bind_param($stmt,'s',$keywords);
mysqli_stmt_execute($stmt);
while(mysqli_stmt_bind_result($stmt,$id,$domain))
{
if(mysqli_stmt_fetch($stmt)) //If 'Rows Fetching' were successful.
{
echo 'Id: ' .$id; echo '<br>';
echo 'Domain: ' .$domain; echo '<br>';
}
else //If 'Rows Fetching' failed.
{
echo 'Sorry! Something went wrong. Try again later.';
}
}
mysqli_stmt_close($stmt);
mysqli_close($conn);
}
?>
<?php
//LOOPS NEVERENDING
$server = 'localhost';
$user = 'root';
$password = '';
$database = 'brute';
$conn = mysqli_connect("$server","$user","$password","$database");
$keywords = 'keyword';
$query = 'SELECT id,domain from links WHERE keywords = ?';
$stmt = mysqli_stmt_init($conn);
if(mysqli_stmt_prepare($stmt,$query))
{
mysqli_stmt_bind_param($stmt,'s',$keywords);
if(mysqli_stmt_execute($stmt)) //If 'Query Execution' was successful.
{
while(mysqli_stmt_bind_result($stmt,$id,$domain))
{
mysqli_stmt_fetch($stmt);
echo 'Id: ' .$id; echo '<br>';
echo 'Domain: ' .$domain; echo '<br>';
}
}
else //If 'Query Execution' failed.
{
echo 'Sorry! Something went wrong. Try again later.';
}
mysqli_stmt_close($stmt);
mysqli_close($conn);
}
?>
Basically, all of the approaches are wrong. If the query fails then there will be an error triggered automatically by PHP as long as you have error reporting enabled, see How to get the error message in MySQLi?. You should not be checking for it manually. Your code is way longer than it needs to be. Consider how it should be done properly:
<?php
$server = 'localhost';
$user = 'root';
$password = '';
$database = 'brute';
// enable error reporting
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$conn = mysqli_connect($server, $user, $password, $database);
mysqli_set_charset($conn, 'utf8mb4');
$keywords = 'keyword';
$query = 'SELECT id,domain from links WHERE keywords = ?';
$stmt = mysqli_prepare($conn, $query);
mysqli_stmt_bind_param($stmt, 's', $keywords);
mysqli_stmt_execute($stmt);
mysqli_stmt_bind_result($stmt, $id, $domain);
// This loop will keep on going as long as fetch() returns true.
// It will return false when it reaches the end
while (mysqli_stmt_fetch($stmt)) {
echo 'Id: ' .$id;
echo '<br>';
echo 'Domain: ' .$domain;
echo '<br>';
}
When you enable mysqli error reporting, your code becomes much simpler. There's no need for any special message to the user. When a query fails then an error will be triggered just like any other PHP error and handled the same way. If you want you can then customize the error page, but that is a completely separate topic.
The loop on mysqli_stmt_fetch() is used to fetch the data from the server. The data will be read row by row, and when there are no more rows mysqli_stmt_fetch() will return false.
mysqli_stmt_bind_result() needs to be called only once. Its purpose is to provide variable placeholders into which the data will be populated.
Their is a mistake in your code that make your code loop forever. In such cases, a while loop in your code is one of the most common cause of this kind of problem.
When you are using any function you should consider to read the documentation of this function and check what kind of errors and what kind of results (returns) it can give you. Functions can throw errors, warning, Exceptions, or return error codes. Also dont underestimate examples on the PHP documentation of each function. It give you a good idea of how things works.
When you are calling a function it's generally good to check the result returned. I will not rewrite all the documentation here but here is an example for mysqli_stmt_bind_result :
https://www.php.net/manual/en/mysqli-stmt.bind-result.php
This part of the procedural example is important for you :
/* bind variables to prepared statement */
mysqli_stmt_bind_result($stmt, $col1, $col2);
/* fetch values */
while (mysqli_stmt_fetch($stmt)) {
printf("%s %s\n", $col1, $col2);
}
Here you can see how mysqli_stmt_bind_result and mysqli_stmt_fetch can be used together to loop through your results.
But this is not perfect for error checking.
The documentation of mysqli_stmt_bind_result says in section Return values :
Returns true on success or false on failure.
So in case of failure of this function you can check for errors this way :
if (!mysqli_stmt_bind_result($stmt, $id, $domain)) {
die("mysqli_stmt_bind_result has failed !"); // of course you can use something more sophisticated than dying...
}
In case of success, and the source of your infinite loop is here, it returns true. So doing while(mysqli_stmt_bind_result($stmt, $id, $domain)) is a mistake, first because you dont have to loop on this function (it's a job for mysqli_stmt_fetch), secondly because mysqli_stmt_bind_result will ever returns true in your case and your while loop will never end.
For mysqli_stmt_fetch now, there is a subtle difference. Check the return values : https://www.php.net/manual/en/mysqli-stmt.fetch.php
Return Value
Description
true
Success. Data has been fetched
false
Error occurred
null
No more rows/data exists or data truncation occurred
Here you have to check for 3 different values and dont forget that null and false can both be evaluated as falsy if you dont take care.
This doesnt allow to display an error :
while (mysqli_stmt_fetch($stmt)) { // is result false or null ? we dont know
printf ("%s (%s)\n", $id, $domain);
}
This is more complete :
$fetchResult = null;
while ($fetchResult = mysqli_stmt_fetch($stmt)) {
printf ("%s (%s)\n", $id, $domain);
}
/* dont forget to use 3 equal signs to also compare variable type */
/* null == false values are considered the same */
/* null === false this also compare variable types, here types are not the same */
if ($fetchResult === false) {
die("mysqli_stmt_fetch failed !");
}
Now you are free to read the documentation of all called functions to do your errors checks.
Also note that another error management (less verbose and error prone) is possible using Exceptions objects like explained by Dharman answer
Trying to update a record using PHP and PDO statements.
The query fires with no errors, and the console reads the update was successful, but there is no change in the table.
So confused as to why this is happening:
<?php
include("../include/sessions.php");
if(isset($_POST['editcriteria']))
{
$value = $_POST['editcriteria'];
$editUID = $value['editUID'];
$editAddDelete = $value['editAddDelete'];
$editeffectiveDate = $value['editeffectiveDate'];
try
{
$update = $conn->prepare("UPDATE primary_vehicle_data SET `add_delete` = :eadddelete,
`effective_date` = :eeffectivedate WHERE `uid` = :euid");
$update->execute([
'eadddelete' => $editAddDelete,
'eeffectivedate' => $editeffectiveDate,
'euid' => $editUID
]);
if($update)
{
echo "Success: Record Updated";
}
else
{
echo "Error: The Vehcile was not updated.";
}
}
catch(PDOException $e)
{
echo "Error: " . $e->getMessage();
}
}
?>
I simplified the above code as much as possible. There were several more parameters, but when I removed the parameters and left it with the 3 parameters above, I still get "Success: Record Updated". But the table is literally unaffected.
Why is this happening and how do I fix it?
* UPDATE *
I already confirmed the connection to the database is good. I'm lost.
$update is a PDOStatement object, so when you test
if ($update)
it will always succeed as a PDOStatement object is equivalent to true.
You should be:
checking the result of $update->execute e.g.
if ($update->execute([ /* params */])) {
checking the value in $update->rowCount, which will tell you if any rows were affected by the query.
May be this question will be sort of "stupid-questions", but still...
I'm new to PHP and SQL and I can't understand what I am doing wrong here:
if(isset($_POST[$logButton])) //Checking for login button pressed
{
//Retrieving information from POST method
$uid = $_POST['login'];
$upwd = $_POST['password'];
//SQL Connection
$mysqli = new mysqli('localhost', 'root', '', 'students');
if(!$mysqli)
{
echo "<h1 class='h1A'>Problem accured while connecting to the DB. " . mysqli_error($mysqli) . "</h1>"; //!!!Delete displaying error msg after dev.
}else
{
$sql = "SELECT * FROM login_data WHERE login = ? AND password = ?"; //SQL query
$stmt = $mysqli->prepare($sql) or die("error1"); //No error
$stmt->bind_param('ss', $uid, $upwd) or die("error2");//No error
$stmt->execute() or die("error3");//Giving DB query. No error
$result = $stmt->fetch() or die("error4".mysqli_error($mysqli)); //Putting query's result into assoc array. !!!Delete displaying error msg after dev. No error
echo print_r($result); //It prints out "11" ? ? ?
if(count($result['id']) < 1) //If no rows found.
{
echo "<h1 class='h1A'>Couldn't find account. Please, recheck login and password.</h1>";
die();
}elseif($result['id'] > 1)//If more then 1 row found.
{
echo "<h1 class='h1A'>Caught 9090 error. Contact the administrator, please.".mysqli_error($mysqli)."</h1>";
die();
}elseif($result['id'] == 1) //If only one row's been found.
{
$_SESSION['isLoggedIn'] = true;
redirectTo('/index.php'); //Declared function.
die();
}
}
}
Here is a part of handler function in lib.php file. This file is included to the html-page and the function is used. No errors displayed and when I print_r $result - it prints out 11. Can't get it.
Well, use print_r without echo :
print_r($result);
or pass second parameter to print_r function so it can return string:
echo print_r($result, true);
See http://php.net/manual/en/function.print-r.php for more info.
if have a piece of code that is to hard for me to solve.. And i don't know how i can find the error more than this.
while($this->_pathLus != $this->hoofdMap) { //loop works fine, tested and confirmd
echo $this->_pathLus . 0; //$this->_pathLus = <data4>
if ($stmtToegang = $db->prepare("SELECT <data>, <data2> FROM `<data3>` WHERE <data> = ? LIMIT 5")) {
$stmtToegang->bind_param("s",$this->_pathLus);
$stmtToegang->execute();
$stmtToegang->bind_result($<data>, $<data2>);
while ($stmtToegang->fetch()) {
echo $<data> . 1;
echo $stmtToegang->error . 2;
}
} else { //to be sure if-stmt-prep is FALSE
echo $stmtToegang->error . 3;
}
$this->_pathLus = preg_replace("/(.*)\/(.*)\/(.*)\//", "$1/$2/", $this->_pathLus); // part of Loop and works
}
What i did to find solution:
check if $stmtToegang is correct everywhere
check if the sql-select is correct
Check if _pathLus is correct
add else on if-stmt-prep to make sure is failed
Results:
<data4>03<data4>03<data4>03<data4>03<data4>03
<data4>03<data4>03<data4>03
<data4>03<data4>03<data4>03<data4>03
<data4>03<data4>03
<data4>03
<data4>03<data4>03
Note: <data>, <data2>, <data3> are replacements for this example
Thanks in advance
Edit: Correction
Edit:
mysqli_prepare() returns a statement object or FALSE if an error
occurred.
But how get the error that Happens ?
How i did find the problem:
i altered echo $stmtToegang->error . 3; into echo $db->error . 3;
This way i found the following error:
Commands out of sync; you can't run this command now
Where i found a solution:
Answer here on SO
Problems was that this stmt-query (select type) was a part of another stmt-query (select type) because:
mysqli uses unbuffered queries by default (for prepared statements;)
So my code to debug a nested prepared statement (select-type) is as followed :
if($stmt = $mysqli->prepare($sql)) {
<$stmt->bind_param()->execute()->bind_result() code>
$stmt->store_result(); // store them !important
while ($stmt->fetch()) {
//code
if($stmt2 = $mysqli->prepare($sql)) {
<$stmt2->bind_param()->execute()->bind_result() code>
$stmt2->store_result(); // store them !important
while ($stmt2->fetch()) {
//code
}
$stmt2->free_result(); // free them
$stmt2->close(); // close them
echo $stmt2->error; // report error
} else {
echo $mysqli->error; // report error
}
}
$stmt->free_result(); // free them
$stmt->close(); // close them
echo $stmt->error; // report error
} else {
echo $mysqli->error; // report error
}
//edit: <$stmt->bind_param()->execute()->bind_result() code> for an better view
Hope it can help somone
Database connecting is working. The SELECT AND UPDATE FUNCTION in the class is not working at all.It is not even showing errors to help me sort out the problem. I am trying to learn how to use the prepare ,bind-param and execute statement. Please can someone help look at the codes and advise what may be wrong with it. Just spent loads of hours on this and just cant figure where the problems is. please can some help me.I am a novice and writing my very first codes . Many thanks in advance
<?php class connect_dbase{
public $mysqli;
public function connection($host="localhost",$user="root",$password="london",$db_name="users")
{
$this->mysqli=new mysqli($host,$user,$password,$db_name);
if ($this->mysqli->connect_error) {
die('Connect Error: ' . $this->mysqli->connect_error);
}
else{
echo " Database connection successful";
}
}
public function display_all($id){
if($stmt = $this->mysqli->prepare("SELECT * FROM user WHERE id =?")){
/* bind parameters for markers */
$stmt->bind_param('i',$id);
/* execute query */
$stmt->execute();
if($stmt->num_row() >0){
echo 'Total results: ' . $resultrol->num_rows;
$result = $stmt->get_result();
while ($row = $result->fetch_assoc()) {
echo $row['name'];
echo $row['email'];
echo $row['address'];}
}
else { echo "no result found";}
}
else
{
echo "cant prepare result";
}
}
public function update_post($name, $address,$email,$mob,$id)
{
$up="UPDATE user SET name=?, address =?,email=?,mobile=? WHERE id =?";
if($stmt=$mysqli->prepare($up))
{
$stmt->bind_param("sssii", $name, $address,$email,$mob,$id);
if($stmt->excute()) {
echo " post updated";
header('location:index.php');
}
else
{
echo "post not executed";
}
}else{ echo " cannot prepare statement";}
}
}
$connect_dbase=new connect_dbase();
$connect_dbase->connection();
$connect_dbase->display_all(2);
$connect_dbase-> update_post("john","kkkkk","kkk#yahoo.com",98765,2);
// These 2 functions- $connect_dbase->display_all(2); and
$connect_dbase-> update_post("john","kkkkk","kkk#yahoo.com",98765,2); are not working when called from the class above .
?>
I agree with #MikeBrant's comments. You should make the connection happen in the constructor if you want to be assured that the connection is successful before you try to call it.
Here's another tip:
if($stmt->num_row() >0){
Note that num_rows() doesn't return anything useful until after the client has fetched the rows. So calling it right after execute() is pretty much guaranteed to make it return the wrong number.
You need to use mysqli::store_result() to transfer the result set from the server to the client, and then num_rows() will work. But be careful if the result set is very large, it could use too much memory.
Taking into account the input from Mike and Bill I have modified your code to make it functional. It could use some more work but it should give you a starting point at the very least. I created a test database with three fields, id, name and email but you should be able to plug in your own database and fields and have it still work.
<?php
class connect_dbase {
public $mysqli;
public function connection($host="localhost",$user="root",$password="",$db_name="test")
{
$this->mysqli=new mysqli($host,$user,$password,$db_name);
if ($this->mysqli->connect_error) {
die('Connect Error: ' . $this->mysqli->connect_error);
} else {
// return a true value here if successful, that way you can check
// if your connection was established
return true;
}
}
public function display_all($id){
if($stmt = $this->mysqli->prepare("SELECT * FROM test WHERE id =?")) {
// some minor changes to the bind and execute statments. I
// wrapped them in an if just to make sure there were no errors
// if i had more time i might make these more elegant rather than just
// echoing them out
/* bind parameters for markers */
if(!($stmt->bind_param('i',$id))) {
echo $stmt->error;
}
/* execute query */
if(!($stmt->execute())) {
echo $stmt->error;
}
// You could also bind the results to specific variables here and return those
//$stmt->bind_result($id,$name,$email);
//$stmt->fetch();
//$result = $name;
//assign the results to a variable and then return that variable
//rather than processing the results here
$result = $stmt->get_result();
return $result;
} else {
// if an error occurs return the error, once again another place for
// improvement but at the very least will show you an error
echo $this->mysqli->error;
}
}
public function update_post($name, $email, $id)
{
$up="UPDATE test SET name=?, email=? WHERE id =?";
// originally had $mysqli->prepare($up), fixed syntax
if($stmt = $this->mysqli->prepare($up))
{
//$stmt->bind_param("sssii", $name, $address,$email,$mob,$id);
$stmt->bind_param("ssi", $name, $email,$id);
// execute was spelled wrong
if($stmt->execute()) {
return true;
} else {
return $stmt->error;
//return false;
}
} else {
return false;
}
}
}
// set up database connection
$connect_dbase = new connect_dbase();
if($connect_dbase->connection()) {
// if connection was successful, call display_all
// and assign the results to $result
$result = $connect_dbase->display_all(2);
// you could do a foreach here also but since there
// was only one result i just echoed the values
while($row = $result->fetch_array()) {
echo $row['id'] . "<br/>";
echo $row['name'] . "<br/>";
echo $row['email'] . "<br/>";
}
// then call update_post
$update_result = $connect_dbase->update_post("asdf","asdf#yahoo.com",2);
// show a message if the update_post was successful
if($update_result) {
echo "Update successful";
}
}
?>
I commented the areas I switched around so you have an idea of what I did.