— y2sunlight 2020-05-02
関連記事
リクエストはPHPの $_GET,$_POST,$_SESSION,$_COOKIE,$_SERVER,$_FILE を対象とします。多くのフレームワークではこれらをまとめて1つのRequestクラスで実装しています。しかし、apricotではなるべく本来のPHPのスタイルを残した形で実装したいと思います。$_GET,$_POST,$_SESSION,$_COOKIEに、FLASH(1回限り有効なセッション変数)を加えてたリクエストを対象として以下の5つのクラスをシングルトンとして実装します。
これらのクラスを総称してリクエストクラスと呼びます。
尚、$_SERVER変数についてはそのまま使用し、$_FILEについては実装を保留します(必要に応じて外部ライブラリを使うか自作する事になると思います)。
Inputクラスはフォームの送信データを取得するクラスです。Inputクラスと後述のQueryStringクラスは共に次に説明するSimpleInputクラスを使って実装します。
SimpleInputクラスは入力データを扱うシンプルで汎用的なクラスです。コンストラクタで入力データを与えて初期化し以下のpublicメソッドを持ちます。
/apricot/core/Foundation
<?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クラスは、上の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
<?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クラスはクエリ文字列を取得する為のクラスです。フォームデータは(GETメソッドの場合でも)Inputクラスによって取得できるので、このクラスの目的は、POSTメソッドのクエリ文字列を取得する場合に限定されると思います。
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
<?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クラスはセッション変数を設定及び取得をするクラスで、SimpleSessionクラスを使って実装します。Sessionクラス後述するフラッシュデータを包含しています。
SimpleSessionクラスは$_SESSIONのラッパークラスです。以下のpublicメソッドを持ちます。
/apricot/core/Foundation
<?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クラスは、上の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
<?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
<?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クラスはフラッシュ変数の設定及び取得を行うクラスで、SimpleFlashクラスを使って実装します。
SimpleFlashクラスは以下のpublicメソッドを持ちます。
/apricot/core/Foundation
<?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クラスは、上のSimpleFlashクラスをシングルトンにしたもので、SimpleFlashのメソッドが全て使用できます。
使用法: Flash::{メソッド}
メソッド | 機能 |
---|---|
has(string $key):bool | フラッシュ変数の存在確認 |
get(string $key, $default = null) | フラッシュ変数の取得 |
set(string $key, $value) | フラッシュ変数の設定 |
remove(string $key) | フラッシュ変数の削除 |
clear() | フラッシュ変数のクリア |
/apricot/core
<?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クラスは$_COOKIEのラッパークラスです。以下のpublicメソッドを持ちます。
/apricot/core/Foundation
<?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クラスは、上の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
<?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
<?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
/** * 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); }