Prepare statement return false but insert successfully - php

When I run the prepare statement to insert some data the database, it returns false, however I can see the new row in the database, anyone knows why? I appreciate for any help. And it only happens on INSERT statement.
$query = "INSERT INTO BbUsers(u_username,u_passhash,u_emailaddr,u_validate) VALUES(?,?,?,?)";
$refArr = array("ssss", $username, $passhash, $email, $vaildHash);
$result = cleanQuery($query, $refArr);
if ($result2) {
sendEmail($email, $hash);
} else {
echo "OOps something went wrong plz try again";
exit;
}
Here is the function for prepare statement
function cleanQuery($prepareState,$Arrs)
{
global $dbcon;
$refArr=array();
$res=$dbcon->prepare($prepareState);
$ref= new ReflectionClass('mysqli_stmt');
$method=$ref->getMethod("bind_param");
foreach($Arrs as $key => &$value)
{$refArr[] = &$value;
}
$method->invokeArgs($res,$refArr);
$res->execute();
$result=$res->get_result();
return $result;
}
I tried to get error information from $res and $dbcon, which it returns 0.
Here's db looks like
CREATE TABLE BbUsers(
u_userid INTEGER PRIMARY KEY AUTO_INCREMENT ,
u_username CHAR(60) UNIQUE ,
u_passhash CHAR(100) ,
u_emailaddr CHAR(255) UNIQUE ,
u_created TIMESTAMP ,
u_lastlogin TIMESTAMP ,
u_validate CHAR(40),
INDEX (u_username , u_emailaddr)
);
Anything else I missed?

