php 定义()与常量

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2447791/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 06:31:21  来源:igfitidea点击:

define() vs. const

phpconstconstants

提问by danjarvis

In PHP, when do you use

在 PHP 中,你什么时候使用

define('FOO', 1);

and when do you use

你什么时候使用

const FOO = 1;

?

?

What are the main differences between those two?

这两者之间的主要区别是什么?

回答by NikiC

As of PHP 5.3 there are two ways to define constants: Either using the constkeyword or using the define()function:

从 PHP 5.3 开始,有两种定义常量的方法:使用const关键字或使用define()函数:

const FOO = 'BAR';
define('FOO', 'BAR');

The fundamental difference between those two ways is that constdefines constants at compile time, whereas definedefines them at run time. This causes most of const's disadvantages. Some disadvantages of constare:

这两种方式的根本区别在于const在编译时定义常量,而define在运行时定义它们。这导致了大多数const的缺点。的一些缺点const是:

  • constcannot 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');
    }
    
  • constaccepts 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 constas well:

    const BIT_5 = 1 << 5;    // Valid since PHP 5.6 and invalid previously
    define('BIT_5', 1 << 5); // Always valid
    
  • consttakes 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 trueas the third argument (Note: defining case-insensitive constants is deprecated as of PHP 7.3.0.):

    define('FOO', 'BAR', true);
    echo FOO; // BAR
    echo foo; // BAR
    
  • const不能用于有条件地定义常量。要定义全局常量,必须在最外层范围内使用它:

    if (...) {
        const FOO = 'BAR';    // Invalid
    }
    // but
    if (...) {
        define('FOO', 'BAR'); // Valid
    }
    

    你为什么要这样做?一种常见的应用是检查常量是否已经定义:

    if (!defined('FOO')) {
        define('FOO', 'BAR');
    }
    
  • const接受静态标量(数字、字符串或其他常量,如true, false, null, __FILE__),而define()接受任何表达式。由于 PHP 5.6 常量表达式也被允许const

    const BIT_5 = 1 << 5;    // Valid since PHP 5.6 and invalid previously
    define('BIT_5', 1 << 5); // Always valid
    
  • const采用普通常量名称,而define()接受任何表达式作为名称。这允许做这样的事情:

    for ($i = 0; $i < 32; ++$i) {
        define('BIT_' . $i, 1 << $i);
    }
    
  • consts 始终区分大小写,而define()允许您通过true作为第三个参数传递来定义不区分大小写的常量(注意:定义不区分大小写的常量自 PHP 7.3.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 constunless one of the above situations occurs:

所以,这是事情的不好的一面。现在来看看我个人总是使用的原因,const除非出现上述情况之一:

  • constsimply 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.
  • constdefines 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 constconstants 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
    
  • const只是读起来更好。它是一种语言结构而不是函数,并且与您在类中定义常量的方式一致。
  • const作为一种语言结构,可以通过自动化工具进行静态分析。
  • const在当前命名空间中定义一个常量,同时define()必须传递完整的命名空间名称:

    namespace A\B\C;
    // To define the constant A\B\C\FOO:
    const FOO = 'BAR';
    define('A\B\C\FOO', 'BAR');
    
  • 由于 PHP 5.6const常量也可以是数组,define()目前还不支持数组。但是,在 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 constcan also be used within a class or interface to define a class constantor interface constant. definecannot be used for this purpose:

最后,注意const也可以在类或接口内使用来定义类常量或接口常量。define不能用于此目的:

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!

除非您需要任何类型的条件或表达式定义,否则使用consts 而不是define()s - 只是为了可读性!

回答by ryeguy

Until PHP 5.3, constcould 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.

在 PHP 5.3 之前,const不能在全局范围内使用。您只能在类中使用它。当您想要设置某种常量选项或与该类相关的设置时,应该使用它。或者,也许您想创建某种枚举。

definecan 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.

define可以用于相同的目的,但只能在全局范围内使用。它应该只用于影响整个应用程序的全局设置。

An example of good constusage 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_ASSOCis defined as). This makes no sense to the reader.

