Blogger Information
Blog 35
fans 0
comment 0
visits 44055
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
PHP命名空间分级管理及trait类的使用场景--2019年10月10日
Victor的博客
Original
1770 people have browsed it

1、写一个分级的命名空间,并实现类的自动加载

2、写一个trait类,理解它的功能与使用场景

【1】命名空间分级管理与类的自动加载

        PHP 作为一种脚本语言,不存在程序入口,在开发中,各种初始化、业务流程都分散在各个不同的文件中,如果引用不同文件中的类,需要一堆 include 函数包含一大堆文件,这即显得笨拙,也不易于后期维护,因此,需要使用自动加载机制来完成这种引用。

实现自动加载管理,首先需要遵循相应的一些规则(主要是PSR-4):

  • 废除了PSR-0中_就是目录分割符的写法,_下划线在完全限定类名中是没有特殊含义了。

  • 类文件名要以 .php 结尾。

  • 一个类存放在一个同名的文件中;

  • 类名必须要和对应的文件名要一模一样,大小写也要一模一样。

  • 命名空间的分层 一定要与 类文件的目录分层 完全一致。  

最终实现将命名空间\类这样的类名,给转换成目录名/类名.php这样的路径,并返回完整路径。

使用自动加载需注意的细节:

  • ____autoload函数马上要在7.2版本的PHP中弃用了,应使用spl_autoload_register()实现,它的好处是可以自定义多个autoloader;

  • 包含spl_autoload_register()的自动加载文件,必须放在根空间下(对应系统的root目录),这样才可以管理根空间内所有的类文件;如果去加载根空间以外的类文件是会报错的。

  • 类的自动加载不可用于PHP的CLI交互模式;

  • 类的查找顺序:优先查找手动include或require进来的类,查找不到的情况下再采用类的自动加载机制;

  • 如果类名比如被用于call_user_func(),则它可能包含一些危险的字符,比如 ../。 建议在这样的函数中不要使用用户的输入,起码需要验证下输入。

  • 自动加载并不是万无一失的,有些特殊场景需单独考虑。

实例说明    (命名空间--->目录结构---->目录下类文件的对应关系):

根空间\                    -------->    ROOT目录                             (Autoloader.php)

\inc\Controller       -------->    ROOT/inc/Controller目录    (Contrl.php)

\inc\model               -------->    ROOT/inc/model目录        (Marticle.php , Mcard.php)

\inc\view                  -------->    ROOT/inc/view目录            (Varticle.php , Vcard.php)

实例代码:

实例
<?php

class Autoloader {
	public static function register() {
		spl_autoload_register(function ($class) {
			$file = str_replace('\\', DIRECTORY_SEPARATOR, $class); 
			$file = __DIR__ . '/' . $file . '.php';
			if (file_exists($file)) {
				include $file;
				return true;
			}
			return false;
		});
	}
}
Autoloader::register();

?>
运行实例 »
点击 "运行实例" 按钮查看在线实例
实例
<?php

namespace _1010;

include 'Autoloader.php';

$a = new \inc\Controller\Contrl();
$b = new \inc\model\Marticle();
$c = new \inc\model\Mcard();
$d = new \inc\view\Varticle();
$e = new \inc\view\Vcard();

?>
运行实例 »
点击 "运行实例" 按钮查看在线实例

【2】Trait 特性

Trait是为减少单继承语言限制,来达到多继承的效果。它可以混入不同结构独立的类中复用方法集。使用关键字“Trait”来声明,类包含的特性,Trait都支持,但不能通过自身实例化对象。

对于重名属性和方法,优先顺序是:当前类成员优先级 > Trait内成员优先级 > 所继承的父类内的成员优先级。

Trait可看作模块化的零部件,可在单个类中,用use引入多个,有成员属性冲突时,使用insteadof和as操作符解决。

以下代码演示一个Trait嵌套和混入的使用场景:

实例
<?php

trait Demo1_trait {
	function method1() {
		echo 'Demo1_trait的方法:method1()';
	}
}

trait Demo2_trait {
	use Demo1_trait;
	function method2() {
		echo 'Demo2_trait的方法:method2()';
	}
}

class Demo {
	use Demo2_trait;
}

$obj = new Demo();
$obj->method1();
$obj->method2();

?>
运行实例 »
点击 "运行实例" 按钮查看在线实例

总结:

1、使用自动加载的好处:

  • 摆脱长长的 include() 与 require();

  • 使用类时才会引入文件,实现了 lazy loading;

  • 无需知道类的实际文件地址,实现了逻辑和实体文件的分离;

  • 相比于绝对路径引入类的文件路径,自动加载机制在当类库目录名或者文件名需要更改的时候,所有include了这个文件的php文件不需要随着修改,这避免了加大源代码目录结构重构的负担;

  • 相比于在php.ini中的include_path引入类的文件路径,自动加载的机制可以节省很多性能问题;

  • 虽然性能和__FILE__魔术方法引入相对类路径的性能相近,但是自动加载机制可以防止或减少require_once,include_once在文件各处的随意使用,也不用计较类与类之间相互依赖的引入顺序;

  • 可以通过带命名空间的引用和别名的方法,解决多个类重名或者同个app目录下及子目录下重名。

2、Trait就像实现某类功能的组件,可以更灵活的复用自定义功能,而不必局限与继承关系上。




Correction status:qualified

Teacher's comments:总结的非常到位
Statement of this Website
The copyright of this blog article belongs to the blogger. Please specify the address when reprinting! If there is any infringement or violation of the law, please contact admin@php.cn Report processing!
All comments Speak rationally on civilized internet, please comply with News Comment Service Agreement
0 comments
Author's latest blog post