Why not using array of errors instead of throwing errors and check if it's not empty later in the code.... Exception handling is very confusing to me , I can not understand it's purpose ... can anybody enlighten me !?
they compare it with die() as better not to stop the execution of the code , why would I stop the execution of code if I don't want to !? ofcourse I do
I'm a beginner programmer , it might be confusing to you as well , or because i'm not very experienced in this ugly thing.
Please in the context of PHP only.
One reason you might decide to throw an exception is because you can add a jump in control flow without an explicit piece of syntax. What do I mean by that?
rather than
$returnVal = doSomeDiskFunction();
if($returnVal == $ERROR_CODEA)
{
// do some stuff
}
else if( $returnVal == $ERROR_CODEB)
{
//do some stuff
}
$returnVal = doSomeOtherDiskFunction();
if($returnVal == $ERROR_CODEA)
{
// do some stuff
}
else if( $returnVal == $ERROR_CODEB)
{
//do some stuff
}
you could just have
try{
doSomeDiskFunction();
doSomeOtherDiskFunction();
}
catch(ExceptionTyepA $exceptionA)
{
//do some stuff
}
catch(ExceptionTypeB $exceptionB)
{
//do some stuff
}
Seems a lot cleaner, yes??? It's also a formal way of alerting calling code that it needs to deal with potential error conditions if you choose to have the exception propogate upwards in the call stack.
Also, exceptions should be used for code that you don't expect to happen, like failing to connect to a database, not code that you DO expect to happen, like a user submitting bad data. The other poster made the point that you kind of expect a user to make a lot of errors filling out a form, so you wouldn't throw an exception when you come across some data that is in a bad user-entered format, because you expect user data to be poor quality.
It really depends what type of error you're talking about.
I always die(); for really bad errors, like if the application couldn't connect to the database.
But for anything that takes user input, like a form, it's better to use arrays of errors that the user can see all at once, instead of correcting one field at a time and repeatedly having to press submit.
(If you want to know in more detail, I often use an array of arrays to display errors, since one field could potentially have multiple things wrong with it. For example, if a user tries to register an account with username "1337", I will use a validator to check against multiple conditions and it will return an array with things like "username must be at least 5 characters long", "username must contain at least three letters", "that username has been disallowed by the administrator" and all those messages will be displayed simultaneously above that particular field)
There is a way to code completely without exception handling. For example, if you have a method that returns the length of an object, have it return -1 if there's been an error. This is how most C API's are built.
That said, when you're building complex systems, and you have a ton of "black box" code that might behave wrongly, exceptions help. The way exceptions work is like this: when someone "throws", folks on the call stack start getting notified. One step at a time. One of these methods can "Catch" the exception and handle it.
Why is this useful: you can have a DB layer that has lots of logic inside that throws exceptions. If something goes wrong there, your DB exception handling code can fail gracefully, showing a nice error message to the user; it can also send a text message to the admin, demanding attention.
You can even create a hierarchy of exception handlers: you can re-throw the exception after you've done something with it.
PHP's exceptions sucks hard, but they still have their basics benefits:
Exception provides much more information about "What went wrong?" in much better form (exception is an object)
They make your code clearer
They are the only reasonable way to break execution of the part of code (that doesn't work as it supposes to), fix (if possible) what need to be fixed and continue without complete failure.
Really it depends on the language. C is similar in that respect -- it doesn't force you to handle an error. Most functions return -1 if they had a problem; it's up to you to check 'errno' to see what happened.
Exceptions are generally a good thing though. You rarely want to blindly continue running if an error occurred (Never never NEVER say "On Error Resume Next" in Visual Basic. Please.). It's quite easy to catch the exception and do nothing if you are sure you don't need to do anything.
Related
Here is some sample code:
try
{
$db->query($sql_q1);
$db->query($sql_q2);
$db->query($sql_q3);
}
catch (Exception $e)
{
echo $e->getMessage();
}
How can I see which query caused the error in catch so I can see it along with the error message? And a line number won't work do me, because my queries are often dynamically built.
Well, first of all, just like Usman Munir said, if you won't catch it, there will be more information than if you catch. Just try to remove that try..catch stuff from your code and you will see the first 15 characters of the query.
But in case you need the entire query, there is a way, though not that it will give it to you right away, like a designated variable that contains specifically "last executed query", but well technically you can
There is a thing called a stack trace, intended for the exact purpose. It can show you all the calls made in your code that led to the error, including all function parameters.
Change your code to this
try
{
$db->query($sql_q1);
$db->query($sql_q2);
$db->query($sql_q3);
}
catch (Exception $e)
{
var_dump($e->getTrace());
// or to get the full error info, just
var_dump($e);
}
and you will see your query in the full glory, though it will be quite a pain to get the actual query automatically if that's your goal. but if you want to just log/visually inspect the error information, it will do.
Not that obviously you should never put var_dump() inside try_catch() in any real life code. Instead, some handling code must be put into your error handler. Especially if your purpose is debugging. Hence, your real life code should be rather this
// somewhere in the bootstrap
include 'error_handler.php';
// anywhere in your code
$db->query($sql_q1);
$db->query($sql_q2);
$db->query($sql_q3);
and in the error_handler.php you can add a code to print the full stack trace. an example for such a file you can find in the article Usman Munir posted a link to (which incidentally I wrote).
Note that stack traces tend to grow really big, and can litter your logs significantly. So consider making extended output optional.
One possible solution if you are trying to know the previously executed query would be to store your SQL in a single variable and change it for each statement. Then if an error occurs with a query you can just echo out the contents of the variable. Unless there is a specific reason you need to have multiple variables to hold your queries.
I've tried to understand OOP for a while now (although haven't had much spare time to do much). While the cars and books analogies helped me understand the concept, I have kept failing trying to find a real world scenario (relating to a PHP program with database access).
Here is my most recent attempt at using OOP. It is a simple program submitting a user message to a database.
require_once('init.php');
require_once('Classes.php');
$message = new ContactMessage($db);
if(!$message->validateForm()){
$message -> returnSessionError('Failed to validate your form. Please try again');
header('Location: ../index.php?p=contact');
}else if($message->checkSubmissions(3,10) == false){ //form info okay, check if ip has submitted more than the allowed times. Sets max for 5mins and 24hrs respectively.
if($message->max5mins == true){ //maximum allowed messages in 5min period
$message ->returnSessionError('Too many messages have been sent from the same IP address.
Please wait at least 5 minutes and try again.');
header('Location: ../index.php?p=contact');
}elseif($message->max24hrs == true) { //max allowed in a day
$message ->returnSessionError('To prevent spam, your IP address has been blocked for 24 hours. Please try again later.');
header('Location: ../index.php?p=contact');
}
}else{ //everything is fine, add to database.
if($message -> insertToDB()){
$message -> returnSuccess('Thank you for your message, I\'ll get back to you ASAP.');
header('Location: ../index.php?p=contact');
}else{
$message -> returnSessionError('Something has gone wrong in our server - Please try again later.');
header('Location: ../index.php?p=contact');
}
}
To me, I'm still seeing my code as using a bunch of functions, except now it's wrapped around a Class. Is this the correct use of OOP, or am I just pretending to use it?
Thanks
In terms of OOP, you're doing it wrong because you're mixing concepts and responsibilities.
What you're doing here is dealing with data validation, including both input's and record's
The form validator basically consists of two parts:
Input validator
It basically checks if values are not empty, their maximal or minimal length.
Record Validator
It basically queries a storage to find out about record existence and generates appropriate error message.
Form Validator itself
Its a bridge between input and record validators. It basically check if fields are valid, then starts checking for records. If both inputs and records are valid, then its isValid() method returns true, otherwise it returns false and populates an array with error messages.
$dataMapper = new ContactMapper($pdo);
$inputValidator = new InputValidator();
$recordValidator = new RecordValidator($dataMapper);
$formValidator = new FormValidator($inputValidator, $recordValidator);
if ($formValidator->isValid($data)) {
if ($dataMapper->insert($data)){
// Success, do something like a redirect
} else {
// Failed to insert
}
} else {
print_r($formValidator->getErrors());
}
What would you gain here?
In terms of OOP, you're adhering to the Single-Responsibility Principle and Separation of Concerns at the same time, because you do encapsulate separated responsibility within a class that serves it. Thus you'll be able to modify one part of an application without altering another one.
Dealing with storage logic - is another responsibility too
And that should be basically encapsulated within a Mapper that abstract an access to a table.
Assumptions
I suppose this file of yours is, alone, just responsible for the execution of this script. No others scripts, neither HTML codes. Let's call it "post.php".
Answering the title question
In the OOP paradigm, you ALWAYS create your code oriented, not just when you can reuse code.
Answering the body question
In my opinion, in order for you to have a good OOP implementation, all scripts must be inside classes, except those that call the methods, and whatever else you need and can't put inside the classes (sorry, it's difficult to be more specific in the latter). You have two possibilities:
GET pages: get infos from the server and mix with the views (i.e. HTMLs; main methods in others languages), creating dinamic pages;
POST pages: targets from yours forms; in separated pages without any HTML, post infos to the server, like yours "post.php".
So, your script should be inside some class, it could be the ContactMessage, and in the "post.php", you just call the method of ContactMessage, something like postMessage, that does all this stuff.
Being more clear, i would create a postMessage method inside the ContactMessage class and call validateForm, checkSubmissions, insertToDB... from other classes (instead of the own ContactMessage), to create the "Single Responsibility" like the others said. One class responsible for the validation, one to abstract the DB and so on...
Final considerations
In my short experience, a real scenario it's a bit more complex than this, but you go adapting along the way corresponding to the needs.
One last thing: i would put all the redirections outside the class, in the "post.php", and would be just two possible redirections, one if fails and one if succeeds.
When I display an error message in php, I usually do it like this,
if($query){
// Success code
}else{
// Error message
$error_msg = "An error occurred.";
return false;
}
and I echo $error_msg variable in the front-end html page.
I am just wondering if that return false after the variable actually does anything, or is it just pointless to put it there?
I am trying to optimize my code and just wanted to make sure! Thanks a lot in advance!
Yes, it tells the function to stop executing, and to return a value "false". So it does something. Whether or not is does something USEFUL depends on your programming.
If you have no executable lines after the echo, and the function is not required to return a value, then it won't actually do anything useful.
If does make it clearer to readers that "this is a stop/failure point" though. And one day you might want to actually trap if it worked or failed - so leaving it in makes it clearer. You also may extend the function without thinking and need to retro-fit the returns - again, leaving it in makes it easier.
On the converse, there is also the old programming style from C / Assembler days that you only have one entry and one exit point for all functions to help with garbage collection. Not a requirement with PHP, but that style does make it nice and neat. In this case, set the return value (if required) and return at the end.
So, go with which suits your style - but think ahead. Making everything pristine and minamlistic (i.e. dropping the line as you don't strictly need it) may not always be the best approach.
The point of the return false is so that you can easily test a function to see if it has worked - without needing to go into any potential error messages and the like.
A function that returns false for a fail can be used in the following manner:
if(someFunction($var))
{
do stuff for function working...
}
else
{
// function failed. Do other stuff.
}
It is also intuitive that a function returns false when it fails. It can be further used like this:
$foo=someFunction($var);
if($foo)
{
again, function has worked.
}//... etc
While the same function returning The function has failed could not be used in tis intuitive manner.
This might be a n00bish question, but whatever. Is okay to use exceptions for form validation? Let's say I have a form which asks users for their name and email, is right to do the following?
try {
if (empty($_POST["name"])) {
throw new UserRegistrationException("Your name cannot be empty.");
}
if (filter_var($_POST["email"])) {
throw new UserRegistrationException("Invalid email");
}
// Save new user into database
} catch (UserRegistrationException $e) {
// Show errors on screen
}
Also -if this is in fact the correct way to do it- if the user submits both an empty name and an invalid email, would both of the exceptions execute or only the one that appears first (the name one in this case)?
I'm using PHP by the way.
I personally like to use exceptions for anything that should stop or alter program flow. In other words, if validation of a particular field changes how data is processed, or requires the process to be repeated, then I always use exception for error handling.
If it's trivial, or I'm simply compiling a list of error messages, then I do not trigger exceptions.
To answer questions, two exceptions cannot be thrown at the same time. The first throw statement that is reached will be thrown. That's not to say that sometimes it doesn't make sense to rethrow as another type of exception.
The use case for exceptions is for exceptional conditions. In this case, do you expect the username and password fields to be blank? If you're displaying a web form, I'd argue that, yes, you do expect blank username and password fields, and so you should be checking for that condition explicitly, rather than throwing an exception.
To answer your specific question, both exceptions will not be thrown if an error is encountered. The throw statement will send the program into the catch block. From there control will flow as normal.
I am using Cakephp but this is a MVC/php doubt
letting the view display the message
vs
echo 'Invalid Data'; exit;
I would like to know is there any pitfalls in the second case like memory leak etc.. Which one is better
EDIT
In case of a ajax call is exit good. and what about memory leak and other issues . Are all variables deallocated
You should use a custom ExceptionHandler (set_error_handler / set_exception_handler) and throw an Exception if you encounter any errors (CakePHP should already provide an ExceptionHandler). Make some space in your view and if the ExceptionHandler/ErrorHandler has a message, show it there to let the user know.
Your second code will just produce a blank page containing the little text. Every user will appreciate if you show the message inside your usual page layout instead of producing a blank page (which looks broken to most people).
The Cake tools to signal errors to the user are session messages and error views.
For "passive" actions like view actions, you should throw a 404 or similar, possibly more specialized error, e.g. if the requested model does not exist:
function view($id) {
$data = $this->Model->read(null, $id);
if (!$data) {
$this->cakeError('error404');
}
...
}
See Error Handling with CakePHP.
For any POST action, you should return the user to the view and display an error message using $this->Session->setFlash('Error!') and appropriate error messages for each invalid form field. That's the default behavior of baked views and controllers.
Terminating the whole script with exit makes for a miserable user experience.
In general, you should avoid exit. Exit is an abnormal termination, and programs should not terminate abnormally. Even if an error occurs, there are still many things that needs to be done - cleanup, logging, notifying the user etc. After all, your operating system doesn't reboot every time it cannot open a file.
performance-wise (AJAX cals)
Use exit().
user experience-wise (standard site nav)
Show the error in a proper formated page keeping the user within your site.