当前位置: 首页 > 后端技术 > PHP

PHP类的自动加载和命名空间解析

时间:2023-03-29 18:29:10 PHP

php使用require(require_once)和include(include_once)关键字来加载类文件。但是在实际的开发项目中,我们基本不会使用这些关键字来加载类。因为这样做会让代码的维护变得相当困难。在实际开发中,我们会在文件开头使用use关键字来使用类,然后直接new类。至于类是如何加载的,一般是由framework或者composer实现的。'。__班级__。'';}}/**Runresult*Output

Person

*/Namespace命名空间并不是一个新东西,很多语言早就支持这个特性(只是名字不一样),其中一个它解决的主要问题是命名冲突!日常生活中似乎很多人都有相同的名字,我们必须用一些标志来区分他们的区别。比如现在我们要用php介绍一个人叫张三,在财务部工作。我们可以这样描述。namespace财务部;classZhangSan{function__construct(){echo'财务部张三';}}这是张三的基本信息,namespace是他的部门logo,class是他的名字。这样每个人都可以知道他是财务部的约翰尼,而不是工程部的约翰尼。非限定名、限定名和完全限定名1.非限定名,或者没有前缀的类名,例如$comment=newComment();如果当前命名空间是BlogArticle,Comment将被解析为BlogArticleComment。如果使用Comment的代码不包含任何命名空间中的代码(在全局空间中),Comment将被解析为Comment。注意:如果使用关键字useonetwoComment;在文件的开头使用,Comment将被解析为*onetwoComment*。2.限定名称,或包含前缀的名称,例如$comment=newArticleComment();如果当前命名空间是Blog,Comment将被解析为BlogArticleComment。如果使用Comment的代码不包含任何命名空间中的代码(在全局空间中),Comment将被解析为ArticleComment。3.完全限定名称,或包含全局前缀运算符的名称,例如$comment=newArticleComment();在这种情况下,Comment总是被解析为ArticleComment。spl_autoload接下来,让我们实现带有命名空间的类的自动加载。我们使用spl_autoload_register()函数执行此操作,这需要您的PHP版本大于5.12。spl_autoload_register函数的作用是将传入的函数(参数可以是回调函数或函数名的形式)注册到SPL的__autoload函数队列中,去除系统默认的__autoload()函数。一旦调用了spl_autoload_register()函数,当调用一个未定义的类时,系统会依次调用所有注册到spl_autoload_register()函数的函数,而不是自动调用__autoload()函数。现在,让我们创建一个使用os作为命名空间的Linux类(建议文件名与类名保持一致):'.__班级__。'';}}接下来在同级目录新建index.php文件,使用spl_autoload_register以函数回调的形式实现自动加载:文件路径'os\\Linux'=>'./Linux.php',);/*根据类名确定文件路径*/$file=$class_map[$class];/*导入相关文件*/if(file_exists($file)){include$file;}});新的\os\Linux();这里我们用一个数组来保存类名和文件路径的关系,这样当传入类名的时候,自动加载器就知道要导入哪个文件来加载类了。但是一旦文件多了,映射数组就会变得很长,维护起来会相当麻烦。如果命名能够遵守统一的约定,就可以让autoloader自动分析并确定class文件所在的路径。接下来要介绍的PSR-4是一个被广泛采用的约定。PSR-4规范PSR-4是关于自动从文件路径加载相应类的相关规范。规范规定一个完全限定的类名需要有如下结构:<顶级命名空间>(<子命名空间>)*<类名>PSR-4规范中必须有一个顶级命名空间,并且它的含义是代表一个特殊的目录(文件基目录)。子命名空间表示类文件相对于文件基目录的路径(相对路径),类名与文件名一致(注意大小写的区别)。例如:在全限定类名appviewnewsIndex中,如果app代表C:Baidu,那么这个类的路径就是C:BaiduviewnewsIndex.php。下面以解析appviewnewsIndex为例,写一个简单的Demo:'C:\Baidu',);/*解析类名文件路径*/$vendor=substr($class,0,strpos($class,'\\'));//取出顶层命名空间[app]$vendor_dir=$vendor_map[$vendor];//文件基目录[C:\百度]$rel_path=dirname(substr($class,strlen($vendor)));//相对路径[/view/news]$file_name=basename($class).'.php';//filename[Index.php]/*输出文件所在的路径*/echo$vendor_dir.$rel_path。DIRECTORY_SEPARATOR。$文件名;