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 将被解析为currentnamespace\foo。如果使用 foo 的代码是全局的,不包含在任何命名空间中的代码,则 foo 会被解析为foo。 警告:如果命名空间中的函数或常量未定义,则该非限定的函数名称或常量名称会被解析为全局函数名称或常量名称。详情参见 使用命名空间:后备全局函数名称/常量名称。

限定名称
,或包含前缀的名称,例如 $a = new subnamespace\foo(); 或 subnamespace\foo::staticmethod();。如果当前的命名空间是currentnamespace,则 foo 会被解析为 currentnamespace\subnamespace\foo。如果使用 foo 的代码是全局的,不包含在任何命名空间中的代码,foo 会被解析为subnamespace\foo。
完全限定名称,或包含了全局前缀操作符的名称,例如,
$a = new \currentnamespace\foo(); 或 \currentnamespace\foo::staticmethod();。在这种情况下,foo 总是被解析为代码中的文字名(literal name)currentnamespace\foo

  定义多个命名空间:

namespace MyProject {

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

namespace AnotherProject {

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

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

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

  

use Wish\WishClient;
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(‘‘);

 

  

 

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。