2015-10-30 4 views
12

どうすればメインのPHPスクリプト戻るfalseクラスまたは関数の中から? クラス/関数の内部からPHPスクリプトからfalseを返すには?

理由:これが原因で内蔵のウェブサーバである:

PHPファイルは、Webサーバーは、それが「ルーター」のスクリプトとして扱われ開始され、コマンドラインで指定された場合。スクリプトは、各HTTP要求の開始時に実行されます。 このスクリプトがFALSEを返すと、要求されたリソースはそのまま返されます。言い換えればPHP Built-in webserver

についてのドキュメントから

内蔵のウェブサーバは、静的ファイルにを果たすことができるように、あなたは、ルータのスクリプトでfalseを返します。ドキュメントからの例:

if (preg_match('/\.(?:png|jpg|jpeg|gif)$/', $_SERVER["REQUEST_URI"])) { 
    return false; // serve the requested resource as-is. 
} else { 
    echo "<p>Welcome</p>"; 
} 

事は、私がWebフレームワークにその動作を追加しようとしているということです:私はindex.phpにその書き込みをする必要はありません。私はむしろ、php_sapi_name() == 'cli-server'と静的資産が要求された場合にスクリプトの実行を停止するクラス(ミドルウェア)にそのロジックをカプセル化したいと思います。

しかし、明らかにreturn falseがメインファイルからではなく、現在のメソッド/関数/ファイルから戻ってくるので、PHPスクリプト全体がどのようにしてfalseをクラスまたは関数から返すようにするか分かりません。

たとえば、exit()と同じ動作を実現する方法はありますか?私は、私は実際には(つまり、特定の終了コードですか?)メインファイル内のreturn falseが実際には何を意味するのかわかりません。

+0

@Terminus 'return false'は、PHPの組み込みサーバに特有の意味を持っています。引用したドキュメントを参照してください。 –

答えて

6

ルーターにクラスメソッドを呼び出し、メソッドがfalseを返す場合は、ルーターファイルからfalseを返します。

もちろん、頭痛になることがあります。あなたが達成したいことを達成するためには、基本的に2つの方法しかありません。

しかし、あなたは例外を乱用し、ケースのための専門的な例外を作成することができますより高速な方法があります:あなたはこの種を持っていたら

StaticFileException.php

<?php 
class StaticFileException extends Exception {} 

router.php

<?php 
try { 
    $c = new Controller(); 
    return $c->handleRequest(); 
} catch (StaticFileException $e) { 
    return false; 
} 

は、ちょうどthrow new StaticFileExceptionの場所にコードがあります。

+0

編集していただきありがとうございました – tacone

+0

アイデアをありがとうございます。私は理想的に 'exit()'やそれを使って 'return false'と同等のものを探しています(もし可能ならば...)。可能であれば、私は本当に回避策を検討しなければならないのではないかと心配しています。/ /しかし、index.phpを可能な限り小さく/シンプルに保ちたいと思います。 –

+0

私は大規模なtry-catchにルータファイル全体をラッピングする方法を複雑にしません。ちなみに、ネストされたコンテキストからのジャンプバックの唯一の方法は、例外をスローすることです。 – tacone

4

あなたのクラスのメソッドがexitを使用して、静的な資産を処理した場合、解決策はreturn falseexitを交換し、そのメソッドの呼び出し元は、単にだけでなく、グローバルスコープにメソッドを返したような単純なことができます。

あなたのクラスが次のようになったら...

class Router 
{ 
    public function handleRequest($uri) 
    { 
     if (is_file($this->docRoot . $uri->path)) { 
      exit; // static file found 
     } else { 
      // handle as normal route 
     } 
    } 
} 

ちょうどあなたのindex.phpはこのような何かを動作するかどうか...

$router = new Router($docRoot); 
$router->handleRequest($_SERVER['REQUEST_URI']); 

は単にhandleRequest方法のインフロントリターンを追加し... return falseであっ

  return false; // static file found 

exitを置き換えますそうですね....

return $router->handleRequest($_SERVER['REQUEST_URI']); 

これは、フレームワーク設計上の副作用が最小である必要があります。コードとリファクタリングはほとんど必要ありません。スクリプトのグローバルスコープからの戻りは、PHPでは1つの副作用しかありません。スクリプトを呼び出します。つまり、include/requireを代入の式として使用した場合)。あなたのケースでは、index.phpが呼び出し側のスクリプトであれば、そのメソッドの前にreturnを追加するだけで、ここで心配することはありません。

もちろん、残りのスクリプトを返すと続行されないので、それがindex.phpの最後のステートメントであることを確認してください。あなたも、単に一時的な値に戻り値を代入して、ロジックのために必要であれば、後で返すことができます....

一般に
$router = new Router($docRoot); 
if ($router->handleRequest($_SERVER['REQUEST_URI'])) { 
    /* if you need to do anything else here ... */ 
} else { 
    return false; // otherwise you can return false for static here 
} 

私は関数/メソッドの内部からexitを呼び出すことであると言うでしょうほぼ決して望ましいです。クラスをテストしてデバッグするのが難しくなり、例外を投げたり、メソッドから戻ったり、呼び出し側に失敗シナリオを処理させたりするような代替手段からのメリットはありません正常に

+0

それは良い考えです。私は今、 'exit()'を全く使わないことを指摘したいと思います。静的ファイルは、組み込みサーバーではサポートされていません。私にとって実装が難しいことの1つは、フレームワークが[ミドルウェア](https://github.com/zendframework/zend-stratigility/blob/master/doc/book/middleware.md)に基づいていることです。ミドルウェア**は 'ResponseInterface'オブジェクト**を返さなければならないので、私は' false'を返すことができません(私は静的ファイル機能を適切にカプセル化されるミドルウェアとして実装したいと思います)。とにかく、それは思考のための食糧、ありがとう。 –

+0

この場合、例外をスローし、グローバルスコープから 'catch'ブロックを使って' return false'を返すようにするのがおそらく最善の策です。 – Sherif

0

これに対処するためにregister_shutdown_functionまたはauto_append_file設定で再生することはできません。本当にいいですが、多分それは仕事をすることができます。

+0

私はあなたの考え方が好きです:P私は恐らく 'register_shutdown_function'は私が関数内にあることを意味するので、falseを返すとスクリプトではなく関数を終了します:/そして' auto_append_file'に対しては可能ですそれを実行時に使用するには、たとえダムのテストファイルであっても、それを動作させることができませんでした(さらに、ユーザーにとって混乱するかもしれませんが、なぜそうではありませんか)。 –

+0

あなたは「終了」について、また内部のPHP Webサーバーとのフレームワークコンテキストについても話しました。なぜなら、私はこれらの目的を果たしたからです。私はあなたに全面的に同意する:両方の非常に良いではない。 –

関連する問題