zoukankan      html  css  js  c++  java
  • php __autoload函数和命名空间。

    5.3后就有了命名空间,从别人家哪里下的API发现很少有包含require,include的代码,但是却实现了所有文件的包含。

    文章目录:
    1.   __autoload使用技巧。
    2.   命名空间介绍和使用。
    3.   两者结合使用优化代码。

    1,__autoload使用技巧:

      原理:当有定义__autoload函数,每次创建一个类的对象就会触发该函数。

      原型:

    function __autoload($classname){
        $classname=str_replace('\','/',$classname);
        require '../src/'.$classname.'.php';
    }

      用__autoload实现自动加载:

    function __autoload($classname){
        requireAll('../src',$class_name)
    }
    
    /**
     * 搜索所有的 $dir目录下的文件,如果存在文件名为 $class_name 的文件就包含它。
     */
    
    function requireAll($dir,$class_name){
        $d=dir($dir);
        while(false!==($entry=$d->read())){
            if($entry=='..') continue;
            if($entry=='.') continue;
            if(is_dir($dir.'/'.$entry)){
                requireAll($dir.'/'.$entry,$class_name);
            }else{
                if($entry==$class_name.'.php'){
                    require_once $dir.'/'.$entry;
                }
            }
        }
        $d->close();
    }

    在目录下,无论那个层次,只要你定义了这个类,并且名字和文件名一致,你就可以创建这个类的对象。


    2,命名空间介绍和使用

      命名空间是为了使类名定义不重复,不是用命名空间的代码往往为了区分一个类似功能的函数命名要多出很多字节,有时候还可能与系统定义的函数发生冲突,命名空间就是为了避免这一类事情的发生。

      命名空间规则:

      默认的是公共的命名空间,在网上截取这一段:

    非限定名称,或不包含前缀的类名称,例如 $a=new foo(); 或 foo::staticmethod();。如果当前命名空间是 currentnamespace,foo 将被解析为currentnamespacefoo。如果使用 foo 的代码是全局的,不包含在任何命名空间中的代码,则 foo 会被解析为foo。 警告:如果命名空间中的函数或常量未定义,则该非限定的函数名称或常量名称会被解析为全局函数名称或常量名称。详情参见 使用命名空间:后备全局函数名称/常量名称。
    
    限定名称
    ,或包含前缀的名称,例如 $a = new subnamespacefoo(); 或 subnamespacefoo::staticmethod();。如果当前的命名空间是currentnamespace,则 foo 会被解析为 currentnamespacesubnamespacefoo。如果使用 foo 的代码是全局的,不包含在任何命名空间中的代码,foo 会被解析为subnamespacefoo。
    完全限定名称,或包含了全局前缀操作符的名称,例如,
    $a = new currentnamespacefoo(); 或 currentnamespacefoo::staticmethod();。在这种情况下,foo 总是被解析为代码中的文字名(literal name)currentnamespacefoo

      定义多个命名空间:

    namespace MyProject {
    
    const CONNECT_OK = 1;
    class Connection { /* ... */ }
    function connect() { /* ... */  }
    }
    
    namespace AnotherProject {
    
    const CONNECT_OK = 1;
    class Connection { /* ... */ }
    function connect() { /* ... */  }
    }

    3,两者结合使用优化代码

      其实原理很简单,当 “new foo()”的时候,会解析成 currentnamespacefoo,所以在 __autoload做一下更改就可以实现自动加载了。

      

    use WishWishClient;
    function __autoload($classname){
        $classname=str_replace('\','/',$classname);
        require '../src/'.$classname.'.php';
    }
    
    
    /**
     * 搜索所有的 $dir目录下的文件,如果存在文件名为 $class_name 的文件就包含它。
     */
    
    function requireAll($dir,$class_name){
        $d=dir($dir);
        while(false!==($entry=$d->read())){
            if($entry=='..') continue;
            if($entry=='.') continue;
            if(is_dir($dir.'/'.$entry)){
                requireAll($dir.'/'.$entry,$class_name);
            }else{
                if($entry==$class_name.'.php'){
                    require_once $dir.'/'.$entry;
                }
            }
        }
        $d->close();
    }
    
    
    $A=new WishClient('');

      

  • 相关阅读:
    luogu 1865 数论 线性素数筛法
    洛谷 2921 记忆化搜索 tarjan 基环外向树
    洛谷 1052 dp 状态压缩
    洛谷 1156 dp
    洛谷 1063 dp 区间dp
    洛谷 2409 dp 月赛题目
    洛谷1199 简单博弈 贪心
    洛谷1417 烹调方案 dp 贪心
    洛谷1387 二维dp 不是特别简略的题解 智商题
    2016 10 28考试 dp 乱搞 树状数组
  • 原文地址:https://www.cnblogs.com/canbefree/p/4012605.html
Copyright © 2011-2022 走看看