清单一
class IReadFileClass
{
function ReadMyFile() {}
}
清单二
class ReadFileClass extends IReadFileClass
{
function ReadMyFile()
{
$fp = fopen('test.txt', "r");
$data = fread($fp, filesize('test.txt'));
fclose($fp);
return $data;
}
}
OK, 我们现在要加入验证用户的功能, 即为ReadFileClass中的方法加入保护控制. 如果采用手动创建代理, 那么你可以继承ReadFileClass或者实现IReadFileClass, 并加入保护代码(其实在PHP4中甚为自由, 因为除了基本类型外都是object-_-). 不过我们现在试试用刚才实现的动态代理来创建Proxy.
请看清单三的ReadFileClassProxy的代码, 注意该类继承自ProxyInvocationHandler类.
清单三
require_once('ProxyFactory.php');
require_once('ProxyInvocationHandler.php');
require_once('Auth.php');
class ReadFileClassProxy extends ProxyInvocationHandler
{
var $object;
function ReadFileClassProxy(&$obj)
{
$this->object = &$obj;
}
//
function NewInstance(&$obj)
{
$proxyFactory = ProxyFactoryInstance();
return $proxyFactory->create(new ReadFileClassProxy(&$obj), get_parent_class(&$obj));
}
// $proxy is not used here, but it is useful.
function Invoke(&$proxy, $method, $parameters)
{
$uname = 'Binzy';
//$uname = 'Jasmin';
if (Auth::CheckAuth($uname))
{
Return parent::Invoke(&$proxy, $method, $parameters);
}
else
{
//
return 'No Permission!';
}
}
}
Auth类是一个进行权限验证的类, 此处我们只是简单的查看传入的UserName, 如果是Binzy, 那么自然是可以看秘密的J, 如果是Jasmin, 那么HoHo, 没得看, 给Binzy点空间嘛:D. 详见清单四.
清单四
class Auth
{
function Auth()
{
}
// bool
//
function CheckAuth($username)
{
if ($username == 'Binzy')
{
return true;
}
return false;
}
}
Ok, 下面我们来使用我们创建的代理. 请见清单五.
清单五
require_once('ReadFileClass.php');
require_once('ReadFileClassProxy.php');
$proxy = ReadFileClassProxy::NewInstance(new ReadFileClass());
print $proxy->ReadMyFile();
结果如下:
如果是Binzy, 那么自然可以知道那个秘密J.
如果是Jasmin, 这个秘密当然不能让她知道.
五、 总结
代理是一个非常有用的模式. PHP4虽然并不是真正的Object-Oriented, 但仍然可以实现你想实现的设计. 写本文的目的有很大部分是希望国内PHP开发者不要再拘泥于现在的开发现状, 开发出更好的PHP软件. 而不是一堆Script的堆积.
六、 感谢
感谢好友Freeman为我做测试.
感谢mmkk的Code Formatter HTC.
七、 参考
1. GoF
2. GoF中译本
3. PHP参考手册 http://www.php.net/manual/en/
八、 相关下载
原代码: http://0926.net/bbs/attachment.php?aid=127
本文地址:http://com.8s8s.com/it/it28947.htm