#はじめに
Laravelを勉強していくうちに、Laravelのオートローダの仕組みが知りたくなり、Laravelのオートローダの仕組みについて調べてみました。
調べて分かったことをここにあげるので、興味のある方は是非見てください。
(個人的な都合により、Laravel5.5を対象にオートローダの仕組みを調べました。)
#大雑把な仕組み
オートローダに関係するファイル
- publicディレクトリ
- index.php
- vendorディレクトリ
- autoload.php
- composerディレクトリ
- autoload_classmap.php
- autoload_namespaces.php
- autoload_psr4.php
- autoload_real.php
- autoload_static.php
- ClassLoader.php
それぞれの役割
- オートローダの読み込み(index.php)
- オートローダの実行(autoload.php)
- オートローダの実装(autoload_real.php)
- オートローダの対象のファイルデータの格納(autoload_classmap.php, autoload_namespace.php, autoload_psr4.php, autoload_static.php)
- ファイルデータの読み込み(ClassLoader.php)
#実際に作ってみた
オートローダーの仕組みを使い、こんなことをやってみました。
やってみたこと
使用したい機能が実装されているファイルを直接requireしなくても、その機能が実行したいファイル上で実行できるようにすること。
使用したファイル
- 親ディレクトリ
- appディレクトリ
- Application.php
- app.php
- autoloader_real.php
- autoloader_static.php
- autoload.php
- ClassLoader.php
- appディレクトリ
それぞれの役割
- オートローダの読み込み(index.php)
- オートローダの実行(autoload.php)
- オートローダの実装(autoload_real.php)
- オートローダの対象のファイルデータの格納( autoload_static.php)
- ファイルデータの読み込み(ClassLoader.php)
- 使いたい機能(Application.php)
実際のコード
Application.phpの機能は、App\Applicationクラスのインスタンスから、successメソッドを実行すると、「Success!」の文字が表示される。
<?php
namespace App;
/**
*
*/
class Application
{
public function success()
{
echo 'Success!';
}
}
?>
このファイルのデータを格納しているautoload_static.phpのコードは
<?php
namespace Vendor;
/**
*
*/
class Autoload_real
{
public static $classMap = array('App\\Application' => __DIR__.'\app\Application.php');
public static function getInitializer(ClassLoader $loader)
{
return \Closure::bind(function () use ($loader)
{
$loader->classMap = Autoload_real::$classMap;
}, null, ClassLoader::class);
}
}
?>
その格納しているファイルデータを読み込んでいるClassLoader.phpのコードは
<?php
namespace Vendor;
/**
*
*/
class ClassLoader
{
private $classMap = array();
function register($prepend = false)
{
spl_autoload_register(array($this, 'loadClass'), true, $prepend);
}
public function loadClass($class)
{
if ($file = $this->findfile($class)) {
include $file;
}
}
public function findfile($class)
{
if (isset($this->classMap[$class])) {
return $this->classMap[$class];
} else {
return false;
}
}
}
?>
読み込んだファイルデータを基にオートローダの実装を行っているautoload_real.phpのコードは
<?php
require __DIR__.'/ClassLoader.php';
/**
*
*/
class Autoload_real
{
private static $loader;
function getLoader()
{
$loader = new Vendor\ClassLoader();
require 'autoload_static.php';
call_user_func(Vendor\Autoload_real::getInitializer($loader));
$loader->register(true);
return $loader;
}
}
?>
実装したオートローダを実行するautoload.phpのコードは
<?php
require_once 'autoload_real.php';
return Autoload_real::getLoader();
?>
最後にオートローダを読み込むindex.phpのコードは
<?php
require 'autoload.php';
$app = new App\Application.php();
$app->success(); //「Success!」と表示される。
?>
#終わりに
今回はLaravelのオートローダについてざっくり見てみました。
オートローダの仕組みを調べるのは大変でしたが楽しかったので、今後もLaravelの他の機能についても調べてみたいと思います。