[框架精髓]PSR-0 Autoloading Standard 自动加载机制的规范,及接合kohana的自动加载逻辑分析。

jackxiang 2012-12-25 14:43 | |
背景:关于自动加载类文件是PHP这种脚本在程序大后为了按需要加载时所需要的一种机制,很有必要。
将__autoload换成loadprint函数。但是loadprint不会像__autoload自动触发,这时spl_autoload_register()就起作用了,它告诉PHP碰到没有定义的类就执行loadprint()。
以上一行摘自:http://blog.csdn.net/panpan639944806/article/details/23192267

/tmp/autoload/autoload.php


/tmp/autoload/aClass.php


/tmp/autoload/bClass.php


运行一下,看一下在加载前和后引入的文件是否一样?不一样有新文件:
[root@test autoload]# php autoload.php  
Array
(
    [0] => /tmp/autoload/autoload.php
)

.:/opt/2012-01-30/php-5.3.10
aClass loaded...bClass loaded...Array
(
    [0] => /tmp/autoload/autoload.php
    [1] => /tmp/autoload/aClass.php
    [2] => /tmp/autoload/bClass.php
)

上面是一个用法,第二个是把__autoload 这个函数都给重定义了:
spl_autoload_register(array('Ko', 'autoload'));//这要就由function __autoload($className)变成了:function autoload($className)
————————————————————结合框架来说这个autoload的事情—————————————————————

/**
* Enable the Ko auto-loader.
*
* @see  http://php.net/spl_autoload_register
*/
spl_autoload_register(array('Ko', 'autoload'));
----于是了解到如下自动加载机制:
英文原文:https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md

以下内容描述了符合自动载入程序互操作性所必须遵守的强制性规范。

强制要求

一个完整的命名空间 (namespace) 和类 (class) 必须使用以下结构: \<Vendor Name>\(<Namespace>\)*<Class Name>
每个命名空间 (namespace) 必须使用供应商名称 (“Vendor Name”)  做为顶层命名空间(top-level namespace).
每个命名空间 (namespace) 的子命名空间 (sub-namespace) 数量不限.
程序从文件系统载入的时候,每个命名空间 (namespace) 的分隔符 (separator) 将被替换为操作系统的目录分隔符 (DIRECTORY_SEPARATOR).
在类名 (CLASS NAME) 中的下划线 ( _) 也将被替换为操作系统的目录分隔符 (DIRECTORY_SEPARATOR) , 在命名空间 (namespace) 中的下划线 (_)不做替换.
从文件系统载入的合格的命名空间 (namespace) 和 类 (class) 必须以 .php 结尾.
供应商名称 (vendor names), 命名空间 (namespaces)  及类名 (class names) 可以使用任意大小写字母的组合.
示例

\Doctrine\Common\IsolatedClassLoader => /path/to/project/lib/vendor/Doctrine/Common/IsolatedClassLoader.php
\Symfony\Core\Request => /path/to/project/lib/vendor/Symfony/Core/Request.php
\Zend\Acl => /path/to/project/lib/vendor/Zend/Acl.php
\Zend\Mail\Message => /path/to/project/lib/vendor/Zend/Mail/Message.php
在命名空间(Namespaces)和类名(Class Names)中的下划线

\namespace\package\Class_Name => /path/to/project/lib/vendor/namespace/package/Class/Name.php
\namespace\package_name\Class_Name => /path/to/project/lib/vendor/namespace/package_name/Class/Name.php
The standards we set here should be the lowest common denominator for painless autoloader interoperability. You can test that you are following these standards by utilizing this sample SplClassLoader implementation which is able to load PHP 5.3 classes.

实现示例

下面的示例函数演示了遵循上述规范的自动加载过程.

SplClassLoader 实现

如果你的程序遵守上面的自动载入程序互操作性规范,可以使用下面的SplClassLoader实现来加载你的类 (classes) . 这也是 PHP 5.3 推荐的遵循本规范的类 (class) 加载方式.
来自:http://www.dunban.com/?p=30

http://gist.github.com/221634


最后参考:
http://www.jb51.net/article/23956.htm
http://blog.csdn.net/hguisu/article/details/7463333
http://www.php.net/manual/zh/function.autoload.php
http://blog.sina.com.cn/s/blog_6915bcb101017p2x.html
http://www.php100.com/html/php/lei/2013/0905/5267.html


YII框架里,一般各种框架都有这样的用法,特别是PHP5的框架:
spl_autoload_register(array('Ko', 'autoload'));
bool spl_autoload_register(array(‘class’,'static_function’))
参数为数组,数组中第一个值为类名,第二个值为方法名,且必须为静态方法。
例:

输出:
---------- 调试PHP ----------
open\OpenAPIModel.php
models\open\OpenAPIModel.php
输出完成 (耗时 0 秒) - 正常终止
在实际运用中文件名里是不能有Model的字符的,通过对findFile的Debug一下得到:
D:\www\iseeyoo\trunk\codes\application\models\open\adminchannellink.php
class open_AdminChannelLinkModel extends Model  //类名包含下划线和Model(如果是Service也一样:class OpenChannelService extends baseService,文件名:\application\services\openchannel.php也不能包含Service字符。),这个规则是:文件命名里不能有Model。(这个得注意下)
{

}
//直接在Core里Debug下,得出上面的规律。
public static function findFile ($dir, $file, $ext = 'php')
{
  if($file == "open_adminchannellink"){
      file_put_contents("d:/wamp/www/aaa.txt","ModelfileDiR=".$dir."\n",FILE_APPEND);
      file_put_contents("d:/wamp/www/aaa.txt","Modelfilepath=".$path."\n",FILE_APPEND);
  }
  打印出:
  ModelfilePosition=open_adminchannellink
  ModelfileDiR=models
  Modelfilepath=models\open\adminchannellink.php


kohana 这个也是支持contrller直接接调用Module层的,实践OK的,理论上就是通过Autoload调用module,Service(文件类名有不同的标记)的类名(这个是有规范的上面有描述),进而拼接出大体位置,让findfile去找到这个文件:
application\controllers\open\index.php

http://domain.com/open/index/index
这一看是contrller下面有一个open(经过路由配置到了open目录的),后有一个index.php的文件里有一个index函数,如果想直接获取这个uri的内容,可以通过这个函数实现,如下:


这个forward吧,其实就相当于YII里的路由控制器访问index目录下的index控制器下面的index的action方法,路由相关知识:
什么是路由:
在框架里边我们通过路由获得控制器和方法,
我们有了控制器的方法,就可以进一步与视图或模型进行交互,
http://网址/index.php?r=控制器/方法
http://网址/index.php?r=user/cc

===============================================================


一般还是有一个autoload函数来做加载的:



自动auto加载代码:

自订义自动加载函数用SPL:

作者:jackxiang@向东博客 专注WEB应用 构架之美 --- 构架之美,在于尽态极妍 | 应用之美,在于药到病除
地址:http://jackxiang.com/post/5877/
版权所有。转载时必须以链接形式注明作者和原始出处及本声明!


最后编辑: jackxiang 编辑于2016-3-17 10:57
评论列表
2012-12-29 15:14 | root Email Homepage
把链接贴上来我给加上,QQ联系你吧,哈哈。
2012-12-28 10:35 | 喜悦村 Email Homepage
博主不厚道啊。一字不落的转了本人博文,参考资料却只字不提。。。。
分页: 1/1 第一页 1 最后页
发表评论

昵称

网址

电邮

打开HTML 打开UBB 打开表情 隐藏 记住我 [登入] [注册]