Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/259.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/backbone.js/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php define()与const_Php_Constants - Fatal编程技术网

Php define()与const

Php define()与const,php,constants,Php,Constants,在PHP中,何时使用 define('FOO', 1); 你什么时候用 const FOO = 1; ? 这两者之间的主要区别是什么?defineI用于全局常量 const我用于类常量 您不能将定义到类范围中,使用const可以。不用说,您不能在类范围之外使用const 另外,使用const,它实际上成为类的一个成员,使用define,它将被推到全局范围。在PHP 5.3之前,const不能在全局范围内使用。您只能在类中使用它。当您想要设置某种常量选项或与该类相关的设置时,应该使用此选项。或

在PHP中,何时使用

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文件
    ),而
    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
    s始终区分大小写,而
    define()
    允许您通过将
    true
    作为第三个参数来定义不区分大小写的常量(注意:从PHP 7.3.0开始,不推荐使用定义不区分大小写的常量,从PHP 8.0.0开始删除):

所以,这是事情不好的一面。现在让我们看看我个人为什么总是使用
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
    常量也可以是数组,而
    define()
    还不支持数组。但是,在PHP7中,这两种情况都支持数组

     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的答案是最好的,但我要在使用名称空间时添加一个不太明显的警告,这样你就不会被意外行为抓住。要记住的是,定义是al
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';