プログラミング

PHPポケモン「オートローダー編」16

PHP PHPポケモン ポケモン
PHPポケモン「オートローダー編」16

 

今までは技やタイプを一括requireという荒業で対応していましたが、フシギダネ系列の技を実装した際に「こんなん全部読み込んでられるか!」と流石になったので、簡易ながらオートローダーを実装していきます。

そして、実装したらしたで色々と問題も浮かび上がってきたので、このあたりは回を進めて行きながら修正予定です。

 

それでは今回はPHPのオートローダー(autoloader)についてご紹介します。

 

一部解釈ミスがあったので、本記事の修正版を挙げています。本記事も参考にしながら本格的且つ簡易的なオートローダーは次記事をご参考ください

PHPポケモン「オートロード編(修正版)」17 おまけ:日本語化 PHPポケモン「オートロード編(修正版)」17 おまけ:日本語化

  前回実装したオートローダーの使い方が盛大に間違っていたので、今回その間違いの説明をしながら、正しい実装方法をご紹介します。 申し訳ありません。(誠意)    オートロードについて(再)  必要なタイミングで必要なファイルをrequireまたはincludeするあれです。   前回spl_autoload_reg...

 

オートローダーとは

簡単に言えば、必要な時に必要なファイルを自動的に読み込む便利な機能のことです。

 

PHPであればspl_autoload_registerという関数使って、指定したファイルをrequireincludeすることができます。 

  

簡易オートローダーの作成

とは言っても、今回は全てのファイルをオートローダーを使って読み込むようなことはしません。あくまで使用するのは「ポケモン」「」「タイプ」というデータベースの用にしているファイルのみです。

※現段階は上記3つですが、必要に応じて増やしていきます

 

通常オートローダーはクラスで作成されますが、インスタンス化するのも面倒なので今回はトレイトで作成します。

※もし都合が悪くなればクラスに変更予定です

 

