This question already has answers here:
What to do with mysqli problems? Errors like mysqli_fetch_array(): Argument #1 must be of type mysqli_result and such
(2 answers)
Closed 2 years ago.
I'm trying to turn MySQLi query errors to Exceptions, but couldn't - mysqli_sql_exception is thrown only if it failed to connect the DB.
I used mysqli_report(MYSQLI_REPORT_STRICT) and procedural MySQLi functions embedded to custom wrapper class.
Former code:
public function mysqlQuery($SQL) {
$this->Result = mysqli_query($this->DBlink, $SQL);
if($this->Result === false)
throw new MySQLiQueryException($SQL, mysqli_error($this->DBlink), mysqli_errno($this->DBlink));
return $this->Result;
}
Question: Is it normal no Warning, nor Exception are thrown when query fails so I have to check if mysqli_query() returned false?
Some time ago I managed to sort this matter out. As it was pointed out in the other answer,
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
is a correct way to tell mysqli to throw exceptions.
Just make sure you don't wrap every query in a try-catch. This is a very common misconception that as soon as you started using exceptions you should start throwing tries and catches left and right. Quite contrary, try-catch should be used warily. While 99% of your errors shouldn't be handled in place, but rather by a site-wide error handler. You may read more on the topic from my article on PHP error reporting
do I have to check if mysqli_query() returned false?
No.
You should be able to do what you require and instruct the mysqli driver to throw exceptions on SQL errors, but you will need to enable MYSQLI_REPORT_ERROR if it is not already....
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT)
mysqli_query() should now throw exceptions on error. You do not need to check the return value for failure (which won't happen anyway because an exception is thrown).
public function mysqlQuery($SQL) {
try {
$this->Result = mysqli_query($this->DBlink, $SQL);
} catch (mysqli_sql_exception $e) {
throw new MySQLiQueryException($SQL, $e->getMessage(), $e->getCode());
}
return $this->Result;
}
(NB: I changed $this->SQL to $SQL in the re-thrown exception.)
I know it's a little too late, but for the sake of posterity. I find MYSQLI_REPORT_STRICT to be to restrictive, certain exceptions where not be raised and hence they could not be handled by the catch block.
mysqli_report(MYSQLI_REPORT_ALL); // Traps all mysqli error
try {
$mysqli = new mysqli('localhost','user,'pwd','db');
/* I don't need to explicitly throw an exception as this is being
done automatically */
} catch(Exception $e) {
echo $e->getMessage();
}
Related
This question already has an answer here:
What to do with mysqli problems? Errors like mysqli_fetch_array(): Argument #1 must be of type mysqli_result and such
(1 answer)
Closed 2 years ago.
I'm trying to turn MySQLi query errors to Exceptions, but couldn't - mysqli_sql_exception is thrown only if it failed to connect the DB.
I used mysqli_report(MYSQLI_REPORT_STRICT) and procedural MySQLi functions embedded to custom wrapper class.
Former code:
public function mysqlQuery($SQL) {
$this->Result = mysqli_query($this->DBlink, $SQL);
if($this->Result === false)
throw new MySQLiQueryException($SQL, mysqli_error($this->DBlink), mysqli_errno($this->DBlink));
return $this->Result;
}
Question: Is it normal no Warning, nor Exception are thrown when query fails so I have to check if mysqli_query() returned false?
Some time ago I managed to sort this matter out. As it was pointed out in the other answer,
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
is a correct way to tell mysqli to throw exceptions.
Just make sure you don't wrap every query in a try-catch. This is a very common misconception that as soon as you started using exceptions you should start throwing tries and catches left and right. Quite contrary, try-catch should be used warily. While 99% of your errors shouldn't be handled in place, but rather by a site-wide error handler. You may read more on the topic from my article on PHP error reporting
do I have to check if mysqli_query() returned false?
No.
You should be able to do what you require and instruct the mysqli driver to throw exceptions on SQL errors, but you will need to enable MYSQLI_REPORT_ERROR if it is not already....
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT)
mysqli_query() should now throw exceptions on error. You do not need to check the return value for failure (which won't happen anyway because an exception is thrown).
public function mysqlQuery($SQL) {
try {
$this->Result = mysqli_query($this->DBlink, $SQL);
} catch (mysqli_sql_exception $e) {
throw new MySQLiQueryException($SQL, $e->getMessage(), $e->getCode());
}
return $this->Result;
}
(NB: I changed $this->SQL to $SQL in the re-thrown exception.)
I know it's a little too late, but for the sake of posterity. I find MYSQLI_REPORT_STRICT to be to restrictive, certain exceptions where not be raised and hence they could not be handled by the catch block.
mysqli_report(MYSQLI_REPORT_ALL); // Traps all mysqli error
try {
$mysqli = new mysqli('localhost','user,'pwd','db');
/* I don't need to explicitly throw an exception as this is being
done automatically */
} catch(Exception $e) {
echo $e->getMessage();
}
This question already has an answer here:
What to do with mysqli problems? Errors like mysqli_fetch_array(): Argument #1 must be of type mysqli_result and such
(1 answer)
Closed 2 years ago.
I'm trying to turn MySQLi query errors to Exceptions, but couldn't - mysqli_sql_exception is thrown only if it failed to connect the DB.
I used mysqli_report(MYSQLI_REPORT_STRICT) and procedural MySQLi functions embedded to custom wrapper class.
Former code:
public function mysqlQuery($SQL) {
$this->Result = mysqli_query($this->DBlink, $SQL);
if($this->Result === false)
throw new MySQLiQueryException($SQL, mysqli_error($this->DBlink), mysqli_errno($this->DBlink));
return $this->Result;
}
Question: Is it normal no Warning, nor Exception are thrown when query fails so I have to check if mysqli_query() returned false?
Some time ago I managed to sort this matter out. As it was pointed out in the other answer,
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
is a correct way to tell mysqli to throw exceptions.
Just make sure you don't wrap every query in a try-catch. This is a very common misconception that as soon as you started using exceptions you should start throwing tries and catches left and right. Quite contrary, try-catch should be used warily. While 99% of your errors shouldn't be handled in place, but rather by a site-wide error handler. You may read more on the topic from my article on PHP error reporting
do I have to check if mysqli_query() returned false?
No.
You should be able to do what you require and instruct the mysqli driver to throw exceptions on SQL errors, but you will need to enable MYSQLI_REPORT_ERROR if it is not already....
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT)
mysqli_query() should now throw exceptions on error. You do not need to check the return value for failure (which won't happen anyway because an exception is thrown).
public function mysqlQuery($SQL) {
try {
$this->Result = mysqli_query($this->DBlink, $SQL);
} catch (mysqli_sql_exception $e) {
throw new MySQLiQueryException($SQL, $e->getMessage(), $e->getCode());
}
return $this->Result;
}
(NB: I changed $this->SQL to $SQL in the re-thrown exception.)
I know it's a little too late, but for the sake of posterity. I find MYSQLI_REPORT_STRICT to be to restrictive, certain exceptions where not be raised and hence they could not be handled by the catch block.
mysqli_report(MYSQLI_REPORT_ALL); // Traps all mysqli error
try {
$mysqli = new mysqli('localhost','user,'pwd','db');
/* I don't need to explicitly throw an exception as this is being
done automatically */
} catch(Exception $e) {
echo $e->getMessage();
}
This question already has answers here:
What to do with mysqli problems? Errors like mysqli_fetch_array(): Argument #1 must be of type mysqli_result and such
(2 answers)
Closed 2 years ago.
I'm trying to turn MySQLi query errors to Exceptions, but couldn't - mysqli_sql_exception is thrown only if it failed to connect the DB.
I used mysqli_report(MYSQLI_REPORT_STRICT) and procedural MySQLi functions embedded to custom wrapper class.
Former code:
public function mysqlQuery($SQL) {
$this->Result = mysqli_query($this->DBlink, $SQL);
if($this->Result === false)
throw new MySQLiQueryException($SQL, mysqli_error($this->DBlink), mysqli_errno($this->DBlink));
return $this->Result;
}
Question: Is it normal no Warning, nor Exception are thrown when query fails so I have to check if mysqli_query() returned false?
Some time ago I managed to sort this matter out. As it was pointed out in the other answer,
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
is a correct way to tell mysqli to throw exceptions.
Just make sure you don't wrap every query in a try-catch. This is a very common misconception that as soon as you started using exceptions you should start throwing tries and catches left and right. Quite contrary, try-catch should be used warily. While 99% of your errors shouldn't be handled in place, but rather by a site-wide error handler. You may read more on the topic from my article on PHP error reporting
do I have to check if mysqli_query() returned false?
No.
You should be able to do what you require and instruct the mysqli driver to throw exceptions on SQL errors, but you will need to enable MYSQLI_REPORT_ERROR if it is not already....
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT)
mysqli_query() should now throw exceptions on error. You do not need to check the return value for failure (which won't happen anyway because an exception is thrown).
public function mysqlQuery($SQL) {
try {
$this->Result = mysqli_query($this->DBlink, $SQL);
} catch (mysqli_sql_exception $e) {
throw new MySQLiQueryException($SQL, $e->getMessage(), $e->getCode());
}
return $this->Result;
}
(NB: I changed $this->SQL to $SQL in the re-thrown exception.)
I know it's a little too late, but for the sake of posterity. I find MYSQLI_REPORT_STRICT to be to restrictive, certain exceptions where not be raised and hence they could not be handled by the catch block.
mysqli_report(MYSQLI_REPORT_ALL); // Traps all mysqli error
try {
$mysqli = new mysqli('localhost','user,'pwd','db');
/* I don't need to explicitly throw an exception as this is being
done automatically */
} catch(Exception $e) {
echo $e->getMessage();
}
This question already has answers here:
How to start and end transaction in mysqli?
(5 answers)
Closed 1 year ago.
How to properly handle errors with transactions and prepared statements when using mysqli?
Snippet:
<?php
$conn = require_once 'dbconn.php';
$conn->autocommit(FALSE);
$stmt_ins_option = $conn->prepare('INSERT INTO options(option_name) VALUES(?)');
$option_name = 'foo';
$stmt_ins_option->bind_param('s', $option_name);
$stmt_ins_option->execute();
$conn->commit();
if($conn->errno) {
$conn->rollback();
echo $conn->error;
}
It won't add it a second time because there's a UNIQUE constraint on that column.
However the script won't report any error either.
What am I missing?
execute returns false on failure, so you may want to check it before committing. Also, rolling back in your code has no effect because you committed transaction previously. I'd write something like
try
{
....
if (!$stmt_ins_option->execute())
{
throw new Exception("Cannot insert record. Reason :".$stmt_ins_option->error);
// surely, it's better to define your own exception hierarchy
}
$conn->commit();
}
catch (Exception $e)
{
$conn->rollback();
// display error/re-raise/ or whatever you think makes sense for your function
}
Is there any way to make mysqli classes throw exceptions instead of me having to check for errors every time
According to this answer you can use the following call to enable exceptions for such errors:
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
See mysqli_driver::$report_mode
There is this question that I found:
What is the advantage of using try {} catch {} versus if {} else {}
If you can add anything to it then please do as I am new to PDO, also what does this mean;
$dbc->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
On the MySQL website it says "ensures the creation of exceptions rather than errors" but I do not understand this, can anyone please elaborate on it please.
Exceptions are catchable via try/catch and are classes with properties, while proceedural errors cannot and are not. Proceedural errors are instead handled by PHP's native error handling.
You can observe the behavior difference by manually triggering them.
to throw an Exception:
throw new Exception();
to trigger a proceedural error:
trigger_error($message, U_USER_ERROR);
Exceptions are bassically the OO way of error handling. Find more information about Exceptions here: http://php.net/manual/en/language.exceptions.php
Well, they are pretty similar. In PHP native error handling you can trow your own errors with trigger_error($error, [$level]) as you can throw your own exceptions with throw new MyException($error); you can set a default error handler with set_error_handler() which will manage all PHP error (except parsing) your own way as you can set a default exception handler with set_exception_handler(). Both PHP native errors and exceptions are automatically triggered/thrown somehow: PHP native errors compiling the script, exceptions if you are using specific items such as (PDO) or something.
Now let's try the same code with different approaches:
With PHP native errors you can do things such as:
$db = new Database();
if ($db === NULL) { trigger_error("Cannot connect to the database", E_USER_ERROR); }
$result = $db->query("UPDATE charlieiscool SET iloveunicorns = 1 WHERE userid = 1");
if (!$result) { trigger_error("Error updating table", E_USER_ERROR); }
$file = 'log.php';
if (!file_exists($file) or !file_get_contents($file)) { trigger_error("$file not found", E_USER_ERROR); }
require($file);
I think this does not really need any explanation. If an error is triggered, the entire script is skipped and you see the error. There are no more things you can do; you could set E_USER_ERROR or E_USER_NOTICE or E_USER_WARNING and handle them differently, but you have not that big choice. Now take a look at a possible OOP approach with try{} catch() {} blocks:
try {
$db = new Database();
if (!$db) { throw new DBEx("Cannot connect to the database"); }
$result = $db->query("UPDATE charlieiscool SET iloveunicorns = 1 WHERE userid = 1");
if (!$result) { throw new QueryEx("Query failed"); }
} catch (PDOException $e) {
echo $e->getMessage();
} catch (DBEx $e) {
$e->customFunction();
} catch (QueryEx) {
$e->customFunctionForQuery();
}
try {
$file = 'log.php';
if (!file_exists($file) or !file_get_contents($file)) { throw new FileEx("$file does not exists"); }
require($file);
} catch (FileEx) {
$e->fileGenerate();
$e->logError();
}
The main difference is that if the first try{} block throw an exception the second try{} will be executed any way. In fact if an exception is thrown, only the rest of the script inside that try{} block will be skipped.
Another difference (the one i love most) is that you can create several classes (extending mains Exception or PDOException or others) and customize very much your error handling behavior. You have unlimited possibilities to customize your classes, adding functions, editing already existing ones. You can add specific function (such as $e->fileGenerate();) and call them inside the catch() {} block where needed.
Notice also that if you want your entire script to stop if an error occurred, means that that error needs trigger_error(); instead if you want that an error only stops a specific block of code related to that error then it's time for try and catch.
You should not use one replacing the other, you should use one beside the other evaluating each errors as it is.
By the way PDO::setAttribute() change default values and options in your database handler. You can for example change your default fetch (used in PDOStatement::fetch()) with $dbh->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_OBJ);.
References:
PDO::setAttribute()
set_error_handler()
set_exception_handler()
Exceptions
Predefined exceptions