use 關鍵字本身不加載任何文件。它只在編譯階段建立「短名稱 → 完全限定名」的映射,運行時遇到短名稱時,觸發 spl_autoload_register() 註冊的自動加載器,傳入完全限定名去查找文件。
| 場景 | 語法 | 說明 |
|---|---|---|
| 類/接口/函數/常量導入 | use Foo\Bar\Baz;use Foo\Bar\Baz as MyBaz; | 當前文件頂部,建立別名 |
| Trait 引入 | class MyClass { use MyTrait; } | 類內部,實現代碼復用 |
| 閉包綁定作用域 | $fn = function() use ($var) { ... }; | 繼承父作用域變量(值捕獲) |
| 命名空間分組導入 (PHP 7+) | use Foo\Bar\{Baz, Qux, Quux as Q}; | 減少重複路徑前綴 |
// 典型框架入口文件
spl_autoload_register(function(string $class) {
// 1. 類名標準化:命名空間分隔符 \ → 目錄分隔符 /
// 2. 根據 PSR-4 映射規則定位文件
// 3. 文件存在則 require_once
// 簡化版 PSR-4
$prefix = 'App\\';
$baseDir = __DIR__ . '/src/';
if (strncmp($class, $prefix, strlen($prefix)) !== 0) return;
$relativeClass = substr($class, strlen($prefix));
$file = $baseDir . str_replace('\\', '/', $relativeClass) . '.php';
if (file_exists($file)) require_once $file;
});
// 使用示例
use App\Controller\UserController; // 編譯時記錄映射
new UserController(); // 運行時觸發自動加載,傳入 "App\Controller\UserController"
public static function autoload($class) {
// 1. 靜態映射表優先(編譯時生成的 classmap.php)
if (isset(self::$map[$class])) return include self::$map[$class];
// 2. 命名空間前綴匹配
if (false !== strpos($class, '\\')) {
$namespace = strstr($class, '\\', true); // 獲取第一級命名空間
if (in_array($namespace, ['think', 'app', 'extend', 'vendor']) || is_dir(LIB_PATH . $namespace)) {
$path = LIB_PATH;
} else {
// 自定義命名空間映射
$nsMap = Config::get('autoload_namespaces');
$path = isset($nsMap[$namespace]) ? dirname($nsMap[$namespace]) . '/' : APP_PATH;
}
$file = $path . str_replace('\\', '/', $class) . EXT;
if (is_file($file)) {
// Windows 大小寫敏感檢查
if (IS_WIN && strpos(str_replace('/', '\\', realpath($file)), $class . EXT) === false) return;
return include $file;
}
}
// 3. 非命名空間類(兼容舊項目):按層級/路徑嘗試
if (!Config::get('app_use_namespace')) {
foreach (explode(',', Config::get('app_auto_load_layer')) as $layer) {
if (substr($class, -strlen($layer)) === $layer) {
if (require_cache(MODULE_PATH . $layer . '/' . $class . EXT)) return;
}
}
foreach (explode(',', Config::get('app_auto_load_path')) as $path) {
if (import($path . '.' . $class)) return;
}
}
}
// vendor/composer/autoload_psr4.php 返回映射表
return [
'Symfony\\Component\\Console\\' => [__DIR__ . '/../symfony/console'],
'Psr\\Log\\' => [__DIR__ . '/../psr/log/Psr/Log'],
'App\\' => [__DIR__ . '/../app'], // 項目自定義
];
// ClassLoader::loadClass() 核心邏輯
foreach ($this->prefixDirsPsr4[$prefix] as $baseDir) {
$file = $baseDir . DIRECTORY_SEPARATOR . str_replace('\\', DIRECTORY_SEPARATOR, $relativeClass) . '.php';
if (file_exists($file)) return require $file;
}
composer dump-autoload -o 生成 classmap,避免運行時文件系統查找use Foo\Bar\Baz; 優於 use Foo\Bar; 再用 new Bar\Baz(),利於靜態分析/IDE 跳轉use TraitA, TraitB { TraitA::method insteadof TraitB; TraitB::method as aliasMethod; }