laravel8 独自ライブラリの利用について

自分で作ったライブラリをlaravelで使えるようにしたい

作成日:2023-07-10, 更新日:2023-07-10

やりたいこと

今まで作ってきたライブラリたちをlaravelでも使いたい

基本

▼私の環境
WIN+Docker+Ubuntuでlaravelを使うための作業メモ

メモ

laravelでは特別に独自ライブラリを簡単に使えるような機能は無いっぽい

やることは2つ。

  • ライブラリの改修
  • 自分で好きなトコにライブラリを置く
  • ライブラリを読み込んで、使う

ライブラリの改修

  • namespaceが必要
  • 「ファイル名」は「クラス名.class.php」ではなく「クラス名.php」にする
  • 「ファイル名」と「クラス名」を一緒にする

▼「サンプル: App/Vendor/hoge.php」の場合

<?php
    namespace App\Vendor; // namespaceが必要 
    class hoge { // 「ファイル名」と「クラス名」を一緒にする

※「hoge.class.php」での読込み方法はあるかもしれないけど、見つけることは出来なかった…

自分で好きなトコにライブラリを置く

▼基本、好きなトコで良いっぽいんで…ひとまず「app」の下に「Vendor」フォルダを作って、ココにライブラリの突っ込んでいく

app/Vendor

ライブラリを読み込んで、使う

方法はいくつかあるっぽい

  • ただ呼び出す
  • ただ呼び出す(サービスコンテナ)
  • 使いやすくする(サービスコンテナ + サービスプロバイダ + ファサード)

ただ呼び出す

$lib_hoge = new \App\Vendor\hoge; // インスタンス作成
$lib_hoge->xxx(); // 自分で用意しているメソッドを実行
// $lib_hoge::xxx(); // staticも同じ感じで使える

一番手っ取り早いし、メンテナンスのときもどのライブラリを使っているのか、PATHがドコなのか…見るべき場所が分かりやすいと思うんだが…コレじゃダメなのか?
10か所ぐらいでインスタンス作成するなら…面倒かもしれないが、それも別の対策方法がありそうな気もする…

▼引数アリでインスタンス作成

$lib_hoge = new \App\Vendor\hoge(xxx);

ただ呼び出す(サービスコンテナ)

app()->bind('hoge', App\Vendor\hoge::class); // 「App/Vendor/hoge.php」を読み込む
$lib_hoge = app()->make('hoge'); // インスタンス作成
$lib_hoge->xxx(); // 自分で用意しているメソッドを実行
// $lib_hoge::xxx(); // staticも同じ感じで使える

普通に「new App\xxx」としたほうが手っ取り早い気がするんだが…こっちのほうが良いという人たちが多いので何かメリットがあるんだろう…

使いやすくする(サービスコンテナ + サービスプロバイダ + ファサード)

上記の「app()->bind()」ってのは…最終的にはファサードに設定して意味がある…というような気もする

  1. サービスプロバイダの用意
  2. サービスプロバイダをconfig/app.phpに追加
  3. ファサードのファイル作成
  4. ファサードに設定(config/app.phpに追加)
  5. 独自ライブラリを使う

ライブラリを追加するたびにサービスプロバイダを用意するのが面倒なので…一つのファイルで対応したい

サービスプロバイダの用意

▼artisanでファイル作成

$ ./vendor/bin/sail php artisan make:provider VendorServiceProvider

→「app/Providers/VendorServiceProvider.php」が作られる

▼「app/Providers/VendorServiceProvider.php」の修正

~ 略 ~
use App\Vendor; // 独自ライブラリの格納先のPATH

class VendorServiceProvider extends ServiceProvider
{
    /**
     * Register services.
     */
    public function register(): void
    {
        $this->app->bind('hoge', Vendor\hoge::class); 
    }

~ 以下、略 ~

サービスプロバイダをconfig/app.phpに追加

▼「config/app.php」に追加

~ 略 ~
'providers' => ServiceProvider::defaultProviders()->merge([
    ~ 略 ~
    App\Providers\VendorServiceProvider::class,
])->toArray(),
~ 以下、略 ~

ファサードのファイル作成

「app」の下に「Facades」のフォルダを作り、その下に各ファイルを置く

▼「app/Facades/HogeFacades.php」

<?php 
namespace App\Facades; 
use Illuminate\Support\Facades\Facade; 
class HogeFacades extends Facade 
{ 
    /** 
     * Get the registered name of the component. 
     * 
     * @return string 
     */ 
    protected static function getFacadeAccessor() 
    { 
        return 'Hoge'; 
    } 
}

ファサードに設定(config/app.phpに追加)

▼「config/app.php」に追加

~ 略 ~
'aliases' => Facade::defaultAliases()->merge([
    // 'Example' => App\Facades\Example::class,
    'Hoge' => App\Facades\HogeFacade::class,
])->toArray(),
~ 以下、略 ~

独自ライブラリを使う

echo \Hoge::xxx(); // staticであろうがなかろうが「->」ではなく「::」になる

一つのサービスプロバイダで対応

ライブラリを追加するたびにサービスプロバイダを用意するのが面倒なので…一つのファイルで対応したい

基本、上記と同じだけど…一部違う

  1. サービスプロバイダの用意 ← 初回のみ必要。2回目以降は不要
  2. サービスプロバイダをconfig/app.phpに追加 ← 初回のみ必要。2回目以降は不要
  3. サービスプロバイダに追加
  4. ファサードのファイル作成
  5. ファサードに設定(config/app.phpに追加)
  6. 独自ライブラリを使う

※「ファサードのファイル作成」以降は、上記と同じ

サービスプロバイダに追加

▼「app/Providers/VendorServiceProvider.php」の修正

~ 略 ~
    public function register(): void
    {
        $this->app->bind('hoge', Vendor\hoge::class); 
        $this->app->bind('foo', Vendor\foo::class); // ← 今回追加
    }

~ 以下、略 ~

インスタンス作成時の引数の渡し方

「app()->make()」でインスタンス作成なんだけど、このときに何かしたら引数を渡すコトが可能
調べたけど、複数種あるし、アチコチ触る必要があるっぽい
そこまでして「app()->make()」を使うメリットを感じず、調査は断念

…ということで、下記のような感じ

  1. 独自ライブラリのファイル名、クラス名を一緒にする
  2. namespaceをセットする
  3. 「xxx.class.php」ってファイル名なら「.class」を削除して「xxx.php」にする
  4. ▼使いたい場所でインスタンス作成して使う
    $foo = xxx;
    $var = xxx;
    $lib_hoge = new \App\Vendor\hoge($foo, $var); // 引数アリでインスタンス作成
    $lib_hoge->xxx(); // 自分で用意しているメソッドを実行
    // $lib_hoge::xxx(); // staticも同じ感じで使える

まとめ

インスタンス作成時に引数を渡したい

ファサードにしないのが無難。もしくは渡し方を自分で調べる

  1. 「App\Vendor」の下に独自ライブラリを置く
  2. ▼使いたい場所でインスタンス作成して使う
    $foo = xxx;
    $var = xxx;
    $lib_hoge = new \App\Vendor\hoge($foo, $var); // 引数アリでインスタンス作成
    $lib_hoge->xxx(); // 自分で用意しているメソッドを実行
    // $lib_hoge::xxx(); // staticも同じ感じで使える

インスタンス作成時に引数は渡さない

ファサードにしようがしまいが好きにすればいい。

独自ライブラリのメンバ変数をあちこちで使いたい

ファサードにしておくと使いまわせて便利
※適当なメソッドを用意してメンバ変数に値をセットさせる

  1. 「App\Vendor」の下に独自ライブラリを置く
  2. サービスプロバイダ、ファサードの設定をしておく
  3. ▼使いたい場所で使う
    \hoge::xxx();

メモ

エラー: クラスの多重宣言?

▼出てきたエラー

Cannot declare class ●●●, because the name is already in use

原因は追加した独自ライブラリにnamespaceを入れていなかった
※namespaceのPATHを間違っても同様のエラーになるらしい

エラー: クラスが見つからない?

▼出てきたエラー

Class "App\Http\Controllers\●●●" not found

原因は呼出し方法

▼エラーが出てきたときの呼出し

echo Hoge::xxx();

▼正しくは「\」が必要っぽい

echo \Hoge::xxx();