PHP中的use关键字及文件的加载详解

前言

可能在大家经常使用框架,写一个Controller或者Model的时候,写了好多use,但是并没有写文件加载的代码,就以为use可以进行文件的自动加载了。

详细介绍

其实,现在流行的php框架,都是基于MVC模式的,大量的使用了命名空间,以提高程序的灵活性。那么框架是怎么实现将use关键字所声明的类库对应的脚本文件进行加载的那?

(1):在通过use关键字进行声明类库的声明的时候,并不会进行脚本的加载,而是在脚本文件真正使用到所对应的类库的时候才会进行加载(这就是所谓延迟加载)。

(2):框架一般在初始化阶段,就声明了__autoload()函数或者是spl_autoload_register()函数(一般会在入口文件中进行声明)。在调用通过use声明的类库的时候,会自动的调用上述的函数,将调用的类库名称传递到函数中(这里的类库名称是包括命名空间的全名称)

<?php
namespace Home\Controller;
function __autoload($class_name) {
 //echo $class_name."<br/>";
 require_once ("./".$class_name . ".php");
}
use Admin\Controller\Index;
new Index; //new Index会触发__autoload()函数,返回Admin\Controller\Index到函数中
?>

(3):框架中定义的__autoload()函数或者是spl_autoload_register()函数在接收到传递过来的类库名称以后,框架会对名称进行处理,分析出类库名称所对应的文件路径,然后进行文件的加载。这里需要注意的是,不同的框架在解析类库名称,分析文件路径的方式是各不一致的,毕竟各自的目录结构是不一样的。

比如说,thinkphp:

 /**
  * 类库自动加载
  * @param string $class 对象类名
  * @return void
  */
 public static function autoload($class) {
  // 检查是否存在映射
  if(isset(self::$_map[$class])) {
   include self::$_map[$class];
  }elseif(false !== strpos($class,'\\')){
   $name   = strstr($class, '\\', true);
   if(in_array($name,array('Think','Org','Behavior','Com','Vendor')) || is_dir(LIB_PATH.$name)){
    // Library目录下面的命名空间自动定位
    $path  = LIB_PATH;
   }else{
    // 检测自定义命名空间 否则就以模块为命名空间
    $namespace = C('AUTOLOAD_NAMESPACE');
    $path  = isset($namespace[$name])? dirname($namespace[$name]).'/' : APP_PATH;
   }
   $filename  = $path . str_replace('\\', '/', $class) . EXT;
   if(is_file($filename)) {
    // Win环境下面严格区分大小写
    if (IS_WIN && false === strpos(str_replace('/', '\\', realpath($filename)), $class . EXT)){
     return ;
    }
    include $filename;
   }
  }elseif (!C('APP_USE_NAMESPACE')) {
   // 自动加载的类库层
   foreach(explode(',',C('APP_AUTOLOAD_LAYER')) as $layer){
    if(substr($class,-strlen($layer))==$layer){
     if(require_cache(MODULE_PATH.$layer.'/'.$class.EXT)) {
      return ;
     }
    }
   }
   // 根据自动加载路径设置进行尝试搜索
   foreach (explode(',',C('APP_AUTOLOAD_PATH')) as $path){
    if(import($path.'.'.$class))
     // 如果加载类成功则返回
     return ;
   }
  }
 }

这里只是举例说明use与文件的自动加载没有关系,不强调各个框架是具体怎么完成自动加载,具体的可以自己看框架代码进行研究。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流。

(0)

