Zend框架之Session库
说到Zend的Session库, 不得不先详细了解一下PHP的Session是如何实现的, 首先要知道一点, 就是不同的web脚本语言或者不同的服务端都可能采取不同的方式来实现Session. 我这里的测试环境是XAMPP 1.7.2, 其中的Apache是2.2.12版. 设置一个测试PHP页面, 代码如下
<?php
session_start();
setcookie("user", "Alex Porter", time()+3600);
if(isset($_SESSION[’views’]))
$_SESSION[’views’]=$_SESSION[’views’]+1;
else
$_SESSION[’views’]=1;
echo "Views=". $_SESSION[’views’];
?>
监听捕获浏览器与服务器之间的http数据:
Step1. 客户端首次访问该页面得到
Step2. 客户端再次访问该页面得到
在Step1中, 注意到客户端首次是没有任何session或者cookie数据发送到服务器的, 而此时服务端的session_start()函数检查发送的http头, 没有发现session相关的值(也就是下面要提到的PHPSESSID值), 于是服务端随机产生了一个Session ID, 并在服务端的线程池中建立一个新的线程, 并将该Session ID与该Session所保存的值相关联, 然后在Step2中服务器通过http头Set-Cookie字段设置了我预设的cookie值views和随机生成的Session ID(PHPSESSID)值, 而在Step2, 也就是不关闭浏览器直接刷新该页面后, 发现浏览器将本地cookie中的views和PHPSESSID两个值都发送到了服务器, 服务端接受到请求后, 获取PHPSESSID的值, 然后在服务端的Session池中查找客户端发送来的Session ID(在这里是64t6plpgl44jbd7fm0h9akspv1), 发现与该ID相关的变量views, 且其值为1, 然后我的代码的效果使得该值自增为2, 于是服务端返回views=2. 其中值得注意的是, 客户端的cookie不仅仅保存着我设置的cookie值, 还保存着服务端生成的Session ID, 而与该Session ID相关的变量及其值, 均保存在服务端的线程池中. 由此可见, 如若我们的浏览器不支持cookie, 那么Apache 2.2.12的PHP Session将无法使用. 实际上在别的语言实现中, 如JSP, [...]
Zend框架之ACL库
Zend框架的ACL库的结构图
Zend的ACL库其实只有两个主要类, Zend_Acl_Role_Registry和Zend_Acl.
Zend_Acl_Role_Registry类定义了Role相关的数据结构和操作函数并负责存储和管理Role之间的父子关系. 具体实现上, Role使用一个关联数组做底层数据结构, 关联数组的key是当前Role的ID值, 关键数组的value又是一个关联数组, 仅包括设计好三段关联数据, 这三段关联数据分别是instance表示当前Role的实体, parents表示父Role的关联数组(该关联数组的key的父Role的ID, value是父Role的实体), children表示子Role的关联数组(该关联数组的key的子Role的ID, value是子Role的实体). 观察这个设计, Zend作者并没有使用常见的二叉树形式来作为底层数据结果, 而这样做的原因正是由php这门的特点做决定的, php的数组的自由度大, 对象复制以引用复制方式完成, 这样一来, 足以得到足够的可靠性和效率, 并充分简化了实现难度, 可见作者OO功底很深, 当然了, 我是php新手, 这样的设计也让我受益匪浅.操作函数上, 主要提供了增(add), 删(remove, removeAll), 查(has,inherits)和获取(get,getParents)的操作, 参数均已RoleID为参数, 要注意的是inherits函数可用于查询间接父子Role关系, 即父子Role不必是直接父子关系, 这这样的行为时通过inherits函数的第三boolean参数来控制的.
Zend_Acl类更是将php的关联数组能力发挥到极致, 在此类中, 封装了对resource相关的数据结果和操作函数并负责存储和管理resource之间的父子关系, 其实实现上resource与role的实现可所完全相同, 不同的仅仅是名字而已, 另外Zend_Acl类还对Role类的共有函数进行了一次重新封装, 基本上就是换了个函数的名字而已, 在C++中, 其实这种封装方式表示了Zend_Acl私有继承Zend_Acl_Role的意义.接下来最为核心的就是Zend_Acl实现的权限管理. 事实上, Zend_Acl采取了模拟NTFS文件系统的权限管理的机制. 在NTFS文件系统中, 在每一个分区中的开始段有一定大小的空间存储着该分区的访问控制列表(ACL), 该列表为每一个资源定义某个自定角色或角色组的访问规则. 而在Zend_Acl类中, 实现了一个复杂关联数组来模拟二叉树的数组结构, 并提供了相应的算法来完成查找工作. 具体来说, 访问控制规则数组rule定义了所有resource, role之间的访问规则, 具体数据结果如下图:
这个图只是一个粗略的说明,其实所有以All开头的元素都是表示默认的访问权限,也就是说,如果没有显式指定role,resource的访问规则的时候将采取的默认的方式,而所有以By开头的元素就是存储这些指定规则的位置, 例如ByResourceID表示一个关联数组, 而这个关联数组的key的Resource的ID, 而value是Resource的下级节点Role的规则,也就是说这个value内含有AllRoles和ByRoleID, [...]

