如何在 PHP 中创建最终变量?
Posted
技术标签:
【中文标题】如何在 PHP 中创建最终变量?【英文标题】:How to make a final variable in PHP? 【发布时间】:2017-05-13 21:10:28 【问题描述】:我找不到,或者我想错了,但是我需要创建一个无法更改的变量,例如只读,例如:
final $finalVar = 'extremely secret number'; // don't change
$finalVar = 'hacked...'; // THROW I GIANT BIG ERROR HERE !
【问题讨论】:
使用常量。 secure.php.net/manual/en/language.constants.php PHP 手册说明:属性不能声明为final,只有类和方法可以声明为final。 php.net/manual/en/language.oop5.final.php @bishop 正确。对于他们的特定用例,一个常数是有效的。但如果他们着眼于更广泛的范围,那么需要注意这一点。 基本上,你需要一个常量,但你想用美元符号编写代码——这就是它的归结。解决方案非常简单——不要再写美元符号,而是使用为特定目的而存在的语言结构。 【参考方案1】:除了常量(如 cmets 中所述)之外,我能想到的唯一方法是使用带有 private
变量的父子关系
class ParentC
private $var = 'bob';
class ChildC extends ParentC
public function setVar()
// Fatal error: Uncaught Error: Cannot access private property ParentC::$var
echo parent::$var;
请注意,a hacky way around that 使用反射类。但是,在大多数情况下,您不能触摸子类中的 private
父变量
【讨论】:
子类不能改变变量,也不能读取。 @Andrea 是的,但你可以创建一个 getter 方法或重载来解决这个问题【参考方案2】:如果要创建不想更改的变量,可以使用常量:
class MyClass
const VERSION = '2.1'; // This constant can be view outside the class,
// but its value can't be changed even in this class
function myMethod ()
echo self::VERSION; // Inside class
或课外:
echo MyClass::VERSION;
功能方法:
define ('VERSION', '2.1');
echo VERSION;
【讨论】:
【参考方案3】:虽然至少从 2012 年开始就有talk 的只读变量,甚至还有RFC 提出对象,但语言中不存在支持。
实现只读变量(或只读变量的集合,对于某些配置值可能很重要)的一种方法是使用中介容器:
class Readonly
public function __construct(...$vars)
$this->vars;
public function __set($var, $value)
if (array_key_exists($var, $this->vars))
throw new \LogicException("Variable $var is read-only");
else
$this->vars[$var] = $value;
public function __get($var)
return array_key_exists($var, $this->vars) ? $this->vars[$var] : null;
protected $vars = [];
这允许您创建只读变量的容器:
$config = new Readonly('apikey');
$config->apikey = 'A01AB020'; // this works, first time set
echo $config->apikey;
$config->apikey = '00000000'; // boom! it's "final"
【讨论】:
我想知道,如果实际解决方案是使用常量,为什么要这么长的答案?这里没有真正的问题,OP 只是不“想要”编写没有美元符号的代码。这似乎完全是过度杀伤IMO,问题出在椅子上,而不是电脑上。 OP 应该学习使用该语言,如果他没有明确的理由不想使用为特定目的提供的构造,则不要屈从于他的意愿。我没有对此投票,但我认为这是不正确的,因为它会误导未来的访问者。 @Mjh 常量只能是标量或数组(通过 5.6+ 中的const
或 7.0+ 中的 define
)。常量会污染全局命名空间。 const
是编译时的,必须在***范围内声明:不在函数、循环或 try/catch 中。 const
不能从变量初始化,如果 OP 从配置文件中读取,这可能很重要。 (define
可以,但是我们在
@bishop 可以定义类级常量。实际的解决方案是使用常量。无论您是通过全局范围还是类别来管理它们 - 由您决定。没有必要避免常量。如果某些东西是不可变的,那么它就不是变量。如果需要保存标量以外的其他内容,那么使用 IoC 和您演示的技术是可行的方法。总有适合这项工作的工具。【参考方案4】:
使用常量:
defined('VARIABLE') OR define('VARIABLE', 'value');
文档:definedefined
【讨论】:
【参考方案5】:使用PHP 8.1,您现在可以将变量声明为只读:
class MyClass
public readonly string $prop;
public function __construct(string $val)
// Can be intialized only once.
$this->prop = $val;
$myclass = new MyClass('Foo');
$myclass->prop; // Read the property
$myclass->prop = 'Bar'; // Error: Cannot modify readonly property
请注意,您只能将只读应用于类型化属性。
【讨论】:
以上是关于如何在 PHP 中创建最终变量?的主要内容,如果未能解决你的问题,请参考以下文章