相关推荐

  • PHP面向对象的进阶学习(抽像类、接口、final、类常量)

    一.抽像类(abstract) 在我们实际开发过程中,有些类并不需要被实例化,如前面学习到的一些父类,主要是让子类来继承,这样可以提高代码复用性 语法结构: 复制代码 代码如下: abstract class 类名{ 属性 $name; 方法(){} //方法也可以为abstract 修饰符 function 方法名(){} } 例: 复制代码 代码如下: abstract class animal{ public $name; public $age; //抽象方法不能有方法体,主要是为了让子

  • php类中的$this,static,final,const,self这几个关键字使用方法

    本篇文章主要分项了一下关于php类中的$this,static,final,const,self这几个关键字使用方法. $this $this表示当前实例,在类的内部方法访问未声明为const及static的属性时,使用$this->value='phpernote';的形式.常见用法如: $this->属性 $this->方法 举例如下: <?php class MyClass{ private $name; public function __construct($name){

  • php中static和const关键字用法分析

    本文实例讲述了php中static和const关键字用法.分享给大家供大家参考,具体如下: static关键字在类中描述的成员属性和成员函数都是静态的. static成员能限制外部的访问,因为static成员是属于类的,而不是属于任何对象实例. 从内存的角度讲,其中对象是放在"堆内存"中,对象的引用是放在"栈内存"中,而静态成员被放在初始化静态段中,在类的第一次加载的时候加入的.可以让对内存中的所有对象所共享.如下图所示: <?php class Person

  • php中final关键字用法分析

    本文实例讲述了php中final关键字用法.分享给大家供大家参考,具体如下: final关键字只能用来定义类和定义方法. 使用final关键字标记的类不能被继承 final class Person{ ....... } class Student extends Person{ ....... } 会出现错误提示.Fatal error :Class Student may not inherit from final class(Person) 使用final关键字标记的方法不能被子类覆盖

  • PHP 面向对象 final类与final方法

    final---用于类.方法前. final类---不可被继承. final方法---不可被覆盖. final类不能被继承. 如果我们不希望一个类被继承,我们使用final来修饰这个类.这个类将无法被继承.比如我们设定的Math类,涉及了我们要做的数学计算方法,这些算法也没有必要修改,也没有必要被继承,我们把它设置成final类型. 复制代码 代码如下: <? //声明一个final类Math final class Math{ public static $pi = 3.14; public

  • 详解PHP中instanceof关键字及instanceof关键字有什么作用

    PHP5的另一个新成员是instdnceof关键字.使用这个关键字可以确定一个对象是类的实例.类的子类,还是实现了某个特定接口,并进行相应的操作.在某些情况下,我们希望确定某个类是否特定的类型,或者是否实现了特定的接口.instanceof操作符非常适合完成这个任务.instanceof操作符检查三件事情:实例是否某个特定的类型,实例是否从某个特定的类型继承,实例或者他的任何祖先类是否实现了特定的接口.例如,假设希望了解名为manager的对象是否为类Employee的实例: $manager

  • PHP中static关键字以及与self关键字的区别

    概述 正在学习设计模式,之前有一篇文章关于单例模式的文章,重新读了这篇文章,发现对static关键字掌握不是很牢靠,重新温习一下. static关键字 PHP手册里对static关键字的介绍如下: 复制代码 代码如下: Declaring class properties or methods as static makes them accessible without needing an instantiation of the class. A property declared as

  • php面向对象全攻略 (十) final static const关键字的使用

    14.final 关键字的应用 这个关键字只能用来定义类和定义方法,不能使用final 这个关键字来定义成员属性,因 为final 是常量的意思,我们在PHP 里定义常量使用的是define()函数,所以不能使用final 来 定义成员属性. 使用final 关键标记的类不能被继承: 代码片段 final class Person{ - - } class Student extends Person{ } 会出现下面错误: Fatal error: Class Student may not

  • PHP中的use关键字及文件的加载详解

    前言 可能在大家经常使用框架,写一个Controller或者Model的时候,写了好多use,但是并没有写文件加载的代码,就以为use可以进行文件的自动加载了. 详细介绍 其实,现在流行的php框架,都是基于MVC模式的,大量的使用了命名空间,以提高程序的灵活性.那么框架是怎么实现将use关键字所声明的类库对应的脚本文件进行加载的那? (1):在通过use关键字进行声明类库的声明的时候,并不会进行脚本的加载,而是在脚本文件真正使用到所对应的类库的时候才会进行加载(这就是所谓延迟加载). (2):

  • 对python中xlsx,csv以及json文件的相互转化方法详解

    最近需要各种转格式,这里对相关代码作一个记录,方便日后查询. xlsx文件转csv文件 import xlrd import csv def xlsx_to_csv(): workbook = xlrd.open_workbook('1.xlsx') table = workbook.sheet_by_index(0) with codecs.open('1.csv', 'w', encoding='utf-8') as f: write = csv.writer(f) for row_num

  • CMD中使用attrib命令设置文件只读、隐藏属性详解

    本文介绍一个cmd下的一个attrib.exe的小程序,它可以用来设置文件的属性.我们知道文件的属性有只读.隐藏.系统.存档和无内容索引等5个,只读和隐藏用得比较多,另外三个用得比较少. 不知道大家有没有用过attrib.exe这个cmd下的小程序,它可以用来设置文件的属性.先来看看它的帮助文件. 复制代码 代码如下: C:\Users\splaybow>help attrib 显示或更改文件属性. ATTRIB [+R | -R] [+A | -A ] [+S | -S] [+H | -H]

  • python中利用await关键字如何等待Future对象完成详解

    前言 本文主要给大家介绍了关于python用await关键字等待Future对象完成的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧. 在下面的例子里,演示了怎么样使用await来等Future对象设置结果完成 示例代码如下: import asyncio def mark_done(future, result): print('setting future result to {!r}'.format(result)) future.set_result(resul

  • JavaWeb项目中dll文件动态加载方法解析(详细步骤)

    相信很多做Java的朋友都有过用Java调用JNI实现调用C或C++方法的经历,那么Java Web中又如何实现DLL/SO文件的动态加载方法呢.今天就给大家带来一篇JAVA Web项目中DLL/SO文件动态加载方法的文章. 在Java Web项目中,我们经常会用到通过JNI调用dll动态库文件来实现一些JAVA不能实现的功能,或者是一些第三方dll插件.通常的做法是将这些dll文件复制到 %JAVA_HOME%\jre\bin\ 文件夹或者 应用中间件(Tomcat|Weblogic)的bin

  • linux中关于ftp查看不到文件列表的问题详解

    今天配置linux服务器的ftp后,登录都正常,使用ftp工具登录后,所有目录都可以通过手工写路径访问,但是文件夹和文件列表看不到数据. 后来分析,总结原因得出结果是跟selinux有关,于是通过关闭selinux后尝试,ftp文件夹和文件列表都正常可以查看了. 如下2张图为解决前和解决后的截图: 1.解决前,通过输入正确的路径可以正常读取访问,但是看不到列表. 2.解决后,可以可视化查看列表数据. 在Linux下设置selinux有三种方法 一.在图形界面中: 桌面-->管理-->安全级别和

  • python中Django文件上传方法详解

    Django上传文件最简单最官方的方法 1.配置media路径 在settings.py中添加如下代码: MEDIA_ROOT = os.path.join(BASE_DIR, 'media') 2.定义数据表 import os from django.db import models from django.utils.timezone import now as timezone_now def upload_to(instance, filename):     now = timezo

  • C/C++中文件的随机读写详解及其作用介绍

    目录 概述 随机读写 函数 例子 指针流成员函数 随机访问二进制数据 概述 文件的操作方式分为顺序读写和随机读写. 顺序读写指文件的指针只能从头移到尾巴. 随机读写指文件指针可以随意移动, 根据需要. 随机读写 文件指针: 在磁盘文件操作中有一个文件指针, 用来指明进行读写的位置. 函数 文件流提供了一些有关文件指针的成员函数: 成员函数 作用 gcount() 返回最后一次输入所读入的字节数 tellg() 返回输入文件指针的当前位置 seekg (文件中的位置) 将输入文件中指针移到指定的位

  • 微信小程序中使用Promise进行异步流程处理的实例详解

    微信小程序中使用Promise进行异步流程处理的实例详解 我们知道,JavaScript是单进程执行的,同步操作会对程序的执行进行阻塞处理.比如在浏览器页面程序中,如果一段同步的代码需要执行很长时间(比如一个很大的循环操作),则页面会产生卡死的现象. 所以,在JavaScript中,提供了一些异步特性,为程序提供了性能和体验上的益处,比如可以将代码放到setTimeout()中执行:或者在网页中,我们使用Ajax的方式向服务器端做异步数据请求.这些异步的代码不会阻塞当前的界面主进程,界面还是可以

  • 基于Python的文件类型和字符串详解

    1. Python的文件类型 1. 源代码--直接由Python解析 vi 1.py #!/usr/bin/python print 'hello world' 这里的1.py就是源代码 执行方式和shell脚本类似: chmod +x 后,./1.py Python 1.py 2. 字节代码 Python源码文件经编译后生成的扩展名为pyc的文件 编译方法: [root@t1 py]# cat 2.py #!/usr/bin/python import py_compile py_compil

随机推荐