+3  A: 

You could create a couple of defines to create named constants for all your error codes :

define('ERROR_CODE_SQL_QUERY', 1);
define('ERROR_CODE_PAGE_NOT_FOUND', 2);
define('ERROR_CODE_NOT_ALLOWED', 3);
// and so on

And, then, use the constants in your code :

if ($errorCode == ERROR_CODE_SQL_QUERY) {
    // deal with SQL errors
}


With that, nowhere in your code you'll use the numerical value : everywhere (except in the on and only file where you put the defines), you'll use the codes.

It means :

  • Less risk of errors, as all numerical values are set in only one file
  • Less risk of errors, as you'll use the constants, that have a name which indicates what it means
  • And code that's easier to read.


Another idea could be to create a class to deal with errors :

class Error {
    const CODE_SQL_QUERY = 1;
    const CODE_PAGE_NOT_FOUND = 2;
    const CODE_NOT_ALLOWED = 3;

    // Add some methods here, if needed
}

And, then, use something like this :

if ($errorCode == Error::CODE_SQL_QUERY) {
    // deal with SQL errors
}


Which one is the best ?

It's probably a matter of personnal preferences... If you need to add some methods to deal with the errors, using a class might be useful. Else, defines are a great solution too.

Pascal MARTIN
That's a great idea. I like hard-coding the numbers with *some* kind of string message indicating what they mean. So the next step: how do I provide an interface to the outside world for the errors? Does an object using the error-triggered object get the string, the error code, or what?
@user151841: It seems to me like you could do whatever you want with a given error code. Personally, I'd use exceptions for this but that seems to be outside what you're looking for.
Billy ONeal
+1  A: 

At the very least, can you bump the code numbers up to be class constants or members?

class MyErrorProneClass { 
    const TURNED_INTO_A_NEWT = 12;
    ...

    public function dontBurnMe() {
        // echo your error here using self::TURNED_INTO_A_NEWT
}

This way you can manage the errors in the same place where you use them, rather than having to maintenance a large central file. I tried something to that effect in the past and it becomes difficult to keep up.

Generating error numbers programmatically may be a better long-term solution. If you could use information about the file or line number (__FILE__ and __LINE__ respectively), that would help.

Hope that moves in the right direction at least.

Thanks, Joe


Edit:

A class member would follow this syntax instead:

class MyErrorProneClass { 
    protected static $turnedIntoANewt = 12;
    ...

    public function dontBurnMe() {
        // echo your error here using self::$turnedIntoANewt
}

Since constants are public by default, you can access them from other classes directly if you want. So, from the outside, the error would be referenced as:

MyErrorProneClass::TURNED_INTO_A_NEWT

For associating to messages, you would use a mapping (either in a database, or in some localization file) from error ID (and frontend/backend) to displayed string. This use of keys for messages isn't optimal, but it would allow you to change error messages without changing code as well.

Joseph Mastey
Joe, I like the idea of using constants within the class. How do I provide an interface from the class to the outside world for those constants and values? I also want to associate them with a table of user- and admin-facing error message strings.Also, what is a class "member"?
A: 

If you don't know already it might be an idea to use trigger_error (), plus an error handler if you want to present the user with a better error message.

DCD
Yeah, but this is like the "use exceptions" answer -- I still have to organize my error codes and strings as I'm working. It just moves the problem.
A: 

Have you thought about using exceptions? They may be a good choice for your problem here although adding them to your project now would probably require some restructuring.

You can extend the basic exception class so it fits your problem in terms the of user / developer error message separation.

lamas
Yeah, well, with exceptions, I still have the problem with organizing the error codes and keeping them all straight. It just moves the problem, doesn't solve it.