今天得知了一种不用include_path而选择用数组来缓存类名来autoload的方法..
这种方法也比较巧妙..我们知道 include_path当设置的目录很多的时候..遍历是非常耗时的.
所以这种方法舍弃include_path..而是自己创建了一个数组..数组的键名为类名..键值为此类对应的路径.
下面是个简单的例子
1
2
3
4
5
6
7
8
9
10
11
|
$classes = array(
'ClassA' => '/home/webroot/ClassA.class.php',
'ClassB' => '/home/webroot/ClassB.class.php',
);
function __autoload($class) {
global $classes;
if(array_key_exists($class, $classes)) {
//存在此类就去包含其路径
require_once($classes[$class]);
}
}
|
但是这种方法又与include_path效率上有什么区别呢?
我们来测试一下吧..
首先我在当前目录下.用程序新建了6个文件夹 分别为a b c d e f
然后每个文件夹内又生成了1000个文件 文件名的规则是这样的 文件夹名+数字
比如文件夹a里面有a0.php到a1000.php
里面的内容就是一个空的类 类名和文件名一样 比如a100.php 中的内容是
目录结构想必大家都明白了..
那么现在我们开始写代码..
先来测试include_path方法 下面是我的代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
<?php
!defined('__DIR__') && define('__DIR__', dirname(__FILE__));
ini_set('include_path',
ini_get('include_path') . PATH_SEPARATOR
. __DIR__ . '/a/' . PATH_SEPARATOR
. __DIR__ . '/b/' . PATH_SEPARATOR
. __DIR__ . '/c/' . PATH_SEPARATOR
. __DIR__ . '/d/' . PATH_SEPARATOR
. __DIR__ . '/e/' . PATH_SEPARATOR
. __DIR__ . '/f/' . PATH_SEPARATOR
);
function __autoload($class) {
require_once($class.'.php');
}
$time=microtime(true);
for($i=0;$i<=100;$i++) {
$class = chr(rand(97, 102)) . rand(0, 1000);
new $class();
}
echo microtime(true)-$time;
|
这种方法在我的机器上运行的时间大概为0.21659898757935左右
下面我们来测试第二种方法..第二种方法需要构造出一个数组..如果是项目来说一般都是手工配置的.在这里我们就用程序生成吧..但是不算在autoload时间内..
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
<?php
!defined('__DIR__') && define('__DIR__', dirname(__FILE__));
//构造出数组
$classes = array();
for($chr=97;$chr<=102;$chr++) {
$tmp = chr($chr);
for($i=0;$i<=1000;$i++) {
$classes[$tmp.$i] = __DIR__."/$tmp/{$tmp}{$i}.php";
}
}
function __autoload($class) {
global $classes;
if(array_key_exists($class, $classes)) {
require_once($classes[$class]);
}
}
$time=microtime(true);
for($i=0;$i<=100;$i++) {
$class = chr(rand(97, 102)) . rand(0, 1000);
new $class();
}
echo microtime(true)-$time;
|
上面的方法在我机器上运行大约的执行时间为0.31368708610535左右..
这样看来..整整慢了0.1秒啊..
那为什么会出现这种情况呢?
我的想法就是 include_path的设置PHP会去物理遍历这个文件..
这个可能在不同的文件系统下所用的时间会有差别..但是大多数文件系统都是基于B+树去搜索文件的..
而在PHP中如果直接用数组来标明的话..array_key_exists最终是调用zend_hash_exists..也就是说是基于hash算法的..
说到这里 会不会是我生成的文件目录太归于规则的缘故呢??