PHP 專案一大,手動 require 檔案就像點餐時每道菜都要自己去廚房端:不是做不到,只是很快就會想喝咖啡冷靜一下。這篇會用一個小型流程,帶你理解 Composer 如何管理依賴、產生自動載入器,以及 composer.jsoncomposer.lock 該怎麼分工。

看完之後,你應該能完成以下事情:

  • 安裝 Composer,建立一個 Composer 專案。
  • 使用 requireinstallupdate 等日常指令。
  • 讀懂 composer.json 的常見欄位。
  • 用 PSR-4 設定自己的類別自動載入。
  • 判斷什麼時候應該提交 composer.lock

php composer icon

Composer 是什麼

Composer 是 PHP 的依賴管理工具。你可以在專案裡宣告需要哪些函式庫,以及允許使用哪些版本範圍;Composer 會解析這些依賴,下載套件與它們需要的其他套件,並把檔案放在專案的 vendor/ 目錄。

這裡有一個容易搞混的地方:Composer 管理的是「每個專案自己的依賴」,不是像作業系統套件管理器那樣,預設把函式庫裝成全機共用。不同專案可以因此使用不同版本,彼此不必為了搶同一杯咖啡而吵架。

Composer 也會產生自動載入器。PHP 程式只要載入 vendor/autoload.php,就能使用已安裝套件提供的類別,不必逐一 require 每個檔案。

安裝 Composer

請先確認電腦已經有 PHP,再依照 Composer 官方的安裝說明操作。macOS 使用 Homebrew 時,可以執行:

brew install composer

安裝完成後,用版本指令確認 Composer 可用:

composer --version

不同作業系統的安裝方式和前置需求可能不同,請以 Composer 官方安裝說明 為準。macOS 的 Homebrew 尚未安裝?可以先看看站內的 Homebrew 安裝教學

建立第一個 Composer 專案

初始化 composer.json

在專案根目錄執行:

composer init

Composer 會以互動問答引導你建立 composer.json。這個檔案是專案的依賴與設定描述,通常放在版本庫的根目錄。

你也可以直接新增套件,讓 Composer 在需要時建立或更新 composer.json

composer require monolog/monolog

monolog/monolog 是 Packagist 上實際存在的套件名稱;如果你要安裝其他套件,請先確認套件名稱與它支援的 PHP 版本。執行 require 後,Composer 會更新 composer.json、解析依賴、建立或更新 composer.lock,並把套件安裝到 vendor/

在 PHP 程式中載入套件

在程式的入口檔案載入 Composer 自動載入器:

<?php

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

接著就能使用套件提供的類別。__DIR__ 代表目前 PHP 檔案所在的目錄,比依賴目前工作目錄更穩定;換句話說,程式從哪裡被執行,不會影響它尋找 vendor/ 的位置。

composer.json 常見欄位

一個專案的設定可以像這樣:

{
    "name": "vendor/project",
    "description": "專案描述",
    "type": "project",
    "require": {
        "monolog/monolog": "*"
    },
    "require-dev": {
        "phpunit/phpunit": "*"
    },
    "autoload": {
        "psr-4": {
            "App\\": "src/"
        }
    },
    "scripts": {
        "test": "phpunit"
    }
}

這段是示意結構,不代表你應該在正式專案中使用 *。實務上應根據套件相容性選擇合適的版本約束,並讓 Composer 寫入 lock 檔來固定實際解析出的版本。

常見欄位如下:

  • name:套件名稱,通常使用 廠商或組織名稱/專案名稱 格式。
  • description:專案或套件的簡短說明。
  • type:套件類型;應用程式與可重複使用的函式庫用途不同。
  • require:正式執行需要的依賴。
  • require-dev:開發、測試或靜態分析需要的依賴。
  • autoload:正式程式碼的自動載入規則。
  • autoload-dev:只在開發情境使用的自動載入規則。
  • scripts:把常用工作包成 Composer 指令,例如 composer test

完整欄位和格式請查閱 Composer 的 composer.json schema,不要把網路文章裡的範例直接當成最新規格。

Composer 與 PSR-4 自動載入

