カテゴリー
Linux

PHP で require、include したくないので Composer のオートロード (autoload) に入門する

環境

Docker の PHP 上で試しました。

  • OS バージョン
    • cat /etc/issue: Debian GNU/Linux 9 \n \l
    • cat /etc/debian_version: 9.5
  • PHP バージョン
    • php -v:
      PHP 7.2.9 (cli) (built: Aug 22 2018 23:59:10) ( NTS )
      Copyright (c) 1997-2018 The PHP Group
      Zend Engine v3.2.0, Copyright (c) 1998-2018 Zend Technologies
      root@794dbcc792c6:~# cat /etc/issue

# Docker で PHP に入る
docker run -it --rm php bash

# OS バージョン
cat /etc/issue
cat /etc/debian_version 

# PHP バージョン
php -v

入門の実践。これだけ打てば体験できる、コマンドまとめ

docker run -it --rm php bash してコンテナの中に入ってからスタートです。

# 適当なディレクトリを作成し、その場所に移動
mkdir ~/testcomposer
cd ~/testcomposer/

# Composer インストール
curl -sS https://getcomposer.org/installer | php
# インストール確認
php composer.phar

# オートロード (Composer プロジェクト) に必要なファイルの作成
cat << 'EOF' > composer.json
{
    "autoload": {
        "psr-4": {
            "myapp\\": "src/"
        }
    }
}
EOF

# オートロードの準備 (Composer プロジェクトのインストール)
# composer.json ファイルの変更をしたら composer update
# autoload の変更のみなら composer dumpautoload で反映可
php composer.phar install

# オートロードを体験するための PHP ファイル作成
cat << 'EOF' > App.php
<?php
require_once "vendor/autoload.php";

use myapp\domain\User;
use myapp\domain\equipment\Weapon;

$weapon1 = new Weapon('sword');
$user1 = new User('user1', $weapon1);
echo $user1->hello();
echo "\n";
echo $user1->attack();
echo "\n";
EOF

mkdir -p src/domain/equipment/

cat << 'EOF' > src/domain/User.php 
<?php
namespace myapp\domain;

use myapp\domain\equipment\Weapon;

Class User {
    private $user_name;
    private $weapon;

    public function __construct($user_name, $weapon) {
        $this->user_name = $user_name;
	$this->weapon = $weapon;
    }

    public function hello() {
        return "{$this->user_name} says hello!";
    }

    public function attack() {
        return "{$this->user_name} attacked with {$this->weapon->weapon_name()}!";
    }
}
EOF

cat << 'EOF' > src/domain/equipment/Weapon.php 
<?php
namespace myapp\domain\equipment;

Class Weapon {
    private $weapon_name;

    public function __construct($weapon_name) {
        $this->weapon_name = $weapon_name;
    }

    public function weapon_name() {
        return $this->weapon_name;
    }
}
EOF

# オートロードを試す
# user1 says hello!
# user1 attacked with sword! と出力されれば成功
php App.php

もしオートロードがなかったら

<?php
require_once "src/domain/User.php";
require_once "src/domain/equipment/Weapon.php";

use myapp\domain\User;
use myapp\domain\equipment\Weapon;

$weapon1 = new Weapon('sword');
$user1 = new User('user1', $weapon1);
echo $user1->hello();
echo "\n";
echo $user1->attack();
echo "\n";

今回のサンプルでは、App.php の 2 ~ 3 行目の require_once の内容が異なるだけです。

したがってオートロードのありがたみを実感し辛いですけれども、さらにクラスファイルが増えた場合、オートロードがない場合はその都度必要なクラスに必要な文だけ require_once を追加していく必要があります。

App.php だけでなく、User.php に必要になるかも知れませんし、もっと別のクラスに必要となるかも知れません。これは、面倒で、管理が厄介です。

オートロードがある場合は、App.php の require_once のみあれば、App.php にも、User.php にも、他の src ディレクトリ配下のクラスにも、require_once は不要です (の、ハズです)。楽です♪

おわりに

非常に久しぶりに PHP を触りました。全部忘れていますね><。

復習がてら、オートロードについて、オートロードだけを導入する体験を、まとめました。

次のページが参考になりました、ありがとうございます!

以上です。

コメントを残す