浅析PHP类的自动加载和命名空间
php是使用require(require_once)和include(include_once)关键字加载类文件。但是在实际的开发工程中我们基本上不会去使用这些关键字去加载类。 因为这样做会使得代码的维护相当的困难。实际的开发中我们会在文件的开始位置用use关键字使用类,然后直接new这个类就可以了. 至于类是怎么加载的,一般都是框架或者composer去实现的。
<?phpuse Illuminate\Container\Container;$container = new Container();
自动加载
我们可以通过一段伪代码来模拟一下在类的实例化工程中类是如何工作的
function instance($class){ // 如果类已加载则返回其实例 if (class_exists($class, false)) { return new $class(); } // 查看 autoload 函数是否被用户定义 if (function_exists('__autoload')) { __autoload($class); // 最后一次加载类的机会 } // 再次检查类是否存在 if (class_exists($class, false)) { return new $class(); } else { // 系统:我实在没辙了 thr<span style="color:transparent">本文来源gaodai#ma#com搞*!代#%^码$网!</span><strong>搞代gaodaima码</strong>ow new Exception('Class Not Found'); }}
php在语言层面提供了**__autoload** 魔术方法给用户来实现自己的自动加载逻辑。当用户去new一个类的时候,如果该类没有被加载,php会在抛出错误前调用**__autoload方法去加载类。下面的例子中的__autoload**方法只是简单的输出要加载类的名称, 并没有去实际的加载对应的类, 所以会抛出错误。
<?phpuse Illuminate\Container\Container;$container = new Container();function __autoload($class){ /* 具体处理逻辑 */ echo $class;// 简单的输出要加载类的名称}/** *
运行结果
Illuminate\Container\ContainerFatal error: Uncaught Error: Class 'Illuminate\Container\Container' not found in D:\project\php\laravel_for_ci_cd\test\ClassLoader.php:5Stack trace:#0 {main} thrown in D:\project\php\laravel_for_ci_cd\test\ClassLoader.php on line 5 */
明白了 **__autoload** 函数的工作原理之后,我们来用它去实现一个最简单自动加载。我们会有index.php和Person.php两个文件在同一个目录下。
//index.php<?phpfunction __autoload($class){ // 根据类名确定文件名 $file = './'.$class . '.php'; if (file_exists($file)) { include $file; // 引入PHP文件 }}new Person();/*---------------------分割线-------------------------------------*///Person.phpclass Person{ // 对象实例化时输出当前类名 function __construct() { echo '<h1>' . __CLASS__ . '</h1>'; }}/**运行结果 * 输出 <h1>Person</h1> */
命名空间
命名空间并不是什么新鲜的事务,很多语言都早就支持了这个特性(只是叫法不相同),它主要解决的一个问题就是命名冲突! 就好像日常生活中很多人都会重名,我们必须要通过一些标识来区分他们的不同。比如说现在我们要用php介绍一个叫张三的人 ,他在财务部门工作。我们可以这样描述。
namespace 财务部门; class 张三{ function __construct() { echo '财务部门的张三'; }}
这就是张三的基本资料 , namespace是他的部门标识,class是他的名称. 这样大家就可以知道他是财务部门的张三而不是工程部门的张三。
非限定名称,限定名称和完全限定名称