设为首页 收藏本站
云服务器等爆品抢先购,低至4.2元/月
查看: 399|回复: 0

[经验分享] PHP架构之注册表

[复制链接]

尚未签到

发表于 2017-3-27 07:14:04 | 显示全部楼层 |阅读模式
  啥是注册表模式?其实很简单!
  注册表的作用是提供系统级别的对象访问功能。我们在编码时通常把“全局变量是不好的”当做信条。不过,凡事都有两面性,全局性的数据访问非常具有吸引力。
  问题来了:
  大多系统都分为几个层,每个层都只通过事先定义好的通道和相邻的层交流。对层的分享使程序变得灵活,替换或修改每个层可以最小化对系统其他部分的影响。但当你需要在一个层中获取不相邻另一个层所需要的信息时,该如何?
  方案一:通过系统的层之间的联系将上下文信息从一个对象传递给另一个需要的对象:在系统中把这些信息从一个对象传递到另一个对象,从一个负责处理请求的控制器对象传递到业务逻辑层的对象,再传递到负责和数据库对话的对象。当然还可以传递ApplicationHelper对象,或者是一个特定的Context对象。
  方案二:必须修改所有对象的接口,判断上下文对象是否是它们需要的。很显然,有时候这种方案会破坏松散耦合。
  方案三:通过注册表模式。注册表类提供静态方法(或单例对象的实例化方法)来让其他对象访问其中的数据(通常是对象)。整个系统中的每个对象都可以访问这些数据对象。
  在实现之前先考虑一下PHP的作用域:
  作用域通常用于描述代码中对象或值的可见程序,变量的生命周期可以用时间来衡量,变量作用域有3个级别。
  一、HTTP请求作用域
  指一个HTTP请求从开始到结束的周期。
  二、会话作用域
  PHP内置了对会话变量的支持。在一次请求结束后,会话变量会被序列化并存储到文件系统或者数据库中,然后在下一个请求开始时取回。存放在cookie中的会话ID和通过查询字符串传递的会话ID被用于跟踪该会话的拥有者。因此,你可以认为某些变量拥有会话级别的作用域。利用这一点,可以在几次请求之间存放对象,保存用户访问的踪迹到数据库中。当然,要小心避免持有同一个对象的不同版本,因此当你把一个会话对象存到数据库时,需要考虑使用一定的锁定策略。
  三、应用程序作用域
  在其他语言中,特别是JAVA,拥有缓存池,即“应用程序作用域”的概念。内存中的变量可以被程序中的所有对象实例访问。PHP没有这样的功能,但是在大规模的应用中,为了访问配置变量,访问应用程序级别的数据是很有用的。
  下面就用注册表实现这三个作用域,类图如下:
DSC0000.png



<?php
namespace woo\base;
require_once( "woo/controller/AppController.php");
abstract class Registry {
abstract protected function get( $key );
abstract protected function set( $key, $val );
}
class RequestRegistry extends Registry {
private $values = array();
private static $instance;
private function __construct() {}
static function instance() {
if ( ! isset(self::$instance) ) { self::$instance = new self(); }
return self::$instance;
}
protected function get( $key ) {
if ( isset( $this->values[$key] ) ) {
return $this->values[$key];
}
return null;
}
protected function set( $key, $val ) {
$this->values[$key] = $val;
}
static function getRequest() {
return self::instance()->get('request');
}
static function setRequest( \woo\controller\Request $request ) {
return self::instance()->set('request', $request );
}
}
class SessionRegistry extends Registry {
private static $instance;
private function __construct() {
session_start();
}
static function instance() {
if ( ! isset(self::$instance) ) { self::$instance = new self(); }
return self::$instance;
}
protected function get( $key ) {
if ( isset( $_SESSION[__CLASS__][$key] ) ) {
return $_SESSION[__CLASS__][$key];
}
return null;
}
protected function set( $key, $val ) {
$_SESSION[__CLASS__][$key] = $val;
}
function setComplex( Complex $complex ) {
self::instance()->set('complex', $complex);
}
function getComplex( ) {
return self::instance()->get('complex');
}
}
class ApplicationRegistry extends Registry {
private static $instance;
private $freezedir = "/tmp/data";
private $values = array();
private $mtimes = array();
private function __construct() { }
static function instance() {
if ( ! isset(self::$instance) ) { self::$instance = new self(); }
return self::$instance;
}
protected function get( $key ) {
$path = $this->freezedir . DIRECTORY_SEPARATOR . $key;
if ( file_exists( $path ) ) {
clearstatcache();
$mtime=filemtime( $path );
if ( ! isset($this->mtimes[$key] ) ) { $this->mtimes[$key]=0; }
if ( $mtime > $this->mtimes[$key] ) {
$data = file_get_contents( $path );
$this->mtimes[$key]=$mtime;
return ($this->values[$key]=unserialize( $data ));
}
}
if ( isset( $this->values[$key] ) ) {
return $this->values[$key];
}
return null;
}
protected function set( $key, $val ) {
$this->values[$key] = $val;
$path = $this->freezedir . DIRECTORY_SEPARATOR . $key;
file_put_contents( $path, serialize( $val ) );
$this->mtimes[$key]=time();
}
static function getDSN() {
return self::instance()->get('dsn');
}
static function setDSN( $dsn ) {
return self::instance()->set('dsn', $dsn);
}
static function setControllerMap( \woo\controller\ControllerMap $map  ) {
self::instance()->set( 'cmap', $map );
}
static function getControllerMap() {
return self::instance()->get( 'cmap' );
}
static function appController() {
$obj = self::instance();
if ( ! isset( $obj->appController ) ) {
$cmap = $obj->getControllerMap();
$obj->appController = new \woo\controller\AppController( $cmap );
}
return $obj->appController;
}
}
//如果你安装了PHP的shm扩展,就可以使用该扩展中函数来实现应用程序注册表
class MemApplicationRegistry extends Registry {
private static $instance;
private $values=array();
private $id;
const DSN=1;
private function __construct() {
$this->id = @shm_attach(55, 10000, 0600);
if ( ! $this->id ) {
throw new Exception("could not access shared memory");
}
}
static function instance() {
if ( ! isset(self::$instance) ) { self::$instance = new self(); }
return self::$instance;
}
protected function get( $key ) {
return shm_get_var( $this->id, $key );
}
protected function set( $key, $val ) {
return shm_put_var( $this->id, $key, $val );
}
static function getDSN() {
return self::instance()->get(self::DSN);
}
static function setDSN( $dsn ) {
return self::instance()->set(self::DSN, $dsn);
}
}
?>

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-355793-1-1.html 上篇帖子: PHP图片上传代码一例 下篇帖子: PHP超级全局变量总结
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表