I am new to PHP and I'm trying to learn PDO. I'm trying to build a page where I can post information (news and such) to a database and another page where I can view the things in the database.
I've read here that people say you shouldn't use the try catch operator to handle error messages. I understood this as you shouldn't use something like:
CreateNews.php
<?php
header("Content-Type: text/html; charset=utf-8");
// Create presets for connection
$dsn = "mysql:host=localhost;dbname=dbname;charset=utf8'";
$opt = array(
PDO::ATTR_EMULATE_PREPARES => false,
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES 'utf8'"
);
// Check if form is being posted
if ($_SERVER['REQUEST_METHOD'] == "POST") {
// Check if fields are empty
if (!$_POST['name'] || !$_POST['email'] || !$_POST['title'] || !$_POST['content'] || !$_POST['timestamp']) {
echo "<p>Please fill in all of the fields!</p>";
exit();
}
else {
try { // Connects to server and executes the transfer of data
$pdo = new PDO($dsn, 'root','', $opt);
$sth = $pdo->prepare("INSERT INTO news (name, email, title, content, timestamp)
VALUES (:name, :email, :title, :content, :timestamp)");
$sth->bindParam(':name', $_POST['name']);
$sth->bindParam(':email', $_POST['email']);
$sth->bindParam(':title', $_POST['title']);
$sth->bindParam(':content', $_POST['content']);
$sth->bindParam(':timestamp', $_POST['timestamp']);
$sth->execute();
}
catch (PDOException $e) {
echo $e->getMessage();
}
echo "<p>Data submitted successfully!</p><br />To create another post <a href" . $_SERVER['PHP_SELF'] . ">click here</a>";
}
}
// Close the connection
$pdo = null;
?>
So I removed the catch PDOException above and then got the error message:
Parse error: syntax error, unexpected 'echo' (T_ECHO), expecting catch (T_CATCH)
If I remove the echo I still get the "expecting catch T_CATCH error.
Have I misunderstood what people mean when they say that you shouldn't use try catch operators?
And if so how should I use it?
Please feel free to comment if you notice anything in the code that I've done wrong or unnecessarily. I'm new to all this and still trying to learn! :)
Thanks!
I've read here that people say you shouldn't use the try catch operator to handle error messages.
These people are quite right.
What to NOT use exceptions for
Exceptions should not be used for normal flow of applications.
Let's take a look at the inverse($x) function from the php manual, which returns 1/$x and throws an exception if you pass in 0 as $x since you cannot divide by 0.
Let's further assume that your variable comes from a posted form, so one could enter 0. In this case you should check with an if-clause for correct values like:
<?php
if (intval($_POST['value']) == 0) {
echo 'You cannot pass 0 into inverse(). Please enter another value.';
} else {
echo 'We computed the inverse: ' . inverse(intval($_POST['value']));
}
?>
You should not use try-catch constructs for this type of use. It is totally expectable in this situation that a user might enter a number the function cannot deal with. You should check inside your normal application flow for wrong values and deal with them.
What to use exceptions for
Let's assume now that the variable $x is filled by supercomplicated_function, which always returns a number and never returns 0. Since you are sure, that the variable will never ever equal 0, why should you check for this case?
Instead you can use try-catch here:
<?php
$x = supercomplicated_function();
try {
$y = inverse($x);
echo 'We computed the inverse: ' . $y;
} catch (Exception $e) {
echo 'Unexpected situation. Do not know how to go on. Aborting.';
die();
}
?>
Clues to look for
If you expect some specific error under normal conditions, you should check for them with an if statement.
If you do not, let exceptions handle the issue.
In your case, you normally do not expect an exception from a query execution. Possible error causes are server has gone away or deadlock. This errors are possible, but not under "normal" conditions. So you do not want to check for them with if statements (you even cannot check for a possible deadlock beforehand).
Therefore in your case you want to use exceptions. That's totally ok.
Related
RollBack () and beginTransaction() not work in my PHP PDO and my table type is innoDB. In the following code my $sql1 is correct and my $sql2 is wrong (I added d to $last_id to just make it wrong). But it still executes sql1 meaning roll back no effect. Thank you for your advice.
<?php
include 'connect.php';
// Get multiple input field's value
try {
// set the PDO error mode to exception
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
// Starts our transaction
$conn->beginTransaction();
foreach ($_POST['phone'] as $value) {
$sql1 = "INSERT INTO tbl_contact_info (type)
VALUES ('$value')";
// use exec() because no results are returned
$conn->exec($sql1);
$last_id = $conn->lastInsertId();
$sql2="INSERT INTO tbl_img (img_type)
VALUES ('$dlast_id')";
$conn->exec($sql2);
}
// Commits out queries
$conn->commit();
echo "New record created successfully";
}
catch(PDOException $e)
{
// Something borked, undo the queries!!
$conn->rollBack();
echo $sql . "<br>" . $e->getMessage();
}
$conn = null;
?>
First of all (and sorry it it's obvious but I realised it's not always clear to everyone) SQL and PHP are different languages. MySQL Server will not react to Undefined variable notices triggered in PHP code.
Secondly, notices are not exceptions so they cannot be caught with try/catch statements. (You can certainly write a custom error handler that will throw exceptions on errors but it doesn't seem to be the case here.)
My problem is kinda simple or it maybe a silly mistake from my side. But I don't know I am just getting unexpected results while using PDO in php.
Code goes like this,
try
{
$_pdo = get_pdo_instance();
$_pdo->beginTransaction();
//query 1
$_pdo->query("some query"); // I have error in query 3 but this query 1 is still executed.
//query 2
$_pdo->query("some query"); // only executes when there are no errors.
//query 3
$_pdo->query("some wrong query"); // let's say I have an error in this sql
$_pdo->commit();
}
catch(Exception $ex)
{
$_pdo->rollback();
}
I am explaining the problem now,
In given example I have some sql error in query 3, so none the queries should run as they all belongs to single transaction.
But in my case query 1 always run even if there are errors in that try block.
Maybe its something simple but I have no idea why this is happening.
Edit:
Function definition,
function get_pdo_instance()
{
try
{
$conn = new PDO('mysql:host='.DB_HOST.';dbname='.DB_NAME, DB_USER, DB_PASS);
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
catch(PDOException $e)
{
die('ERROR: ' . $e->getMessage());
}
return $conn;
}
Exceptions are used only for PHP errors. In the code above, you're trying to catch a MySQL error. When PHP reads your try block, everything looks fine, and it therefore has no exception to catch.
You can do error checking with PDO and MySQL like:
if(!$_pdo->query("some query")) {
// Do something
}
See the documentation for PDO Error Handling. You need to turn exception raising on.
try {
$_pdo = get_pdo_instance();
$_pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$_pdo->beginTransaction();
$_pdo->query("some query");
$_pdo->query("some query");
$_pdo->query("some wrong query");
$_pdo->commit();
}
catch(Exception $ex) {
$_pdo->rollback();
}
Here is my solution,
I was catching Exception, instead in this case I had to do catch PDOException.
I guess that solved my problem, but I haven't tested this thing completely. I will post updates if any.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 7 years ago.
Improve this question
Ok, so I've looked around stack, google, etc.... There doesn't seem to be a "Correct" answer for this!
Since I started learning PHP I've used try{}catch() blocks. Some people say that It's wrong and some people say that it's fine. I will continue to use them but before I go ahead Im wondering if Im using them correctly? I am nesting try { try{}catch() {} }catch(){} within each other, is this a good practise? Doing this does make the code a bit jumbled! If there was a better way to do what Im doing I'd definitely consider it.
Here is a block of code that I'm working on at the moment, am I wrong in nesting try blocks?
try{
$sql = "select * from users where email = '$email'";
$stmt = $dbConnection->query($sql);
$returned = $stmt->fetch();
if($stmt->rowcount() == 0){
echo "ERROR";
}else{
try{
$adminId = $returned['uID'];
$auth_key = generateAuth();
$sqlHousehold = "INSERT INTO household (adminId, hhName,auth_key) VALUES ($adminId, '$hhName', '$auth_key')";
$stmt = $dbConnection->query($sqlHousehold);
$id = $dbConnection->lastInsertId();
/*Update the newly created householdID into the admins column*/
$sql = "UPDATE users set hhID = $id where uID = $adminId";
$stmt = $dbConnection->query($sql);
/*
RETURN the group auth key (Share this to members of fam) + user auth key (store on phone)
*/
return '{"user_auth_key":"'.$user_auth_token.'", "group_auth_key":"'.$auth_key.'"}';
}catch(PDOException $e){
}
}
}catch(PDOException $er){
exit("PDO ExCEPTION !^!^!^!^! " .$er);
}
No need to have inner try catch block. List all the exceptions in the outer catch block.
Another try catch block inside a try catch will increase the overhead & make your code slower. Better to use only outer try catch
No need to nest exceptions, you can use multiple catch statements for the same try, having the same results. E.g.
try {
// some code that might throw exceptions
} catch(ExceptionType1 $ex) {
// handle the first exception
} catch(ExceptionType2 $ex) {
// handle the second exception
} catch(ExceptionTypeN $ex) {
// handle the last exception
} catch(Exception $ex) {
// catch all other exceptions
}
For your particular case, however, you are catching in both try/catch the same type of exception (PDOException). Which doesn't need an inner try/catch block as it's already handled by the outer try/catch block. PDOException means most of the time problems when connecting to the database or when querying data, and this is OK to be handled in only one place.
My opinion is no.
It is just bloating the overhead unnecessarily. I know that it is not always the neatest or most useful option but switch actually runs faster than if else statements: http://php.net/manual/en/control-structures.switch.php
Also, having debug code in there will slow things down if it gets bigger in the long run. If the code works why waste the resources on debugging it?
Edit
Simple error handling logic:
// Error handlers
function doError ($e) {
$_SESSION['error'] = $e;
header('Location: http://website.com/error.php');
exit;
}
function getError () {
if (isset($_SESSION['error']) {
return $_SESSION['error'];
} else {
die('Fatal Error!');
exit;
}
}
function clearError () {
unset($_SESSION['error']);
}
// Error handling when conditions are not met
if (!myCondition()) {
doError('Condition not met!');
}
// Error template / error.php
$e = getError();
$html = '
<!DOCTYPE html>
<html>
<title>Fatal Error!</title>
<body>
<h1>A fatal error occurred</h1>
<p>'.$e.'</p>
</body>
</html>
';
echo $html;
clearError();
The outer try-catch block will catch all the exceptions caught inside it. If your actions in catch will differ for different parts of the code it appeared in - then nesting them might be useful. Otherwise, if both catch blocks are going to do the same thing - there is no point in doing it.
I have writen this pice of code that should insert into my Database some event data, but it does not insert a thing in the DB, can you tell me why?
try {
$pdo = new PDO("mysql:host={$dbhost};dbname={$dbname}", $dbuser, $dbpass);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
catch( PDOException $excepiton ) {
echo "Connection error :" . $excepiton->getMessage();
}
try{
$sql = "INSERT INTO events_DB (event_id, event_end_time, event_location, event_name) VALUES (:event_id, :event_end_time, :event_location, :event_name) ON DUPLICATE KEY UPDATE event_id = :event_id, event_end_time = :event_end_time, event_location = :event_location, event_name = :event_name";
$stm = $db->prepare($sql);
$stm->execute(array(":event_id" => $event[id], ":event_end_time" => $event[end_time], ":event_location" => $event[location], ":event_name" => $event[name]));
}
catch ( PDOException $exception )
{
// decomentati sa vedeti erorile
echo "PDO error :" . $exception->getMessage();
}
Thanks
The code you've posted is different than the code you're running as the posted code would result in a syntax error at parse time and never actually run.
However, what's happening is the SQL being sent to the prepare method is not valid in some way so that the result returned and stored in $stm is a boolean (false) rather than a valid statement object. Double check your SQL (you could try running it in another application such as phpMyAdmin or via the mysql command-line program) to ensure its validity. You could also add some error handling to find the cause with:
$stm = $db->prepare($sql);
if (!$stm) {
die($db->errorInfo());
}
Edit: You've modified the posted source code which now shows use of exception handling. However, you've commented out the line that echos the exception message. This information will be useful in telling you what's causing the error condition. Uncomment to see the message (which will most likely inform you that the SQL is invalid and which part of it caused the error).
Try to remove the <br> tag from the first line and a " is messing
$sql = "INSERT INTO events_DB (event_id, event_end_time, event_location, event_name);"
This day is my first time using PDO. And when I try 'INSERT' with PDO, it does nothing.
This is my code :
session_start();
if($_GET['feedback']!="")
{
$fb = $_GET['feedback'];
$date = date('Y-m-d H:i:s');
$query = "INSERT INTO feedback(number, sender, content, date) VALUES (NULL,?,?,?)";
$STH = $DBH->prepare($query);
$STH->bindParam(1, $_SESSION['alias']);
$STH->bindParam(2, $fb);
$STH->bindParam(3, $date);
$STH->execute();
}
I have tried a 'SELECT' query with PDO and it works.
What should I do?
why dont you try and enclose your code in try and catch blocks to get any exceptions:
try {
//your code
} catch( PDOEXception $e ) {
echo $e->getMessage(); // display error
exit();
}
This should give you a clue whats going wrong.
What should I do?
Error reporting.
Check tag wiki for the example.
It is essential to set ERRMODE_EXCEPTION as a connection option as it
will let PDO throw exceptions on connection errors. Setting
ATTR_DEFAULT_FETCH_MODE is also a good idea.
Please note that connection errors shouldn't be catched, at least not
using try..catch operator. A custom exception handler could be used,
but not required. Especially for new users, it is okay to have
unhandled exceptions, as they are extremely informative and helpful.