PHP | define() vs. const
As of PHP 5.3 there are two ways to define constants: Either using the const
keyword or using the define()
function:
const FOO = 'BAR';
define('FOO', 'BAR');
The fundamental difference between those two ways is that const
defines constants at compile time, whereas define
defines them at run time. This causes most of const
's disadvantages. Some disadvantages of const
are:
const
cannot be used to conditionally define constants. To define a global constant, it has to be used in the outermost scope:if (...) {
const FOO = 'BAR'; // Invalid
}
// but
if (...) {
define('FOO', 'BAR'); // Valid
}Why would you want to do that anyway? One common application is to check whether the constant is already defined:
if (!defined('FOO')) {
define('FOO', 'BAR');
}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 BIT_5 = 1 << 5; // Valid since PHP 5.6 and invalid previously
define('BIT_5', 1 << 5); // Always validconst
takes a plain constant name, whereasdefine()
accepts any expression as name. This allows to do things like this:for ($i = 0; $i < 32; ++$i) {
define('BIT_' . $i, 1 << $i);
}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):define('FOO', 'BAR', true);
echo FOO; // BAR
echo foo; // BAR
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:namespace A\B\C;
// To define the constant A\B\C\FOO:
const FOO = 'BAR';
define('A\B\C\FOO', 'BAR');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.const FOO = [1, 2, 3]; // Valid in PHP 5.6
define('FOO', [1, 2, 3]); // Invalid in PHP 5.6 and valid in PHP 7.0
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:
class Foo {
const BAR = 2; // Valid
}
// But
class Baz {
define('QUX', 2); // Invalid
}
Summary
Unless you need any type of conditional or expressional definition, use const
s instead of define()
s - simply for the sake of readability!
What is the difference between using the constant() function and referencing a constant directly by name?
Try this it, should work
define("MAXSIZE", 100);
$x = "MAXSIZE";
echo constant($x);
The method constant()
will return the value of a defined constant if you have string variable of it.
Consider this example.
define("MAX", 1000);
define("MIN", 1);
$val = 50;
$const = null;
if ( $val < 50 ) {
$const = "MAX";
} else {
$const = "MIN";
}
echo constant($const); // output 1
DEFINE vs Variable in PHP
DEFINE makes a constant, and constants are global and can be used anywhere. They also cannot be redefined, which variables can be.
I normally use DEFINE for Configs because no one can mess with it after the fact, and I can check it anywhere without global-ling, making for easier checks.
static const vs #define vs enum
It depends on what you need the value for. You (and everyone else so far) omitted the third alternative:
static const int var = 5;
#define var 5
enum { var = 5 };
Ignoring issues about the choice of name, then:
- If you need to pass a pointer around, you must use (1).
- Since (2) is apparently an option, you don't need to pass pointers around.
- Both (1) and (3) have a symbol in the debugger's symbol table - that makes debugging easier. It is more likely that (2) will not have a symbol, leaving you wondering what it is.
- (1) cannot be used as a dimension for arrays at global scope; both (2) and (3) can.
- (1) cannot be used as a dimension for static arrays at function scope; both (2) and (3) can.
- Under C99, all of these can be used for local arrays. Technically, using (1) would imply the use of a VLA (variable-length array), though the dimension referenced by 'var' would of course be fixed at size 5.
- (1) cannot be used in places like switch statements; both (2) and (3) can.
- (1) cannot be used to initialize static variables; both (2) and (3) can.
- (2) can change code that you didn't want changed because it is used by the preprocessor; both (1) and (3) will not have unexpected side-effects like that.
- You can detect whether (2) has been set in the preprocessor; neither (1) nor (3) allows that.
So, in most contexts, prefer the 'enum' over the alternatives. Otherwise, the first and last bullet points are likely to be the controlling factors — and you have to think harder if you need to satisfy both at once.
If you were asking about C++, then you'd use option (1) — the static const — every time.
Why 'defined() || define()' syntax in defining a constant
Due to the || being (in C, Java, C#, php) being "short-circuited" (if the first operand is true, the second is not evaluated because the expression has already been evaluated to be true, no matter what the second is.
So this is classic C-style "brevity" in action. Use as fewer lines of code as possible, even though its doing exactly the same as something more longhand.
So it reads: if defined(...), don't do the define() bit...
if not defined(), do try to evaluate the define() bit and in the process, it'll define the constant.
PHP | define() vs. const
As of PHP 5.3 there are two ways to define constants: Either using the const
keyword or using the define()
function:
const FOO = 'BAR';
define('FOO', 'BAR');
The fundamental difference between those two ways is that const
defines constants at compile time, whereas define
defines them at run time. This causes most of const
's disadvantages. Some disadvantages of const
are:
const
cannot be used to conditionally define constants. To define a global constant, it has to be used in the outermost scope:if (...) {
const FOO = 'BAR'; // Invalid
}
// but
if (...) {
define('FOO', 'BAR'); // Valid
}Why would you want to do that anyway? One common application is to check whether the constant is already defined:
if (!defined('FOO')) {
define('FOO', 'BAR');
}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 BIT_5 = 1 << 5; // Valid since PHP 5.6 and invalid previously
define('BIT_5', 1 << 5); // Always validconst
takes a plain constant name, whereasdefine()
accepts any expression as name. This allows to do things like this:for ($i = 0; $i < 32; ++$i) {
define('BIT_' . $i, 1 << $i);
}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):define('FOO', 'BAR', true);
echo FOO; // BAR
echo foo; // BAR
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:namespace A\B\C;
// To define the constant A\B\C\FOO:
const FOO = 'BAR';
define('A\B\C\FOO', 'BAR');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.const FOO = [1, 2, 3]; // Valid in PHP 5.6
define('FOO', [1, 2, 3]); // Invalid in PHP 5.6 and valid in PHP 7.0
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:
class Foo {
const BAR = 2; // Valid
}
// But
class Baz {
define('QUX', 2); // Invalid
}
Summary
Unless you need any type of conditional or expressional definition, use const
s instead of define()
s - simply for the sake of readability!
What is the difference between #define and const?
The #define
directive is a preprocessor directive; the preprocessor replaces those macros by their body before the compiler even sees it. Think of it as an automatic search and replace of your source code.
A const variable declaration declares an actual variable in the language, which you can use... well, like a real variable: take its address, pass it around, use it, cast/convert it, etc.
Oh, performance: Perhaps you're thinking that avoiding the declaration of a variable saves time and space, but with any sensible compiler optimisation levels there will be no difference, as constant values are already substituted and folded at compile time. But you gain the huge advantage of type checking and making your code known to the debugger, so there's really no reason not to use const variables.
Using a const in const
In versions of PHP prior to 5.6 you cannot do this. The only way to build a constant from constituant parts in those versions of PHP is to use define(). I'd have to look it up to be sure but I don't think you can use define() to define a class/interface constant.
As of PHP 5.6, you will be able to define constants like this, but only if they're defined in terms of other constants.
define() vs const
Related Topics
How to Catch Curl Errors in PHP
PHP Sort Array by Subarray Value
How to Create an Array For Json Using PHP
PHP Associative Array Duplicate Keys
How to Handle the Warning of File_Get_Contents() Function in PHP
Efficient Jpeg Image Resizing in PHP
How to Remove Line Breaks (No Characters!) from the String
Guzzlehttp - How Get the Body of a Response from Guzzle 6
Automatic Post-Registration User Authentication
Reading Very Large Files in PHP
Passing $_Post Values With Curl