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
就可以说明问题当前的文件内不存在这个类。这样就很好理解了。