目次

Apricot リクエストクラス

y2sunlight 2020-05-02

Apricot に戻る

関連記事

リクエストはPHPの $_GET,$_POST,$_SESSION,$_COOKIE,$_SERVER,$_FILE を対象とします。多くのフレームワークではこれらをまとめて1つのRequestクラスで実装しています。しかし、apricotではなるべく本来のPHPのスタイルを残した形で実装したいと思います。$_GET,$_POST,$_SESSION,$_COOKIEに、FLASH(1回限り有効なセッション変数)を加えてたリクエストを対象として以下の5つのクラスをシングルトンとして実装します。

これらのクラスを総称してリクエストクラスと呼びます。

尚、$_SERVER変数についてはそのまま使用し、$_FILEについては実装を保留します(必要に応じて外部ライブラリを使うか自作する事になると思います)。


Input

Inputクラスはフォームの送信データを取得するクラスです。Inputクラスと後述のQueryStringクラスは共に次に説明するSimpleInputクラスを使って実装します。

SimpleInputクラス

SimpleInputクラスは入力データを扱うシンプルで汎用的なクラスです。コンストラクタで入力データを与えて初期化し以下のpublicメソッドを持ちます。

/apricot/core/Foundation

SimpleInput.php
<?php
namespace Core\Foundation;
 
/**
 * Very Simple Input Class
 */
class SimpleInput
{
    /**
     * SimpleInput Data
     * @var array
     */
    private $input = null;
 
    /**
     * Create Simple Input
     */
    public function __construct(array $input=null)
    {
        $this->input = !empty($input) ? $input : array();
    }
 
    /**
     * Checks if a key is present
     * @param string $key
     * @return boolean
     */
    public function has(string $key):bool
    {
        return array_key_exists($key, $this->input);
    }
 
    /**
     * Get input data
     * @param string $key
     * @param string $default
     * @return mixed
     */
    public function get(string $key, string $default = null)
    {
        if ($this->has($key))
        {
            return $this->input[$key];
        }
        else
        {
            return $default;
        }
    }
 
    /**
     * Get all input data
     * @return array
     */
    public function all():array
    {
        return $this->input;
    }
 
    /**
     * Get a subset of the input for only specified keys
     * @param array|mixed $keys array or arguments list
     * @return array
     */
    public function only($keys):array
    {
        $key_arr = is_array($keys) ? $keys : func_get_args();
        return array_only($this->input, $key_arr);
    }
 
    /**
     * Get a subset of the input except for specified keys
     * @param array|mixed $keys array or arguments list
     * @return array
     */
    public function except($keys):array
    {
        $key_arr = is_array($keys) ? $keys : func_get_args();
        return array_except($this->input, $key_arr);
    }
 
    /**
     * Set input data
     * @param string $key
     * @param string $value
     */
    public function set(string $key, string $value)
    {
        $this->input[$key] = $value;
    }
 
    /**
     * Remove input data
     * @param array|mixed $keys array or arguments list
     */
    public function remove($keys)
    {
        $key_arr = is_array($keys) ? $keys : func_get_args();
        foreach($key_arr as $key)
        {
            if ($this->has($key))
            {
                unset($this->input[$key]);
            }
        }
    }
}


Inputクラス

Inputクラスは、上のSimpleInputクラスをシングルトンにしたもので、SimpleInputのメソッドが全て使用できます。初期化時にHTTPメソッドによってGET変数またはPOST変数の何れかを使用してクラスを生成します。Inputクラスは、フォームの入力データを取得する場合に使用します。

使用法: Input::{メソッド}

メソッド機能
bool has(string $key)キー指定よる入力データの存在確認
string get(string $key, string $default = null)キー指定よる入力データの取得
array all()全ての入力データの取得
array only(array|mixed $keys)必要入力データのみの取得
array except(array|mixed $keys)不要なものを除く入力データの取得
set(string $key, string $vale)入力データの設定
remove(string $key)入力データの削除

/apricot/core

Input.php
<?php
namespace Core;
 
use Core\Foundation\Singleton;
use Core\Foundation\SimpleInput;
 
