プログラミング

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ポケモン46
プログラミング
PHP,PHPポケモン,ポケモン
そらをとぶ&あなをほる編 PHPポケモン46

チャージ中の回避技 以前は「ロケットずつき」や「ソーラービーム」をサンプルとしてチャージ技を実装しましたが、今回は少し特別な効果をもったチャージ技を実装します。それが「そらをとぶ」と「あなをほる」です。これらは初代ポケモンでも重宝される技であり、チャージ中に相手からの攻撃を回避することができま...

【配列とは】初心者が最短でPHPを使えるようになるための実践的な学び方
プログラミング
foreach,PHP,配列
【配列とは】初心者が最短でPHPを使えるようになるための実践的な学び方

  初心者の方、今からプログラミングを始める方、HTMLとCSSの領域から抜け出せない人たちを対象にした、PHPをできるだけ使えるようになるための方法を紹介するコーナー。 栄えある第二回は【配列編】です。   第一回を飛ばしてこのページへに来てしまい「変数って何?」というレベルの人は、第一回の【変数編...

英語できたらブログで稼げる 【ネオコピペ】
ライティング
ブログ,翻訳,英語
英語できたらブログで稼げる 【ネオコピペ】

  2010年に楽天が社内公用語の英語化を宣言したのは、多くの人が耳にしたことがあるでしょう。 私からすると、「英語ができることは強み」だという考えから、「これからは英語ができないと行きていけないのでは?」と考えを変えさせられるような、そんな出来事でした。   多言語できるデメリットを見つけるのは難...

画像に文字スペースを確保する簡単テクニックを3つ教えます【サムネイル作りで大活躍】
デザイン
Illustrator,Photoshop,サムネイル,バナー
画像に文字スペースを確保する簡単テクニックを3つ教えます【サムネイル作りで大活躍】

  サムネイル用の画像に文字スペースが無くて困っている・・・   せっかくいい写真が撮れたり、フリー画像が見つかったとしても、文字を配置するスペースが確保できずにせっかくのオブジェクトに重ねてしまったり、断念して別の画像を使用するようなケースはかなり多いです。 ですが、せっかく良い画像が見つ...

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

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

【Laravel】1対1リレーションをわかりやすく解説(belongsTo)
プログラミング
Laravel,PHP
【Laravel】1対1リレーションをわかりやすく解説(belongsTo)

Laravelの1対1リレーションのbelongsToについて、公式マニュアルでは専用単語ばかりでどうしてもわかりにくいと感じてしまっている方へ向けて、わかりやすく解説しました。 ※例で紹介しているコードについては、一部英語を日本語表記で使用している部分もありますので、コピペで使用する方は必要に応じて置き換え...

事業所検索サービス「児発ねっと」児童発達支援・放課後等デイサービス
ビジネスモデル
SEO対策,プログラミング,児童デイサービス,児童発達支援,放課後等デイサービス
事業所検索サービス「児発ねっと」児童発達支援・放課後等デイサービス

どうも、児発ねっとの中の人です。 この度は児童発達支援・放課後等デイサービスといった療育施設の事業所検索サービス「児発ねっと」を開始することになりました。 本ブログでは、プログラミングやデザインといった内容のコンテンツを紹介しているため、児発ねっとのサービスは少し異色になります。なので、今回...

HPバー色変更編(アニメーション) PHPポケモン53
プログラミング
PHP,PHPポケモン,ポケモン
HPバー色変更編(アニメーション) PHPポケモン53

HPバーの色変更 残りHPの割合に合わせて色クラスをセットしていましたが、ダメージを受けた際の判定処理(動的は変更)が未実装でしたので、今回はコチラを対応します。   残数(割合)の判定 HPの色判定は、HTMLの描画時とJSによるHP変動時に行います。animateメソッド前や後に行うと変更のズレが生じるため、a...

カテゴリ

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