zoukankan      html  css  js  c++  java
  • PHP自动加载类__autoload()浅谈

    在面向对象编程中,都是以对象为单位的操作,如果我有两个不同的类,类A和类B,在同一个文件里,实例化对象,就能在这个文件同时调用类A和类B的函数

     1 <?php
     2 #a.php
     3 
     4 class A{
     5     public function funA()
     6     {
     7         echo 'The class:'.__class__.'<br/>';
     8     }
     9 }
    10 
    11 class B{
    12     public function funB()
    13     {
    14         echo 'The class:'.__class__.'<br/>';
    15     }
    16 }
    17 $a = new A();
    18 $b = new B();
    19 $a->funA(); //The class:A
    20 $b->funB(); //The class:B

    两个类都在同一个文件,所有能运行成功,但现在大部分应用都分MVC,不同类专门处理特定的事物,比如C(Controller),只执行与事物有关的逻辑操作,这些文件很明显分属于不同目录下:

    |—root

        |—controller

            |—controllerA.php

        |—model

           |—modelA.php

      |—view

            |—viewA.php

    这时我要在modelA.php里怎么引用controllerA.php的函数呢?这就用到__autoload()了。

     1 <?php
     2 #保存在MyClass.php
     3 
     4 class MyClass {
     5 
     6     public function getNamespace()
     7     {
     8         return get_class($this);
     9     }
    10 }

    现在我们在同级目录下引用这个类

     1 <?php
     2 
     3 function __autoload($name)
     4 {
     5     $file = realpath(__DIR__).'/'.$name.'.php';
     6     if(file_exists($file))
     7         {
     8                 require_once($file);
     9         if(class_exists($name,false))
    10                 {
    11             return true;
    12                 }
    13                 return false;
    14           }
    15           return false;
    16 }
    17 
    18 $obj = new MyClass();
    19 echo $obj->getNamespace();    //输出 MyClass;

     当你引用不存在的类时,__autoload就会被调用,并且你的类名会被作为参数传送过去(当你同时使用命名空间,包含命名空间部分会一起作为参数传送)。

    下面我们把命名空间和自动加载类合并使用

    命名空间,PHP从5.3开始支持命名空间(namespace),这个在C语言里非常常见,刚开始我不理解,直到我完整接触一个项目,需要加载在不同目录下Class时,恍然大悟。OK,下面讲一讲自己的理解吧。

    用不同的命名空间区别相同的函数名,同时命名空间也可以作为引入类文件的路径。

    (在WEB项目中,当在client输入一个url时,一般会有一个入口文件,在这个文件里解析你要调用的controller,以及传递的参数,然后动态的加载相应类文件,这其实就牵扯到一点路由规则,当然还有另外一种,在项目初始化之初就把所有类文件全部加载在内存中,这样,每次请求响应都不用再加载,常驻内存后响应要快点。)

     1 <?php
     2 #首先建立一个MyClass目录,在该目录下新MyClass.php文件,代码如下。
     3 
     4 namespace MyClass;
     5 
     6 class MyClass {
     7 
     8         public function getNamespace()
     9         {
    10                 return get_class($this);
    11         }
    12 }
     1 <?php
     2 #在跟MyClass目录同级的目录下,新建一个文件,内容如下
     3 function __autoload($name)
     4 {
     5     $class_path = str_replace('\',DIRECTORY_SEPARATOR,$name);   //把表示命名空间的分割符号,转换成表示目录结构的斜线
     6     $file = realpath(__DIR__).'/'.$class_path.'.php';   
     7     if(file_exists($file))
     8         {
     9                 require_once($file);    //引入文件
    10         if(class_exists($name,false))    //带有命名空间的类名
    11                 {
    12             return true;
    13                 }
    14                 return false;
    15           }
    16           return false;
    17 }
    18 echo MyClassMyClass::getNamespace();    //输出: MyClassMyClass;

    这样非常容易避免了,当一个项目非常大时,不停的require文件。

    让我们再思考,有没有更工程化的解决方案?当然有,我们可以建立自己的 Autoload 类,在这个类里面自动加载不同的类(可以包含命名空间),需要引用其他类的文件,只需要显示写入这个 Autoload 类即可。

    具体实现放在下一篇博客 ^_^ .( http://www.cnblogs.com/CpNice/p/4369399.html )

  • 相关阅读:
    Chromium 和Webkit 3月14日的最近进展:多标签选择、标签标题省略、动画API和新的Chromium Logo
    奇妙的HTML5 Canvas动画实例
    XNA那些事(一) 框架工作原理
    实现跨浏览器的HTML5占位符
    编写超级可读代码的15个最佳实践
    谈HTML5和CSS3的国际化支持
    HTML5 Guitar Tab Player
    如何设置让网站禁止被爬虫收录?robots.txt
    YourPHP笔记
    Robots.txt  禁止爬虫
  • 原文地址:https://www.cnblogs.com/CpNice/p/4119925.html
Copyright © 2011-2022 走看看