【PHP】Composerのオートローダの挙動を利用してvendor以下のコードの一部を上書きする

  • 2021年4月13日
  • PHP

 The composer.json Schema – Composer
 ComposerはPHPのパッケージマネージャです。パッケージマネージャということからかパッケージのオートロードとその拡張機能があります。これを使うと一々 require 等ファイル読み込みを気にして記述する必要がなくなります。この機能は主によく composer.json と同階層に置かれる vendor ディレクトリ内の外部ライブラリを読み込むために使われます。
 作りたいものの要件を満たすために外部ライブラリそのものでなく、外部ライブラリを改造したものを使う必要がある時がままあります。この時に使える方策は例えば以下です。

  • PHP の extends によって外部ライブラリを継承したコードを用いる。差分がわかりやすく改造もシンプルで済みやすいですが、改造すべき場所や規模によっては、他方法よりただ不便になることもあります
  • 外部ライブラリのコード全体をプロジェクト内にコピーして、それを改造する。完全に管理可能であり、ソースコードが散逸することもないという点で便利ですが、外部ライブラリ自体のバージョンアップについていくのが難しくなります
  • 外部ライブラリのコード全体をフォークして、フォーク先のリポジトリで改造して composer でインストールする。管理こそ上述 2 つより難しいですが、管理は十分可能な上ライブラリのバージョンアップを反映させやすいです。複数プロジェクトでまとめて扱うことも容易です

 上述三つの他にインターフェースを満たした引数オブジェクトを渡すとよしなにしてくれる dependency injection がうまく働いているライブラリもあります。これらのいずれでもなく、少々黒魔術的ですが Composer のファイルの読み込み優先度を利用して外部ライブラリのファイルを部分的に差し替えるという方法もあります。
 この方法は例えば次の様にできます。

vendor/grimzy
│
// 省略
└── laravel-mysql-spatial
    ├── src
    │   ├── Eloquent
    │   │   ├── BaseBuilder.php
    │   │   ├── Builder.php
    │   │   ├── SpatialExpression.php
    │   │   └── SpatialTrait.php
// 省略

 と元々ファイルがあるところ

vendor_override/cpt
└── laravel-mysql-spatial
    └── src
        └── Eloquent
            ├── BaseBuilder.php
            ├── Builder.php
            ├── SpatialExpression.php
            └── SpatialTrait.php

 と元々のファイルと同一の namespace と名前で改造したファイルを置き(ここでは Eloquent 以下のみを改変)、

# もともとの外部ライブラリ
<?php

namespace Grimzy\LaravelMysqlSpatial\Eloquent;

use Illuminate\Database\Query\Expression;

class SpatialExpression extends Expression
{
    # もともとの外部ライブラリのコード
}
# 改造した方のファイル
<?php

namespace Grimzy\LaravelMysqlSpatial\Eloquent;

use Illuminate\Database\Query\Expression;

class SpatialExpression extends Expression
{
    # 改造版コード
}

 composer.json のオートローダ設定に次の様に部分的に namespace と対応を明示します。
[json] {
“autoload”: {
“psr-4”: {
“Grimzy\\LaravelMysqlSpatial\\Eloquent\\”: “vendor_override/cpt/laravel-mysql-spatial/src/Eloquent/”
},
}
}
[/json]  これによって外部ライブラリのファイルを部分的に変更できるため相当自由にライブラリの改変ができます。

>株式会社シーポイントラボ

株式会社シーポイントラボ

TEL:053-543-9889
営業時間:9:00~18:00(月〜金)
住所:〒432-8003
   静岡県浜松市中央区和地山3-1-7
   浜松イノベーションキューブ 315
※ご来社の際はインターホンで「316」をお呼びください

CTR IMG