/**
 * Input Class - SimpleInput Wrapper($_POST or $_GET depending on the method)
 *
 * @method static SimpleInput getInstance()
 * @method static bool has(string $key)
 * @method static string get(string $key, string $default = null)
 * @method static array all()
 * @method static array only(array|mixed $keys)
 * @method static array except(array|mixed $keys)
 * @method static set(string $key, string $vale)
 * @method static remove(string $key)
 */
class Input extends Singleton
{
    /**
     * Create SimpleInput instance.
     * @return SimpleInput
     */
    protected static function createInstance()
    {
        $inputs = self::getRawData();
        return new SimpleInput($inputs);
    }
 
    /**
     * Get raw input data depending on the method
     * @return array
     */
    public static function getRawData()
    {
        return strtoupper($_SERVER['REQUEST_METHOD']) =='POST' ? $_POST : $_GET;
    }
}


QueryString

QueryStringクラスはクエリ文字列を取得する為のクラスです。フォームデータは(GETメソッドの場合でも)Inputクラスによって取得できるので、このクラスの目的は、POSTメソッドのクエリ文字列を取得する場合に限定されると思います。

QueryStringクラス

QueryStringクラスは、上述のSimpleInputクラスをシングルトンにしたもので、SimpleInputのメソッドが全て使用できます。SimpleInputのコンストラクタにGET変数与えてクラスを生成します。

使用法: QueryString::{メソッド}

メソッド機能
bool has(string $key)キー指定よる入力データの存在確認
string get(string $key, string $default = null)キー指定よる入力データの取得
array all()全ての入力データの取得
array only(array|mixed $keys)必要入力データのみの取得
array except(array|mixed $keys)不要なものを除く入力データの取得
set(string $key, string $vale)入力データの設定
remove(string $key)入力データの削除

/apricot/core

QueryString.php
<?php
namespace Core;
 
use Core\Foundation\Singleton;
use Core\Foundation\SimpleInput;
 
/**
 * QueryString Class - SimpleInput Wrapper($_GET only)
 *
 * @method static SimpleInput getInstance()
 * @method static bool has(string $key)
 * @method static string get(string $key, string $default = null)
 * @method static array all()
 * @method static array only(array|mixed $keys)
 * @method static array except(array|mixed $keys)
 * @method static set(string $key, string $vale)
 * @method static remove(string $key)
 */
class QueryString extends Singleton
{
    /**
     * Create SimpleInput instance.
     * @return SimpleInput
     */
    protected static function createInstance()
    {
        return new SimpleInput($_GET);
    }
}


Session

Sessionクラスはセッション変数を設定及び取得をするクラスで、SimpleSessionクラスを使って実装します。Sessionクラス後述するフラッシュデータを包含しています。

SimpleSessionクラス

SimpleSessionクラスは$_SESSIONのラッパークラスです。以下のpublicメソッドを持ちます。

/apricot/core/Foundation

SimpleSession.php
<?php
namespace Core\Foundation;
 
/**
 * Very Simple Session Class - $_SESSION Wrapper
 */
class SimpleSession
{
    /**
     * Flash Data
     * @var SimpleFlash
     */
    private $flash = null;
 
    /**
     * Create Simple Session
     */
    public function __construct()
    {
        session_name(config('session.name'));
 
        // ini_set
        $ini_values = config('session.ini',[]);
        foreach($ini_values as $key=>$value)
        {
            if (isset($value))
            {
                try
                {
                    ini_set("session.{$key}", $value);
                    \Core\Debug::debug("ini_set(session.{$key})=".ini_get("session.{$key}"));
                }
                catch(\Throwable $e)
                {
                    \Core\Debug::error("ini_set(session)",[$key,$value]);
                };
            }
        }
    }
 
    /**
     * Session Start
     */
    public function start()
    {
        // Start Session
        session_start();
        $this->flash = new SimpleFlash();
    }
 
    /**
     * Checks if session has started
     * @return bool
     */
    public function isStarted():bool
    {
        return (array_key_exists(session_name(), $_COOKIE));
    }
 
    /**
     * Checks if a key is present
     * @param string $key
     * @return bool
     */
    public function has(string $key):bool
    {
        return array_key_exists($key, $_SESSION);
    }
 
