I have function that performs a mysql_query() and then does some other stuff.
I want to be able to perform another mysql_query() only if the first one succeeds.
Here is the function
function myFunction($qtext)
{
mysql_query($qtext) or die(mysql_error() . "\n");
//do some more stuff
return true;
}
I'm calling the function and attempting to check if it failed with an if else conditional...
if(!myFunction($query_text))
{
echo "first query failed";
}
else
{
mysql_query($query_text1) or die (mysql_error() . "\n");
}
This seems to work when the first query passes, but if the first query fails it goes to the or die and returns the mysql_error() text and the echo "first query failed"; line in the conditional is never reached.
Ideally id like to be able to alert the user with the mysql_error text but without or dieing, so I can run more code in the conditional.
Any help with explanations of behavior is greatly appreciated.
Thanks.
p.s.
I'm a beginner... I'm not sure if Im using the return true; properly in the function
You're always returning true in the function - you need to also return false if you're checking it in an if() statement.
function myFunction($qtext) {
// run the query
$sql = mysql_query($qtext);
// see if there was a result (or whatever you're checking)
if(mysql_num_rows($sql) > 0) {
// do some more stuff
return true;
} else {
return false;
}
}
Also, you really should learn mysqli or POD instead of mysql, as mysql is depreciated. I also recommend you don't use die() unless you're testing. Build an error handling function instead - it's actually quite easy and will handle errors gracefully instead of abruptly killing the script and annoying your users. You also don't want to print error messages directly to your browser because it can compromise your site's security. :)
Just an FYI: I use a database class and run my queries like this. It's fast and clean.
if($db->get_results("SELECT email FROM users WHERE email='".$db->escape($email)."'")) {
return true;
} else{
return false;
}
To prevent "or die" from happening, replace it with return false:
function myFunction($qtext)
{
$result = mysql_query($qtext);
if ($result === false)
{
return false;
}
//do some more stuff
return true;
}
that way your check later on will work and condition will fire. You don't have to use "or die", that is reserved for the cases where you want to halt all execution.
die() kills the script instantly. That function will never return any value if you call die() inside it, you will never be able to perform other queries. Only the destructors of instanced object are still ran after a die() call, and with several restrictions.
If you want to be able to continue doing stuff after a query fails, you must never call die(). Instead, just check if mysql_query() returned FALSE as Tim suggested. Note the === operator, its important to a proper error check here.
If you still want to print the error like die() would, use print() or echo instead.
Related
I'm not sure if i'm doing this right.
This is the problem:
if ($result->execute() && $result2->execute()){}
Is this something that can be done or not?
My goal is to do something inside IF only if both queries works.
I couldn't find nothing online about that.
You can certainly do this. PDO's execute() statement returns true on success and false on failure. I would change the style somewhat so it's easier to read, but there's no reason you can't do this.
$success1 = $result->execute();
$success2 = $result2->execute();
if ( $success1 and $success2 ) {
// Do stuff here on failure
}
else {
// Do stuff on failure here
}
So I have this code in a php file:
$query="INSERT INTO tec (name) VALUES ('$name')";
$done=mysql_query($query);
if($done == 'null') {
$output = json_encode(array('type'=>'error', 'message' => $mess['error'].$done.'</b></div>'));
} else {
$output = json_encode(array('type'=>'success', 'message' => $mess['success']));
}
It inserts a name into a table named "tec". If $done == 'null' then I print an error message.
The problem is that when I run the code, it inserts the data correctly, but I get the error message.
I tried to read $done and its equal to 1.
Should I do something like:
if($done == 1){
//OK
}else{
//NOT OK
}
Or is there any way to fix this?
The documentation says that mysql_query returns FALSE on error. That means instead of testing whether it's equal to 'null' (a string which compares as TRUE), you could just test the boolean-ness directly:
if($done){
//OK
}else{
//NOT OK
}
I would be remiss if I didn't mention that the mysql_* family of functions is deprecated, unsafe, and will be removed from future versions of PHP! Instead, I can personally recommend PDO, which I've used with a good amount of success.
As per the documentation of mysql_query function's php manual
For SELECT, SHOW, DESCRIBE, EXPLAIN and other statements returning resultset, mysql_query() returns a resource on success, or FALSE on error.
For other type of SQL statements, INSERT, UPDATE, DELETE, DROP, etc, mysql_query() returns TRUE on success or FALSE on error.
So, search if it's TRUE or FALSE.
if ($done == TRUE) {
Hi I think you should use boolean
just try this (you'd better use mysqli instead mysql
if(!done)
{
// something wrong
echo mysql..
}
else
{
// everything works fine....
}
The error catching must be like the following:
if($done === false){
//NOT OK
}else{
//OK
}
But as #John Conde mentioned do not use mysql_* because its deprecated.
I know there are many questions similar to my question. But I really can not figure the problem here. I have class named 'UsersClass' which is responsible on every task related to users. And I use mysqli prepare statement to insert or select data from the database, the problem is that in many cases prepare statement return false. I solved the issue by making new connection every while, but this caused another issue in other functions "2006: Mysql server has gone away" See code below please:
Here and in other functions the prepare return false.
function isPostingAllowed() {
$this->setPsSelectUsers($this->_connection->prepare("Select * from userpermissions where userpermissions.UserId = ? and userpermissions.PermissionId = 1"));
$this->_psSelectUsers->bind_param('i',$this->UserId);
$this->_psSelectUsers->execute();
if ( false===$this->_psSelectUsers ) {
die('prepare() failed: ' . htmlspecialchars($this->_connection->error));}
if ($this->_psSelectUsers->fetch()){
return true;
}else{
return false;
}}
function setPsSelectUsers($stmt) {
$this->unsetPsSelectUsers();
// mysqli_close($this->_Connection);
// $this-> __construct();
$this->_psSelectUsers= $stmt;}
When I uncomment these two lines The first function will work and prepare staement will not return false, but in this case the following function will throw error 2006:
function checkUserAuthentication() {
$this->setPsSelectUsers($this->_connection->prepare("SELECT UserLogInName FROM Users WHERE UserLogInName=? AND UserPassword=?"));
$this->_psSelectUsers->bind_param('ss',$this->UserLogInName, $this->UserPassword);
$this->_psSelectUsers->execute();
if ($this->_psSelectUsers->fetch()){
return true;
}else{
return false;
}}
So How to solve the first problem without making new problem?
Problem:
... I use mysqli prepare statement to insert or select data from the database, the problem is that in many cases prepare statement return false.
That's because you're running the queries in out of order fashion i.e. you're executing ->prepare() before closing the previous statement object. Given your current code, add the following error reporting code in your prepared statements,
if(!$this->_connection->prepare(...)){
printf('errno: %d, error: %s', $this->_connection->errno, $this->_connection->error);
die();
}
If you look at $this->_connection->error, you'll see the following error,
Commands out of sync; you can't run this command now
This issue has been documented in many forums, such as:
From the MySQL documentation,
If you get Commands out of sync; you can't run this command now in your client code, you are calling client functions in the wrong order.
From this SO thread,
You can't have two simultaneous queries because mysqli uses unbuffered queries by default (for prepared statements;...
Solution:
Execute the commands in correct order, (See this example code)
Open up the connection (Once: at the very beginning, not during the execution of every query)
Create a prepared statement
Bind parameters
Execute the query
Bind result variables
Fetch value into those bound variables
Close the statement object
Close the connection (Once: at the very end, not during the execution of every query)
(Follow steps 2 to 7 for executing all of your queries, though one or more steps might be optional based on of your query)
So the solution is, close the previous statement object before calling ->prepare() again. Take this method call $this->unsetPsSelectUsers(); out of the setPsSelectUsers() method and place it before the if ($this->_psSelectUsers->fetch()){...}else{...} block of isPostingAllowed() and checkUserAuthentication() methods. Furthermore, save the status of $this->_psSelectUsers->fetch() method call in a variable and use it in the subsequent if block. So your code should be like this:
public function isPostingAllowed() {
$this->setPsSelectUsers($this->_connection->prepare("Select * from userpermissions where userpermissions.UserId = ? and userpermissions.PermissionId = 1"));
if(!$this->_psSelectUsers){
printf('errno: %d, error: %s', $this->_connection->errno, $this->_connection->error);
die();
}
$this->_psSelectUsers->bind_param('i',$this->UserId);
$this->_psSelectUsers->execute();
$status = $this->_psSelectUsers->fetch();
$this->unsetPsSelectUsers();
if ($status){
return true;
}else{
return false;
}
}
private function setPsSelectUsers($stmt){
$this->_psSelectUsers= $stmt;
}
private function unsetPsSelectUsers() {
if (isset($this->_psSelectUsers)) {
$this->_psSelectUsers->close();
unset($this->_psSelectUsers);
}
}
public function checkUserAuthentication() {
$this->setPsSelectUsers($this->_connection->prepare("SELECT UserLogInName FROM Users WHERE UserLogInName=? AND UserPassword=?"));
if(!$this->_psSelectUsers){
printf('errno: %d, error: %s', $this->_connection->errno, $this->_connection->error);
die();
}
$this->_psSelectUsers->bind_param('ss',$this->UserLogInName, $this->UserPassword);
$this->_psSelectUsers->execute();
$status = $this->_psSelectUsers->fetch();
$this->unsetPsSelectUsers();
if ($status){
return true;
}else{
return false;
}
}
Moreover, you don't have to use this setPsSelectUsers() method anymore, you can directly use the property $_psSelectUsers in your methods like this:
$this->_psSelectUsers = $this->_connection->prepare(...);
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'.
I'm using this code:
$mysqli = new mysqli(...);
$sql = file_get_contents("my_sql_file.sql");
$result = $mysqli->multi_query($sql);
if (!$result)
report_error(); //my function
while ($mysqli->more_results()) {
$result = $mysqli->next_result();
if (!$result)
report_error();
}
However the 'while' loop in the code above turned out to be an infinite loop. Anything wrong?
Actually your code doesn't really make sense. The proper way to handle multiqueries is the following (see php manual)
if ($mysqli->multi_query($query)) {
do {
// store first result set
if ($result = $mysqli->store_result()) {
while ($row = $result->fetch_row()) {
// do something with the row
}
$result->free();
}
else { error_report(); }
} while ($mysqli->next_result());
}
else { error_report(); }
The code provided in the question reaches to an infitie loop because "If your second or late query returns no result or even if your query is not a valid SQL query, more_results(); returns true in any case.", see this note on php.net: http://us3.php.net/manual/en/mysqli.multi-query.php#104076
And further more, mysqli_more_results always returns true in the code because the results are not discarded, must call mysqli_store_results to discard result after each call to mysqli_next_result. See: http://us3.php.net/manual/en/mysqli.multi-query.php#91677
There is no official way to catch all errors when executing MySQL text (multi-commands separated by semicolons) by mysqli_multi_query. The function mysqli_multi_query will stop execution when it faces a bad SQL command, so it is only possible to catch the first error (no matter where the error occurs, in the first SQL command or any other SQL command in the SQL text).
Related to Jon's answer to this question: When does mysqli_multi_query stop execution?
And as noted in http://www.php.net/manual/en/mysqli.multi-query.php#106126 The first error can be catched by scanning mysqli_next_result coz: $mysqli->next_result() will return false if it runs out of statements OR if the next statement has an error.
Finally the answer is that results must be discarded after calling to mysqli_next_result using mysqli_store_result:
$mysqli = new mysqli(...);
$sql = file_get_contents("my_sql_file.sql");
$result = $mysqli->multi_query($sql);
if (!$result)
report_error(); //my function
while ($mysqli->more_results()) {
$result = $mysqli->next_result();
//important to make mysqli_more_results false:
$discard = $mysqli->store_result();
if (!$result)
report_error();
}