Developer

魁!小野の塾 小さな管理機能を作ってみようの巻 第19話
2021.08.26
Lv2

魁!小野の塾 小さな管理機能を作ってみようの巻 第19話

小さな管理機能を作ってみよう 第19話

初心者向け、PHPプログラム構築講座です。
初心者といっても、PHPの勉強を少し行い、LAMP環境が自分で構築でき、少しアプリケーションを作成しているレベルを対象とします。
まったくの初心者の場合は、わからない部分が出てくると思います。
できるだけ細かく説明は入れていきますが、説明がわからない場合は、PHPやMySQLの初心者講座をご覧ください。

対象のスキルレベル

  • LAMP環境の構築
  • PHP言語が読める
  • HTML, CSS, Javascriptが少しわかる
  • Bootstrapのドキュメントをみて、HTMLが書ける
  • Ajax(非同期通信)を利用したことがある
  • SESSIONを利用したことがある

構築環境

  • Windows10
  • XAMPP(PHP7.3.2, MariaDB 10.1.38)

共通のJavascriptを実装

今回の通信は、submitではなく、非同期通信で行います。まとめて処理を書きたいので、共通のJavascriptを整備して行きたいと思います。
Controller側で必要なのは、2つのパラメータになります。

  1. process クラス名で、拡張子(.php)をつけるとファイル名
  2. method 関数名 クラスの中の関数名になります

2つのパラメータを送信しないと、処理が実行されない仕掛けになっています。
パラメータは、metaタグに値として入れようかと思います。(hiddenでも良いのですが、今回はあまり関係ないのでmetaタグにします)

早速非同期部分の共通化に着手しようと思います。

assets/js/script.js

まず、非同期部分のコードから追記していきます。