    /**
     * Get session data
     * @param string $key
     * @param mixed $default
     * @return mixed
     */
    public function get(string $key, $default = null)
    {
        if ($this->has($key))
        {
            return $_SESSION[$key];
        }
        else
        {
            return $default;
        }
    }
 
    /**
     * Set session data
     * @param string $key
     * @param mixed $value
     */
    public function set(string $key, $value)
    {
        $_SESSION[$key] = $value;
    }
 
    /**
     * Remove session data
     * @param string $key
     */
    public function remove(string $key)
    {
        if ($this->has($key))
        {
            unset($_SESSION[$key]);
        }
    }
 
    /**
     * Clear session data
     */
    public function clear()
    {
        $_SESSION = [];
    }
 
    /**
     * Destroy session data
     */
    public function destroy()
    {
        $this->clear();
        if($this->isStarted())
        {
            $params = session_get_cookie_params();
            setcookie(session_name(), '', time() -24*60*60,
                $params['path'], $params['domain'], $params['secure'], $params['httponly']);
        }
        session_destroy();
    }
 
    /**
     * Get flash data
     * @return \Core\Foundation\SimpleFlash
     */
    public function flash()
    {
        return $this->flash;
    }
}


Sessionクラス

Sessionクラスは、上のSimpleSessionクラスをシングルトンにしたもので、SimpleSessionのメソッドが全て使用できます。

使用法: Session::{メソッド}

メソッド機能
start()セッションの開始
isStarted():boolセッションが開始されているか否かの判定
has(string $key):boolセッション変数の存在確認
get(string $key, $default = null)セッション変数の取得
set(string $key, $value)セッション変数の設定
remove(string $key)セッション変数の削除
clear()セッション変数のクリア
destroy()セッションの破棄
flash():SimpleFlashフラッシュデータの取得

/apricot/core

Session.php
<?php
namespace Core;
 
use Core\Foundation\Singleton;
use Core\Foundation\SimpleSession;
 
/**
 * Session Class - SimpleSession Wrapper
 *
 * @method static SimpleSession getInstance()
 * @method static void start()
 * @method static bool has(string $key)
 * @method static mixed get(string $key, mixed $default = null)
 * @method static void set(string $key, mixed $vale)
 * @method static void clear()
 * @method static void remove(string $key)
 * @method static void destroy()
 * @method static \Core\Foundation\SimpleFlash flash()
 */
class Session extends Singleton
{
    /**
     * Create SimpleSession instance.
     * @return SimpleSession
     */
    protected static function createInstance()
    {
        return new SimpleSession();
    }
}


設定ファイル

セッションには以下の初期設定ファイルが存在します。

/apricot/config/setting

session.setting.php
<?php
return
[
    'name' => 'SID'.substr(md5(env('APP_SECRET', env('APP_NAME'))),0,16),
    'ini' =>[
        'gc_maxlifetime' => null,   /* default: 1440[sec] */
        'gc_probability' => null,   /* default: 1         */
        'gc_divisor' => null,       /* default: 100       */
        'cookie_lifetime' => null,  /* default: 0[sec]    */
    ],
];


Flash

フラッシュとは、セッション内で一回限りだけ有効なセッション変数のことです。Flashクラスはフラッシュ変数の設定及び取得を行うクラスで、SimpleFlashクラスを使って実装します。

SimpleFlashクラス

SimpleFlashクラスは以下のpublicメソッドを持ちます。

/apricot/core/Foundation

SimpleFlash.php
<?php
namespace Core\Foundation;
 
use Core\Debug;
 
/**
 * Very Simple Flash Class
 */
class SimpleFlash
{
    /*
     * Flash Data
     */
    private $flash;
 
    /*
     * Flash Session key
     */
    private const FLASH = '_flash';
 
    /**
     * Create Flash
     */
    public function __construct()
    {
        $this->flash = array_key_exists(self::FLASH,$_SESSION) ? $_SESSION[self::FLASH] : array();
        Debug::debug($this);
        unset($_SESSION[self::FLASH]);
    }
 
    /**
     * Checks if a key is present
     * @param string $key
     * @return boolean
     */
     public function has(string $key):bool
    {
        return array_key_exists($key, $this->flash);
    }
 
    /**
     * Get flash data
     * @param string $key
     * @param mixed $default
     * @return mixed
     */
    public function get(string $key, $default = null)
    {
        if ($this->has($key))
        {
            return $this->flash[$key];
        }
        else
        {
            return $default;
        }
    }
 
