【问题标题】:Php define() Constants Inside Namespace Clarification命名空间内的 Php define() 常量说明
【发布时间】:2013-08-17 08:23:30
【问题描述】:

正如标题所述,我真的很想澄清这一点。我已经阅读了一些关于这个主题的文章和帖子,但有些东西对我来说并不合适。我会补充一点,我对 PHP 有点陌生。好的,这就是我想了解的内容;

namespace Information;
define('ROOT_URL', 'information/');
define('OFFERS_URL', ROOT_URL . 'offers/');

namespace Products;
define('ROOT_URL', 'products/');
define('OFFERS_URL', ROOT_URL . 'offers/');

我希望常量是可构造的,即从基本常量构建常量,这就是我使用define('NAME', value);的原因。

我的问题是,ROOT_URL 的值会产生相对于其命名空间的值吗?像这样;

$info_offers_url = \Information\OFFERS_URL;  ('information/offers/')
$prod_offers_url = \Products\OFFERS_URL;     ('products/offers/')

或者定义();将 ROOT_URL 放在全局范围内,因此我不应该这样做吗?有更好的做法吗?

非常感谢所有帮助。

【问题讨论】:

  • 引自名称:Like superglobals, the scope of a constant is global. 它们没有命名空间
  • @Mark Ba​​ker,非常感谢。我如何将您的回答标记为答案,然后打勾?只是想给你更多的代表点

标签: php namespaces constants


【解决方案1】:

define() 将完全按照指定定义常量。

基本知识:要在命名空间中定义常量,您必须在调用 define() 时指定命名空间,即使您是从命名空间中调用 define()

下面的例子会一目了然。

以下代码将在全局命名空间中定义常量MESSAGE(即\MESSAGE)。

<?php
    namespace test;
    define(‘MESSAGE’, ‘Hello world!’);
?>

以下代码将在“test”命名空间中定义两个常量。

<?php
    namespace test;
    define(‘test\HELLO’, ‘Hello world!’);
    define(__NAMESPACE__ . ‘\GOODBYE’, ‘Goodbye cruel world!’);
?>

在太空中使用

namespace Product;
use const test\HELLO;

【讨论】:

    【解决方案2】:

    如果你想在命名空间中定义一个常量,你需要在你对define()的调用中指定命名空间,即使你是从一个命名空间中调用define()。下面我试过的例子会很清楚。

    以下代码将在全局命名空间中定义常量“CONSTANTA”(即“\CONSTANTA”)。

    <?php
    namespace mynamespace;
    define('CONSTANTA', 'Hello A!');
    ?>
    

    如果你想为命名空间定义常量,你可以像这样定义

    <?php
    namespace test;
    define('test\HELLO', 'Hello world!');
    define(__NAMESPACE__ . '\GOODBYE', 'Goodbye cruel world!');
    ?>
    

    否则,您可以使用const 在当前命名空间中定义一个常量:

    <?php
    
    namespace NS;
    
    define('C', "I am a constant");
    const A = "I am a letter";
    
    echo __NAMESPACE__, , PHP_EOL; // NS
    echo namespace\A, PHP_EOL; // I am a letter
    echo namespace\C, PHP_EOL; // PHP Fatal error:  Uncaught Error: Undefined constant 'NS\C'
    

    取自Manual

    【讨论】:

    • 对于它的价值,这是来自用户 cmets,而不是来自实际手册。
    • 您还可以导入命名空间常量:use const Foo\BAR。注意 const.
    • 能够导入它们也证明它是真正的命名空间,而不是名称中允许的反斜杠。
    • 顺便说一句,通过显式写出绝对路径来定义(即以'\'开头,例如define('\test\HELLO', 'Hello world!');不起作用。
    【解决方案3】:

    使用命名空间常量相当容易,但您必须使用 const 关键字。

    那么就可以直接用反斜杠\调用常量了:

    namespace Dummy\MyTime;
    const MONTHS = 12;
    const WEEKS = 52;
    const DAYS = 365;
    
    
    namespace Test;
    use Dummy\MyTime;
    
    $daysPerWeek = MyTime\DAYS / MyTime\WEEKS;
    $daysPerMonth = MyTime\DAYS / MyTime\MONTHS;
    
    echo "Days per week: $daysPerWeek\n"; // 7.0192307692308
    echo "Days per month: $daysPerMonth\n"; // 30.416666666667
    

    我认为这比使用define 更干净。

    话虽如此,只有在使用 PHP >= 5.6 时,您想要的(将标量表达式分配给常量)才会起作用:

    namespace Information;
    const ROOT_URL = 'information/';
    const OFFERS_URL = ROOT_URL . 'offers/';
    
    namespace Products;
    const ROOT_URL = 'products/';
    const OFFERS_URL = ROOT_URL . 'offers/';
    
    namespace Test;
    $info_offers_url = \Information\OFFERS_URL; // information/offers/
    $prod_offers_url = \Products\OFFERS_URL;    // products/offers/
    

    希望对你有帮助。

    来源:http://php.net/manual/en/migration56.new-features.php

    【讨论】:

    • 这个答案虽然不是直接针对define(),但还是很有用的。
    • 不太确定“必须”,我可以为另一个命名空间定义一个常量,然后通过 use 将其导入第三个命名空间。 define('Foo\BAR', 'baz');use const Foo\BAR;,甚至可以从任何命名空间访问这些:echo \Foo\BAR;
    • @Progrock 感谢您的澄清,我在写答案时并不知道 :)
    猜你喜欢
    • 2012-11-15
    • 2013-06-12
    • 2010-11-08
    • 2014-01-24
    • 1970-01-01
    • 1970-01-01
    • 2011-05-10
    • 2011-01-05
    • 1970-01-01
    相关资源
    最近更新 更多