リクエストURLによって処理を分けデータを取得するRequestクラス

MVCフレームワーク

PHPではクライアントから送信されたデータをスーパーグローバル変数の$_POSTや$_GETで取得することができます。
ここではクライアントから送信されたリクエストに関わる情報を取得するためのクラスを作成します。リクエストに関する情報はすべてRequestインスタンスで管理し、HTTP通信におけるリクエストを扱うためのクラスとなります。

MVCフレームワークでは、リクエストされたURLに対しルーティングという仕組みを実行することで処理を分けます。
つまり、リクエストされたURLによって実行すべきコントローラーとアクションを割り出し、レスポンス用のページをレンダリングしてこれをクライアントに返すという流れです。

なお、Requestクラスを操作するのは、コントローラーのみとします。クライアントからのリクエストを処理する際には、コントローラークラスのアクションメソッドがRequestクラスのメソッドを呼び出し、リクエスト時に送信されたデータやURLの情報を取得し、処理を進めます。

Requestクラスの機能として以下のメソッドを定義します。

  • getHostName()メソッドにてホスト名を取得
  • getRequestUri()メソッドにてホスト部分より後ろの値を返す
  • getBaseUri()メソッドでフロントコントローラーまでのパスを返す
  • isPost()メソッドでリクエストメソッドがPOSRかどうか判定
  • getPath()メソッドでフロントコントローラーのあとに続くパスを返す
  • getGet()メソッドでGET、getPost()メソッドでPOST送信された情報を取得

では各メソッドを用意していきましょう。

RequestクラスでリクエストURLとリクエストメソッドを処理

アプリケーションにアクセスがあった場合、すべてのアクセスをindex.phpで受けて、それから各コントローラーへの振り分けを行います。
このため、URLを扱う際には2つの情報が必要になります。

1つ目の情報はベースとなるURL。フロントコントローラーへのパスのうち、URLのホスト部分を除いた部分です。例えば次のようなURLであるとします。

http://example.com/foo/bar/index.php

このように/foo/bar以下にフロントコントローラー「index.php」が配置されている場合は、/foo/bar/がベースのURLとなります。

2つ目の情報はベースのURLより後ろのパス情報です。この部分をフレームワーク内部でパス情報として利用します。パス情報を用いて、リクエストされたURLと各コントローラーの対応付けを行うというわけです。

パス情報を取得する際に使用する定数は以下の二つです。

$_SERVER[‘REQUEST_URI’]ページにアクセスするために指定されたURLのうちホスト部分より後ろの値を返す
$_SERVER[‘SCRIPT_NAME’]現在のスクリプトのパス。スクリプト自身のページを指定するのに有用です。__FILE__ 定数には、カレント(すなわち読み込まれた)ファイルのパスとファイル名が 含まれます

URLの例をいくつか紹介して、どの部分がREQUEST_URIなのか説明します。

【例1】

http://example.php/
REQUEST_URI/
SCRIPT_NAMEindex.php
ベースとなるURLなし
パス情報/

【例2】

http://example.php/login.php/list?foo=bar
REQUEST_URI/login.php/list?foo=bar
SCRIPT_NAME/login.php/list?foo=bar
ベースとなるURL/login.php
パス情報/list

【例3】

http://example.php/foo/bar/index.php/user
REQUEST_URI/foo/bar/index.php/user
SCRIPT_NAME/foo/bar/index.php/user
ベースとなるURL/foo/bar/
パス情報/user

【例3】についてはindex.phpを省略としてhttp://example.php/foo/bar/userとしてアクセスすることも可能です。

getHostName()メソッドでホスト名を取得

サーバーのホスト名を取得します。$_SERVER[‘HTTP_HOST’]で取得し、戻り値として返します。もしホスト名が含まれていない場合は$_SERVER[‘SERVER_NAME’]を参照してApache側に設定されているホスト名を戻り値として返します。

<?php
class Request {
    public function getHostName(){
        if(isset($_SERVER['HTTP_HOST'])){
            return $_SERVER['HTTP_HOST'];
        } else {
            return $_SERVER['SERVER_NAME'];
        }
    }
}
?>

getRequestUri()メソッドでホスト部分より後ろの値を取得

次に、$_SERVER[‘REQUEST_URI’]に格納されている値を戻り値として返します。

public function getRequestUri(){
    return $_SERVER['REQUEST_URI'];
}

getBaseUrl()メソッドでフロントコントローラーまでのパスを返す

フロントコントローラーとはホスト部分の後ろからの部分、ベースとなるURLでしたね。
そのため、以下の情報を取得します。

  • 現在のプログラムのパスを取得($_SERVER[‘SCRIPT_NAME’]で取得)
  • getReauestUri()でホスト部分以降のパスを取得
public function getBaseUrl() {
        $scriptName = $_SERVER['SCRIPT_NAME'];
        $requestUri = $this->getRequestUri();

        //フロントコントローラーがURLに含まれる場合
        if(strpos($requestUri, $scriptName)){
            
        }
    }

strpos()メソッド

strpos($haystack, $needle)

