リクエストのオブジェクト化

リクエストのカプセル化

PHPではリクエスト変数は$_POST、$_GET等のスーパーグローバル変数より取得します。
これらは、どこからでも参照できます。クラスの中だろうが外だろうが関係無しです。
しかも、値をセットすることも出来てしまいます。

これらのことは、オブジェクト指向の隠蔽性という考え方に反するものです。
そもそも、リクエスト情報が書き換えられるのはおかしなことです。
なので、リクエストも一つのオブジェクトととらえ、クラス化することにします。

クラス化して取得のみできるような形にし、決まりごととしてグローバル変数は直接参照しないということにしてしまいます。

リクエスト変数クラス

RequestVariables.php
<?php

// リクエスト変数抽象クラス
abstract class RequestVariables
{
    protected $_values;

    // コンストラクタ
    public function __construct() 
    {
        $this->setValues();
    }

    // パラメータ値設定
    abstract protected function setValues();

    // 指定キーのパラメータを取得
    public function get($key = null)
    {
        $ret = null;
        if (null == $key) {
            $ret = $this->_values;
        } else {
            if (true == $this->has($key)) {
                $ret = $this->_values[$key];
            }
        }
        return $ret;
    }

    // 指定のキーが存在するか確認
    public function has($key)
    {
        if (false == array_key_exists($key, $this->_values)) {
            return false;
        }
        return true;
    }
}

?>
Post.php
<?php

// POST変数クラス
class Post extends RequestVariables
{
    protected function setValues()
    {
        foreach ($_POST as $key => $value) {
            $this->_values[$key] = $value;
        }		
    }		
}


?>
QueryString.php
<?php

// GET変数クラス
class QueryString extends RequestVariables
{
    protected function setValues()
    {
        foreach ($_GET as $key => $value) {
            $this->_values[$key] = $value;
        }		
    }		
}

?>

単純にクラスに配列フィールドを持ち、
POSTやGETの値をそのまま保持しているだけです。

PostとQueryStringは別々のクラスですが、違いは保持している値が$_POSTなのか$_GETなのかだけの違いで、処理はほぼ共通します。

なので、ほとんどの処理はRequestVariablesとして抽象クラスを作りました。
唯一異なる値のセットの部分だけ抽象メソッドとしています。
RequestVariablesを継承してPostクラスとQueryStringクラスをそれぞれ作成し、
値のセットのメソッドのみ実装しています。

リクエストクラス

ここでは、リクエストという一つのオブジェクトが存在し、
その中にPOSTやGETが含まれるという形にしたいと思います。

なのでリクエストクラスを作成します。

Request.php
<?php

class Request
{
    // POSTパラメータ
    private $post;
    // GETパラメータ
    private $query;
    
    // コンストラクタ@
    public function __construct()
    {
        $this->post = new Post();
        $this->query = new QueryString();
    }

    // POST変数取得
    public function getPost($key = null)
    {
        if (null == $key) {
            return $this->post->get();
        }
        if (false == $this->post->has($key)) {
            return null;
        }
        return $this->post->get($key);
    }

    // GET変数取得
    public function getQuery($key = null)
    {
        if (null == $key) {
            return $this->query->get();
        }
        if (false == $this->query->has($key)) {
            return null;
        }
        return $this->query->get($key);
    }
}

?>

コントローラーでの利用

リクエストオブジェクトを直接操作するのはコントローラークラスのみとします。
なので、コントローラーのフィールドとして保持しておくのが良いでしょう。

以下は利用例です。

<?php

class CartController
{
    private $request;

    // コンストラクタ
    public function __counstruct()
    {
        // リクエスト
        $this->request = new Request();
    }

    public function displayAction()
    {
        // カート内容表示処理
    }
    
    public function addAction()
    {
        // 追加する商品の商品IDをPOSTから取得
        $post = $this->request->getPost();
        $productId = $post['product_id'];
        
        // カートへの商品の追加処理
    }
}

?>