define() vs const

Pretty straightforward question: In PHP, when do you use

define('FOO', 1);

and when do you use

const FOO = 1;

What are the main differences between those two?


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 anyways? 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, 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);
    }
    
  • const s are always case sensitive, whereas define() allows you to define case insensitive constants by passing true as the third argument:

    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 defines a constant in the current namespace, while define() has to be passed the full namespace name:

    namespace ABC;
    // To define the constant ABCFOO:
    const FOO = 'BAR';
    define('ABCFOO', '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, valid in PHP 7.0
    
  • As const s are language constructs and defined at compile time they are a bit faster than define() s.

    It is well known that PHP define() s are slow when using a large number of constants. People have even invented things like apc_load_constants() and hidef to get around this.

    const s make the definition of constants approximately twice as fast (on development machines with XDebug turned on even more). Lookup time on the other hand does not change (as both constant types share the same lookup table): Demo.

  • 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!


    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 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 ['fooBAR' => 1, 'BAZ' => 2, 'fooBAZ' => 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.

    链接地址: http://www.djcxy.com/p/3620.html

    上一篇: 返回IEnumerable <T>与IQueryable <T>

    下一篇: define()vs const