解析在PHP中使用全局变量的几种方法(3)


<?
function &getInstance() {
    static $me;
    if (is_object($me) == true) {
        return $me;
    }
    $me = new Registry;
    return $me;
}
?>


这样它就可以作为一个单件来使用,比如:

复制代码 代码如下:


<?php
$db = new DBConnection;
$settings = new Settings_XML;
$user = new User;
// Register objects
$registry =& Registry::getInstance();
$registry->set ('db', $db);
$registry->set ('settings', $settings);
$registry->set ('user', $user);
function test() {
    $registry =& Registry::getInstance();
    $db =& $registry->get('db');
    $settings =& $registry->get('settings');
    $user =& $registry->get('user');
    // Do something with the objects
}
?>


正如你看到的,我们不需要把私有的东西都传递到一个函数,也不需要使用“global”关键字。所以注册器模式是这个问题的理想解决方案,而且它非常的灵活。

请求封装器
虽然我们的注册器已经使“global”关键字完全多余了,在我们的代码中还是存在一种类型的全局变量:超级全局变量,比如变量$_POST,$_GET。虽然这些变量都非常标准,而且在你使用中也不会出什么问题,但是在某些情况下,你可能同样需要使用注册器来封装它们。
一个简单的解决方法就是写一个类来提供获取这些变量的接口。这通常被称为“请求封装器”,下面是一个简单的例子:

复制代码 代码如下:


<?php
Class Request {
    var $_request = array();
    function Request() {
        // Get request variables
        $this->_request = $_REQUEST;
    }
    function get($name) {
        return $this->_request[$name];
    }
}
?>


上面的例子是一个简单的演示,当然在请求封装器(request wrapper)里面你还可以做很多其他的事情(比如:自动过滤数据,提供默认值等等)。
下面的代码演示了如何调用一个请求封装器:

复制代码 代码如下:


<?php
$request = new Request;
// Register object
$registry =& Registry::getInstance();
$registry->set ('request', &$request);
test();
function test() {
    $registry =& Registry::getInstance();
    $request =& $registry->get ('request');
    // Print the 'name' querystring, normally it'd be $_GET['name']
    echo htmlentities($request->get('name'));
}
?>


正如你看到的,现在我们不再依靠任何全局变量了,而且我们完全让这些函数远离了全局变量。

结论
在本文中,我们演示了如何从根本上移除代码中的全局变量,而相应的用合适的函数和变量来替代。注册模式是我最喜欢的设计模式之一,因为它是非常的灵活,而且它能够防止你的代码变得一塌糊涂。
另外,我推荐使用函数参数而不是单件模式来传递注册器对象。虽然使用单件更加轻松,但是它可能会在以后出现一些问题,而且使用函数参数来传递也更加容易被人理解。

您可能感兴趣的文章:

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/0792dfba2334f6a995155f01eb825377.html