プログラミング

引き継ぎ考慮のメッセージID重複回避編 PHPポケモン 58

PHP PHPポケモン ポケモン
引き継ぎ考慮のメッセージID重複回避編 PHPポケモン 58

今回のPHPポケモンでは内部の作り込みをしていきます。見た目への反映は無いので、プレイを楽しみにしている人や、ポケモンが好きで毎日チェックしてくれているような人は、ブラウザをバックしてもらって問題ありません。

 

それでは、前々回辺りから保留にしていた「メッセージIDに重複回避対策」についてです。

 

引き継ぎ処理による重複対策

メッセージIDが重複しないように、セッションに生成した値を格納していましたが、処理が終わればすべて破棄して次の処理へ移行しています。その関係上、技習得で導入したレスポンスやメッセージ、モーダルの引き継ぎで「引き継いだデータで使用されているIDと重複する可能性」が出てきてしまいました。

接頭語を除けば16桁のランダム文字列を生成しているため、これが多くても10個程度の新しく生成したIDと重複する可能性はほぼ0%と言っても良いでしょう。しかし、問題は「0ではない」ということです。0ではない以上は対策が必要です。

 

それでは対策方法についてです。

メッセージの引き継ぎがあった場合、そのIDを重複チェック用のセッションに格納します。これをメイン処理の前に行うことで、メッセージIDの重複チェックの対象に引き継いだメッセージIDも含めていきましょう。

 

まずはコントローラーの親クラスのコンストラクタに以下の判定を追加しましょう。

 

