プログラミング

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

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

 

注目の記事

PHPポケモン(α)攻略wiki「最初のポケモン」
雑記
PHPポケモン,wiki,ポケモン
PHPポケモン(α)攻略wiki「最初のポケモン」

リリースから一ヶ月、遂にPHPポケモン(α)の攻略Wiki(仮)が公開です!   というのは大嘘で、内部の大幅変更の関係上、今回はPHPポケモンをプレイするにあたってのオススメなどをまとめて見た次第です。 ちなみに、バトルシステム自体は本家に沿って作成しているので、種族値や技性能に精通している人はブラウザ...

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

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

ピカチュウから学ぶオブジェクト指向 〜クラス継承編〜 2
プログラミング
PHP,PHPポケモン,オブジェクト指向,ポケモン
ピカチュウから学ぶオブジェクト指向 〜クラス継承編〜 2

  ピカチュウから学ぶオブジェクト指向の第2弾はオブジェクトの継承についてです。 前回作成したピカチュウクラスを使用するので、もし基礎的な内容を学習したい人は、以下の記事を参考にしてください。   オブジェクトの継承が理解できれば、複雑で規模の大きなシステムを構築することができるようになり...

プログラミングで躓く人必見!一人前になるためのSDCとは
プログラミング
プログラミング学習
プログラミングで躓く人必見!一人前になるためのSDCとは

  「プログラミング学習を始めたけど中々身につかない」 「挑戦したいけど何から始めればいいかわからない」   プログラミング教育が始まるとともに、プログラミング学習のニーズも日々高まってきています。ですが、興味はあっても中々挑戦までは至らなかったり、始めたは良いものの現実は厳しく躓いてし...

なぜ、お金を配るの?悪質メール・SNSを利用した詐欺的手法への対処法とは
ネットワーク
amazon,SNS,Twitter,お金配り,楽天,迷惑メール
なぜ、お金を配るの?悪質メール・SNSを利用した詐欺的手法への対処法とは

定期的に書きたくなるコラムのコーナー! 今回は、迷惑メールやSNSのDMを活用した悪質な勧誘、巷で流行っているお金配りを隠れ蓑のした巧妙な詐欺的手法などをいくつかご紹介、その対策・リクス回避の方法をまとめました。   まず結論からお伝えすると 「怪しいと思うなら手を出すな」 です。その詳細を知りたい...

できるやつの「雑学力」
雑記
勉強法,雑学力
できるやつの「雑学力」

  テレビのコメンテーター、討論番組の出演者で活躍するほとんどの人は物知りだ。 あなたも「よくそんなことまで知っているな」と思ったことはあるだろう。 現代で起業して成功し続ける人のほとんどが、常に新しい情報を取り入れている。 そして得た情報に対して、歴史情報と照らし合わせ、自分なりの意見や解釈を...

大半のネットワークビジネスが成立しない理由とは【権利収入の落とし穴】
マーケティング
MLM
大半のネットワークビジネスが成立しない理由とは【権利収入の落とし穴】

  誘われたけど、欠点が上手く説明できない 権利収入って本当にもらえるの?   ネットワークビジネスと聞けば、良い印象を抱かない人がほとんどでしょう。ですが、「何故?」と問われて説明できる人は意外にも少数派です。 そして、SNSを積極的に活用している人ならば、一度は誘いを受けたことがあるの...

フリーランスが打ち合わせで押さえておきたい3つのポイント【収入アップします】
フリーランス
フリーランス,営業
フリーランスが打ち合わせで押さえておきたい3つのポイント【収入アップします】

  フリーランスになれば、デザイナーやプログラマーといった制作をメインとする仕事の人でもクライアントと打ち合わせをしなければいけません。 特に独立や起業前のキャリアとして営業職に縁がなかった人からすれば、打ち合わせが苦手な人は多いはずです。   今回は、そういった営業ベタでやり方が分からない...

カテゴリ

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