In PHP, you can declare constants in two ways:
With
define
keyworddefine('FOO', 1);
Using
const
keywordconst FOO = 1;
- What are the main differences between those two?
- When and why should you use one and when use the other?
NikiC's answer is the best, but let me add a non-obvious caveat when using namespaces so you don't get caught with unexpected behavior. The thing to remember is that defines are always in the global namespace unless you explicitly add the namespace as part of the define identifier. What isn't obvious about that is that the namespaced identifier trumps the global identifier. So :
<?php
namespace foo
{
// Note: when referenced in this file or namespace, the const masks the defined version
// this may not be what you want/expect
const BAR = 'cheers';
define('BAR', 'wonka');
printf("What kind of bar is a %s bar?\n", BAR);
// To get to the define in the global namespace you need to explicitely reference it
printf("What kind of bar is a %s bar?\n", \BAR);
}
namespace foo2
{
// But now in another namespace (like in the default) the same syntax calls up the
// the defined version!
printf("Willy %s\n", BAR);
printf("three %s\n", \foo\BAR);
}
?>
produces:
What kind of bar is a cheers bar?
What kind of bar is a wonka bar?
willy wonka
three cheers
Which to me makes the whole const notion needlessly confusing since the idea of a const in dozens of other languages is that it is always the same wherever you are in your code, and PHP doesn't really guarantee that.
Until PHP 5.3, const
could not be used in the global scope. You could only use this from within a class. This should be used when you want to set some kind of constant option or setting that pertains to that class. Or maybe you want to create some kind of enum.
define
can be used for the same purpose, but it can only be used in the global scope. It should only be used for global settings that affect the entire application.
An example of good const
usage is to get rid of magic numbers. Take a look at PDO's constants. When you need to specify a fetch type, you would type PDO::FETCH_ASSOC
, for example. If consts were not used, you'd end up typing something like 35
(or whatever FETCH_ASSOC
is defined as). This makes no sense to the reader.
An example of good define
usage is maybe specifying your application's root path or a library's version number.
I believe that as of PHP 5.3, you can use const
outside of classes, as shown here in the second example:
http://www.php.net/manual/en/language.constants.syntax.php
<?php
// Works as of PHP 5.3.0
const CONSTANT = 'Hello World';
echo CONSTANT;
?>
Yes, const are defined at compile-time and as nikic states cannot be assigned an expression, as define()'s can. But also const's cannot be conditionally declared (for the same reason). ie. You cannot do this:
if (/* some condition */) {
const WHIZZ = true; // CANNOT DO THIS!
}
Whereas you could with a define(). So, it doesn't really come down to personal preference, there is a correct and a wrong way to use both.
As an aside... I would like to see some kind of class const that can be assigned an expression, a sort of define() that can be isolated to classes?
Most of these answers are wrong or are only telling half the story.
For example:
const AWESOME = 'Bob'; // Valid
Bad example:
const AWESOME = whatIsMyName(); // Invalid (Function call)
const WEAKNESS = 4+5+6; // Invalid (Arithmetic)
const FOO = BAR . OF . SOAP; // Invalid (Concatenation)
To create variable constants use define() like so:
define('AWESOME', whatIsMyName()); // Valid
define('WEAKNESS', 4 + 5 + 6); // Valid
define('FOO', BAR . OF . SOAP); // Valid
I know this is already answered, but none of the current answers make any mention of namespacing and how it affects constants and defines.
As of PHP 5.3, consts and defines are similar in most respects. There are still, however, some important differences:
const FOO = 4 * 3;
doesn't work, but define('CONST', 4 * 3);
does. define
must include the namespace to be defined within that namespace.The code below should illustrate the differences.
namespace foo
{
const BAR = 1;
define('BAZ', 2);
define(__NAMESPACE__ . '\\BAZ', 3);
}
namespace {
var_dump(get_defined_constants(true));
}
The content of the user sub-array will be ['foo\\BAR' => 1, 'BAZ' => 2, 'foo\\BAZ' => 3]
.
=== UPDATE ===
The upcoming PHP 5.6 will allow a bit more flexibility with const
. You will now be able to define consts in terms of expressions, provided that those expressions are made up of other consts or of literals. This means the following should be valid as of 5.6:
const FOOBAR = 'foo ' . 'bar';
const FORTY_TWO = 6 * 9; // For future editors: THIS IS DELIBERATE! Read the answer comments below for more details
const ULTIMATE_ANSWER = 'The ultimate answer to life, the universe and everything is ' . FORTY_TWO;
You still won't be able to define consts in terms of variables or function returns though, so
const RND = mt_rand();
const CONSTVAR = $var;
will still be out.
As of PHP 5.3 there are two ways to define constants: Either using the
const
keyword or using thedefine()
function:The fundamental difference between those two ways is that
const
defines constants at compile time, whereasdefine
defines them at run time. This causes most ofconst
's disadvantages. Some disadvantages ofconst
are:const
cannot be used to conditionally define constants. To define a global constant, it has to be used in the outermost scope:Why would you want to do that anyway? One common application is to check whether the constant is already defined:
const
accepts a static scalar (number, string or other constant liketrue
,false
,null
,__FILE__
), whereasdefine()
takes any expression. Since PHP 5.6 constant expressions are allowed inconst
as well:const
takes a plain constant name, whereasdefine()
accepts any expression as name. This allows to do things like this:const
s are always case sensitive, whereasdefine()
allows you to define case insensitive constants by passingtrue
as the third argument (Note: defining case-insensitive constants is deprecated as of PHP 7.3.0 and removed since PHP 8.0.0):So, that was the bad side of things. Now let's look at the reason why I personally always use
const
unless one of the above situations occurs:const
simply reads nicer. It's a language construct instead of a function and also is consistent with how you define constants in classes.const
, being a language construct, can be statically analysed by automated tooling.const
defines a constant in the current namespace, whiledefine()
has to be passed the full namespace name:Since PHP 5.6
const
constants can also be arrays, whiledefine()
does not support arrays yet. However, arrays will be supported for both cases in PHP 7.Finally, note that
const
can also be used within a class or interface to define a class constant or interface constant.define
cannot be used for this purpose:Summary
Unless you need any type of conditional or expressional definition, use
const
s instead ofdefine()
s - simply for the sake of readability!