...

View Full Version : Better way to stop script then DIE()?



Vigilante
02-16-2006, 11:12 PM
Hi guys, I'd like to know what you do when you have to stop a script, except without using die().

As you know, as soon as php parses a die(), nothing else happens on that page. For most pages this may be fine. But on some pages, you still need to have, say, a sidebar and foot displayed. But if the script dies before the footer is displayed, it won't show up, thus leaving your page half-rendered.

The only way I know to get around this is to wrap ALL your code in wide IF statements such as:

if (condition) {

LOTS of page code

} else {

your error

}
In this code, because I don't use a die statement, the rest of the page renders beyond my error message.

Even this is acceptable for some pages, smaller pages with not much code.
But then, in larger pages, that have multiple conditional statements strewn about, keeping track of 3, 4 or 10 of these huge conditions becomes a huge pain. So lets say your page is made up of:

-------------------
header
-------------------

body

-------------------
footer
-------------------

You cannot have any DIE statements within the header or body because the body or footer won't display. And also, through this page you may have as many as 5 or more error conditions in which case you want to display an error, and then render the rest of the page.

What kind of strategy do you employ for error management like this? In a theoretical situation, lets say you have 3 mysql calls in various parts of the page, but if the call fails, you need to stop with an error. The usual syntax is:

mysql_query("find cool stuff") or die("There was an error getting stuff!");

What would you do instead?

Thanks.

brothercake
02-17-2006, 12:06 AM
Well I'm no PHP expert, but I'd say the general lesson here is to avoid procedural code. If you write scripts as objects, then you have the flexibility to use return statements to halt the execution of the code at any point in time.

fci
02-17-2006, 12:09 AM
well, you could use OO to abstract it,(ah, brothercake just beat me to it) or, depending on the error you could redirect the use to another page which tells the user what the error was (pass an error number in the get string).

