/    Sign up×
Community /Pin to ProfileBookmark

Defensive Coding

I’ve put together a first draft on a little article about defensive coding in PHP. I’d appreciate any feedback on the content: does it make sense, are the examples clear, any glaring omissions, etc.? I’m not worried about things like spelling and grammar at this point, I’ll clean that up later.

Thanks

And here’s the article: [url]http://www.charles-reace.com/article.html[/url]

to post a comment
PHP

17 Comments(s)

Copy linkTweet thisAlerts:
@ShmohelAug 11.2005 — Very well written ND. I think I may take up your idea of turning all error emssages on while scripting. Thanks!
Copy linkTweet thisAlerts:
@BeachSideAug 11.2005 — My absolute favorite line... I am still laughing over this...

We want to output a "nice" error message that looks professional, implying that everything is under control and we're sure it will be better in the morning.
[/quote]
Copy linkTweet thisAlerts:
@rch10007Aug 13.2005 — I think you are going to help save alot of computers from being thrown out the window with this article. Ok, maybe only mine - but it's a start!
Copy linkTweet thisAlerts:
@ShrineDesignsAug 13.2005 — One of the common mistakes I see many novice PHP developers make is to assume that everything should work as coded.[/quote]awsome openning sentance, great minds think alike lol, great job nogdog
Copy linkTweet thisAlerts:
@Jeff_MottAug 13.2005 — ...and wherever you currently have die("some message") just change it to error("some message"[, TRUE|FALSE])[/quote]I'm not up on my PHP, but are you able to override the functionality of core functions? For instance, instead of changing every single die to error, could you instead define die to do something different?
Copy linkTweet thisAlerts:
@NogDogauthorAug 13.2005 — I'm not up on my PHP, but are you able to override the functionality of core functions? For instance, instead of changing every single die to error, could you instead define die to do something different?[/QUOTE]
I seem to recall that PHP does not allow this, but I'll have to look into it to be sure, as that's a good idea.
Copy linkTweet thisAlerts:
@Stephen_PhilbinAug 13.2005 — Well written. Clean and clear. I like. ?

I know you're probably already on it, but I think a section on SQL injection and promotion of mysql_real_escape_string() over magic quotes GPC or addslashes (assuming MySQL is the database in question of course) would definitely be a good thing.

Actually, I think making a sticky with links to well written and clear articles like this, on some of the important basics of PHP would be a good thing.
Copy linkTweet thisAlerts:
@SheldonAug 13.2005 — I like the article Nog Dog, iI like the easy way you have written it so that even a novice (Much of myself) can understand what you are on about. i like how you say to include some of the variables in the error message.

Nice work!

Sheldon
Copy linkTweet thisAlerts:
@bokehAug 13.2005 — Instead of using die() at the coding stage and changing later you could use error() but have:
[code=php]function error($error)
{
die($error);
}[/code]


This would save changing die() to error() after debugging has finished. All that would be needed is changing the above function to your function.

Does this make any sense?
Copy linkTweet thisAlerts:
@NogDogauthorAug 13.2005 — Instead of using die() at the coding stage and changing later you could use error() but have:
[code=php]function error($error)
{
die($error);
}[/code]


This would save changing die() to error() after debugging has finished. All that would be needed is changing the above function to your function.

Does this make any sense?[/QUOTE]

Yes. And I've confirmed by experimentation that you can not redefine a function.

Maybe a follow-up article in the works with some of the ideas here? I think I want to avoid introducing too much in one article.

Thanks to all for the feedback.
Copy linkTweet thisAlerts:
@SheldonAug 13.2005 — Yes that does make sence, saves going throught and making changes to everything.

But one question? would that mean that the same error message would come up with everything?


Sheldon
Copy linkTweet thisAlerts:
@GenixdeaeAug 14.2005 — good job nogdog, much like everyone else said, you did great on it.

?
Copy linkTweet thisAlerts:
@NogDogauthorAug 15.2005 — Instead of using die() at the coding stage and changing later you could use error() but have:
[code=php]function error($error)
{
die($error);
}[/code]


