魔法使いの卵

WEBエンジニアの卵の成長記録

namespaceとオートローダーについて少し知ったので殴り書き程度に残しておく

namespaceとオートローダーについてのメモ

名前空間とオートローダーについて、ほんのすこしだけわかった気になっているので、今後のとっかかりとして忘れないように書き留めておく

※ ここでのオートローダーとはcomposerを使ったオートローダのことを指す

環境

  • PHP5.6.10
  • Composer 1.0-dev

なぜnamespaceを使うのか

PHP 言語の強みはその単純さです。したがって、皆さんが PHP の初心者なのであれば、名前空間はいずれ理解する必要がある概念の 1 つにすぎません。しかし、皆さんが以下のいずれかに当てはまる場合には、名前空間の使用を検討する必要があります。 何百という PHP ファイルを持つ大規模なアプリケーションを開発する場合 アプリケーションがコーディング・チームによって開発されている場合 PHP V5.3 と名前空間を使用するフレームワークの使用を計画している場合 他の言語 (Java™、Ruby、Python など) では名前空間 (あるいはパッケージのような類似機能) を使用していた場合 比較的小規模のアプリケーションを 1 人で開発している場合には、名前空間は必要ないかもしれません。しかし、それ以外の人々にとっては、名前空間を使用することでクラス構造をすっきりと体系化することができ、もちろん、名前の衝突を防ぐことができるようになります。この 2 つの理由から、多くのフレームワーク開発者は名前空間を採用するようになっています。例えば Zend Framework (巨大な PHP フレームワーク) は Zend Framework V2.0 で名前空間を使用しています。

namespaceの参照の方法

  • クラス名の接頭辞として名前空間を指定する
  • 名前空間をインポートする
  • 名前空間にエイリアスを付ける

namespaceの解釈のされ方

  • \my\name は my\name と同義
  • \Exceptionは Exception と同義

namespaceをつける時に気をつけること

  • namespace自体は好きな様につけることができる
    • 適当につけるとあとからわかりにくくなる
  • ディレクトリ構造に合わせたnamespaceが好ましい

オートローダーで必要なもの

  • php5.3以上
  • Composer

オートローダーを利用する準備

  • composer.jsonにautoloadを利用するディレクトリとnamespaceを記述する
{
    "autoload": {
        "psr-4": {"App\\": "App/"}
    }
}
  • "psr-4": {"App\": "App/"}とした場合

    • "App\"がnamespace
    • "App/"がディレクトリ
  • 記述後反映させる為に以下のコマンドを叩く

composer dumpautoload

エントリーポイント

  • エントリーポイントとは
    • 処理の起点のこと。
      • Frameworkだとindexがエントリーポイントとなる
    • エントリーポイントとして利用している場合はファイルにrequireを使う必要はない
    • エントリーポイントがない場合は各クラスファイル等で一度requireをする必要がある

Laravel5.1のエントリーポイント

laravel5.1/public/index.php

<?php

/**
 * Laravel - A PHP Framework For Web Artisans
 *
 * @package  Laravel
 * @author   Taylor Otwell <taylorotwell@gmail.com>
 */

/*
|--------------------------------------------------------------------------
| Register The Auto Loader
|--------------------------------------------------------------------------
|
| Composer provides a convenient, automatically generated class loader for
| our application. We just need to utilize it! We'll simply require it
| into the script here so that we don't have to worry about manual
| loading any of our classes later on. It feels nice to relax.
|
*/

require __DIR__.'/../bootstrap/autoload.php';

/*
|--------------------------------------------------------------------------
| Turn On The Lights
|--------------------------------------------------------------------------
|
| We need to illuminate PHP development, so let us turn on the lights.
| This bootstraps the framework and gets it ready for use, then it
| will load up this application so that we can run it and send
| the responses back to the browser and delight our users.
|
*/

$app = require_once __DIR__.'/../bootstrap/app.php';

/*
|--------------------------------------------------------------------------
| Run The Application
|--------------------------------------------------------------------------
|
| Once we have the application, we can handle the incoming request
| through the kernel, and send the associated response back to
| the client's browser allowing them to enjoy the creative
| and wonderful application we have prepared for them.
|
*/

$kernel = $app->make(Illuminate\Contracts\Http\Kernel::class);

$response = $kernel->handle(
    $request = Illuminate\Http\Request::capture()
);

$response->send();

$kernel->terminate($request, $response);

例:エントリーポイントがない場合のオートローダー

<?php
namespace App\Controller;
require_once __DIR__ .'/vendor/autoload.php';

オートローダーを使って実際に別ファイルのクラスを読み込みたい場合

  • 今回はあくまで一例としてコントローラーからモデルクラスのメソッドを呼ぶようにする

  • コントローラーの処理

    • 対象のディレクトリを指定しなくても'vendor/autoload.php';でオートロードできるようにしている
    • use でどのnamespaceを対象にするのかを指定する
    • オートローダーで対象のディレクトリを読み込んでいるためClass not foundが起きない
<?php
namespace App\Controller;
require_once __DIR__ .'/../../vendor/autoload.php';
use App\Model\MembersDao;

class MembersController
{
    /**
     * 会員全件取得
     * @return array
     */
    public function findAll()
    {
        $members = new MembersDao();
        $result = $members->findAll();
        return $result;
    }
}
  • モデルの処理
<?php

namespace App\Model;
use App\Model\DB;
use PDO;

class MembersDao
{
    /**
     * 全会員一覧
     *
     * @return array
     */
    public function findAll()
    {
        $dao = new DB();
        $dbh = $dao->dbConnect();
        $sql = "select * from members";
        return $dbh->query($sql);
    }

}

オートローダーを使わないとどうなるの?

  • コントローラーがこうなります
<?php
class MembersController
{
    /**
     * 会員全件取得
     * @return array
     */
    public function findAll()
    {
        require_once '対象のファイルまでのパス';
        $members = new MembersDao();
        $result = $members->findAll();
        return $result;
    }
}
  • モデルもこうなります
<?php
class MembersDao
{
    /**
     * 全会員一覧
     *
     * @return array
     */
    public function findAll()
    {
        require_once '対象のファイルまでのパス';
        $dao = new DB();
        $dbh = $dao->dbConnect();
        $sql = "select * from members";
        return $dbh->query($sql);
    }

}
  • 処理の度にrequireを記述する
  • requireだらけのものになる
  • require地獄というものになる。

オートローダーを使うことのメリットってなに

  • 自分の好きなところにファイルを設置することができるようになる
  • require地獄から抜け出すことができるようになる
  • ルールさえまもっていれば楽できる

オートローダーのデメリットってなに?

  • phpのバージョンが古いと使えないのでが辛い
  • PSR-0からPSR-4に変わったのでそのへん注意

おもったこと

  • 割りと理解するのに時間がかかった

参考元:

PHP V5.3 の名前空間を利用して、理解しやすく保守の容易なコードを作成する

PHP: FAQ: 名前空間について知っておくべきこと - Manual