    /**
     * Set flash data
     * @param string $key
     * @param mixed $value
     */
    public function set(string $key, $value)
    {
        $_SESSION[self::FLASH][$key] = $value;
        $this->flash[self::FLASH] = $value;
    }
 
    /**
     * Remove flash data
     * @param array|mixed $keys array or arguments list
     */
    public function remove(string $key)
    {
        if ($this->has($key))
        {
            unset($_SESSION[self::FLASH][$key]);
            unset($this->flash[$key]);
        }
    }
 
    /**
     * Clear flash data
     */
    public function clear()
    {
        unset($_SESSION[self::FLASH]);
        $this->flash = array();
    }
}


Flashクラス

Flashクラスは、上のSimpleFlashクラスをシングルトンにしたもので、SimpleFlashのメソッドが全て使用できます。

使用法: Flash::{メソッド}

メソッド機能
has(string $key):boolフラッシュ変数の存在確認
get(string $key, $default = null)フラッシュ変数の取得
set(string $key, $value)フラッシュ変数の設定
remove(string $key)フラッシュ変数の削除
clear()フラッシュ変数のクリア

/apricot/core

Flash.php
<?php
namespace Core;
 
use Core\Foundation\CallStatic;
 
/**
 * Flash Class - SimpleFlash Wrapper
 *
 * @method static SimpleFlash getInstance()
 * @method static bool has(string $key)
 * @method static mixed get(string $key, mixed $default = null)
 * @method static void set(string $key, mixed $vale)
 * @method static void remove(string $key)
 * @method static void clear()
 */
class Flash extends CallStatic
{
    /**
     * Get Flash instance.
     * @return Flash
     */
    public static function getInstance()
    {
        return \Core\Session::flash();
    }
}


Cookieクラスはクッキーの設定及び取得を行うクラスで、SimpleCookieクラスを使って実装します。

SimpleCookieクラス

SimpleCookieクラスは$_COOKIEのラッパークラスです。以下のpublicメソッドを持ちます。

/apricot/core/Foundation

SimpleCookie.php
<?php
namespace Core\Foundation;
 
/**
 * Very Simple Cookie Class - $_COOKIE Wrapper
 */
class SimpleCookie
{
    /**
     * Cookie Data
     * @var array
     */
    private $cookie = null;
 
    /**
     * Cookie saved forever (Default value)
     */
    private const FOREVER = 365*24*60*60;
 
    /**
     * Create Simple Cookie
     */
    public function __construct()
    {
        $this->cookie = !empty($_COOKIE) ? $_COOKIE : array();
    }
 
    /**
     * Checks if a key is present
     * @param string $key
     * @return boolean
     */
    public function has(string $key):bool
    {
        return array_key_exists($key, $this->cookie);
    }
 
    /**
     * Get cookie data
     * @param string $key
     * @param string $default
     * @return string|null
     */
    public function get(string $key, string $default = null)
    {
        if ($this->has($key))
        {
            return $this->cookie[$key];
        }
        else
        {
            return $default;
        }
    }
 
    /**
     * Set cookie data
     * @param string $key
     * @param string $value
     * @param int $expires_sec (not time()*60*60, but 60*60 )
     * @return bool return true if successfuly
     */
    public function set(string $key, string $value, int $expires_sec=0):bool
    {
        if($this->sendCookie($key, $value, $expires_sec))
        {
            $this->cookie[$key] = $value;
            return true;
        }
        return false;
    }
 
    /**
     * Set Cookie forever
     * @param string $key
     * @param string $value
     * @return bool return true if successfuly
     */
    public function forever(string $key, string $value):bool
    {
        return $this->set($key, $value, config('cookie.forever',self::FOREVER));
    }
 
    /**
     * Remove Cookie
     * @param string $key
     */
    public function remove(string $key)
    {
        if ($this->has($key))
        {
            unset($this->cookie[$key]);
            $this->sendCookie($key, '', -3600);
        }
    }
 
