为什么';PHP是否允许私有常量?

为什么';PHP是否允许私有常量?,php,constants,private,Php,Constants,Private,为什么PHP不允许私有常量 我知道有一些变通方法,比如使用私有静态属性 然而,从OOP或软件设计的角度来看,原因是什么 为什么PHP不允许私有常量 在PHP中,常量是接口的一部分,接口始终是公共的(这就是接口的用途) 我也看到了 我很确定这就是设计明智的原因 关于你问题下的评论,有人想降低常数的可见性,以便以后更改它们,我想说这听起来更像是一个变量,而不是一个不改变其值的常数。它是恒定的。tl;tr 不实现私有常量的理由是什么? class a { /*private*

为什么PHP不允许私有常量

我知道有一些变通方法,比如使用私有静态属性

然而,从OOP或软件设计的角度来看,原因是什么

为什么PHP不允许私有常量

在PHP中,常量是接口的一部分,接口始终是公共的(这就是接口的用途)

我也看到了

我很确定这就是设计明智的原因

关于你问题下的评论,有人想降低常数的可见性,以便以后更改它们,我想说这听起来更像是一个变量,而不是一个不改变其值的常数。它是恒定的。

tl;tr

不实现私有常量的理由是什么?

    class a { 
        /*private*/ const k = 'Class private constant k from a'; 
    }

    class b extends a
    {
        const k = 'Overridden private constant a::k with Class constant k from b';

        const k_a = parent::k; 

        // fatal error: self-referencing constant
        #const k_selfref = self::k . ' + ' . self::k_selfref; 

        // fatal error: "static::" is not allowed in compile-time constants
        #const k_staticref = static::k; 
    }

    // direct static access would no longer work, if private 
    // you need an instance of the parent class or an inheriting class instance
    echo a::k; 
    echo b::k;  
    echo b::k_a;

    $obj_b = new b;
    echo $obj_b::k;
    echo $obj_b::k_a;
这是一个好问题

<强>他们真的考虑过了吗?< /强>

    class a { 
        /*private*/ const k = 'Class private constant k from a'; 
    }

    class b extends a
    {
        const k = 'Overridden private constant a::k with Class constant k from b';

        const k_a = parent::k; 

        // fatal error: self-referencing constant
        #const k_selfref = self::k . ' + ' . self::k_selfref; 

        // fatal error: "static::" is not allowed in compile-time constants
        #const k_staticref = static::k; 
    }

    // direct static access would no longer work, if private 
    // you need an instance of the parent class or an inheriting class instance
    echo a::k; 
    echo b::k;  
    echo b::k_a;

    $obj_b = new b;
    echo $obj_b::k;
    echo $obj_b::k_a;
我不知道

  • 在搜索PHP内部邮件列表时,我没有找到关于此主题的任何内容。 除非一个内部成员说出来,否则我们永远不会知道

    关于该语言的历史——一个比特1:1C方法包装,一些比特来自Perl(regexp),一些比特来自Java(oop)——在寻找新的语言特性时,这个想法可能突然出现

    我将把“私有常量”的概念与VisualBasic或Java联系起来。我怀疑VB对PHP有很大或任何影响。VB允许在“模块”中定义“私有常量”——这是默认的访问范围。VisualBasic不允许在接口和名称空间中使用常量(但PHP允许)

    PHP可能包含一些来自Java的OOP概念,但有一个很大的区别:常量是Java中的变量。其访问修饰符/可见性级别为:“公共、私有、最终和静态”。私有常量声明如下所示:
    “private static final String MYCONST=”My constant“
    这是OOP-故事的结尾。与此相比,PHP常量访问感觉更粗糙-但它更简单,您仍然有解决方法

  • 报告中的第一条评论是:

    这看起来很明显,但类常量总是公开可见的。 它们不能成为私人或受保护的。我看不出有这样的说法 在任何地方的文档中

    为什么这很明显?“为什么类常量默认为public而不是private?” 也许,这是缺少的语言特性,因为并非所有的类成员都可以正确隐藏。 他是对的,当你从Java或VB到PHP,这个问题就会出现

  • 让我们看一下。PHP的当前实现状态是:类常量始终是公共的和静态的。因此,一次又一次地,Facebook为编写如此详细的文档而赞不绝口:作者考虑了不同的可见性或访问控制级别

