PHP - use 文によるインポート
名前空間を使うと、クラスの完全修飾名は App\Http\Controllers\UserController のように長くなる。毎回この名前をフルで書くのは現実的ではない。use 文を使えば、クラスや関数、定数をインポートして短い名前で参照できるようになる。
use 文の基本
use 文はファイルの先頭、namespace 宣言の直後に記述する。インポートしたクラスは、以降そのクラス名だけで使えるようになる。
<?php
namespace App\Services;
use App\Models\User;
use App\Repositories\UserRepository;
class UserService
{
private UserRepository $repository;
public function find(int $id): User
{
return $this->repository->findById($id);
}
}use App\Models\User と宣言することで、\App\Models\User と書く代わりに単に User と書けるようになった。コードの可読性が大きく向上する。
use 文がない場合との比較
use 文を使う場合と使わない場合で、同じ処理がどれほど違って見えるか確認してみよう。
毎回 \App\Models\User や \App\Repositories\UserRepository のようにフルパスを書く必要があり、コードが冗長になる
ファイル冒頭で一度インポートすれば、以降は User、UserRepository だけで済み、コードが簡潔になる
ただし use 文は「名前の短縮」であって、クラスを自動的に読み込む機能ではない。ファイルの読み込み自体はオートローダー(PSR-4)が担当しており、use 文はあくまで名前解決の仕組みだという点に注意が必要だ。
エイリアス(as)
同じクラス名が異なる名前空間に存在する場合、そのままインポートすると名前が衝突する。as キーワードでエイリアス(別名)を付ければ、この問題を回避できる。
<?php
namespace App\Services;
use App\Models\User as AppUser;
use External\Auth\User as AuthUser;
class MigrationService
{
public function migrate(AuthUser $source): AppUser
{
return new AppUser($source->getName());
}
}App\Models\User と External\Auth\User はどちらもクラス名が User だが、as で AppUser と AuthUser に分けることで共存させている。
エイリアスを使う典型的な場面をまとめておこう。
上の例のように、異なるパッケージに同名のクラスがある場合。Laravel では Illuminate\Support\Facades\Request と Illuminate\Http\Request の使い分けでよく見かける。
VeryLong\Namespace\Path\SomeClassName のような深い階層のクラスを SomeName のように縮めたい場合にも有効だ。
関数・定数のインポート
use 文はクラスだけでなく、関数や定数もインポートできる。それぞれ use function と use const を使う。
<?php
namespace App\Utils;
use function App\Helpers\formatDate;
use function App\Helpers\formatCurrency;
use const App\Config\DEFAULT_LOCALE;
class Formatter
{
public function format(int $timestamp): string
{
return formatDate($timestamp, DEFAULT_LOCALE);
}
}クラスの use とは異なり、use function や use const は実務ではそこまで頻繁に使われない。ほとんどのプロジェクトではクラスベースの設計が主流であり、名前空間付きの関数や定数を定義する機会自体が少ないためだ。
グループ use 宣言
PHP 7.0 以降、同じ名前空間から複数のクラスをインポートする場合、波括弧でグループ化できるようになった。
<?php
namespace App\Services;
use App\Models\{User, Post, Comment};
use App\Repositories\{UserRepository, PostRepository};
class ContentService
{
// User, Post, Comment, UserRepository, PostRepository が使える
}グループ use を使うと、共通部分の繰り返しがなくなりインポート部分がすっきりする。
use App\Models\User; use App\Models\Post; use App\Models\Comment; と 3 行必要
use App\Models\{User, Post, Comment}; の 1 行で完結する
ただしグループ内に多くのクラスを詰め込みすぎると、かえって読みにくくなる。1 グループあたり 3〜5 クラス程度に留めるのが実用的だろう。
use 文の配置ルールとスコープ
use 文を書く位置には明確な決まりがある。
namespace 宣言
use 文(インポート)
クラス定義や関数定義
この順序は PSR-12 コーディング規約でも定められている。use 文をクラス定義の途中やメソッド内に書くことはできず、必ずファイルの冒頭部分にまとめなければならない。
<?php
declare(strict_types=1);
namespace App\Http\Controllers;
use App\Models\User;
use App\Services\UserService;
use Illuminate\Http\JsonResponse;
class UserController
{
public function __construct(
private UserService $service
) {}
public function show(int $id): JsonResponse
{
$user = $this->service->find($id);
return new JsonResponse($user);
}
}declare → namespace → use → クラス定義という流れが、PHP ファイルの標準的な構造だ。多くの IDE やコードフォーマッターもこの順序を前提としており、守っておけば自動整形との相性も良い。
もう一つ押さえておくべきなのは、use 文の効果はそのファイルの中だけに限定されるという点だ。あるファイルで use App\Models\User と書いても、別のファイルには一切影響しない。Python の import や Java の import と同様に、使うファイルごとに毎回 use 文を書く必要がある。「一度書けばプロジェクト全体に反映される」という誤解は初学者に多いが、use はあくまでファイルローカルな名前解決だ。
trait の use との違い
PHP にはもう一つ別の use がある。クラスの内部で trait を取り込むときに使う use だ。
<?php
namespace App\Models;
use App\Traits\HasTimestamps; // 名前空間の use(名前解決)
class Post
{
use HasTimestamps; // trait の use(コード合成)
}同じ use キーワードだが、役割はまったく異なる。ファイル冒頭の use は完全修飾名を短くするための名前解決であり、クラス内部の use は trait のメソッドやプロパティをそのクラスに合成する仕組みだ。書く場所が違うので文法上は曖昧さがないものの、初めて見ると混乱しやすいポイントなので意識しておきたい。
未使用の use 文
インポートしたが実際に使っていない use 文は、コードに悪影響を与えないが、放置すると可読性が下がる。PHP 自体は未使用の use 文に対して警告を出さないため、静的解析ツールや IDE の機能で検出・自動削除するのが一般的だ。PHPStan や PHP-CS-Fixer を導入していれば、未使用のインポートを自動的にクリーンアップしてくれる。
use 文を正しく使いこなせば、名前空間の恩恵を受けながらも簡潔で読みやすいコードが書ける。次はオートローディングとの連携を理解することで、ファイルの読み込みまで含めた全体像が見えてくるはずだ。