765

In PHP, you can declare constants in two ways:

  1. With define keyword

    define('FOO', 1);
    
  2. Using const keyword

    const FOO = 1;
    

  • What are the main differences between those two?
  • When and why should you use one and when use the other?
Your Common Sense
  • 156,878
  • 40
  • 214
  • 345
danjarvis
  • 10,040
  • 3
  • 22
  • 21
  • 11
    About performance (waste of time with micro-optimization as me), see [this answer](http://stackoverflow.com/a/2458276/287948): `const` is two times faster than `define`. About page load time and memory usage: see [this question](http://stackoverflow.com/q/7062137/287948) and [this article](http://imrannazar.com/Memory-Usage-of-Constants-in-PHP)... See also something about opcode cache [here](http://stackoverflow.com/q/23477295/287948). – Peter Krauss May 25 '14 at 07:57

9 Answers9

1185

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 like true, false, null, __FILE__), whereas define() takes any expression. Since PHP 5.6 constant expressions are allowed in const as well:

     const BIT_5 = 1 << 5;    // Valid since PHP 5.6 and invalid previously
     define('BIT_5', 1 << 5); // Always valid
    
  • const takes a plain constant name, whereas define() accepts any expression as name. This allows to do things like this:

     for ($i = 0; $i < 32; ++$i) {
         define('BIT_' . $i, 1 << $i);
     }
    
  • consts are always case sensitive, whereas define() allows you to define case insensitive constants by passing true 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, while define() 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, while define() 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 consts instead of define()s - simply for the sake of readability!

Amritpal Nagra
  • 650
  • 2
  • 6
  • 14
NikiC
  • 100,734
  • 37
  • 191
  • 225
  • 2
    As I know with PHP 5.6 you'll get the possibility to use simple scalar expressions even with the ``const`` language construct - see https://wiki.php.net/rfc/const_scalar_exprs – mabe.berlin Mar 14 '14 at 15:34
  • 11
    Another benefit to using `const` is the lack of quotes, meaning it is formatted the same where it is used in your IDE. – rybo111 Jun 10 '15 at 14:58
  • One more difference - you can not define with a value of array, while with `const` you can. So: `define('C', []);` won't work, while `const C = [];` will. – Kaspars Foigts Jul 20 '15 at 12:32
  • Is there any way you can use access modifiers to declare constants in php.. something like: `public const LIMIT_NUM = 32` – Karue Benson Karue May 12 '16 at 08:29
  • @KarueBensonKarue If it's a class constant, this will be possible in PHP 7.1, see https://wiki.php.net/rfc/class_const_visibility. For freestanding constants this wouldn't make any sense, as we currently don't have a concept of namespace-level visibility. – NikiC May 12 '16 at 08:31
  • 11
    This should be what's in the PHP docs. It's the best explanation I've seen, especially the part most people forget (compile vs. runtime). – James Feb 04 '17 at 23:15
  • 5
    `define('a', $_GET['param']);`, `const b = a;` works perfectly and gets the value while `const c = $_GET['param'];` is invalid. Is `const` really compile time? I hardly think so... (tested on PHP 7.0.7) – mcserep Aug 04 '17 at 09:41
  • 2
    https://wiki.php.net/rfc/case_insensitive_constant_deprecation "_In PHP 8.0: Remove the possibility of declaring case-insensitive constants._" for anyone else venturing here into the future in regards to case sensitivity – Scuzzy Jul 18 '18 at 21:23
  • @mcserep - I had just done that experiment myself, and was now researching why that would be possible if "const" is compile time! Then I found your comment.. :) – Nuno Aug 28 '22 at 12:50
199

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.

Daniel
  • 1,155
  • 1
  • 10
  • 15
ryeguy
  • 65,519
  • 58
  • 198
  • 260
  • 13
    It might be worth mentioning the use of `const` with namespaces. – salathe Mar 15 '10 at 14:54
  • 32
    It should also be noted that PHP5.3 can very much use const in the global scope. – Gordon Dec 01 '10 at 19:10
  • 5.2 can as well. The beauty of consts vs. defines is that you must prefix them with the class name. Using them makes code more readable and prettier. And that's a bonus for me. – lucifurious Dec 16 '10 at 03:01
  • 1
    @ryeguy but what about after PHP 5.3 where const can be used globally just like define? – andho Nov 29 '12 at 08:03
  • 1
    @andho, chalk up another to the PHP dance of one-step-forward, one-step-backward, dance of "improvements". He. :) – Prof. Falken Feb 18 '13 at 15:01
41

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:

  • Consts cannot be defined from an expression. const FOO = 4 * 3; doesn't work, but define('CONST', 4 * 3); does.
  • The name passed to 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.

GordonM
  • 31,179
  • 15
  • 87
  • 129
  • 9
    I couldn't resist asking: Did you consciously define `FORTY_TWO` as 54? – Punchlinern Jul 21 '14 at 09:16
  • 10
    "Six by nine? Forty two? I always said there was something fundamentally wrong with the universe" Check out the works of Douglas Adams if you need a full explanation. – GordonM Jul 21 '14 at 11:04
  • 2
    Oh. I was aware that 42 is the answer life, the universe, and everything but I'd missed the Six by nine-part. Thanks for the explanation! – Punchlinern Jul 21 '14 at 11:10
25

define I use for global constants.

const I use for class constants.

You cannot define into class scope, and with const you can.

Also, with const, it actually becomes a member of the class, and with define, it will be pushed to global scope.

Mark Shust at M.academy
  • 6,300
  • 4
  • 32
  • 50
Jacob Relkin
  • 161,348
  • 33
  • 346
  • 320
23

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;
?>
mattle
  • 339
  • 2
  • 4
20

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.

slartibartfast
  • 528
  • 4
  • 8
  • 2
    Yeah, but `BAR` and `\foo\BAR` are just *not* the same constants. I agree it's really confusing, but if you also consider things like the namespacing logic being consistent this way, and that neither `const` nor `define()` is like a C *macro* (`#define`), then PHP can have some excuse. – Sz. Jun 04 '14 at 09:32
  • 3
    The const notion is *exactly* the way it should behave -- you are in a namespace! You want it without the namespace identifier, then create it outside of the namespace.. This also makes it consistent with the const being defined in a class, even if it uses different syntax. Yes, define is consistent too, in a different way. – Gerard ONeill Mar 18 '15 at 21:35
15

Most of these answers are wrong or are only telling half the story.

  1. You can scope your constants by using namespaces.
  2. You can use the "const" keyword outside of class definitions. However, just like in classes the values assigned using the "const" keyword must be constant expressions.

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
AwesomeBobX64
  • 327
  • 2
  • 4
7

To add on NikiC's answer. const can be used within classes in the following manner:

class Foo {
    const BAR = 1;

    public function myMethod() {
        return self::BAR;
    }
}

You can not do this with define().

Marcus Lind
  • 10,374
  • 7
  • 58
  • 112
6

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?

MrWhite
  • 43,179
  • 8
  • 60
  • 84