让我们看看接口、类、常量和可见性:

  • “const”与“private static”的概念有何不同

    静态变量可以更改,常量不能更改。 不能将函数的运行时值分配给常量(
    const a=sprintf('foo%s','bar');
    ),而是分配给私有静态变量

  • 接口可能有常量-无法重写它们

  • 类可能有一个常量,该常量可能被继承类/接口覆盖

  • 还有一种称为“常量接口模式”的OOP模式——它描述了仅用于定义常量的接口的使用,并让类实现该接口,以实现对这些常量的方便语法访问

    提供了一个接口,因此您可以描述一组函数,然后在实现类中隐藏函数的最终实现。这允许您更改函数的实现,而无需更改使用方式。接口的存在是为了公开API

    并且通过在接口中定义常量并通过类实现接口,常量成为API的一部分。事实上,您将实现细节泄漏到API中。这就是为什么有些人认为这是反模式,其中Joshua Bloch(java)。

现在,让我们结合一些概念,看看它们是否合适

让我们假设我们试图避免上面的批评,然后您需要引入一种语法,允许对常量进行限定访问,但在API中隐藏常量。您可以通过可见性级别提出“访问控制”:“公共、私有、受保护、朋友、敌人”“。目标是防止包或类的用户依赖该包或类的实现的不必要细节。这都是关于隐藏实现细节的,对吗

那么“接口”中的“私有常量”呢?

    class a { 
        /*private*/ const k = 'Class private constant k from a'; 
    }

    class b extends a
    {
        const k = 'Overridden private constant a::k with Class constant k from b';

        const k_a = parent::k; 

        // fatal error: self-referencing constant
        #const k_selfref = self::k . ' + ' . self::k_selfref; 

        // fatal error: "static::" is not allowed in compile-time constants
        #const k_staticref = static::k; 
    }

    // direct static access would no longer work, if private 
    // you need an instance of the parent class or an inheriting class instance
    echo a::k; 
    echo b::k;  
    echo b::k_a;

    $obj_b = new b;
    echo $obj_b::k;
    echo $obj_b::k_a;
这实际上可以解决上面的批评,对吗? 但将界面与“私有”相结合是没有意义的。这些概念是相反的。 这就是界面不允许“私有”访问/可见性级别的原因。 “接口”中的“私有”常量也将是互斥的

那么“类”中的“私有常量”呢?

    class a { 
        /*private*/ const k = 'Class private constant k from a'; 
    }

    class b extends a
    {
        const k = 'Overridden private constant a::k with Class constant k from b';

        const k_a = parent::k; 

        // fatal error: self-referencing constant
        #const k_selfref = self::k . ' + ' . self::k_selfref; 

        // fatal error: "static::" is not allowed in compile-time constants
        #const k_staticref = static::k; 
    }

    // direct static access would no longer work, if private 
    // you need an instance of the parent class or an inheriting class instance
    echo a::k; 
    echo b::k;  
    echo b::k_a;

    $obj_b = new b;
    echo $obj_b::k;
    echo $obj_b::k_a;
有好处吗?

    class a { 
        /*private*/ const k = 'Class private constant k from a'; 
    }

    class b extends a
    {
        const k = 'Overridden private constant a::k with Class constant k from b';

        const k_a = parent::k; 

        // fatal error: self-referencing constant
        #const k_selfref = self::k . ' + ' . self::k_selfref; 

        // fatal error: "static::" is not allowed in compile-time constants
        #const k_staticref = static::k; 
    }

    // direct static access would no longer work, if private 
    // you need an instance of the parent class or an inheriting class instance
    echo a::k; 
    echo b::k;  
    echo b::k_a;

    $obj_b = new b;
    echo $obj_b::k;
    echo $obj_b::k_a;
  • 类中的私有常量不会在API中公开。这是很好的OOP

  • 从外部访问父常量将是类和/或继承访问

    echo a::k
    ,现在可以工作了-可能会以“致命错误:尝试在没有类实例或继承的情况下访问私有常量”作为响应

  • (如果没有为常量分配运行时值,这可能仍然只在编译时起作用。但我不确定这一点。)

有注意事项吗?

    class a { 
        /*private*/ const k = 'Class private constant k from a'; 
    }

    class b extends a
    {
        const k = 'Overridden private constant a::k with Class constant k from b';

        const k_a = parent::k; 

        // fatal error: self-referencing constant
        #const k_selfref = self::k . ' + ' . self::k_selfref; 

        // fatal error: "static::" is not allowed in compile-time constants
        #const k_staticref = static::k; 
    }

    // direct static access would no longer work, if private 
    // you need an instance of the parent class or an inheriting class instance
    echo a::k; 
    echo b::k;  
    echo b::k_a;

    $obj_b = new b;
    echo $obj_b::k;
    echo $obj_b::k_a;
  • 我们将失去对常量的直接静态访问