PHP Singleton或静态交叉脚本

时间:2013-08-12 18:33:22

标签: php scripting static singleton

所以我有一些类只需要初始化一次就可以用数据填充它们。现在我想用AJAX单独访问它们,但没有再次初始化它们。我在PHP中读到了关于单例的内容,但我想知道是否可以在多个脚本中使用相同的类实例,这可以单独调用。例如:

<?php
class Example {
    private $instance;
    private $A;

    public function __construct() {}
    public function __clone() {}
    public function singleton() {
        if (self::$instance === null) {
             self::$instance = new Example;
        return self::$instance;
    }
    public function setA($val) {
        $this->A = $val;
    }
    public function getA() {
        return $this->A;
    }
}
?>

script_a.php:

<?php
include_once('example.class.php');
Example::singleton()->setA(10);
?>

script_b.php:

<?php
include_once('example.class.php');
echo Example::singleton()->getA();
// Would this output 10?
?>

我还读到在脚本执行结束时将从内存中删除静态函数,这是否也适用于单例?如果是这样,有没有办法让上述事情发生?

3 个答案:

答案 0 :(得分:0)

Singleton不会在多个请求中保留状态 - 您应该使用会话。一旦你使用了session,那么使用单例模式是没有意义的。

一个非常简单的解决方案:

script_a.php:

<?php
session_start();
$_SESSION['A'] = 10;
?>

script_b.php:

<?php
session_start();
if(isset($_SESSION['A'])) {
    echo $_SESSION['A'];
    // do the rest of processing
}
?>

如果不在多个客户端之间共享数据(适用于单个客户端 - 多个请求),则会话即可 在客户端共享的多个请求之间保留状态的另一种方法是缓存(您可以缓存标量,数组,数据库连接或对象),并对此进行更多检查link

答案 1 :(得分:0)

不,Singleton模式不会跨脚本执行任何操作。 PHP中的单例主要用于获取类的预初始化或自初始化实例,而不是通过构造函数传递对象,或者在只需要一个类时创建类的几十个相同副本。

例如:

class MySingleton {
  private static myInstance = NULL;

  private function __construct() {}

  public static getInstance($arg) {
    if( is_null(self::myInstance) ) {
      echo "INIT HERE!";
      self::myInstance = new MySingleton();
    }
    return self::myInstance();
  }
}

class myClass {
  public $single;
  public function __construct() {
    $this->single = MySingleton::getInstance();
  }

}

$one = new myClass(); // INIT HERE is echoed
$two = new myClass();

$one->single->someVar = 'foo';
echo $two->single->someVar; // foo

$two->single->someVar = 'bar';
echo $one->single->someVar; // bar

基本上,PHP世界中的大多数人都使用单例作为数据库类,因此他们只需要为每个脚本打开一个与数据库的连接。旧屁之间存在一些争论,即这种方法存在固有问题,其中预处理语句可能相互干扰[这是真的]并且使用SQL变量可能会有问题。 [也是]但是只要你知道你必须完全完成一个SQL语句才能调用另一个使用单例的对象方法,那么你应该没问题。

答案 2 :(得分:0)

您可以使用APC cache

class Singleton {
    private $a;
    private static $key = 'my_unique_singleton_key';

    // this functions must be private for a real Singletone
    private function __construct() {}
    private function __clone() {}
    private function __wakeup() {}

    // automatically save object during the script shutdown
    private function __destruct() {
        apc_add(self::$key, self::getInstance());
    }

    public static function getInstance() {
        static $instance;

        if (null === $instance) {
            if (apc_exists(self::$key)) {
                $instance = apc_fetch(self::$key);
            } else {
                $instance = new self();
                apc_add(self::$key, $instance);
            }
        }

        return $instance;
    }

    public function setA($val) {
        $this->a = $val;
    }

    public function getA() {
        return $this->a;
    }
}

这可以简单地用作:

echo Singleton::getInstance()->getA();