/assets/js/script.js(抜粋)
[javascript highlight=””] /* XHR */
/* xhrのパス(URL)を記載します。index.phpがある部分を対象にしています。 */
var api = ‘/pjin/admin/api/’;
function _$xhr(data, callback){
/* 全体をtry-catchで囲む必要はあまりないですが、念のため */
try{
$.ajax({
url: api,
type: ‘POST’, /* http method は POST 限定 */
data: data,
dataType: ‘json’
}).done((json, status, xhr) => {
/* 内容をconsoleに出力 */
console.log(‘done’, json, status, xhr);
/* trait(Result)の定義でstatusがあるので、成功したか確認 */
if(json.status == ‘success’){
/* 成功した場合は、callback関数を実行 */
callback(json);
}else{
/* アプリケーションで失敗した場合は、画面にエラーを表示 */
displayError(json.errors);
}
}).fail((xhr, status) => {
/* そもそも非同期通信に失敗、画面にエラーを表示 */
console.log(‘fail’, xhr, status);
displayError(status);
}).always(() => {
/* ここは成功時も失敗時も必ず通る */
console.log(‘always’);
});
}catch($e){
/* jQueryのCDN未指定などの場合にここに来ます。 */
console.log($e);
}
}
/* エラーを表示します */
function displayError(status){
/* エラーメッセージのテンプレート */
var $alert = [
‘<div class="alert alert-danger" role="alert" style="text-align:left;">’,
‘ <h3><i class="fas fa-exclamation-triangle"></i> ERROR</h3>’,
‘ <hr>’,
‘ %alertMessage%’,
‘</div>’,
].join(”);
/* statusの型チェック */
if($.type(status) == ‘object’){
/* objectの場合は、キー、値の組み合わせに変更 */
var items = Object.entries(status).map(([key, value]) => ({key, value}));
var alertMessage = ”;
/* 全てのメッセージを出力します */
$.each(items, function(idx, el){
alertMessage += ‘<p class="ps-3">’+el[‘value’]+'</p>’;
});
/* テンプレートから%alertMessage%の部分を置換します */
$alert = $alert.replace(‘%alertMessage%’, alertMessage);
}else{
/* テンプレートから%alertMessage%の部分を置換します */
$alert = $alert.replace(‘%alertMessage%’, ‘<p class="ps-3">’+status+'</p>’);
}
/* class="error" と指定がある要素にエラー情報を追加します。 */
$(‘.error’).append($alert);
}
[/javascript]

大きく2つの関数を定義しています。

  1. _$xhr(data, callback)
  2. displayError(status)

_$xhr(data, callback) は非同期通信部分を担当しています。引数は2つで、dataはFORM要素をserializeArray()したもの又は、{name: ‘name’, value: ‘value’} の形式で配列を想定しています。
また、index.php(リクエストの受け口)は、processmethod を受取ることを前提としているので、[{‘name’: ‘process’, ‘value’: ‘index’},{‘name’: ‘method’, ‘value’: ‘doMain’}] とControllerのファイル名とメソッド名が入っていることを想定しています。
callbackは非同期通信終了後に引数としてレスポンスのjsonを受取る関数を想定しています。関数の最初に _ を入れているのはシステムで利用しますよ!とかprivateですよとかいう意味で利用することが多いです。

displayError(status) は非同期通信部分の失敗(アプリケーションのチェックによる失敗や、非同期通信での失敗)時に、画面にエラーを表示する関数です。

続いて、processとmethodを決定する部分の共通化をしていきたいと思います。また、非同期通信部分の共通化を行います。

/assets/js/script.js(抜粋)
[javascript highlight=””] /* プロセスの決定(Controllerファイル名) */
function $process(process){
/* metaタグに持つ予定なので、メタタグのcontentにセット */
$(‘meta[name=process]’).attr(‘content’, process);
}
/* メソッドの決定(Controller内の関数名) */
function $method(method){
/* metaタグに持つ予定なので、メタタグのcontentにセット */
$(‘meta[name=method]’).attr(‘content’, method);
}
/* $paramは非同期通信で送信するオブジェクト(FORM要素ないのserializeArrayしたもの */
function routeControl($param){
/* metaタグに設定してあるprocessとmethodを送信データに追加します */
$param.push({‘name’: ‘process’, ‘value’: $(‘meta[name=process]’).attr(‘content’)});
$param.push({‘name’: ‘method’, ‘value’: $(‘meta[name=method]’).attr(‘content’)});
return $param;
}
/* validation */
function validation($forms){
var result = true;
/* FORM要素分ループします */
$forms.each(function(idx, form){
/* 各要素(input, select, textarea)のcheckValidityを実行 */
if (!form.checkValidity()) {
/* エラーがある場合は、falseを返却 */
result = false;
}
/* 要素にwas-validated(validation終了)のクラスを追加 */
$(form).addClass(‘was-validated’);
});
return result;
}
/* 非同期通信の呼び出し部分 */
function $xhr($form, callback){
/* 送信するデータはFORM要素 + process + method */
var data = routeControl($form.serializeArray());
/* エラー表示領域をクリア */
$(‘.error’).empty();
/* 入力チェックを実施 */
if(!validation($form)){
/* 入力チェックがNGの場合は、終了 */
return false;
}
/* 入力チェックOKの場合は、非同期通信を実行 */
_$xhr(data, callback);
}
[/javascript]

今回は、5つのメソッドを追加しています。

  1. $process(process)
  2. $method(method)
  3. routeControl($param)
  4. validation($forms)
  5. $xhr($form, callback)

$process(process) metaタグにprocessを設定 ※HTMLには後程metaタグを追加する

$method(method) metaタグにmethodを設定 ※HTMLには後程metaタグを追加する

routeControl($param) metaタグに設定された、processとmethodを、非同期の送信パラメータに追加します。配列なのでpushして、形式を{name: ‘name’, value: ‘value’}にしています。

validation($forms) bootstrap標準のValidationの仕掛けをjQueryで書き直し、実行できるようにしたものです。

$xhr($form, callback) 非同期通信を受取ります。$form はFORM要素を受取ります。毎回 serializeArray を呼ぶのが面倒なので共通化。また、processとmethodを送信パラメータに追加。Validation(入力値チェック)を実施後、送信処理を実行。

ここまでで、ひとまず非同期通信のJavascriptは実装が完了しました。
ログインから順番に実装していきたいのですが、ユーザ情報のパスワードは暗号化されているため、パスワードをPHPで作成し、登録する必要があります。
ですので、一番最初は、ユーザを登録する部分から実装していきたいと思います。
きりが良いので、今回はここまでとします。

魁!小野の塾