marek_mar
02-17-2006, 12:14 AM
trigger_error() (http://www.php.net/trigger_error)
try, throw and catch (http://www.php.net/exceptions) - exceptions (PHP5 only)
return (http://www.php.net/return) (functions/methods)
register_shutdown_function() (http://www.php.net/manual/en/function.register-shutdown-function.php)

chump2877
02-17-2006, 12:16 AM
if you want the entire page to load, then just echo out your error messages....

but if you eliminate the errors in your code, this would not be a problem...

GO ILLINI
02-20-2006, 05:42 AM
I know there is an exit() but Im not sure what it does... maybe it ends the entire page? or maybe it just ends the php. Not sure...




ILLINI

Kurashu
02-20-2006, 06:53 AM
Exit() is an alais of die().

GO ILLINI
02-20-2006, 07:04 AM
ohh, ok. Like I said i wasnt sure what it was



ILLINI

Kid Charming
02-20-2006, 07:55 AM
but if you eliminate the errors in your code, this would not be a problem...

Not all errors come from the code.

Vigilante
02-20-2006, 08:57 PM
Yes, not all errors come from code. Let me give you an example in point.

This page is a simple page for users to answer a question form.
There are many checks such as:

are they logged in? If not, stop
have they already answered this form? if so, stop
are there various other conditions? if so, stop

During these checks, there are maybe 5 or more mysql calls. Simply because I want good programming form, I make sure each call has a die() in case the call fails for whatever reason, so I can handle the error rather then an ugly php error.

I hear what you're saying about object oriented code and classes. While that sounds really good. Wouldn't it be similar like:

Run functionname() or die("function failed")
??

Note that most "functions" would also output text in themselves. So I'm not sure exactly how to go about this. Because my code would end up looking like this:

run function 1 or stop somehow
run function 2 or stop somehow
run function 3 or stop somehow

So then on any particular error, I would have to prevent other function calls from running?

Maybe I'm just making this overly complicated :)

firepages
02-20-2006, 11:26 PM
...so I can handle the error...
but die() is not handling the error , its over-reacting ;)

Procedural or OO is not the point (you can call die() from within a class method as well) , die() is great for development but for production you should catch and handle the errors , I agree if's are an ugly solution to this and some form of abstraction (functions or classes) help.

The main point however is that there should be no reason to die() anywhere in production code anyway, you can predict where and when an error is likely to occur and handle it, in worst cases (like db connection not working or catching malicious code injecton attempts) a simple header() to a sorry page should suffice. (OK I sometimes use die() with a nasty message for code injections ;))

The only fatal cases I can think of are file-read/write operations failing or basic SQL errors etc all of which should be cleaned up during development.

dragon
02-21-2006, 02:52 AM
What about something like this:



echo $header;

switch($action)
{
case('login'):
if(isset($all_needed_variables))
login($all_needed_variables);
else
bad_login();
break;
case('show_item')
if(isset($all_needed_variables))
show_item($all_needed_variables);
else
request_item_to_show();
break;
default:
echo $all_popular_stuff;
}

echo $footer;

Vigilante
02-21-2006, 11:22 PM
I guess maybe I'm not giving all the details.

The case statement would be good, but under certain cases I would even need multiple cases to run, not just any particular one.
I will do some research and think about the suggestions thus far.

Remember that my code is just an "included" page. Meaning the header, footer, navigation and everything is outside my own little script. This leaves using header:location out. As it would return "headers already sent by...".

Anyhow, I'll write back here with whatever I think up.
And yes I agree that all code can be "cleaned up" in development. But it is still good practice to handle every possible error condition properly.
I don't mind die() for all but the most requent errors. Such as "you are not logged in!". This is not a code-based error, so it obviously needs to be handled without a die(). But you all have given me some ideas about that.

Thanks

fci
02-22-2006, 07:28 AM
Remember that my code is just an "included" page. Meaning the header, footer, navigation and everything is outside my own little script. This leaves using header:location out. As it would return "headers already sent by...".


// put this in a global file:
ob_start();

//use this when you want to redirect, wrap it in a function to suit your needs:
header("Location: $your_url");
ob_end_flush();





I don't mind die() for all but the most requent errors. Such as "you are not logged in!". This is not a code-based error, so it obviously needs to be handled without a die(). But you all have given me some ideas about that.
if user not logged in, redirect to a URL with part of the url they were trying to access URL encoded .. then they can login and be redirected to that URL (but you must make sure it is a valid one somehow or could lead someone to be redirected to somewhere unsafe..)

Vigilante
02-23-2006, 10:39 PM
I've been doing some reading about trigger_error, set_error_handler and so forth. Not sure I really want to use my own global error handler. Only because, remember, my script is only in include in someone else's page. So I don't want to suddenly handler all their errors as well.
My error handling has to be self-contained.

As for error conditions, this not being my page, I don't have control over it. Some idiot could get in there and delete a file, screw up the database, change a file name; any number of things could cause errors in my code, even if I coded it perfectly in dev.

Try, catch is a good alternative, but unfortuneatly it is pretty much the same as using big if-then conditions. Think about it

try {
some stuff that hopefully doesn't fail, if good, next try
try {
next level of code that hopefully doesn't fail
try {
possibly many many levels before script is done
} catch {
oh man failed 3rd try
}
} catch {
oh man failed 2nd try
}
} catch {
oh dang you had a 1st level error
}


As you can see, it can get just as ugly as big if-then conditions.
I don't know what I'm looking for fellas, i guess I just want it similar to this idea:

codeline 1
codeline 2
codeline 3
maybefailcondition or GOTO ERRORTHING
rest of code here
//
//any more code here will NOT execute if ERRORTHING is ever called.

function ERRORTHING {
echo some errors
// now need to make sure no other script is executing in my include
// but that the rest of the page is rendered beyond my include
}


I program like Basic and Visual Basic and languages that have a way to just jettison the code anywhere I like. But php always wants to keep executing. And indeed it needs to, but ONLY after my own script, and not within.

I figure I could also just create a boolean error flag, so if the flag is set, no code executes, but that seems rediculous cause then all my code as to look like

if (!$errflag) { keep coding }

I would have to make very small chunks of IF statements for each possible error-creating code. That just gets ugly too.

Where is my thinking going wrong?
I have not ridden the possibility of wrapping more stuff into classes, but at this point I cannot go rewrite all my code. But I will do that in any new projects. I'm sure it will make things easier.

marek_mar
02-23-2006, 10:56 PM
<?php
print 'hi' . "\n";

try
{
print 'trying' . "\n";
if(rand(0, 1))
{
throw new Exception('New Exception');
}
print 'This will get printed unless that exeption above will be thrown' . "\n";
if(true)
{
throw new Exception('New Exception');
}
print 'This won\'t get printed';
}
catch (Exception $e)
{
var_dump($e);
}
?>

You could reorder it in such a way so that you try only the things thast may couse errors.

Mhtml
02-24-2006, 01:58 AM
See this is why I like to use a template engine. At the end of everything it will output a template given a string filename, then depending on the state of things that filename is generated based on conditions and exceptions relevant to the given data. Even if I have an error I don't use die() unless it is absolutely crticial, I just pass in a dynamic template include for an error message template instead of the page content, or supplimental to that content.

You need to look at the way in which you write your code, think modularly.



EZ Archive Ads Plugin for vBulletin Copyright 2006 Computer Help Forum