I'm using WAMP as my platform. Running the following code (pdodb is a framework for working with PDO):
<?PHP
$mysql = pdodb::getInstance();
$query = " SELECT PhysicalID FROM PhysicalInfo
WHERE barcode=0";
$mysql->Prepare($query);
$res = $mysql->Execute($query);
?>
PHP halts upon "Execute()" e.g. the next lines are not executed! I used try/catch to catch (Exception e) but even the error message in catch is not displayed! needless to say that there's no use inserting $res->errorInfo() after the execute() because it won't run either. Although, if I set the database in my code:
$query = " SELECT PhysicalID FROM **carinfo.**PhysicalInfo
WHERE barcode=0";
The code runs perfectly. Using PHPMyAdmin, I get the following error on the first query:
#1046 - No database selected
The problem is:
Why does PHP halt on this and the rest of the program after
$mysql->Execute($query); is not run.
How could I get the error message to check for it in my program (it's pretty ugly to have your code stop without any warning).
Related
I have to include database connection in some PHP scripts. So I require() first and then put my queries after. If viewed as a single script, it amounts to something like this:
Try {
$connect = new PDO("mysql:host={$DB_host};dbname={$DB_name}; charset=utf8mb4",$DB_user,$DB_pass);
$connect->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
Catch(PDOException $e) {
echo $e->getMessage();
}
// Then I put the queries here
It works, but my question is: is this safe? I've seen in most tutorials that they put all the queries within Try { } curly brackets. And what is the difference between putting the queries within Try { } and putting it after ?
If for whatever reason your query fails the program will crash at the line of code that was executing the query. There may be justification to do this if this a behavior that you desire in your code, for whatever reason.
Without the error handling your program will just break whenever an error is thrown. So unless you specifically need to have the query outside of the try catch (I couldn't guess what for), then you will just be creating trouble for yourself in the future.
If an exception occurs during your query (For instance, if it can't execute the query properly because of a missing quote), the error will not be caught and the execution of your script will halt.
Error handling is usually always preferred when possible. If there is a problem fetching data, inserting data, or simply a typo in your query, you should always have a way to notify a user that an error has occurred (And also, log it for further investigation for yourself.)
I have a PHP script using PDO Transactions.
$PDO->beginTransaction();
$sth = $PDO->prepare("INSERT INTO tbl_last_packing_upload (folderID, subfolderID) VALUES (1, 1)");
$sth->execute();
For some reason, this works locally (the INSERT runs), but not when I push it to my remote server.
To get my INSERT to work remotely, I need to put it ABOVE the $PDO->beginTransaction(); line. The following works remotely:
$sth = $PDO->prepare("INSERT INTO tbl_last_packing_upload (folderID, subfolderID) VALUES (1, 1)");
$sth->execute();
$PDO->beginTransaction();
Why does my INSERT not fire on my remote server when I have it placed inside the beginTransaction? I have many other PHP scripts on the same remote server using transactions and they all work fine.
Any ideas?
Unless there is an existing open transaction ($PDO->beginTransaction() was previously called but uncommitted), there should be no issue with the code as posted. If there was an open transaction, PDO would throw an exception when attempting to start a new one.
You already have PDO setup to throw exceptions rather than error silently with
$PDO->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
and if your transaction and INSERT statement code are wrapped in a try/catch block, you will need to debug and inspect the error caught in the catch block.
An error caught in catch (PDOException $e) {...} won't go into PHP's built-in error reporting mechanism on its own, so you'll need to force it to print to a location you can read. On a production web server, you won't want to print it to the screen, so instead I would recommend writing it to the web server's error log with PHP's error_log() function. A simple write to the default log location requires only the message as a parameter.
try {
// everything posted above
} catch (PDOException $e) {
// Caught an error, write it to the log
error_log("Error at line " . __LINE__ . " in " . __FILE__ . ": " . $e->getMessage());
// Whatever else you already do to handle the error...
// etc...
}
I'm fairly new to PDO. I have a try and catch which catches and displays errors when something doesnt exist i.e a table.
However, how can i show the error message/cause for sql failed commands.
For example below i was trying to insert the word "enabled" into a tiny int column - however, only showed me a blank screen - had to debug myself. How can i show SQL failed error messages?
$db = new PDO('mysql:host='.$dateBaseHost.';dbname='.$dateBaseName, $dateBaseUsername, $dateBasePassword);
$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
// set/get variables
$id = (isset($_GET['id']) === true) ? $_GET['id'] : die("ID not set") ; // ? : shorthand if else
$action = (isset($_GET['action']) === true) ? $_GET['action'] : die("Action not set") ; // ? : shorthand if else
// query
$query = $db->prepare(" UPDATE `telephoneCountries` SET `enabled`= :action WHERE `id` = :id ");
// bind parameters - avoids SQL injection
$query->bindValue(':id', $id);
$query->bindValue(':action', $action);
// try... if not catch exception
try {
// run the query
$query->execute();
}
catch (PDOException $e){
//sendErrorMail($e->getMessage(), $e->getFile(), $e->getLine());
echo $e->getMessage();
echo $e->getFile();
echo $e->getLine();
}
i was trying to insert the word "enabled" into a tiny int column
it's fairly OK to mysql. 0 will be inserted.
how can i show the error message/cause for sql failed commands.
for the real errors you have to just setup PHP to display them
ini_set('display_errors',1);
so - you'll be able to see every uncaught exception.
Also, if you are only going to display an error message, but not handle the error itself, just don't use try..catch at all. PHP will do all the job already. That's the point.
Most people do confuse error reporting with error handling. The latter shouldn't be used for the former. When dealing with error messages, your only goal is to make PHP to raise them, and to set up the proper destination:
on a development server an error message have to be show on-screen
on a live sever it shouldn't be shown, but logged instead.
without all these try-catch blocks you'll be able to control error messages (including non-exceptions) by means of a couple ini settings or single error handler function (which I mentioned to you in the other answer).
use try..catch only if you are going to handle the error itself - say, to connect to another server for example.
So, to answer your question more verbosely:
Set PDO in exception mode. Done already.
Remove all try..catch blocks that deals with error messages only.
Setup PHP to show errors on a development server using ini directive above.
On a live server it is strongly recommended to log errors instead of emailing them. But if you still want it this way - use single custom exception handler function to send emails instead of hundreds try..catch blocks
Im trying to make my script output the error on screen but the error keeps outputting into error_log and killing the script,
This is my current code
try{
$db->query("SELECT `test`.`test` FROM `test` WHERE `test`.`test` = test");
echo("no work?");
}catch(PDOException $er){
print("Still dont work");
}
$db->query... returns a error like it should but the script dies there, outputs into the error_log and wont finish it like i would like it to.
Can anyone help?
Just to sum up some of the responses i got, it is not the actual die() function that is killing the script, it's the error it's self at $db->query().
As the name would suggest, die() makes your script die (i.e, exit) after printing the message you pass it.
If you just want it to print the error, use print() instead of die().
I have a script that produces a report. For most widgets* it produces a report with no problem. For a particular widget it exits in the middle during a mysql query and a 500 is returned to the browser. By inserting writes to the php_error log I know the exact last line to be executed and it's always the same line. It's not a timeout because other widget reports run longer (and it bombs out in about 10 seconds).
Also, I've tried running the query it's trying to run in phpadmin and it runs OK.
When this abort occurs I see nothing appear in php_error.log, nothing in apache's error log and when I surround the offending statement with a try/catch, no exception is caught.
Is there somewhere else I can look that might show what error is occurring?
* by widget I'm not referring to a UI component. I'm using widget in the sense of fictional product from a fictional company
addendum ======================================================================
Since it was requested I posted the code although I think the problem isn't the code since it works in all but this once case. The problem is more likely in the data for this particular case.
error_log('['.__FILE__.']['.__LINE__."] check");
$table = new metrics_sessions();
//here I print out the SQL statement that will eventually be executed
error_log('['.__FILE__.']['.__LINE__."] check: "."guider_slug=? ".($effective_mindate!=null?" and date>'".$effective_mindate."'":"").($effective_maxdate!=null?" and date<'".$effective_maxdate." 23:59:59'":"").($effective_version!=0 && $effective_version!="all"?" and version=".$specific_version:"").($effective_campaign!==null && $effective_campaign!="all" ?" and campaign='".$effective_campaign."'":"")." order by date");
// BELOW IS THE LAST LINE I SEE IN PHP ERROR
error_log('['.__FILE__.']['.__LINE__."] check");
try {
$sessions = $table->Find("guider_slug=? ".($effective_mindate!=null?" and date>'".$effective_mindate."'":"").($effective_maxdate!=null?" and date<'".$effective_maxdate." 23:59:59'":"").($effective_version!=0 && $effective_version!="all"?" and version=".$specific_version:"").($effective_campaign!==null && $effective_campaign!="all" ?" and campaign='".$effective_campaign."'":"")." order by date",array($param_gslug));
error_log('['.__FILE__.']['.__LINE__."] check");
}catch(Exception $e){
error_log('['.__FILE__.']['.__LINE__."] check");
error_log('Caught exception: '.$e->getMessage());
error_log('File: '.$e->getFile());
error_log('Line: '.$e->getLine());
error_log('Trace: '.$e->getTraceAsString());
}
error_log('['.__FILE__.']['.__LINE__."] session count: ".count($sessions));
Check for error supression operators (#) in your code and the code you are calling.
Try editing your error php.ini file to allow warnings and error codes to be displayed.
error_reporting = E_ALL | E_STRICT
This would be sufficient.