1

所以我有一些类只需要初始化一次就可以用数据填充它们。现在我想用 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;
    }
}
?>

脚本_a.php:

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

脚本_b.php:

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

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

4

3 回答 3

0

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

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

脚本_a.php:

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

脚本_b.php:

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

如果不在多个客户端之间共享数据,会话是可以的(适合单个客户端 - 多个请求)。
保存跨客户端共享的多个请求的状态的另一种方法是缓存(您可以缓存标量、数组、数据库连接或对象),为此请查看此链接的更多信息

于 2013-08-12T18:46:22.093 回答
0

您可以为此使用APC 缓存

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();
于 2013-08-12T20:21:18.687 回答
0

不,单例模式不做任何跨脚本的事情。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 语句,那么您应该没问题。

于 2013-08-12T19:04:45.360 回答