2

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

3 回答 3

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();
于 2012-10-02T04:14:44.887 回答
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首先,我将from的可见性更改privateprotected。一般来说,除非有很好的理由使用 ,否则private我更喜欢使用protected变量。

其次,您可能想要重新评估My\Hash类和calculate_and_return_a_string()函数之间的关系(您使用过call_user_func)。也许找到一种注入计算值的方法,这将使类与函数分离并消除额外的依赖关系。

最后,重新评估是否需要将它放在自己的类中可能是值得的。如果您只使用它来存储和注册单个变量,那么使用注册表或类似的东西可能会更好。当然,我看不到整个上下文,所以只有你会知道这是否适用。

于 2012-10-02T04:32:08.720 回答
0

天哪,我刚刚发现static关键字 to 可用于创建一个私有作用域,每次调用该函数时都可以重新访问该作用域:

<?php
namespace my;

/**
 * my\get_prefix()
 */
function get_prefix () {
    static $prefix; 
    if ( !isset($prefix) ) {
        // calculate $prefix (only runs once)
    }
    return $prefix;
}

请参阅此线程php.net/manual/en/language.variables.scope.php

于 2012-10-02T05:07:05.860 回答