PHP"使用"关键字和自动加载

时间:2018-04-26 13:10:11

标签: php namespaces autoload

我的问题分为三部分:

  1. 放入use语句是否会立即触发自动加载器,还是等到使用该类? (延迟加载)

  2. 如果自动加载不以延迟加载方式完成,是否会对性能产生负面影响?

  3. 最好遵循哪种模式,为什么? PhpStorm显示"不必要的完全限定名称......"作为代码问题,use语句未被使用。

  4. 以下是具有use语句的Laravel控制器的示例类定义:

    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语句的同一个类:

    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');
        }
    }
    

2 个答案:

答案 0 :(得分:5)

1)当您执行new Class()语句时,该类会自动加载。

2)见1)

3)最好遵循哪种模式以及为什么?:

我建议使用use,因为您可能会遇到名称空间很长并且代码无法读取的情况。

来自php docs

  

此示例尝试从中加载类MyClass1和MyClass2   文件分别为MyClass1.php和MyClass2.php。

<?php
spl_autoload_register(function ($class_name) {
    include $class_name . '.php';
});

$obj  = new MyClass1();
$obj2 = new MyClass2(); 
?>

命名空间只是用于组织类的附加功能。

编辑:正如@IMSoP在评论中指出的那样,新的并不是自动加载器被触发的唯一时间。访问class constantstatic methodstatic property也会触发class_exists

答案 1 :(得分:1)

use statement可以被认为是一个C预处理宏,如果你熟悉它们:它会在编译时重写当前文件 让你写一个简短的长类,函数或常量名的名称。它不会触发自动加载,因为它不关心类是否存在。

例如,如果您编写use Foo\Bar\Baz as X,那么在X被提及为类名的任何地方,PHP编译器都会重写提及Foo\Bar\Baz。只有在提及类的代码(例如new XX::FOOX::doSomething())实际运行时才会看到是否确实存在类Foo\Bar\Baz,并在必要时触发自动加载器。

常用表单use Foo\Bar\Baz只是use Foo\Bar\Baz as Baz的简写,将别名Baz指定给类名Foo\Bar\Baz

作为the manual points out,别名仅在编译时处理,因此动态查找不会使用它。在上面的示例中,class_exists('X')将返回false,但您可以使用class_exists(X::class)强制在运行时扩展类名称 - X::class将由编译器扩展为字符串{{1 }}

'\Foo\Bar\Baz'语句是否使代码更好是因为风格问题:意图是你的代码在没有完全限定的类名的情况下会更具可读性,但它对于代码实际上运行。