I've noticed many (all?) PHP constants have a single-letter prefix, like E_NOTICE
, T_STRING
, etc. When defining a set of class constants that work in conjunction with one another, do you prefer to follow similar practice, or do you prefer to be more verbose?
class Foo {
// let's say 'I' means "input" or some other relevant word
const I_STRING = 'string';
const I_INTEGER = 'integer';
const I_FLOAT = 'float';
}
开发者_如何学C
or
class Bar {
const INPUT_STRING = 'string';
const INPUT_INTEGER = 'integer';
const INPUT_FLOAT = 'float';
}
Up until 5.3 PHP was limited to a single global namespace. Meaning any constants declared with define
or built into the language required a prefix to partition themselves - namespacing on the cheap, if you will.
About constants themselves: while E_NOTICE
is easier to type than ERROR_NOTICE
the former has the major disadvantage of not being self-documenting. When in a global context not only do you need to partition constants out by prefix, these prefixes should also be as descriptive as possible.
Class constants are a slightly different beast, as you'll always be referencing them by class name - partitioning will be built in. So you'll end up with Account::STATUS_CONFIRMED
and Account::STATUS_BANNED
. But if I planned on having several dozen statuses, I'd put these in their own class, e.g. AccountStatus::CONFIRMED
, AccountStatus::BANNED
, etc.
Whatever naming convention you decide on for constants the major considerations are partitioning and self-documenting names (verbosity).
For things like constants I prefer to be verbose. I find it makes the code easier to comprehend later (or for folks who didn't write it), and since I use an IDE, I don't usually have to worry about typing the whole long name out when I'm coding.
Inside a class, you're better off not using prefixes at all, unless they're extremely meaningful in their contexts. The letter prefix you see with constants is because there were no namespaces in PHP when they were introduced; but classes are some form of namespacing, so this isn't really necessary.
If you are, however, going to use a prefix anyways, I suggest you use the most meaningful one—that is, the full word instead of a single letter. I wouldn't have guessed myself that I
meant INPUT
.
The reason most PHP constants have the prefix is to namespace them, so that . For example, in E_USER_ERROR
, the E_
does two things:
- It tells you that the constant is related to the error handling system
- It makes it so that if you want to have a constant called
USER_ERROR
in your application, you can.
In PHP5, we can use class constants, so namespacing is no longer necessary. See for example the DATE_
constants. The equivalent of DATE_ATOM
is DateTime::ATOM
, where DateTime
is the PHP class that deals with dates. DATE_ATOM
still exists, presumably for legacy reason, but were that constant created today, it would simply be called DateTime::ATOM
.
In your case, it might make sense to define an input class that would have these constants:
class input {
public const STRING='string';
public const INTEGER = 'integer';
public const FLOAT = 'float';
}
I prefer to be more verbose
class Bar {
const INPUT_STRING = 'string';
const INPUT_INTEGER = 'integer';
const INPUT_FLOAT = 'float';
}
This makes the code easier to read for the next person who has to work on the code. You could consider adding your own framework-prefix to the constants (eg.: XYZ_INPUT_STRING) that'll decrease the change of having a conflict with other components that you might use. A downside of being more verbose is that variablenames tend to get longer, but a good IDE supports code completion so you don't have to type the whole variable name.
Prefixes are used to namespace symbols. Eg. since constants are declared in the global scope, you can use a prefix to specify the context of it and avoid clashing with other uses of the symbol in a different context.
Since class constants already exists in a context (the class), there is really no need to prefix it further. Instead of your example, this would probably make more sense:
class Input {
const STRING = 'string';
const INTEGER = 'integer';
const FLOAT = 'float';
}
That said, I find that constants (class or global) are generally not something I use very much in PHP. You can usually replace a constant with a more specific methodname, and this generally make the code much more maintainable. For example, instead of something like this:
$foo->addParameter("foo", Input::STRING);
You could do this:
$foo->addStringParameter("foo");
It's easier to read and it's easier to write.
Unlike C and friends, in dynamic languages we rarely, if ever, need pre-declared constants. because descriptive string values work just as fine. There is no real benefit of using
if($account->status == AccountStatus::CONFIRMED)
compared to
if($account->is('confirmed'))
The latter is more readable and requires less code.
Before you start writing an indignant comment, look how jQuery does it: http://api.jquery.com/animate/ . 'hide', 'toggle', 'fast' etc are actually constants, they are simply not declared as such.
精彩评论