コントローラー(/App/Controllers/Controller.php
// メッセージIDの重複回避
if(
    isset($_SESSION['__data']['before_reponses'])
    || isset($_SESSION['__data']['before_messages'])
    || isset($_SESSION['__data']['before_modals'])
){
    $this->avoidMessageId();
}

 

issetを使って、引き継ぎがされているかをチェックしています。もし該当セッションにデータが格納されていれば、avoidMessageIdというメソッドを呼びだして、既に使用されているメッセージIDを取り出します。

 

array_filterを使った抽出

それでは、IDの抽出方法について見ていきましょう。これにはarray_filter関数を使用します。

 

第1引数に対象となる配列を指定し、第2引数でコールバック関数を指定します。

第1引数では、メッセージIDを値とした配列を指定する必要があるので、技習得時に引き継ぎ処理でも使用したarray_keysまたはarray_columnを使いましょう。

 

レスポンスからIDを抽出
array_keys($_SESSION['__data']['before_responses'])
メッセージからパラメーターを抽出
array_column($_SESSION['__data']['before_messages'], 1)
モーダルからパラメーターを抽出
array_column($_SESSION['__data']['before_modals'], 0)

 

レスポンスにはキーとして、メッセージには配列の2番目(添字1)、モーダルには1番目(添字0)にメッセージIDが格納されています。なので、それぞれに合わせた方法で取り出しました。

 

ですが、これではレスポンスの場合はメッセージID以外の添字やキー、メッセージとモーダルには空の値などが含まれることになります。なので、ここからメッセージIDのみを抽出するため、array_filterの第2引数のコールバック関数で判定を行います。

// array_fillterコールバック用関数
function callback($msg_id){
    // 行頭にmsgがついているかを判定
    return preg_match('/^msg/', $msg_id);
}

 

preg_matchを使って正規表現で、行頭がmsgで始まるものだけを判定しました。もし一致すれば1、一致しなければ0が返り値となり、1が返った場合だけarray_filterの返り値として配列に格納されていきます。

 

例として、レスポンスからメッセージIDを抽出する処理を見てみましょう。

// 格納用の空配列
$results = [];
// array_fillterコールバック用関数
function callback($msg_id){
    // 行頭にmsgがついているかを判定
    return preg_match('/^msg/', $msg_id);
}
// レスポンス
if(isset($_SESSION['__data']['before_responses'])){
    $results = array_filter(
        array_keys($_SESSION['__data']['before_responses']),
        'callback'
    );
}

 

メソッド内でコールバック用の関数を事前に用意しておき、array_filterで呼び出しています。抽出結果は変数の$resultsに格納していきます。

 

array_diffによる差分チェック

次に、抽出したIDの差分チェックを行います。例えば、レスポンスとメッセージを引き継いだ場合、もちろんそこには同じIDが含まれることになります。重複チェック用のセッション内で既に重複した値が入っているのはおかしいので、もし取り出した値が既に抽出されていなければ結果へ追加するという処理が必要になります。

そのために配列の差分をチェックするarray_diff関数を使用します。 

 

第1引数には比較元の配列、第2引数以降には比較対象の配列が入ります。今回のケースであれば、まずレスポンスからメッセージIDを抽出して$resultsに格納しています。メッセージからメッセージIDを抽出して、その結果が$resultsとかぶっているものは必要ありませんね。

array_diffでは、比較元(第1引数)の中で比較対象(第2引数以降)には無い値を配列として返り値にするので、第1引数に新しく取り出した配列、第2引数に$resultsを指定して差分を取り出します。

メッセージからIDを抽出するケースを見てみましょう。

$msg_ids = array_filter(
    array_column($_SESSION['__data']['before_messages'], 1),
    'callback'
);
$diff = array_diff($msg_ids, $results);

 

これで$diffに、既に取り出されたメッセージID以外のメッセージIDが格納することができます。

最後にこの結果を$resultsに追加するためのarray_mergeを使用しましょう。 

// メッセージ
if(isset($_SESSION['__data']['before_messages'])){
    $msg_ids = array_filter(
        array_column($_SESSION['__data']['before_messages'], 1),
        'callback'
    );
    // 結果の差分を格納
    $results = array_merge($results, array_diff($msg_ids, $results));
}

これで差分だけを$resultsに追加することができました。

 

以下、avoidMessageIdメソッドの最終コードです。

/**
* メッセージIDの重複回避
*
* @return void
*/
private function avoidMessageId()
{
    // 格納用の空配列
    $results = [];
    // array_fillterコールバック用関数
    function callback($msg_id){
        // 行頭にmsgがついているかを判定
        return preg_match('/^msg/', $msg_id);
    }
    // レスポンス
    if(isset($_SESSION['__data']['before_responses'])){
        $results = array_filter(
            array_keys($_SESSION['__data']['before_responses']),
            'callback'
        );
    }
    // メッセージ
    if(isset($_SESSION['__data']['before_messages'])){
        $msg_ids = array_filter(
            array_column($_SESSION['__data']['before_messages'], 1),
            'callback'
        );
        // 結果の差分を格納
        $results = array_merge($results, array_diff($msg_ids, $results));
    }
    // モーダル
    if(isset($_SESSION['__data']['before_modals'])){
        $msg_ids = array_filter(
            array_column($_SESSION['__data']['before_modals'], 0),
            'callback'
        );
        // 結果の差分を格納
        $results = array_merge($results, array_diff($msg_ids, $results));
    }
    // 重複回避用セッションに格納
    $_SESSION['__message_ids'] = $results;
}

 

これで、引き継ぎも含めたメッセージIDの重複を回避することができるようになりました。

 

まとめ

いかがだったでしょうか。

今回のPHPポケモンでは、引き継ぎも含めたメッセージIDの重複回避方法をご紹介しました。

 

プログラミング上達のコツは「どうなっているか」がどれだけ理解出来ているかです。コピペでもサイトやシステムは動作しますが、それを本格的に自分のものにしていくためには、やはり「どの処理で、どの値が、どうなっているか」をしっかりと理解できていなければなりません。

また、便利な関数をどれだけ使いこなせるかも、よりスマートかつ負担の少ないシステムを作り上げるためには必要なことです。そして、関数すべてを覚える必要はありません。必要に応じて再現できる関数があるかどうかを公式マニュアルなどを参考にしながら探して、それを使えれば良いのです。

その中でも、コールバック関数を引数として必要とするような関数は、その結果や記述方法がややこしくなりがちです。そういったときは、オンラインエディターなどを使って、細かくどういった値が返却されるのかをチェックしていくと良いでしょう。

 

現在プログラミング学習に取り組んでいる方や、WEBプログラミングに興味がある人は、ぜひ参考にしてみてくださいね。

 

注目の記事

ポケモン図鑑編 PHPポケモン 88
プログラミング
PHP,PHPポケモン,ポケモン
ポケモン図鑑編 PHPポケモン 88

ポケモン図鑑とは ポケモンに出会ったり、仲間にしたりすると、ポケモン図鑑のデータがどんどんと埋まっていきます。PHPポケモンでもこの仕組みを実現させるために、ポケモン図鑑を作成していきましょう。   クラスによる管理 ポケモン図鑑はクラス管理をしていきます。プレイヤー1人に対して1つのポケモン図...

PHPポケモン「タイプ実装編」15
プログラミング
PHP,PHPポケモン,ポケモン
PHPポケモン「タイプ実装編」15

ポケモンのタイプについて  2020年剣盾シリーズでのポケモンでは、全18タイプが実装されています。初代では15タイプ(あく、はがね、フェアリーを除く)からスタートして、たった3つのタイプしか増えていない、と感じる方もいるかも知れませんが、この追加に関してもバトルの歴史を大きく動かしてきたのです...

ピカチュウから学ぶオブジェクト指向 〜ステータス導入編〜 6
プログラミング
PHP,PHPポケモン,オブジェクト指向,ポケモン
ピカチュウから学ぶオブジェクト指向 〜ステータス導入編〜 6

  PHPをピカチュウ(ポケモン)から学ぶ大人気コーナー、第6回目は「ステータス機能の導入編」です。   前回(第5回)で終了段階でのサンプルコードを公開しているので、もし本記事から始める人はぜひそちらを参考にしてください。    ※お詫び   調べたところによると、ポケモンの経験...

【脱初心者向けプログラミング学習】処理を追え!「今、変数には何が入ってる?」
プログラミング
HTML,PHP,プログラミング学習
【脱初心者向けプログラミング学習】処理を追え!「今、変数には何が入ってる?」

  初心者から中々抜け出せない 1から処理をかけない   そんな悩みを抱えたプログラミング学習者に向けて、「脱初心者のためのプログラミング学習」についてPHPを例にまとめました。 やり方自体は同じですので、他の言語をメインとしている人は自分の環境に置き換えながら学習して、初心者から抜け出しましょ...

HPバーアニメーション 後編 フロント側の対応 PHPポケモン 44
プログラミング
PHP,PHPポケモン,ポケモン
HPバーアニメーション 後編 フロント側の対応 PHPポケモン 44

HPバーアニメーション それでは前回に続き、HPバーのアニメーションづくりをしていきましょう。前回、メッセージに合わせてレスポンスを返却するというサーバー側の仕組みを作成しました。なので、今回はそれをフロント側で受け取り、タイミングよくアニメーションで再現します。   フロント側(js)の処理 前回...

捕獲処理実装編 PHPポケモン 80
プログラミング
PHP,PHPポケモン,ポケモン
捕獲処理実装編 PHPポケモン 80

捕獲処理の作成 前回モンスターボールのクラスを作成したので、今回は捕獲判定までの一連の処理を仕上げていきます。サービス自体は他のアイテムと一緒にするためItemServiceを呼び出し、その中で使用されたアイテムを判断して分岐を作ります。   バトル中のアイテムサービス(/App/Services/Battle/ItemService.ph...

ポケモンセンター編 PHPポケモン 37
プログラミング
PHP,PHPポケモン,ポケモン
ポケモンセンター編 PHPポケモン 37

ポケモンセンター  バトルシステムを作る関係上、どうしてもダメージを受けることが多くなってきたので、そろそろポケモンセンターを建設(作成)します。 とは言っても、ポケモンセンターに行って交換やらボックス整理などができるわけではなく、ただ回復ポイントを設置するだけの簡単な処理です。   HPの回復 ...

SEO対策で役立つ!ライティングスキルを向上させる3ステップ
ライティング
SEO,ブログ
SEO対策で役立つ!ライティングスキルを向上させる3ステップ

  ブログやメール、SNSなどライティングスキルが問われる場面が多く、それは質に直結しています。各プラットフォームによって特徴はありますが、基礎的な文章力自体がついていれば多様な場面で役立つことは間違いありません。 文章の質が高くなれば、ブログであればSEOに強い価値のあるサイトになりますし、SNS...

カテゴリ

SEO対策 イベント デザイン ネットワーク ビジネスモデル フリーランス プログラミング マーケティング ライティング 動画編集 雑記

タグ

5G Adobe AfterEffects AI ajax amazon Animate api artisan atom Automator AWS Bluetooth CSS CVR description EC-CUBE4 ECショップ ESLint Facebook feedly foreach function Google Google AdSense Honeycode htaccess HTML IEEE 802.11ax Illustrator Instagram IoT JavaScript jQuery jQuery UI keyword LAN Laravel Linux MacBook MAMP meta MLM MySQL NoCode note OS OSI参照モデル Paypal Photoshop PHP phpMyAdmin PHPポケモン PremierePro rss SEO SEO対策 Sequel Pro Skype SNS SSH Symfony TCP/IP title Toastr Trait Twig Twitter UCC V系 WAN WebSub Wi-Fi wiki Windows WordPress XAMPP xml Xserver YouTube YouTuber Zoom アーティスト アウトプット アクセス層 アニメーション アフィリエイト イーブイ インターネット インプット エンジニア オブジェクト指向 お金配り クリック単価 クリック数 コミュニケーション能力 コロナ コンサルティング サムネイル システムエンジニア スタートアップ スタイルシート スパム データベース ディープフェイク デザイナー デザイン テレワーク ナンパ ニュース ネットワークモデル ノマドワーク バナー ピカチュウ ビジネス フィード フリーランス ブロガー ブログ プログラマー プログラミング プログラミング学習 プログラミング教育 プロトコル ホームページ制作 ポケモン マークアップ マーケティング メール リモートワーク レンダリング 三井住友 三宮 仕事依頼 児童デイ 児童デイサービス 児童発達支援 公開鍵 初心者 助成金 勉強法 営業 広告 広告収入 必勝マニュアル 放課後等デイサービス 朝活 楽天 深層学習 無線LAN 独立 神戸 福祉 秘密鍵 翻訳 自己啓発 英語 見積書 計算機 読書 起業 迷惑メール 配列 銀の弾丸 集客 雑学力