PHP 的 "use" 关键字和自动加载
PHP's "use" Keyword and Autoloading
我的问题分为三个部分:
放入 use
语句会立即触发自动加载器,还是等到 class 被使用? (延迟加载)
如果自动加载不是以延迟加载的方式完成,是否会对性能产生负面影响?
最好遵循哪种模式,为什么?当未使用 use
语句时,PhpStorm 将 "Unnecessary fully qualified name..." 显示为代码问题。
下面是一个 class 定义 Laravel 控制器的示例,其中包含 use
语句:
namespace App\Http\Controllers;
use Carbon\Carbon;
class FooController extends Controller
{
/**
* This action uses the Carbon class
*/
public function bar1()
{
return view('foo.bar1', ['now' => new Carbon()]);
}
/**
* This action does not use the Carbon class
*/
public function bar2()
{
return view('foo.bar2');
}
}
没有 use
语句的相同 class:
namespace App\Http\Controllers;
class FooController extends Controller
{
/**
* This action uses the Carbon class
*/
public function bar1()
{
return view('foo.bar1', ['now' => new \Carbon\Carbon()]);
}
/**
* This action does not use the Carbon class
*/
public function bar2()
{
return view('foo.bar2');
}
}
1) class 会在您执行 new Class()
语句时自动加载。
2) 见 1)
3) 最好遵循哪种模式,为什么?:
我建议使用 use
,因为您可能会遇到这样的情况:您的命名空间非常长,您的代码将变得不可读。
来自php docs:
This example attempts to load the classes MyClass1 and MyClass2 from
the files MyClass1.php and MyClass2.php respectively.
<?php
spl_autoload_register(function ($class_name) {
include $class_name . '.php';
});
$obj = new MyClass1();
$obj2 = new MyClass2();
?>
命名空间只是组织 classes 的一个附加功能。
编辑: 正如@IMSoP 在评论中指出的那样,new 并不是自动加载器被触发的唯一时间。访问 class constant, static method, or static property will also trigger it, as will running class_exists.
use
statement 可以被认为是一个 C 预处理宏,如果你熟悉那些:它在编译时重写当前文件 到让您为长 class、函数或常量名称写一个短名称。它不会触发自动加载,因为它不关心 class 是否存在。
例如,如果您编写 use Foo\Bar\Baz as X
,那么在任何地方 X
被提及为 class 名称,PHP 编译器会重写它以提及 Foo\Bar\Baz
代替。只有当提到 class 的代码(例如 new X
、X::FOO
、X::doSomething()
)实际上是 运行 时,它才会查看是否真的存在 class Foo\Bar\Baz
,并根据需要触发自动加载器。
常用形式 use Foo\Bar\Baz
只是 use Foo\Bar\Baz as Baz
的 shorthand,将别名 Baz
分配给 class 名称 Foo\Bar\Baz
。
因为the manual points out别名只在编译时处理,所以动态查找不会使用它。在上面的示例中,class_exists('X')
将 return false,但您可以使用 class_exists(X::class)
扩展别名 - 编译器会自动将完整的 class 名称替换为字符串,所以在 运行 时间,表达式将是 class_exists('\Foo\Bar\Baz')
.
use
语句是否使您的代码更好因此完全是风格问题:目的是您的代码在没有长的完全限定 class 名称的情况下将更具可读性,但它会代码实际上 运行s.
没有任何区别
我的问题分为三个部分:
放入
use
语句会立即触发自动加载器,还是等到 class 被使用? (延迟加载)如果自动加载不是以延迟加载的方式完成,是否会对性能产生负面影响?
最好遵循哪种模式,为什么?当未使用
use
语句时,PhpStorm 将 "Unnecessary fully qualified name..." 显示为代码问题。
下面是一个 class 定义 Laravel 控制器的示例,其中包含 use
语句:
namespace App\Http\Controllers;
use Carbon\Carbon;
class FooController extends Controller
{
/**
* This action uses the Carbon class
*/
public function bar1()
{
return view('foo.bar1', ['now' => new Carbon()]);
}
/**
* This action does not use the Carbon class
*/
public function bar2()
{
return view('foo.bar2');
}
}
没有 use
语句的相同 class:
namespace App\Http\Controllers;
class FooController extends Controller
{
/**
* This action uses the Carbon class
*/
public function bar1()
{
return view('foo.bar1', ['now' => new \Carbon\Carbon()]);
}
/**
* This action does not use the Carbon class
*/
public function bar2()
{
return view('foo.bar2');
}
}
1) class 会在您执行 new Class()
语句时自动加载。
2) 见 1)
3) 最好遵循哪种模式,为什么?:
我建议使用 use
,因为您可能会遇到这样的情况:您的命名空间非常长,您的代码将变得不可读。
来自php docs:
This example attempts to load the classes MyClass1 and MyClass2 from the files MyClass1.php and MyClass2.php respectively.
<?php
spl_autoload_register(function ($class_name) {
include $class_name . '.php';
});
$obj = new MyClass1();
$obj2 = new MyClass2();
?>
命名空间只是组织 classes 的一个附加功能。
编辑: 正如@IMSoP 在评论中指出的那样,new 并不是自动加载器被触发的唯一时间。访问 class constant, static method, or static property will also trigger it, as will running class_exists.
use
statement 可以被认为是一个 C 预处理宏,如果你熟悉那些:它在编译时重写当前文件 到让您为长 class、函数或常量名称写一个短名称。它不会触发自动加载,因为它不关心 class 是否存在。
例如,如果您编写 use Foo\Bar\Baz as X
,那么在任何地方 X
被提及为 class 名称,PHP 编译器会重写它以提及 Foo\Bar\Baz
代替。只有当提到 class 的代码(例如 new X
、X::FOO
、X::doSomething()
)实际上是 运行 时,它才会查看是否真的存在 class Foo\Bar\Baz
,并根据需要触发自动加载器。
常用形式 use Foo\Bar\Baz
只是 use Foo\Bar\Baz as Baz
的 shorthand,将别名 Baz
分配给 class 名称 Foo\Bar\Baz
。
因为the manual points out别名只在编译时处理,所以动态查找不会使用它。在上面的示例中,class_exists('X')
将 return false,但您可以使用 class_exists(X::class)
扩展别名 - 编译器会自动将完整的 class 名称替换为字符串,所以在 运行 时间,表达式将是 class_exists('\Foo\Bar\Baz')
.
use
语句是否使您的代码更好因此完全是风格问题:目的是您的代码在没有长的完全限定 class 名称的情况下将更具可读性,但它会代码实际上 运行s.