一个良好const用法的例子是摆脱幻数。看看PDO 的常量。例如,当您需要指定提取类型时,您可以输入PDO::FETCH_ASSOC。如果没有使用常量,你最终会输入类似35(或任何FETCH_ASSOC定义为)的内容。这对读者来说毫无意义。

An example of good defineusage is maybe specifying your application's root path or a library's version number.

一个良好define用法的例子可能是指定应用程序的根路径或库的版本号。

回答by GordonM

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:

从 PHP 5.3 开始,consts 和defines 在大多数方面是相似的。但是,仍然存在一些重要差异:

  • Consts cannot be defined from an expression. const FOO = 4 * 3;doesn't work, but define('CONST', 4 * 3);does.
  • The name passed to definemust include the namespace to be defined within that namespace.
  • 不能从表达式定义常量。 const FOO = 4 * 3;不起作用,但define('CONST', 4 * 3);确实如此。
  • 传递给的名称define必须包括要在该名称空间中定义的名称空间。

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].

用户子数组的内容将为['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:

即将推出的 PHP 5.6 将允许使用const. 您现在可以根据表达式定义常量,前提是这些表达式由其他常量或文字组成。这意味着以下内容应自 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.

还是会出来。

回答by mattle

I believe that as of PHP 5.3, you can use constoutside of classes, as shown here in the second example:

我相信从 PHP 5.3 开始,您可以const在类之外使用,如第二个示例所示:

http://www.php.net/manual/en/language.constants.syntax.php

http://www.php.net/manual/en/language.constants.syntax.php

<?php
// Works as of PHP 5.3.0
const CONSTANT = 'Hello World';

echo CONSTANT;
?>

回答by Jacob Relkin

defineI use for global constants.

define我用于全局常量。

constI use for class constants.

const我用于类常量。

You cannot defineinto class scope, and with constyou can. Needless to say, you cannot use constoutside class scope.

你不能define进入类范围,const你可以。不用说,您不能使用const外部类范围。

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

此外,使用const,它实际上成为类的成员,使用define,它将被推送到全局范围。

回答by slartibartfast

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 alwaysin 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 :

NikiC 的答案是最好的,但让我在使用命名空间时添加一个不明显的警告,这样您就不会被意外行为所困扰。要记住的事情是定义始终在全局命名空间中,除非您明确添加命名空间作为定义标识符的一部分。不明显的是命名空间标识符胜过全局标识符。所以 :

<?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.

对我来说,这让整个 const 概念毫无必要地令人困惑,因为在许多其他语言中 const 的想法是,无论您在代码中的哪个位置,它总是相同的,而 PHP 并不能真正保证这一点。

回答by AwesomeBobX64

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.
  1. 您可以使用命名空间来限定常量的范围。
  2. 您可以在类定义之外使用“const”关键字。但是,就像在类中一样,使用“const”关键字分配的值必须是常量表达式。

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(),如下所示:

define('AWESOME', whatIsMyName()); // Valid
define('WEAKNESS', 4 + 5 + 6); // Valid
define('FOO', BAR . OF . SOAP); // Valid

回答by MrWhite

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:

是的,const 是在编译时定义的,因为 nikic 状态不能像define() 那样分配表达式。但是也不能有条件地声明 const 的(出于同样的原因)。IE。你不可以做这个:

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.

而你可以使用define()。所以,这并没有真正归结为个人喜好,两者都有正确和错误的使用方式。

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?

顺便说一句......我想看到某种可以分配表达式的类const,一种可以与类隔离的define()?

回答by Marcus Lind

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

添加NikiC的答案。const可以通过以下方式在类中使用:

class Foo {
    const BAR = 1;

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

You can not do this with define().

你不能用define().

回答by Николай Лубышев

No one says anything about php-doc, but for me that is also a very significant argument for the preference of const:

没有人对 php-doc 发表任何意见,但对我来说,这也是一个非常重要的论据,即偏好const

/**
 * My foo-bar const
 * @var string
 */
const FOO = 'BAR';