2

一度だけ計算する必要がある値があります。constただし、最初に計算するためにいくつかの関数を実行する必要があるため、宣言には使用できません。ある程度保護された方法で保存し、(ネームスペース化された) グローバル関数でアクセスできるようにしたいと考えています。これを行うのに適したパターンは何ですか? ここに私が持っているものがあります:

オプション1-うまく機能しますが、定数に対してのみ機能するため、これは使用できません:

<?php 
namespace my;

const PREFIX = 'example';

/**
 * my\get_prefix()
 */
function get_prefix () {
    return PREFIX;
}

オプション 2 - 名前空間付き関数は、構成済みの名前空間付き public static クラスの値にアクセスします。

<?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

一見すると、これは遅延読み込みの優れた候補のように見えます。

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)。おそらく、計算された値を注入する方法を見つけてください。これにより、クラスが関数から分離され、余分な依存関係が削除されます。

最後に、これを独自のクラスに入れる必要があるかどうかを再評価する価値があるかもしれません。単一の変数を保存および登録するためにのみ使用している場合は、レジストリなどを使用する方がよい場合があります。もちろん、私は文脈全体を見ることはできないので、これが当てはまるかどうかはあなただけが知っているでしょう.

于 2012-10-02T04:32:08.720 に答える
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 に答える
0

OMG staticto キーワードを使用して、関数が呼び出されるたびに再アクセスできるプライベートスコープを作成できることを発見しました。

<?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 に答える