Php define()与const
在PHP中,何时使用Php define()与const,php,constants,Php,Constants,在PHP中,何时使用 define('FOO', 1); 你什么时候用 const FOO = 1; ? 这两者之间的主要区别是什么?defineI用于全局常量 const我用于类常量 您不能将定义到类范围中,使用const可以。不用说,您不能在类范围之外使用const 另外,使用const,它实际上成为类的一个成员,使用define,它将被推到全局范围。在PHP 5.3之前,const不能在全局范围内使用。您只能在类中使用它。当您想要设置某种常量选项或与该类相关的设置时,应该使用此选项。或
define('FOO', 1);
你什么时候用
const FOO = 1;
?
这两者之间的主要区别是什么?
define
I用于全局常量
const
我用于类常量
您不能将
定义到类范围中,使用const
可以。不用说,您不能在类范围之外使用const
另外,使用
const
,它实际上成为类的一个成员,使用define
,它将被推到全局范围。在PHP 5.3之前,const
不能在全局范围内使用。您只能在类中使用它。当您想要设置某种常量选项或与该类相关的设置时,应该使用此选项。或者您可能想创建某种枚举
define
可以用于相同的目的,但只能在全局范围内使用。它只能用于影响整个应用程序的全局设置
好的const
用法的一个例子是去掉幻数。看一看。例如,当需要指定提取类型时,可以键入PDO::fetch_ASSOC
。如果不使用const,您最终会键入类似35
(或者定义为FETCH\u ASSOC
的内容)。这对读者来说毫无意义
良好的
define
用法的一个示例可能是指定应用程序的根路径或库的版本号 我相信从PHP5.3开始,您可以在类之外使用const
,如第二个示例所示:
从PHP 5.3开始,有两种方法:使用
const
关键字或使用函数:
const FOO = 'BAR';
define('FOO', 'BAR');
这两种方法的根本区别在于const
在编译时定义常量,而define
在运行时定义常量。这导致了大部分常量的缺点。const
的一些缺点是:
不能用于有条件地定义常量。要定义全局常量,必须在最外层范围内使用它:const
你为什么要这么做?一个常见的应用是检查常量是否已定义:if (...) { const FOO = 'BAR'; // Invalid } // but if (...) { define('FOO', 'BAR'); // Valid }
if (!defined('FOO')) { define('FOO', 'BAR'); }
接受静态标量(数字、字符串或其他常量,如const
、true
、false
、null
),而\uuuuuuuuuuu文件
接受任何表达式。由于PHP 5.6常量表达式也可以在define()
中使用:const
const BIT_5 = 1 << 5; // Valid since PHP 5.6 and invalid previously define('BIT_5', 1 << 5); // Always valid
s始终区分大小写,而const
允许您通过将define()
作为第三个参数来定义不区分大小写的常量(注意:从PHP 7.3.0开始,不推荐使用定义不区分大小写的常量):true
const
,除非出现上述情况之一:
读起来更漂亮。它是一种语言构造而不是函数,并且与在类中定义常量的方式一致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');
- 由于PHP5.6
常量也可以是数组,而const
还不支持数组。但是,在PHP7中,这两种情况都支持数组define()
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
也可以在类或接口中用于定义一个类或接口常量<代码>定义不能用于此目的:
class Foo {
const BAR = 2; // Valid
}
// But
class Baz {
define('QUX', 2); // Invalid
}
摘要
除非您需要任何类型的条件定义或表达式定义,否则请使用
const
s而不是define()
s-这仅仅是为了可读性 是的,const是在编译时定义的,因为nikic states不能像define()的那样被分配一个表达式。但是const也不能有条件地声明(出于同样的原因)。也就是说,你不能这样做:
if (/* some condition */) {
const WHIZZ = true; // CANNOT DO THIS!
}
而您可以使用define()。所以,这并不是个人喜好的问题,两者都有正确和错误的使用方法
作为旁白。。。我希望看到某种类型的类常量可以被分配一个表达式,一种可以被隔离到类的define()。我知道这已经得到了回答,但是当前的回答都没有提到名称空间以及它如何影响常量和定义 从PHP5.3开始,const和defines在很多方面都是相似的。然而,仍然存在一些重要的差异:
- 无法从表达式中定义常量<代码>常量FOO=4*3代码>不起作用,但
定义('CONST',4*3)代码>可以李>
- 传递给
的名称必须包括要在该名称空间中定义的名称空间define
- 传递给
namespace foo
{
const BAR = 1;
define('BAZ', 2);
define(__NAMESPACE__ . '\\BAZ', 3);
}
namespace {
var_dump(get_defined_constants(true));
}
用户子数组的内容将是['foo\\BAR'=>1,'BAZ'=>2,'foo\\BAZ'=>3]
==更新===
即将发布的PHP5.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;
但是,您仍然无法根据变量或函数返回定义常量,所以
const RND = mt_rand();
const CONSTVAR = $var;
仍然会被淘汰 NikiC的答案是最好的,但我要在使用名称空间时添加一个不太明显的警告,这样你就不会被意外行为抓住。需要记住的是,除非您exp
namespace foo
{
const BAR = 1;
define('BAZ', 2);
define(__NAMESPACE__ . '\\BAZ', 3);
}
namespace {
var_dump(get_defined_constants(true));
}
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;
const RND = mt_rand();
const CONSTVAR = $var;
<?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);
}
?>
What kind of bar is a cheers bar?
What kind of bar is a wonka bar?
willy wonka
three cheers
const AWESOME = 'Bob'; // Valid
const AWESOME = whatIsMyName(); // Invalid (Function call)
const WEAKNESS = 4+5+6; // Invalid (Arithmetic)
const FOO = BAR . OF . SOAP; // Invalid (Concatenation)
define('AWESOME', whatIsMyName()); // Valid
define('WEAKNESS', 4 + 5 + 6); // Valid
define('FOO', BAR . OF . SOAP); // Valid
class Foo {
const BAR = 1;
public function myMethod() {
return self::BAR;
}
}
/**
* My foo-bar const
* @var string
*/
const FOO = 'BAR';