我有一个只需要计算一次的值。我不能使用const
来声明它,因为我需要运行一些函数来进行初始计算。我希望能够以某种受保护的方式存储它并在(命名空间的)全局函数中访问它。这样做的好方法是什么?这就是我所拥有的:
选项1 - 效果很好但仅适用于常量,所以我不能使用它:
<?php
namespace my;
const PREFIX = 'example';
/**
* my\get_prefix()
*/
function get_prefix () {
return PREFIX;
}
选项2 - 命名空间函数从预配置的命名空间公共静态类访问值:
<?php
namespace my;
class Hash {
public static $prefix;
public static function configure () {
self::$prefix = call_user_func(function () {
// calculate and return a string
});
}
}
Hash::configure();
/**
* my\get_prefix()
*/
function get_prefix () {
return Hash::$prefix;
}
选项3 - 类似于#2,但此处配置在第一次调用get_prefix
时运行,并且每次都被检查为字符串:
<?php
namespace my;
class Hash {
public static $prefix;
}
/**
* my\get_prefix()
*/
function get_prefix () {
if ( is_string(Hash::$prefix) )
return Hash::$prefix;
Hash::$prefix = call_user_func(function () {
// calculate and return a string
});
return Hash::$prefix;
}
选项4 - 完全受静态方法/私有var保护,但如果通过my\get_prefix()
调用则添加额外的函数调用:
<?php
namespace my;
class Hash {
private static $prefix;
public static function configure () {
if ( isset(self::$prefix) ) return;
self::$prefix = call_user_func(function () {
// calculate and return a string
});
}
public static function get_prefix () {
return self::$prefix;
}
}
Hash::configure();
/**
* my\get_prefix()
*/
function get_prefix () {
return Hash::get_prefix();
}
答案 0 :(得分:1)
我会通过组合选项#3和#4(延迟加载)来解决它:
class Hash
{
private static $prefix;
public static function getPrefix()
{
if (is_null(self::$prefix)) {
// the value is not set yet, so generate it
self::$prefix = function_that_generates_prefix();
}
return self::$prefix;
}
}
$prefix = Hash::getPrefix();
答案 1 :(得分:1)
乍一看,这看起来像是懒人装载的绝佳选择。
namespace My;
class Hash
{
protected static $prefix;
public static function getPrefix()
{
if (null === self::$prefix) {
self::$prefix = calculate_and_return_a_string();
}
return self::$prefix;
}
}
$prefix = My\Hash::getPrefix();
有几点需要注意。首先,我将My\Hash::$prefix
的可见度从private
更改为protected
。一般来说,除非有充分理由使用private
,否则我更倾向于使用protected
变量。
其次,您可能希望重新评估My\Hash
类和calculate_and_return_a_string()
函数(您使用call_user_func
)之间的关系。也许找到一种方法来注入计算值,这将使类与函数分离并删除额外的依赖。
最后,重新评估是否需要将它放在自己的类中可能是值得的。如果您只是使用它来存储和注册单个变量,那么最好使用注册表或类似的东西。当然,我无法看到整个背景,所以只有你知道这是否适用。
答案 2 :(得分:0)
OMG我刚刚发现static
关键字可用于创建一个私有范围,每次调用该函数时都可以重新访问:
<?php
namespace my;
/**
* my\get_prefix()
*/
function get_prefix () {
static $prefix;
if ( !isset($prefix) ) {
// calculate $prefix (only runs once)
}
return $prefix;
}
请参阅this thread和php.net/manual/en/language.variables.scope.php