See the documentation:
mysqli_stmt::get_result
Returns a resultset for successful SELECT queries, or FALSE for other DML queries or on failure. The mysqli_errno() function can be used to distinguish between the two types of failure.
So $res->get_result() works only as you expect for select.
To check if your prepared statement was executed correctly, you can directly use the return parameter for execute:
mysqli_stmt::execute
Returns TRUE on success or FALSE on failure.
You should probably use two different functions, one for select-statements that return a result set (that you by the way have to fetch(), otherwise further queries won't work, read the note in the documentation to execute()), and one for other statements, that return true or false.
And you obviously have to replace if ($result2) { with if ($result) {, but I assume that is just a typo.

Related

php sql search issues

ok here is my code maybe someone out there can explain what I am doing wrong here as I just don't get it. My understanding of this is that IF the stmt finds a result it will then run the code in the {} and hence return a result. And IF there is no result then it would return nothing, as the IF statement is false. But I am getting a return in postman even though the ID that I am searching is false. It does not exist on the table. Why do I get a return?
public function getDoc($ID){
if( $xromstmt = $this->con->prepare("SELECT adegree, bdegree, cset, dset FROM xromdb WHERE ID = ?")) {
$xromstmt->bind_param("s", $ID);
$xromstmt->execute();
$xromstmt->bind_result($adegree, $bdegree, $cset, $dset);
$xromstmt->fetch();
$evalxrom = array();
$edocxrom = array();
some other code here dealing with the return etc... } <-- the end bracket
to the if statement. There is nothing past this bracket.
} bracket to getDoc
The if statement that you have is just checking that the prepare was successful. To see if there was any data returned from the query, you need to check the result of the call to fetch. Try something like this:
if ($xromstmt = $this->con->prepare("SELECT adegree, bdegree, cset, dset FROM xromdb WHERE ID = ?")) {
$xromstmt->bind_param("s", $ID);
$xromstmt->execute();
$xromstmt->bind_result($adegree, $bdegree, $cset, $dset);
if ($xromstmt->fetch()) {
$evalxrom = array();
$edocxrom = array();
...
some other code here dealing with the return etc...
}
}
You should probably also check the result of the call to execute.
The $xromstmt->prepare statement does not search the database it sets-up the search; the database is not searched until $xromstmt->execute. The execute and prepare statements will return true or false if the statement was run correctly (i.e. no errors in your code) regardless of whether any results were found.
What you want is to use is the number of rows from the query, 0 if no results found:
$num_rows = mysql_num_rows($xromstmt)
then run if statements of $num_rows
Hope this helps

Php Mysqli simple class method for INSERT, UPDATE, DELETE and Search

I have the following code in my CRUD class
//function to execute prepared statement query
//$sql = select , insert, update and or delete query => insert into table(col,col,col,...col) values(?,?,?,...?);
//$dataTypes = "ssidb", it could be any char in s=>string, i=>integer, d=>double and b=>blob data
//$param = $val1,$val2,$val3,....$valn, this is an option coma separated values to bind with query
public function dbQuery($sql,$dataTypes="",$param=""){
try{
$this->connect();
$stmt = $this->con->stmt_init();
$stmt = $this->con->prepare($sql);
$stmt->bind_param($dataTypes, $param);
if($stmt->execute() === true){
return true;
}
else{
return false;
}
}catch(Exception $e){
$this->errorMsg = $e->getMessage();
}
$this->closeConnection();
}
I am calling this method from my index page like this:
if(isset($_POST['btnSearch'])){
//search for some record with primary key
$sno = intval($_POST['sno']);
$sql = "SELECT sno,std_name,email,roll_number FROM table_1 WHERE sno = ?";
$dTypes = "i";
$params = $sno;
if($db->dbQuery($sql,$dTypes,$params)){
echo('Record exists');
}
else{
echo('Record did not found'.$db->errorMsg);
}
}//search for record
//inserting values to table_1 table
This always return true either there is any record exists or not?
Whats going wrong with this code?
There are many flaws in your code, and it will never work as intended, even after fixing this particular problem.
Before starting with a class, you need to practice heavily with raw API functions, and learn how to use them by heart. Otherwise your class will be just a straw house that will crumble from a softest touch.
Now to your problem.
To solve it, you need to understand one very important mathematical conception, that reads "empty result is not an error". 10 - 5 - 5 = 0 doesn't mean there is an error in your calculations! It merely means that the result is zero.
Exacly the same is here. When a database returns no rows, it doesn't mean there is an error. It just meams that there is zero (no) data to return.
The opposite is true as well: if there is no error, it doesn't mean that there are rows found.
To see whether any row were returned or not, you need to fetch this very row.
Therefore, instead of checking execute() result, just fetch your row into a variable and then check whether it contains anything.

$result is showing true every time

i just started learning PDO...
function authenticate($username,$password)
{
$result=$this->con->query("select * from user where UserName='".$username."' AND Password='".$password."'");
var_dump($result->rowCount()); //return null
if($result)
echo "hey going great";
else
echo "Hey are you gone mad?";
}
i am calling above function with username and password... but it's returning hey going great part every time if i will pass wrong username and password also...
i tried with $result->rowCount() but it's also returning null value...
Can you suggest me what i am doing wrong here?
You are doing almost everything wrong.
First and foremost, the only reason for using PDO is using placeholders in the query.
You shouldn't also check the query result right in the function. So, make it
function authenticate($username,$password)
{
$sql = "SELECT * FROM user WHERE UserName=? AND Password=?";
$stm = $this->con->prepare($sql);
$stm->execute([$username,$password]);
return $stm->fetch();
}
and then call
if($userdata = $user->authenticate($username,$password))
echo "hey going great";
else
echo "Hey are you gone mad?";
Assuming $this->con is an instance of PDO:
PDO->query() only returns false on failure.
$result will be an instance of PDOStatement, which always evaluates to true
PDOStatement->rowCount() returns the number of rows affected by the last DELETE, INSERT, or UPDATE statement executed by the corresponding PDOStatement object.
If the last SQL statement executed by the associated PDOStatement was a SELECT statement, some databases may return the number of rows returned by that statement. However, this behaviour is not guaranteed for all databases and should not be relied on for portable applications.
Edit: By the way, your application would be more safe, if you use PDO->prepare() (& bound parameters) instead of PDO->query().
if($result)
This will always check for if the variable has any info. When ever you run a query and store in this var , it will store number of rows returned . Even if it is wrong , it will return a neg value which sets the variable.
Basically your if is just checking if the variable exists , it does exist in both cases.
if($result->rowCount()>0){
echo "hey going great";
}else{
echo "Hey are you gone mad?";
}
you can try it as:
$result=$this->con->query("select * from user where UserName='".$username."' AND Password='".$password."'");
var_dump($result->rowCount()); //return null
$num_row=$result->rowCount();
if($num_row > 0)
echo "hey going great";
else
echo "Hey are you gone mad?";

how to transform a function from mysql into mysqli

hello i would like to transform a mysql-function into a mysqli version. this function is for checking if an user exists or not. so i'm new to functions and even to mysqli. thats why i'm having problems while transforming it.
the mysql-version is:
function a($uname){
return (mysql_result(mysql_query("SELECT COUNT (`a`) FROM `table_1` WHERE `a`='$uname'"), 0) == 1) ? true : false;
}
the mysqli-version i thought would be:
function a($uname){
return (mysqli_num_rows(mysqli->query("SELECT COUNT (`a`) FROM `table_1` WHERE `a`='$uname'"), 0) == 1) ? true : false;
}
i know that there is no mysql_result anymore. i decided to use mysqli_num_rows. but this function does not work and i have no clue why. error_reporting is enabled but when calling the page, i will get a blank page with no error messages?!
so if there is someone who could help me out i really would appreciate.
thanks alot.
You need a helper function to put all dirty mysqli internals behind the scenes.
Like safemysql. It can mimic mysql_result as well:
function a($uname){
global $db; // with mysqi you have to connect once and then use this connection
return (bool)$db->getOne("SELECT COUNT (1) FROM table_1 WHERE a=?s"), $uname);
}
and can solve dozens of similar issues.
Freely from the documentation:
mysqli->query returns either a mysqli_result object for queries, which actually return some results, 'false' for failed queries and 'true' for all other queries (if successful).
You will not know anything about the result of your query, unless you check the result more thoroughly.
Try something like this: (This assumes that the connection has been successfully established, and that $uname has been properly escaped.)
function a($uname) {
$found = false;
$result = mysqli->query("SELECT `a` FROM `table_1` WHERE `a`='$uname'");
if($result) {
//We used a 'SELECT' query and the query was successful. That means, we now have a mysqli_result object.
$found = ($result->num_rows == 1); //Determines, if something was actually found or not.
$result->close(); //Frees some ressources. Not necessary, but doesn't hurt either.
} else { //The query failed, as such we have nothing to evaluate.
die("Queryerror: ".mysqli->error);
}
return $found;
}
I changed the query parameter from 'COUNT' to 'a', because otherwise 'num_rows' will ALWAYS return 1, even if the actual count is '0'. This way, it returns the number of matched rows, essentially return '0' for 'no match' or '1' for 'match'.

record updated? when $stmt->execute() $stmt->affected_rows

considering the following for my question:
$success = false;
$err_msg = '';
$sql = 'UPDATE task SET title = ? WHERE task_id = ?';
$conn = connect('w'); // create database connection: r= read, w= write
$stmt = $conn->stmt_init(); // initialize a prepared statement
$stmt->prepare($sql);
$stmt->bind_param('si', $_POST['title'], $_POST['id']);
$stmt->execute();
If i want to check if an insert or a deletion was succesfull, i could easily check for the affected_rows, like this:
if ($stmt->affected_rows > 0) {
$success = true;
} else {
$err_msg = $stmt->error;
}
If $stmt->affected_rows equals -1, it means that $stmt->execute() executed correctly but did not insert the record or did not delete the record successfully.
But, what about an update ? What is the correct way to deal with an update?
The way i do it is by checking for the return value :
$isRecordUpdated = $stmt->execute();
if (!$isRecordUpdated) {
// execute failed, therefore NO record updated!
} else {
//execute success, record updated!
}
Is that the correct way you guys are doing it?
It seems to me that there are really two equivalent and correct ways of doing this: either by checking the return value of execute as you do, or by checking the affected_rows value. -1 means the query errored out; 0 means that it did not affect (delete or update) any rows because there were none matching the query.
Since it seems there is no "better" way, you should pick what would be most convenient for your code. If e.g. using one approach over the other means that you can then share code among all types of queries, you might want to pick that one.
Why not store the value from mysql-affected-rows into a property of that object when you call execute()?
http://php.net/manual/en/function.mysql-affected-rows.php

Categories