オートローダー(/Traits/AutoLoaderTrait.php
<?php
 
trait AutoLoaderTrait
{
    /**
    * オートローダー
    *
    * @param string $class_name
    * @param string $folder
    * @return void
    */
    protected function autoLoader($class_name, $folder='')
    {
        if(!empty($folder)){
            // フォルダ指定されていれば最後にスラッシュを付与
            $folder = $folder.'/';
        }
        spl_autoload_register(function($class_name) use($folder){
            // クラス名からファイルを検索
            $path = __DIR__ . '/../Classes/'.$folder.$class_name.'.php';
            if(file_exists($path)){
                // 見つかった場合は読み込み実行
                require $path;
            }
        });
    }
}

 

それではautoLoaderのメソッドを見ていきましょう。

protected function autoLoader($class_name, $folder='')
{
    if(!empty($folder)){
        // フォルダ指定されていれば最後にスラッシュを付与
        $folder = $folder.'/';
    }
    spl_autoload_register(function($class_name) use($folder){
        // クラス名からファイルを検索
        $path = __DIR__ . '/../Classes/'.$folder.$class_name.'.php';
        if(file_exists($path)){
            // 見つかった場合は読み込み実行
            require $path;
        }
    });
}

 

引数の1つ目はクラス名です。渡されたクラス名は読み込む対象となるファイル名として使用されるため、必ず作成したクラス名とファイル名は一致させておきましょう。

第2引数では、フォルダを選べる仕様です。オートローダーでは、指定のクラスがどのパスに存在しているかを探し出さなければなりません。ですが、様々な階層を調べるのはそれだけでも大きな手間になります。今回はオートローダーを使ったファイルの読み込み、現状Classesフォルダ以下に限定されているため、ポケモンであればPokemon、技であればMoveのように選んで読み込みができるようにしています。

※現仕様では上位階層のファイルも読み込めてしまいますが、今回はスルーします。もし参考にシステムへ組み込もうと考えている人はご注意ください。

 

ではsql_autoload_registerについて見てみましょう。

spl_autoload_register(function($class_name) use($folder){
    // クラス名からファイルを検索
    $path = __DIR__ . '/../Classes/'.$folder.$class_name.'.php';
    if(file_exists($path)){
        // 見つかった場合は読み込み実行
        require $path;
    }
});

 

第1引数にはコールバック関数が渡されます。今回は無名関数を引数に記述しています。

コールバック関数の引数にはクラス名が入ります。今回は$folderも使用したいので、useを使ってコールバック関数内で使えるように変数を渡しています。

あとは、パス作成して存在をチェック、もし見つかればrequireするといった単純な仕様になっています。

  

インスタンス化トレイトの修正

 それでは作成したオートローダーを使って、該当クラスのファイルを読み込んでいきましょう。まずは前回作成したインスタンス化トレイトの修正からです。

 

インスタンス化トレイト(/Traits/InstanceTrait.php
<?php
 
trait InstanceTrait
{
 
    /**
    * インスタンス化関数
    * @param string $class_name
    * @return object
    */
    protected function getInstance($class_name)
    {
        // 存在チェックをして読み込み
        if(class_exists($class_name)){
            return new $class_name();
        }
    }
 
    /**
    * ポケモンのインスタンス化関数
    * @param string $class_name
    * @return object
    */
    protected function getPokemonInstance($class_name)
    {
        // ポケモンフォルダを指定してオートローダーを実行
        $this->autoLoader($class_name, 'Pokemon');
        return $this->getInstance($class_name);
    }
 
    /**
    * 技のインスタンス化関数
    * @param string $class_name
    * @return object
    */
    protected function getMoveInstance($class_name)
    {
        // ポケモンフォルダを指定してオートローダーを実行
        $this->autoLoader($class_name, 'Move');
        return $this->getInstance($class_name);
    }
 
    /**
    * タイプのインスタンス化関数
    * @param string $class_name
    * @return object
    */
    protected function getTypeInstance($class_name)
    {
        // ポケモンフォルダを指定してオートローダーを実行
        $this->autoLoader($class_name, 'Type');
        return $this->getInstance($class_name);
    }
}

ポケモン用、技用、タイプ用の3つを追加しました。それぞれに用意したのは、array_mapのコールバック関数で使用している関係上、引数でフォルダを指定するとなれば少し複雑化してしまうため、今回は必要数用意するという方法を取りました。

 

それぞれ、呼び出されたタイプに合わせてオートローダーを実行してからインスタンスの取得をしています。 

これで、数多くのrequire_onceをせずに欲しいクラスのファイルだけを取得することが可能です。

 

ポケモンクラスの修正

 では、技やタイプを呼び出しているポケモン回りから修正を加えていきましょう。

 

ポケモンクラス(/Classes/Pokemon.php
<?php
require_once(__DIR__.'/../Traits/AutoLoaderTrait.php');
require_once(__DIR__.'/../Traits/ResponseTrait.php');
require_once(__DIR__.'/../Traits/InstanceTrait.php');
require_once(__DIR__.'/../Traits/Pokemon/SetTrait.php');
require_once(__DIR__.'/../Traits/Pokemon/GetTrait.php');
 
// ポケモン
abstract class Pokemon
{
    use AutoLoaderTrait;
    use ResponseTrait;
    use InstanceTrait;
    use SetTrait;
    use GetTrait;
 
--省略
 
    /**
    * 現在のレベルで覚えられる技があるか確認する処理
    *
    * @var integer
    */
    protected function checkMove()
    {
        // レベルアップして覚えられる技があれば習得する
        $level_move_keys = array_keys(array_column($this->level_move, 0), $this->level);
        foreach($level_move_keys as $key){
            $move_class = $this->level_move[$key][1];
            // オートローダーを使った技クラスの読み込み
            $this->autoLoader($move_class, 'Move');
            // 覚えようとしている技(クラス)が存在かつ重複していないか
            if(class_exists($move_class) && !in_array($move_class, $this->move, true)){
                // 技クラスをセット
                $this->setMove($move_class);
                // インスタンス化
                $move = new $move_class();
                $this->setMessage($move->getName().'を覚えた!', 'success');
            }
        }
    }
 

 

 まずページの最初で、作成したオートローダーのトレイトを読み込みます。不要になった一括読み込み用のIncludeは削除しました。

次に、技の確認用メソッド(checkMove)です。今まではすべての技ファイルが既に読み込まれていましたが、今回は必要に応じて読み込めば良いので、class_existsの前に技指定でオートローダーを実行させました。

 

次に、タイプの読み込みもしなければならなのでGet関係のメソッドを見直しましょう。

 

Get格納トレイト(/Traits/Pokemon/GetTrait.php
/**
* 覚えている技の一覧を取得する
* @return array
*/
public function getMove()
{
    // array_mapで配列内の技クラスをインスタンス化
    return array_map([$this, 'getMoveInstance'], $this->move);
}
 
--省略
 
/**
* タイプの取得
*
* @param string|array|object $return
* @var void
*/
public function getTypes($return='object')
{
    /**
    * タイプ名の取得用関数
    * @param object
    * @var string
    */
    function getTypesName($obj){
        return $obj->getName();
    }
    // array_mapで配列内のタイプクラスをインスタンス化
    $types = array_map([$this, 'getTypeInstance'], $this->types);
    switch ($return) {
        case 'string':
        // array_mapでタイプ名の配列にしたものを、implodeで文字列に変換
        $types = implode(',', array_map('getTypesName', $types));
        break;
        case 'array':
        // array_mapでタイプ名の配列にして返却
        $types = array_map('getTypesName', $types);
        break;
    }
    return $types;
}

 

技の一覧取得用メソッド(getMove)と、タイプ取得用メソッドにオートロードを追加しました。これでrequire_once地獄から抜け出すことが出来ました。

※現状だと一部class_existsによるオートロードが働いています。こちらは別回で修正予定です。

 

 

まとめ

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

今回のPHPポケモンでは「オートローダーの実装」をご紹介しました。

0からの構築をすると、回を進めて行くごとに粗が目立ったり「こうしておけば良かった」というのがどんどん浮かんできます。本来の開発では設計書や仕様書を作り進めていくことをオススメしますが、学習目的であればプログラミングの理解を深めていくためのきっかけにもなります。

現在学習中の方は、ぜひ参考にしてくださいね。

 

注目の記事

HTMLの基本設計「よくわかるSEO対策」構造化(マークアップ)編
SEO対策
HTML,SEO,マークアップ
HTMLの基本設計「よくわかるSEO対策」構造化(マークアップ)編

  HTML5がリリースされて随分経ちました。 それにより多くのタグが増え、それにより今までデザインを目的と使用されていたものが「構造化」という本来の役割を持たされるようになりました。    構造化は、目に見えにくい部分です   それぞれの役割を理解していなければ、せっかくきれいなサ...

コンテンツ配信業でバズるために大切な3つの法則〜『1ヶ月でチャンネル登録者数1000人』は参考にするな
マーケティング
YouTube,YouTuber,ブログ
コンテンツ配信業でバズるために大切な3つの法則〜『1ヶ月でチャンネル登録者数1000人』は参考にするな

  YouTubeやブログを始めたけど思ったように伸びない・・・   こういった人は、チャンネル登録者数を伸ばす方法などの動画を見ても参考にならなく、結果に繋がらないという場合がほとんどです。 その理由は、その人自身に問題があるわけではなく、動画の前提条件がそもそも違っているからです。   今回は「...

PHPポケモン(α)攻略wiki「稼ぎ方特集」
雑記
PHP,PHPポケモン,ポケモン
PHPポケモン(α)攻略wiki「稼ぎ方特集」

前回に引き続き、連続wiki投稿でPHPポケモン溺愛ユーザーにとっては歓喜の2日間です。   という冗談も踏まえつつ、今回は「稼ぐ」ということについて真面目に考察してみたいと思います。もしリアル世界での「稼ぐ」を目的に来た人は、盛大にブラウザバックしてください。   PHPポケモンにおける「稼ぐ」...

数字が増える毎日投稿テクニック【銀の弾丸はありません】
ライティング
YouTuber,ブロガー,銀の弾丸
数字が増える毎日投稿テクニック【銀の弾丸はありません】

  まずは以下のグラフを御覧ください。     私が管理しているYouTubeのチャンネルで、1日投稿ができない日がありました。 そうすると、その日がいつなのかすぐわかるぐらい露骨に視聴者数が減ったのです。それほど、毎日投稿することは結果に大きく影響します。   今回は、本ブログで何度も切り口を変え...

PHPポケモン「バトルシステム編〜努力値の獲得〜」33
プログラミング
PHP,PHPポケモン,ポケモン
PHPポケモン「バトルシステム編〜努力値の獲得〜」33

努力値の実装 今回はポケモンのやりこみ要素の一つ、努力値システムを導入します。既に努力値の項目は「ピカチュウで学ぶオブジェクト指向」の段階で実装し、ステータス計算にも判定済みですが、肝心な「努力値を獲得する仕組み」自体は出来ていませんでした。なので、バトルシステムも終盤となったこのタイミングで...

進化直後の技習得編 PHPポケモン 65
プログラミング
PHP,PHPポケモン,ポケモン
進化直後の技習得編 PHPポケモン 65

進化直後の技習得 パーティー機能を導入に合わせて、至る場所を修正することになり、合わせて未実装だった機能を導入していきます。 見た目にはわからない部分や、とある条件が重ならなければ起こらない部分の作り込みが多いため、プレイユーザー目線からすると少し面白みが無いかも知れません。 ですが、そういっ...

ノーコード開発で将来プログラミングは不要?我々は何を学ぶべきなのか
プログラミング
amazon,AWS,Honeycode,NoCode,プログラミング学習
ノーコード開発で将来プログラミングは不要?我々は何を学ぶべきなのか

  近年、プログラミングの需要は増え勢いを増していますが、それ以上にノーコードというソースコードを打たなくでもアプリ開発ができるというソフトウェアやプラットフォームが普及してきました。 これにより一部の期待感とは別に、プログラマーという職業は今後不要になるのではないかと危機感を抱く人が出て...

【Wi-Fi6とは】スマホやPCの買い替えは必要?騙されないための基礎知識
ネットワーク
5G,IEEE 802.11ax,Wi-Fi
【Wi-Fi6とは】スマホやPCの買い替えは必要?騙されないための基礎知識

  本格的に5G普及への取り組みが始まり、Wi-Fi6といった新世代の規格が出たことによって、超情報化社会へ加速しました。 ですが、こういったナンバリングが一般化することによって、わからずに高性能な機器を斡旋されて無駄な購入をさせられたり、わからないことを理由に詐欺的営業を仕掛けてくる悪意ある人...

カテゴリ

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 独立 神戸 福祉 秘密鍵 翻訳 自己啓発 英語 見積書 計算機 読書 起業 迷惑メール 配列 銀の弾丸 集客 雑学力