3

PHPスーパーグローバルに直接アクセスする必要がないように、のラッパーSessionを作成したかったのです。Requestスーパーグローバルのラッパーを作成して使用すると、ラッパークラスをモックできるため、アプリケーションの単体テストが簡単になることに気付きました。

ラッパークラスを作成しようとしているときに、いくつかのサンプルラッパークラスを調べました。それらのいくつかは、初期化時にスーパーグローバルをクラスプロパティとして格納します。

class Session
{
    protected $vars;

    public function __construct()
    {
        session_start();

        // POINT OF INTEREST
        // Store the superglobal as a class property
        $this->vars = $_SESSION;
    }    

    public function get($index)
    {
        // POINT OF INTEREST
        // Accesses the class property instead of the superglobal
        return $this->vars[$index];
    }

    public function write($index, $value)
    {
        // Writes both class property and session variable
        $this->vars[$index] = $value;
        $_SESSION[$index] = $value;
    }
}

私の質問:ラッパークラスを作成するときに、スーパーグローバルに直接アクセスするのではなく、クラスのプロパティとしてスーパーグローバルを格納する特別な理由はありますか?上記のコードを次のコードと比較してください。

class Session
{
    public function __construct()
    {
        session_start();
    }

    public function get($index)
    {
        // Accesses the superglobal directly
        return $_SESSION[$index];
    }

    public function write($index, $value)
    {
        // Accesses the superglobal directly
        $_SESSION[$index] = $value;
    }
}

IMO、とにかくラッパークラスがモックされるので、なぜスーパーグローバルをクラスプロパティとして保存するのが面倒なのですか?多くの人がこれを行う特別な理由はありますか?スーパーグローバルに直接アクセスするのではなく、ラッパーのプロパティとしてスーパーグローバルを保存する必要がありますか?

ご入力いただきありがとうございます。

4

2 に答える 2

5

セッションはかなり特殊なケースです。しかし、あなたはスーパーグローバルをラップする理由があるかどうか尋ねました。考えられる理由は次のとおりです(順序が正しくない、または完全ではない)。

  1. コードをグローバル状態に依存しにくくし、テストを容易にするため。グローバル状態に依存するコードをテストできます。しかし、その状態が通知されるコードをテストするよりも難しく、壊れやすいものです。

  2. 真のグローバル状態では不可能な興味深いことを行うために、偽のリクエストやサブリクエストを実行できるため、コードをより柔軟にするため。

  3. コードの移植性を高めるため。ラッパーでラップすることにより、引用符の削除、文字セット変換の処理など、プラットフォームに依存するものを中央の場所で処理できます。これにより、プラットフォーム間または複数のプラットフォーム間のシフトの処理が容易になります。

  4. 変数に追加の制約を適用します。$ _SESSIONを使用すると、必要なものを内部に設定できるため、問題が発生する可能性のあるシリアル化できない状態になってしまう可能性があります。ラッパーを使用すると、状態をチェックして、必要な制約に一致するかどうかを判断できる1つの集中ポイントが得られます。

  5. コードを読みやすくするため。もちろん、メソッドで$ _POSTにアクセスすると、ほぼすべてのphp開発者があなたが何をしているのかを知っています。しかし、彼らはその実装の詳細について知る必要がありますか?それとも$request->getFromPostData('foo');もっと冗長ですか?

  6. リクエストクラスにブレークポイントを設定し、リクエスト変数にアクセスするすべてのオカレンスをすぐに見つけることができるため、コードのデバッグを容易にするため(直接アクセスしない限り)。

  7. クラスの依存関係を理解し​​やすくするため。スーパーグローバルを使用するクラスのAPIを提供した場合、そのクラスがそれにアクセスしたかどうか、したがってクラスが何を操作する必要があるかを正確に知ることはできません。ただし、リクエストクラスを挿入する必要がある場合は、クラスが実際に動作するためにリクエストから何かを必要としていることが一目でわかります。したがって、読みやすさが向上し、APIがより明確になります。

現実にはもっと多くの理由がありますが、それは私が頭のてっぺんから考えることができる理由です。

于 2011-04-26T20:36:33.170 に答える
3

重要な理由はないと思います。後で参照しているスーパーグローバルを変更した場合、クラスのコード全体ではなく、コンストラクターで置き換える必要があるためかもしれません。

この観点から、writeあなたが述べたように、クラスプロパティとセッション変数の両方を書き込む最初の実装のメソッドはあまり賢明ではないと思います。

ただし、これはすべて少しやり過ぎ(そして考えすぎ)のようです。シンプルに保ち、あなたに役立つことをしてください。

于 2011-04-26T20:06:20.950 に答える