4

クラス内でのグローバル関数の使用に関する質問ですが、MVCシステムに取り組んでいます。

次のメソッドは、モデルなどのクラスのメソッドを呼び出すクラスの一部であり、私の質問は、redirect()と呼ばれるグローバル関数がそこにあるということです。ブートストラップファイルは、すべてのコントローラーがアクセスする必要がある場合があるため、これは悪い習慣です。または、すべてのコントローラーが親コントローラーを拡張するため、これをコントローラークラスのメソッドにするのが最善です。

public function post($slug){

  if(!$slug){ redirect('blog'); }

  $data = $this->model->getPost($slug);
  $this->view->render('blog/single', $data);
}

それとも、静的クラスの方が理にかなっていますか?単純なリダイレクト機能については、少し上に見えます。

4

3 に答える 3

7

グローバル関数は必ずしも悪い習慣ではありません。注意すべき点が2つあります。

命名:関数の名前が衝突を回避し、それが何に関連しているかが明らかであることを確認する必要があります。あなたのリダイレクト関数、それはリクエストリダイレクトを実行することが期待されます。代わりに、メソッドが他のより具体的なものに関連している場合は、コンテキスト情報を前に付けることで、それが当てはまることを明確にする必要があります。

状態:グローバル関数はステートレスである必要があります。これは、関数が指定された入力に対して常に同じ結果を提供する必要があることを意味します。時間帯や変数の値などによって異なることをする場合、一般的にこれは悪いことです。それは明らかな落とし穴のように見えるかもしれませんが、その問題にはもっと微妙なバージョンがあります。このルールの明らかな例外は、実際には時刻を要求することです...

そこにあるコードはこれらの2つのルールに従っているように見えるので、これを行うことは完全に受け入れられます。

編集テスト容易性の問題があります。クラスで必要な(またはそうあるべき)グローバル関数を参照しているため、これをモックすることはできません。たとえば、リダイレクトの例では、リダイレクト関数をトリガーせずにクラスを適切にテストすることはできず、関数のモックバージョンを使用して実際のリダイレクトメソッドが呼び出されたことを検出することはできません。

于 2012-12-30T23:49:37.113 に答える
2

グローバル関数を使用すると、クラスがテストできなくなるため、お勧めできません。目的のメソッドをオブジェクトに配置し、依存関係としてクラスに渡す必要があります。

于 2012-12-30T23:43:01.220 に答える
1

コメントで示しているように、これは小さなワンライナーメソッドです。PHP5.3を使用する場合は、グローバルではなくラムダ関数を使用して、まったく新しいクラスを作成するよりも渡す方がよいでしょう。

依存関係が注入され、ブートストラップをコントローラーに公開してそこにラムダを格納し、必要な場所で呼び出すようにコーディングするように設計します。

ラムダの使用については、 http://fabien.potencier.org/article/17/on-php-5-3-lambda-functions-and-closuresを参照してください。DIの例でも、うまくいけばいくつかの洞察が得られます。

于 2012-12-31T01:34:48.160 に答える