0.为什么需要单入口?
原因很简单,需要确保自动加载类的函数注册成功。单入口确保这点的一种简单实现。设置好重写URL;一个入口PHP文件(常见的是各大框架的index.php);自动加载使用spl_autoload_register配合PHP闭包。一个简单的实现如下代码:
spl_auto_register(function($universal){
$separator = strrpos($universal,'\\');//获取命名空间和类名的分隔符位置
$globle = $separator === FALSE;//类是否在全局命名空间
$name = $globle ? $universal : substr($universal,$separator);//获取类名
$space = $globle ? '' : substr($universal,0,$separator);//获取命名空间
$path = './path/'.$class.'.class.php';//只是把类名和路径进行组合,没用到命名空间(请自定义路径映射)。
if(is_file($path)require $path;
});
以上这种函数的注册要早于对类的引用(单入口确保这点),这样在接下来的代码中直接使用类。
1.配合静态函数实现模块化
加入我在'./path/'目录下定义了这样的类(类文件的路径为:'./path/Demo.class.php'):
namespace Space;
abstract class Demo{
static function method(){
echo "I'm demo";
}
}
在其他文件中使用Demo类的method静态函数就可以直接使用:
Space\Demo::method();
这样把不同的函数归类到不同的类中,就可以实现函数的自动加载。
2.自动加载可以避免重复加载
PHP比较简单的避免重复加载是使用require_once,但是如果把函数模块化到类中,再利用自动记载可以避免重复加载。
比如我们有这么一个用于配置数据库的文件(路劲:'./configuration/database.php'):
$db_type = 'mysql';
$db_name = 'demodb';
$db_host = 'localhost';
$db_port = '3306';
$db_user = 'demouser';
$db_pass = 'demopass';
这样的配置看似引入了多个全局变量,其实不然。以下我们实现一个通过以上数据库参数new一个PDO的例子(路径:'./path/Database.class.php'):
namespace Space;
abstract class Database{
private static $dsn;
private static $username;
private static $password;
static function newPDO(){
return new PDO(self::$dsn,self::$username,self::$password);
}
static function initialize(){
require './configuration/database.php';
self::$dsn = $db_type.':dbname='.$db_name.
';host='.$db_host.';port='.$db_port;
self::$username = $db_user;
self::$password = $db_pass;
}
}
Database::initialize();
这样要在别处不仅不需要引入'./configuration/database.php',而且要生成一个PDO只需:
$pdo = Space\Database::newPDO();
以上过程没有引入一个全局变量,因为'./configuration/database.php'只在Database的initialize作用域里引入。
同时也解决的静态类成员初始化位置的问题(在加载类时初始化)。
总结
以上过程加载一般的类(不限只有静态方法的类),单入口其实并非必须(确保的加载函数的注册就够了),但是单入口却是实现最简单和常见的方法。函数的自动加载借助静态方法也实现了,同时还把函数模块化(放在不同的类里),静态成员初始化也一并解决。