I have couple of mysql queries in PHP and at the end of each query I did this
mysql_query(STRING) or die(mysql_error());
This is fine as far as I am in DEV environment but I dont want production users to see these errors. Any good Idea to remove this messages by just setting ON OFF.
Apart from the fact that you shouldn't use mysql_ as they're deprecated, you can simply make another function:
define('DEV', true);
function mysql_query_custom() {
$result = call_user_func_array('mysql_query', func_get_args());
if ($result === false) {
if (DEV) {
die(mysql_error());
}
}
return $result;
}
mysql_query_custom(STRING);
Lots of ways to do it. The most terse and most like you're doing now:
// do this once
$PRODUCTION = true;
// now use
mysql_query() or ($PRODUCTION ?: die(mysql_error()));
I caution though this is not a maintainable way to debug in the long term. There's a lot of good alternatives in this thread.
Whatever you do, develop a comprehensive error detection, logging, and response mechanism in your code. If you're using a framework, leverage its facilities.
Even easier you could just replace all die( with error_handle( or something else, and include this function:
function error_handle($err) {
die($err); // Comment this line out if you don't want the error to be displayed.
}
This is also great because you could extend the code to log errors etc in production. You could in addition define a $debug-variable somewhere in your global code if you are using Git or other version-control-systems.
Edit: I suggest replace all die( and not just die to avoid replaces where you don't want it, if you e.g use die in a sentence or something.
Then set a configuration variable called $DEBUG and just wrap your logic in a conditional if/else?
$DEBUG = true;
if ($DEBUG) {
mysql_query(STRING) or die(mysql_error());
}
else {
mysql_query(STRING);
}
const DEBUG = true;
function fail($message) { die (DEBUG ? $message : ''); }
...
use_mysql_query_even_though_it_sucks() or fail(mysql_error());
// seriously. Use mysqli.
Better still, use something like this:
if($_SERVER['SERVER_NAME'] != "dev.mydomain.com"){
ini_set("display_errors",0);
ini_set("log_errors", 1);
}
It saves you having to remember to disable the errors when you upload it to the production server.
Related
I am new to CodeIgniter, but am very familiar with MVC frameworks such as Symfony.
I am making a change to a custom helper function, where I am retrieving data from the db. I do not think the DB retrieval is working, but I am not getting any errors. The helper function is simply ignoring errors. There are no errors in the log file (log_threshold = 4) and die() is also being ignored.
I am going to post the helper function below, but my question is not what is wrong with my code (if anything), the question is why are the errors and die() being ignored and what can I do to fix this?
function getRates() {
$ci=& get_instance();
$ci->load->database();
$ci->db->select('currency_values.*');
$ci->db->from('version1.currency_values');
$currencyValues = $ci->db->get();
$lastUpdated = strtotime($currencyValues->result()[0]->last_updated);
die(">>> $lastUpdated <<<"); //This gets ignored
if ($lastUpdated > time() - 600)
{
//Code here that SHOULD be running
}
else
{
//Code here that ALWAYS runs, most likely because db retrieval is not working
}
try to use try and catch and print the exception error
try
{
}
catch(Exception $e){
echo $e;
}
There is no way PHP is ignoring die() call. Confirm it by putting few dummy :
echo "1\n"; at multiple places or by
using exit() instead of die(). Though a complete guess, probably the interpreter is reading code from somewhere else. Such case if not that rare.
For the concern of no error being reported and DB retrieval failing, you may use PHP exception handling or set error_reporting to E_ALL.
error_reporting(E_ALL);
ini_set('display_errors', 1);
I have some 2000 lines of code in php... some place i have some echo here and there to know that this or that is done properly... but i what more tracing and echo on each and every task done... i what echo in function enter and before function return... but all these echo polluate the code and the screen, and it's a nigtmare to remove or comment it out when ready for production...
the question, how to say, echo this and that, but when i say debug off, stop echo..how do you that in your code... what i tought was
global $debug_echo;
$debug_echo = true;
if ($debug_echo) {echo "function xyz - start";}
if ($debug_echo) {echo "function xyz - end";}
...
...
so with this, i can turn debug everywhere with one change... does it make sense ?
Best thing to do for debugging, would be to use a constant. So at the top of your file, or wherever you want to declare debug mode on or off you do this
define('DEBUG', true);
Then to check you just want to do
if(DEBUG === true) { echo 'something here'; }
You only have to declare the constant once, and then it's available throughout the entire scope of the code, providing it's declared somewhere.
In a core file, such as config.php (which is usually included in all sub files in a web app), have something similar to this:
$debug = true;
if($debug){
ini_set('display_errors', 1);
error_reporting(E_ALL);
}else{
error_reporting(0);
}
then just change true to false to disable debugging.
If you want to dump errors in the middle of scripts, such as MySQL queries, then that's a whole different kettle of fish.
Check out this slideshow: http://www.slideshare.net/asgrim1/errors-exceptions-logging-php-hants-oct-13
Here is something you can do:
function is_dev() {
return isset($_SERVER['APP_ENV'] AND $_SERVER['APP_ENV'] === 'DEV')
}
..In your apache virtual host configuration / .htaccess
SetEnv APP_ENV DEV
If you are using a framework or creating your SQL queries dynamically, you can output them if is_dev() returns true.
if(is_dev()) {
echo $sql;
}
Is it a good or bad practice to authenticate and then just exit() the function or to wrap the whole result of the authentication in an if statement? Example
function foo($uid)
{
$allowed = $auth->checkIfAllowed($uid);
if ($allowed == false) exit();
//continue with senstive code here
}
}
OR
function foo($uid)
{
$allowed = $auth->checkIfAllowed($uid);
if ($allowed == true)
{
// do sensitive stuff
}
}
I would like to take this opportunity to talk about exit; (as others have stated both work, the second is more explicit then the first, and give you the opportunity to send a nice error message to the user). My main beef (I have several with exit;) is that people should stop using it in libraries, i.e. code that can/will be used in other projects... You know how irritating it is to debug those? Throw exceptions, trigger fatal errors, but give me something with a description.
/rant
Your examples are equivalent.
However, it's not usually useful to the end user to just exit the script abruptly. Instead, send your user a useful error message printed in HTML rather than the plain text you would get from a die() call, for example.
function foo($uid)
{
$allowed = $auth->checkIfAllowed($uid);
if ($allowed == false)
{
$errormsg = "You are not allowed to view this page";
}
else
{
//continue with senstive code here
}
}
Later, print the error in HTML, rather than just aborting the script:
<div class='error'><?php echo $errormsg; ?></error>
Either or. I don't think it'll make a difference. It relatively the exact same thing. In programming there are many ways to program things, never on right way in most instances.
They are absolutely the same. The indentation and coding style is the only difference. In both cases the sensitive code won't execute unless the authentication is done successfully.
It's usually better to be expressive in your code though, so I'd recommend the second method.
I usually, test code with PHP code, special PHP variables with var_dump and print_r
But I always end up placing them everywhere and messing up the code.
Is it common to include them or place them in an organised way?
No, it's not! You shouldn't rely on var_dump and print_r for testing and debugging. Instead start writing unit tests and start using a debugger!
What you need, in order to write quality PHP code, is an IDE like PhpStorm, Aptana, Eclipse, Zend Studio or NetBeans which provide you with an easy way to integrated debugging and unit testing.
There are two good debuggers for PHP, Zend Debugger and Xdebug.
There is one de facto standard for writing unit tests for PHP, phpUnit.
Use var_dump and print_r only occasionally and never leave them in the code! I strongly disagree with Sam Starlings method. I think it inhibits the development of best practices.
I would also advice using some sort of 'ENVIRONMENT' constant for defining the environment instead of the localhost/IP approach.
Why not wrap every var_dump or print_r in this way:
if($debug) {
var_dump($foo);
}
Then you can set $debug = true at the top of every file - or even better, in a file that is included by every other file, so that you can globally turn debugging on or off. You can also programatically set the debug flag like this:
if($_SERVER['SERVER_NAME'] == "localhost") {
$debug = true;
} else {
$debug = false;
}
Sam's solution is useful, and probably sufficient for many very small projects, but it does involve adding a lot of superfluous code to application logic. In a similar case I would define something like
function aray_out($arr, $continue = NULL) {
echo '<pre>';
(is_array($arr)) ? print_r($arr) : var_dump($arr);
echo '</pre>';
if(!$continue)
exit();
}
When something isn't working as expected, we can just bash out array_out($_SESSION) (or whatever), save and retry, removing the line once we're confident our variables are holding the right stuff. Wrapping the output in <pre> tags makes it a lot more readable.
We could also require_once 'debug.php' in our malfunctioning scripts, using that file to dump our environment.
# debug.php
$your_ip = '192.168.0.1';
if($_SERVER['REMOTE_ADDR'] == $your_ip || $_SERVER['REMOTE_ADDR'] == '127.0.0.1') {
array_out($_SERVER, 1);
array_out($_SESSION, 1);
array_out($_POST, 1);
# etc.
}
This has the added benefit of giving us information, as we have set the IP address we are accessing the server from, but leaving output for other users the same.
Of course, more serious use cases need more serious tools.
Is there a way in PHP to try to include a file, but if the file contains errors that stop it from compiling to just skip that file from inclusion?
You can call php -l on the file in question. This will shell out and slow though.
it doesn't handle runtime errors like die() though.
test.php:
<?php
function check_code_file($filename)
{
$filename = escapeshellcmd($filename);
system("php -l $filename 2>/dev/null 1>/dev/null", $status);
if ($status) return false;
return true;
}
if (check_code_file('test-good.php'))
{
include('test-good.php');
}
if (check_code_file('test-bad.php'))
{
include('test-bad.php');
}
print "finished\n";
test-good.php:
<?php
print "here\n";
test-bad.php:
<?php
die(
$ php test.php
here
finished
A less than ideal solution I thought I'd mention here for posterity. The original idea is here.
You can capture the E_PARSE error you would receive on a bad 'require' and hand it off to a shutdown function. The idea is to suppress the parsing error...
register_shutdown_function('post_plugin_include');
#require 'bad_include.php';
Then do your primary execution after the fact.
function post_plugin_include() {
if(is_null($e = error_get_last()) === false) {
// do something else
}
}
Like I said, less than ideal but interesting nonetheless.
Depending on the PHP version you could use php_check_syntax() (practically the same as php -l).
But its a moo point really..
Either you need the stuff your trying to include or you dont include it.