组件
组件
整个xts框架都由组件构成。xts提供的所有功能被封装在若干个组件对象里,组件可以通过配置绑定在XComponentFactory类上以方便调用,XComponentFactory类还有一个缩写,就是X类。xts的组件需要实现xts\IComponent接口,这个接口的定义了xts组件必需是可配置的,而且要支持Getter和Setter的类。
interface IComponent {
/**
* @param array $conf
* @return void
*/
public static function conf($conf=array());
/**
* @param string $name
* @return mixed
*/
public function __get($name);
/**
* @param string $name
* @param mixed $value
* @return void
*/
public function __set($name, $value);
/**
* @param string $name
* @return bool
*/
public function __isset($name);
/**
* @return array
*/
public function getConf();
}
xts本身已经提供了一批组件,涵盖小型项目需要的各项功能,包括:
- apple——应用路由器
- cache——内存缓存(支持使用memcache或者redis)
- cc——文件缓存(本机缓存)
- db——MySQL数据库查询器
- orange——对象关系映射(ORM)类
- view——RainTPL模板引擎
- valley——表单数据验证器
- redis——PhpRedis的xts封装
- smarty——Smarty模板引擎的xts包装(需要用户自己下载smarty程序)
自定义组件
用户也可能开发自己的组件,或者把第三方库包装成xts组件。
开发自己的组件比较简单,可以直接继承xts\Component
类,在这个类中已经实现了IComponent接口,完成了基本的Getter和Setter支持。如果要把第三方的库包装成xts组件,就需要用户自己实现IComponent接口。实现IComponent接口时可以参考xts\Component
类中的代码,xts中类的属性Getter的命名格式应该是getFullName这样的驼峰命名。未来xts考虑提供一个trait来实现这个接口的基本功能。
组件工厂
XComponentFactory类能根据配置生成组件对象实例。它支持单例模式,配置单例模式后生成的实例会在组件工厂内保留一份引用,下次请求时会直接return,不会再重新new创建实例。下面的配置定义了一个view组件:
- 它是xts\Hail类的实例
- 初始化以前应该先require
{{X_LIB_ROOT}}/hail.php
文件(X_LIB_ROOT是xts框架的库目录路径常量) 它要求启用单例支持
array( 'component' => array( 'view' => array( 'class' => '\xts\Hail', 'require' => X_LIB_ROOT.'/hail.php', 'singleton' => true, 'conf' => array( 'tpl_dir' => X_PROJECT_ROOT.'/protected/view', 'tpl_ext' => 'html', 'compile_dir' => X_RUNTIME_ROOT.'/compiled_template', 'enable_clip' => false, 'cacheId' => 'cc', // string to cache component id or false to disable cache 'cacheDuration' => 60, // page cache duration, second ) ), ), ),
在前面马上开始的例子里X::view()
会触发xts\XComponentFactory
类中的__callStatic
魔术方法,这个魔术方法会取回配置文件里定义的组件ID为view的组件,在实例化之前,配置中conf数组会传递给组件类的conf静态方法。在前面xts配置的例子里,配置文件定义了apple、db、view三个组件,就可以用X::apple()
、X::db()
、X::view()
的方式直接访问。
使用XComponentFactory初始化组件的时候,参数会传递给组件类的构造函数。比如下面的组件配置声明了一个不使用单件的orange组件,返回xts\Orange
类的实例:
array(
'component' => array(
'orange' => array(
'class' => '\\xts\\Orange',
'singleton' => false,
'conf' => array(
'queryId' => 'db',
'enableCacheByDefault' => false,
),
),
),
),
调用X::orange('user')
的时候,组件工厂会返回相当于new Orange('user')
的执行结果。