haystackは検索先の文字列で、needleは検索する文字列です。needleが見つかった位置を返します。haystackの先頭で見つかった場合は0、2文字目で見つかった場合は1を返します。

rtrim()メソッド

rtrim($str, $mask)

文字列の最後から空白(もしくはその他の文字)を取り除きます。$strが操作対象の文字列となり、$maskが削除する文字列となります。

dirname()メソッド

dirname($path)

$pathパスに含まれる親ディレクトリのパスを返します。

getPath()メソッドでフロントコントローラーの後に続くパスを返す

フロントコントローラー以降の部分のパス情報を戻り値として返すメソッドを作成します。処理の手順は以下の通りになります。

  • getBaseUrl()メソッドで、フロントコントローラーを取得する。
  • getRequestUri()メソッドで、リクエストされたURLのホスト部分より後の値を取得する。
  • リクエストURLに「?」が含まれていれば、?以降の値を取り除く
  • ③の値からベースとなるURLを取り除いて、パス情報として返す。
public function getPath(){
    $baseUrl = $this->getBaseUrl();
    $requesturi = $this->getRequestUri();
    //リクエストされたURLのホスト部分以降に「?」が含まれているか
    //「?」の位置を取得して$spに代入
    if(true == ($sp = strpos($requestUri, '?'))) {
        //「?」の開始位置が格納されている$spにより、
        //「?」以降の値を取り除く
        $requestUri = substr($requestUri, 0 , $sp);
    }

    //$requestUriからベースとなるURL部分取り除いた値を取得
    $path = (string)substr($requestUri, strlen($base_uri));

    return $path;
}

substr()メソッド

substr($string, $start, ,[ int $length])

文字列の中から指定した文字数ぶんの文字列を切り出します。$stringに入力文字列、$startに検索開始位置(開始は0なので注意)、切り取る文字数となります。

GETやPOSTリクエストの処理

ここでは以下の処理をするためのメソッドを定義していきます。

  • isPostGet()メソッドでPOSTかGETか判定
  • getGet()メソッドで$_GET変数から情報を取得
  • getPost()メソッドで$_POST変数から情報を取得

リクエストがPOSTかGETかどうか調べるisPostGet()メソッド

$_SERVER[‘REQUESR_METHOD’]にリクエストのメソッドが格納されているので、この値がPOSTであればtrueを返しましょう。

public function isPostGet(){
    if($_SERVER['REQUESR_METHOD'] === 'POST'){
        return true;
    } else {
        return
    }
}

GETで送信された情報を取得するgetGet()メソッド

パラメーターでキー名を受け取り、そのキーの値を返します。キーが存在しない場合に備えてデフォルト値を返すための第2パラメーターを用意します。第2パラメーターの値はnullにします。

public function getGet($name, $param = null){
    if(isset($_GET[$name])){
        return $_GET[$name];
    }
    //キーが存在しなければ$paramを返す
    return $param;
}

POSTで送信された情報を取得するgetPost()メソッド

GETの場合と同様にPOSTで送信された場合の処理を作成します。

public function getPost($name, $param = null){
    if(isset($_POST[$name])){
        return $_POST[$name];
    }
    //キーが存在しなければ$paramを返す
    return $param;
}

Request.phpのコードまとめ

<?php
class Request {
    public function getHostName(){
        if(isset($_SERVER['HTTP_HOST'])){
            return $_SERVER['HTTP_HOST'];
        } else {
            return $_SERVER['SERVER_NAME'];
        }
    }

    public function getRequestUri(){
        return $_SERVER['REQUEST_URI'];
    }

    public function getBaseUrl() {
        $scriptName = $_SERVER['SCRIPT_NAME'];
        $requestUri = $this->getRequestUri();

        //フロントコントローラーがURLに含まれる場合
        if(strpos($requestUri, $scriptName === 0)){
            return $scriptName;
        //フロントコントローラーが省略されている場合の処理
        } else if (strpos($requestUri, dirname($scriptName === 0))){
            return rtrim(dirname($scriptName), '/');
        }
        return '';
    }

    public function getPath(){
        $baseUrl = $this->getBaseUrl();
        $requesturi = $this->getRequestUri();
        //リクエストされたURLのホスト部分以降に「?」が含まれているか
        //「?」の位置を取得して$spに代入
        if(true == ($sp = strpos($requestUri, '?'))) {
            //「?」の開始位置が格納されている$spにより、
            //「?」以降の値を取り除く
            $requestUri = substr($requestUri, 0 , $sp);
        }

        //$requestUriからベースとなるURL部分取り除いた値を取得
        $path = (string)substr($requestUri, strlen($base_uri));

        return $path;
    }

    public function isPostGet(){
        if($_SERVER['REQUESR_METHOD'] === 'POST'){
            return true;
        } else {
            return
        }

    }

    public function getGet($name, $param = null){
        if(isset($_GET[$name])){
            return $_GET[$name];
        }
        //キーが存在しなければ$paramを返す
        return $param;
    }

    public function getPost($name, $param = null){
        if(isset($_POST[$name])){
            return $_POST[$name];
        }
        //キーが存在しなければ$paramを返す
        return $param;
    }
    
}
?>

コメント

タイトルとURLをコピーしました