访问命名空间公共函数中的私有值

时间:2012-10-02 04:11:50

标签: php namespaces

我有一个只需要计算一次的值。我不能使用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();
}

3 个答案:

答案 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 threadphp.net/manual/en/language.variables.scope.php