【问题标题】:Why can't PHP have a constant object?为什么 PHP 不能有一个常量对象?
【发布时间】:2017-01-31 04:00:21
【问题描述】:

我有一个键值数据库表,其中存储了一些设置。

我想在 PHP 常量对象中包含这些设置,因为它们不应该是可编辑的。

在 PHP7 中我们现在可以这样做:

define('MySettings', array(
    'title' => 'My title'
    // etc
));

// And call it with
echo MySettings['title'];

而且效果很好。

但为什么我不能这样做:

define('MySettings', (object) array('title' => 'My title'));

所以我可以这样称呼它:

echo MySettings->title;
// or
echo MySettings::title;

这只是因为我认为将其输入为对象属性/常量($obj->key$obj::key)比输入为数组($array['key'])更快、更漂亮

这是不可能的吗?

【问题讨论】:

  • 因为从技术上讲,对象不可能是恒定的。它们可以包含代码,这意味着可以更改对象的内部结构,这意味着它们不是恒定的。这就是为什么你有常量 - 这是一个承诺/保证你塞进常量的东西永远不会改变。
  • 目前正在讨论未来版本的 PHP 以支持不可变对象的提案。这将允许程序创建具有一组值的对象,并且一旦创建对象,这些值将是固定的并且不可更改。您可以在此处阅读更多信息:wiki.php.net/rfc/immutability。但是请注意,它现在不在 PHP (7.0) 中,也不会在即将发布的 7.1 版本中。根据讨论的进展情况,它可能会进入 7.2,但在现阶段对此做出任何承诺还为时过早。

标签: php object constants


【解决方案1】:

对于 PHP,所有对象都是可变的。由于常量不应在运行时更改,但对象可以更改,因此目前不支持对象常量。

phpdoc about constants中声明:

当使用 const 关键字时,只有标量数据(布尔值、整数、 float 和 string) 可以包含在 PHP 5.6 之前的常量中。从 PHP 5.6 起,可以将常量定义为标量 表达式,也可以定义一个数组常量。它是 可以将常量定义为资源,但应该避免, 因为它可能会导致意想不到的结果。

虽然数组存在不一致之处,但没有给出为什么允许使用数组常量的原因。 (我什至认为这是一个糟糕的调用。)必须注意array-constants 是不可变的,因此尝试更改它们会导致致命错误,如 php7 中的这段代码所示:

<?php
$aNormalMutableArray = ['key' => 'original'];
$aNormalMutableArray['key'] = 'changed';
echo $aNormalMutableArray['key'];

define(
    'IMMUTABLE_ARRAY',
    [
        'key' => 'original',
    ]
);
IMMUTABLE_ARRAY['key'] = 'if I am an array, I change; if I am a constant I throw an error';
echo IMMUTABLE_ARRAY['key'];

投掷:

PHP Fatal error:  Cannot use temporary expression in write context
in ~/wtf.php on line 12

为什么不能定义具有类似错误的对象常量?一个人必须要问那存在的力量。

我建议远离数组和对象作为常量。而是创建一个不可变对象或改用immutable collections

由于您正在寻找某种语法,因此已经有了class constants 的概念。

<?php
class MyClass
{
    const CONSTANT = 'constant value';

    function showConstant() {
        echo  self::CONSTANT . "\n";
    }
}

echo MyClass::CONSTANT . "\n";

$classname = "MyClass";
echo $classname::CONSTANT . "\n"; // As of PHP 5.3.0

$class = new MyClass();
$class->showConstant();

echo $class::CONSTANT."\n"; // As of PHP 5.3.0

也可以在接口中定义它们。

【讨论】:

  • 感谢您的回答。在类常量中,我必须对 php 文件中的所有常量进行“硬编码”,但我想让它动态化,所以当我在数据库设置表中创建新行时,它可以作为设置使用。但这对于类常量是不可能的。如果有道理。这就是我使用常量数组的原因。
  • @user245734 虽然很感激,但 cmets 并不意味着感谢。投票或接受答案就足够了:)
  • @user245734 根据您关于避免硬编码所有常量的后续问题:这是一个后续问题,并不完全在您原始问题的范围内。随意提出一个新问题。
  • -1 "常量对象没有意义,因为对象根据定义是可变的。"常量对象可以很有意义,尤其是。与价值对象。其次,“根据定义可变”并不能真正解释任何事情。数组“根据定义是可变的”,但您继续证明常量数组神奇地不可变。
  • @leo-the-manic 我可能用词有误。我并不是说不可变对象作为一种设计选择是一个坏主意。我是说在 php 作为一种语言的上下文中,它认为所有对象都是可变的。是的,PHP 确实神奇地为数组常量创建了一个不可变数组。但它不适用于对象。我展示了 PHP 的不一致之处。他们将来可能会通过使用 ImmutableObject 或删除数组常量来解决此问题。或者这可能是php 上的另一个条目;)这是否阐明了我的意图?
猜你喜欢
  • 2021-02-12
  • 2016-07-09
  • 1970-01-01
  • 1970-01-01
  • 2022-01-01
相关资源
最近更新 更多