2010-02-24 41 views
7

不变,我想定义一个类常量使用现有的常量和字符串的串联。我不能预先定义它,因为只有标量可以用于预定义常量,所以我现在将它作为我的构造函数的一部分,并使用defined()函数检查它是否已经定义。这个解决方案有效,但我的常数现在是不必要的全局。定义类在PHP

有没有一种方法来定义在PHP运行时类常量?

谢谢。

回答

9

参见PHP manual on Class constants

该值必须是一个常量表达式,而不是(例如)一个变量,属性,数学运算的结果,或一个函数调用。

换句话说,这是不可能的。你可以用runkit_constant_add这样做,但这种猴子补丁强烈不鼓励。

+3

考虑使用静态变量。 http://php.net/manual/en/language.oop5.static.php – Matchu 2010-02-24 23:02:28

+1

正在使用define()认为猴子补丁?是否有理由在运行时定义全局常量是可以接受的,而定义类常量是不是? – joshs 2010-02-25 00:31:28

+0

@josh使用define()*因此*不被视为monkey-patching。你必须有一个机制来定义常量,并且在技术上这总是在运行时发生。然而,这种常数的想法是提供*全局可用*,*固定*值,这就是为什么你通常在脚本之上声明常量的原因。以后或者基于某些条件做这样的事情是我会考虑错误的用法,因为那时你使用常量就像变量一样,在重新定义或删除它们的情况下,我会认为它是不好的monkeypatching,因为它改变了PHP的内部行为。 – Gordon 2010-02-25 08:14:20

3

另一种选择是使用魔术方法__get()和__set()来拒绝更改某些变量。这不是一个常量,只是一个只读变量(从其他类的角度来看)。事情是这样的:

// Completely untested, just an idea 
// inspired in part from the Zend_Config class in Zend Framework 
class Foobar { 

    private $myconstant; 

    public function __construct($val) { 
     $this->myconstant = $val; 
    } 

    public function __get($name) { 
     // this will expose any private variables 
     // you may want to only allow certain ones to be exposed 
     return $this->$name; 
    } 

    public function __set($name) { 
     throw new Excpetion("Can't set read-only property"); 
    } 
} 
3

你不能做的正是你想做的事,每Gordon's answer什么。但是,你可以做这样的事情。你只能设置一次:

class MyClass 
{ 
    private static $myFakeConst; 

    public getMyFakeConst() 
    { 
     return self::$myFakeConst; 
    } 

    public setMyFakeConst($val) 
    { 
     if (!is_null(self::$myFakeConst)) 
      throw new Exception('Cannot change the value of myFakeConst.'); 

     self::$myFakeConst = $val; 
    } 
}