use、include、reflection

include的优先级大于use,如果没有成功引入文件,那么后续类的使用(new操作)将不会成功。

在使用laravel框架时,因为框架的作用,根本感受不到include的存在。 导致误以为只要use了某个类就能成功使用。 而实际情况是框架使用了autoload机制。 所以你实际使用的文件其实都是暗中有引入的。 只不过因为框架的便利而忽视了。

以laravel举例

入口文件index.php

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

vendor 中的 autoload.php 中是 composer 的自动加载

//getLoader()就是引入文件`autoload_real.php`中的方法,佐证类的使用离不开引入文件
require_once __DIR__ . '/composer/autoload_real.php';

return ComposerAutoloaderInit7676602d36c501898335a7762ee2c6ba::getLoader();

getLoader() 追踪过去 $loader->register(true) 详细代码如下

    public function register($prepend = false)
    {
        spl_autoload_register(array($this, 'loadClass'), true, $prepend);
    }

    public function loadClass($class)
    {
        if ($file = $this->findFile($class)) {
            includeFile($file);

            return true;
        }
    }

由此可以看出实际上类的使用还是离不开include引入文件,只不过因为框架的优势而更加便利了。

代码实例

目录结构

test.php
<?php namespace Test\Test2;
//include '/Users/Anna/wwwroot/anna-php/Test/Test2/Url.php';
use Test\Test3\Url2;
class TestController {

    public function url()
    {
        $a = new \ReflectionClass('Test\Test3\Url2');
        //$a = new url2();
        var_dump($a);
    }
Url.php
<?php namespace Test\Test3;

class Url2 {
    public function index()
    {
        return 1;
    }

use

use 仅仅起到了声明命名空间的作用 例如 new url2()

  • 在成功 include Url.php 文件的前提下
    • use Test\Test3\Url as url; 才能成功实例化 url2 这个类(类名不区分大小写)
    • 没有use Test\Test3\Url as url; 会在当前命名空间查找该类,不能成功实例化url2 这个类 (全命名空间也可成功实例化)
  • 没有成功 include Url.php 情况下报错:

    无论是否正确use了这个类 都无法实例化成功。

    Fatal error: Uncaught Error: Class 'Test\Test3\Url2' not found in /Users/Anna/wwwroot/anna-php/Test/Test2/test.php on line 13


原理

只有include了之后 这个文件里相当于追加写入了Url.php 这个文件的所有内容。

此时进行实例化类只要保证命名空间正确,就能成功实例化Url2这个类。

use的作用正是声明了命名空间

如果没有使用use声明该类的完整命名空间的话,使用全命名空间也是可以成功实例化该类的,use还有另一个作用是简化类名。

reflection

只有成功的include Url.php文件reflection才能成功反射

new \ReflectionClass('Test\Test3\Url');

ReflectionClass的参数需要是完整的命名空间否则无法成功反射。

和是否Use无关,一定要是完整的命名空间。

未成功include则会报错:

Fatal error: Uncaught ReflectionException: Class Test\Test3\Url2 does not exist in /Users/Anna/wwwroot/anna-php/Test/Test2/test.php on line 12

does not exist in /Users/Anna/wwwroot/anna-php/Test/Test2/test.php 就可以说明问题当前的文件内不存在这个类。这样就很好理解了。