This would save changing die() to error() after debugging has finished. All that would be needed is changing the above function to your function.

Does this make any sense?[/QUOTE]

This inspired me to come up with the following function:
[code=php]
function error($text, $fatal = FALSE)
{
if(!defined('DEBUG') or DEBUG == FALSE) # not in debug mode
{
# ouput error text to log file:
$path = "C:\"; # specify where log files will be saved
$this = array_pop(explode("/", $_SERVER['PHP_SELF']));
$file = "$path$this.log";
error_log(date("Y/m/d-h:m:s") . " --> $textn", 3, $file);
if($fatal)
{
$msg = <<<EOD
<p class="error">We're sorry, but an unrecoverable error occurred processing
your request. If this problem persists, please contact the
<a href="mailto:{$_SERVER['SERVER_ADMIN']}">webmaster</a>.</p>
EOD;
die($msg);
}
}
else # in debug mode
{
if($fatal)
{
die("<pre>ERROR: $text</pre>");
}
else # not fatal, so just output error text
{
echo("<pre>ERROR: $text</pre>");
}
}
}
[/code]

Now all I need to do is incude() it into any script, and if I want to run in debug mode (have any errors reported directly to the normal output) just define a constant DEBUG as TRUE; otherwise it will run in non-debug mode, outputting all error text to the log file:
[code=php]
include "include.php"; # file that includes error() function
define('DEBUG', TRUE); # run this script in debug mode
# ... rest of script follows
# sample error situation:
mysql_query($query) or error("Query failed: " . mysql_error(), TRUE);
[/code]
Copy linkTweet thisAlerts:
@Jeff_MottAug 16.2005 — Just another suggestion (going back to my Perl roots): using a boolean for fatal or not is not going to be very readable in the main body of code.... or error("don't work", FALSE);
... or error("also don't work", TRUE);
Perhaps instead you could write two different functions for the simple purpose of readability.... or Error("don't work");
... or FatalError("also don't work");
In Perl this would be synonymous with the operations [font=courier]die[/font] and [font=courier]warn[/font].
Copy linkTweet thisAlerts:
@ShrineDesignsAug 16.2005 — or you could do something like[code=php]$var = '';

if(empty($var))
{
error('$var is empty', E_USER);
}
unset($var);

if(!isset($var))
{
error('$var is not set', E_FATAL);
}[/code]
Copy linkTweet thisAlerts:
@NogDogauthorAug 16.2005 — Hmm...maybe I'll add...
[code=php]
define('FATAL', TRUE);
define('NONFATAL', FALSE);
[/code]

...to my include file, then I can just call the error function as...
[code=php]
error("error message", FATAL);
# or #
error("error message", NONFATAL);
[/code]

Jeff's idea of two functions has some merit, too, maybe actually calling them warn() and error(). Guess I just have to decide which way I prefer: one function with 2 parameters, or two functions with one parameter.
Copy linkTweet thisAlerts:
@Stephen_PhilbinAug 16.2005 — I'd go for one function with two parameters. I actually think TRUE and FALSE are more readable because of the casing making them stand out and if you're been doing this sort of thing for longer than five minutes, your eye has probably already trained its self to spot a TRUE in a haystack from the other side of the continent you're on.
×

Success!

Help @NogDog spread the word by sharing this article on Twitter...

Tweet This
Sign in
Forgot password?
Sign in with TwitchSign in with GithubCreate Account
about: ({
version: 0.1.9 BETA 5.8,
whats_new: community page,
up_next: more Davinci•003 tasks,
coming_soon: events calendar,
social: @webDeveloperHQ
});

legal: ({
terms: of use,
privacy: policy
});
changelog: (
version: 0.1.9,
notes: added community page

version: 0.1.8,
notes: added Davinci•003

version: 0.1.7,
notes: upvote answers to bounties

version: 0.1.6,
notes: article editor refresh
)...
recent_tips: (
tipper: @AriseFacilitySolutions09,
tipped: article
amount: 1000 SATS,

tipper: @Yussuf4331,
tipped: article
amount: 1000 SATS,

tipper: @darkwebsites540,
tipped: article
amount: 10 SATS,
)...