    /**
     * Send Cookie
     * @param string $key
     * @param string $value
     * @param int $expires_sec (not time()*60*60, but 60*60 )
     * @return bool return true if successfuly
     */
    private function sendCookie(string $key, string $value, int $expires_sec=0):bool
    {
        $expires = ($expires_sec==0) ? 0 : time() + $expires_sec;
        $path = config('cookie.path','');
        $domain = config('cookie.domain','');
        $secure = config('cookie.secure',FALSE);
        $httponly = config('cookie.httponly',FALSE);
 
        return setcookie($key, $value, $expires, $path, $domain, $secure, $httponly);
    }
}


Cookieクラス

Cookieクラスは、上のSimpleCookieクラスをシングルトンにしたもので、SimpleCookieのメソッドが全て使用できます。

使用法: Cookie::{メソッド}

メソッド機能
has(string $key):boolクッキーの存在確認
get(string $key, $default = null)クッキーの取得
set(string $key, string $value, int $expires_sec=0):boolクッキーの設定(有効期限付き)
forever(string $key, string $value):boolクッキーの設定(永続的)
remove(string $key)クッキーの削除

/apricot/core

Cookie.php
<?php
namespace Core;
 
use Core\Foundation\Singleton;
use Core\Foundation\SimpleCookie;
 
/**
 * Lang Class - SimpleCookie($_COOKIE) Wrapper
 *
 * @method static SimpleCookie getInstance()
 * @method static bool has(string $key)
 * @method static string get(string $key, string $default = null)
 * @method static bool set(string $key, string $value, int $expires_sec=0):bool
 * @method static bool forever(string $key, string $value)
 * @method static bool remove(string $key)
 */
class Cookie extends Singleton
{
    /**
     * Create SimpleCookie instance.
     * @return SimpleCookie
     */
    protected static function createInstance()
    {
        return new SimpleCookie();
    }
}


設定ファイル

クッキーには以下の初期設定ファイルが存在します。

/apricot/config/setting

cookie.setting.php
<?php
return
[
    'path' => '',
    'domain' => '',
    'secure' => FALSE,
    'httponly' => FALSE,
];
設定値の詳細は、PHPマニュアルのsetcookieを参照して下さい。


ヘルパー関数

リクエスト処理用のヘルパー関数に追加します。inputLabels()はInputクラスからバリデーションの項目名を取得するのに便利な関数です。その他のget()メソッドはHTMLテンプレートでよく使われる関数です。

ヘルパー関数機能
inputLabels
(string $message_key):array
フォームデータのラベル配列を取得します
input
(string $key, $default=null):string
フォームデータを取得
queryString
(string $key, $default=null):string
クエリ文字列を取得
session
(string $key, $default=null):mixed
セッション変数を取得
flash
(string $key, $default=null):mixed
フラッシュ変数を取得
cookie
(string $key, $default=null):string
クッキー変数を取得

/apricot/core/helpers

boilerplates.php
/**
 * Get Input Labels
 * @param string $message_key
 * @return array
 */
function inputLabels(string $message_key):array
{
    $labels = [];
    foreach(array_keys(Core\Input::all()) as $name)
    {
        $dot_key = "{$message_key}.{$name}";
        if (Core\Lang::has($dot_key))
        {
            $labels[$name] = Core\Lang::get($dot_key);
        }
    }
    return $labels;
}
 
/**
 * Get input($_GET or $_POST depending on the method) data
 * @param string $key
 * @param mixed $default
 * @return string
 */
function input(string $key, $default=null)
{
    return Core\Input::get($key, $default);
}
 
/**
 * Get QueryString data
 * @param string $key
 * @param mixed $default
 * @return string
 */
function queryString(string $key, $default=null)
{
    return Core\QueryString::get($key, $default);
}
 
/**
 * Get session($_SESSION) date
 * @param string $key
 * @param mixed $default
 * @return mixed
 */
function session(string $key, $default=null)
{
    return Core\Session::get($key, $default);
}
 
/**
 * Get flash date
 * @param string $key
 * @param mixed $default
 * @return mixed
 */
function flash(string $key, $default=null)
{
    return Core\Flash::get($key, $default);
}
 
/**
 * Get cookie($_COOKIE) date
 * @param string $key
 * @param mixed $default
 * @return string
 */
function cookie(string $key, $default=null)
{
    return Core\Cookie::get($key, $default);
}