Composer 是工具;PSR-4 是 PHP-FIG 制定的自動載入規範。PSR-4 描述命名空間如何對應到檔案路徑,Composer 則可以讀取這項設定並產生自動載入器。兩者不是同一件事,就像咖啡機和咖啡豆:常常一起出現,但職責不同。

設定 PSR-4

假設專案結構如下:

project/
├── composer.json
├── src/
│   └── Controllers/
│       └── UserController.php
└── public/
    └── index.php

composer.json 加入:

{
    "autoload": {
        "psr-4": {
            "App\\": "src/"
        }
    }
}

在這個映射下,App\Controllers\UserController 會對應到 src/Controllers/UserController.php。類別的命名空間、類別名稱與檔案路徑要一致:

<?php

namespace App\Controllers;

class UserController
{
    public function index(): string
    {
        return 'Hello, Composer!';
    }
}

設定或新增自動載入規則後,重新產生自動載入檔:

composer dump-autoload

然後在入口檔載入 vendor/autoload.php,就可以使用 new UserController()。PSR-4 的重點不是魔法,而是大家遵守同一套「命名空間對應路徑」的規則;規則一致,檔案就不用到處報到。

日常最常用的 Composer 指令

composer require

新增正式依賴:

composer require vendor/package

若套件只在測試或開發時使用,可加入 --dev

composer require --dev vendor/package

這個指令會修改 composer.json,並重新解析與安裝依賴。

composer install

依照目前的 composer.lock 安裝依賴:

composer install

在拉下專案原始碼、CI 或部署環境中,通常應優先使用 install。有 lock 檔時,Composer 會使用其中記錄的精確版本;沒有 lock 檔時,則會先解析依賴並建立它。

composer update

依照 composer.json 允許的版本範圍重新解析依賴:

composer update

這會更新 composer.lock。它不是「每次安裝都該執行」的按鈕,而是你有意識地要更新依賴時才使用。否則一個看似平凡的更新,可能讓整個專案一起喝雙倍濃縮。

只更新單一套件及其必要依賴時,可以指定套件名稱:

composer update vendor/package

composer remove

移除依賴:

composer remove vendor/package

Composer 會同步更新 composer.jsoncomposer.lockvendor/

composer dump-autoload

重新產生自動載入檔,但不負責重新解析依賴:

composer dump-autoload

如果只是修改 autoload 設定或需要重建 autoloader,使用這個指令即可,不必為了重建自動載入器而更新所有套件。

正式環境也可以使用 Composer 文件描述的最佳化選項,例如:

composer dump-autoload --optimize

是否使用最佳化,以及要不要採用更嚴格的 classmap 選項,應依專案的部署方式測試後決定。

composer showcomposer validate

查看已安裝套件:

composer show

檢查 composer.json 與 lock 檔:

composer validate

當你接手別人的專案,這兩個指令很適合當作快速健康檢查:先看有哪些依賴,再確認設定檔是否合理。

composer.lock 要不要提交

composer.lock 記錄 Composer 解析出的精確依賴版本。它讓團隊成員、CI 和部署環境能安裝同一組版本,避免「我這裡可以跑」成為專案最常見的考古謎題。

一般可依專案類型判斷:

  • 應用程式:通常應提交 composer.lock,讓每次安裝都使用經過確認的依賴版本。
  • 可供其他專案安裝的函式庫:lock 檔對使用者安裝你的函式庫不會產生同樣的鎖定效果,因此是否提交可依團隊測試流程決定;Composer 官方文件也說明,函式庫可以不提交 lock 檔。

不論哪一種專案,都不要把 vendor/ 當成依賴版本的主要紀錄。版本與相容性約束寫在 composer.json,精確解析結果則由 composer.lock 保存。

一個實用的工作流程

新專案可以依這個順序開始:

composer init
composer require vendor/package
composer install

日後從版本庫取得程式碼時:

composer install

需要有計畫地更新依賴時:

composer update
composer validate

如果新增了自己的 PSR-4 類別映射,再執行:

composer dump-autoload

掌握這個分工後,Composer 就不再像一個只會吐出紅字的黑盒子:composer.json 描述需求,composer.lock 固定結果,vendor/autoload.php 負責把類別帶進來。剩下的問題,先讓 Composer 解;解不出來,再泡一杯咖啡一起看錯誤訊息。

參考資料