Làm thế nào một người có thể tạo một lớp Singleton bằng các lớp PHP5?
Làm thế nào một người có thể tạo một lớp Singleton bằng các lớp PHP5?
Câu trả lời:
/**
* Singleton class
*
*/
final class UserFactory
{
/**
* Call this method to get singleton
*
* @return UserFactory
*/
public static function Instance()
{
static $inst = null;
if ($inst === null) {
$inst = new UserFactory();
}
return $inst;
}
/**
* Private ctor so nobody else can instantiate it
*
*/
private function __construct()
{
}
}
Để sử dụng:
$fact = UserFactory::Instance();
$fact2 = UserFactory::Instance();
$fact == $fact2;
Nhưng:
$fact = new UserFactory()
Ném một lỗi.
Xem http://php.net/manual/en/lingu.variables.scope.php#lingu.variabled.scope.static để hiểu phạm vi biến tĩnh và lý do cài đặt static $inst = null;
hoạt động.
PHP 5.3 cho phép tạo ra một lớp Singleton có thể kế thừa thông qua liên kết tĩnh muộn:
class Singleton
{
protected static $instance = null;
protected function __construct()
{
//Thou shalt not construct that which is unconstructable!
}
protected function __clone()
{
//Me not like clones! Me smash clones!
}
public static function getInstance()
{
if (!isset(static::$instance)) {
static::$instance = new static;
}
return static::$instance;
}
}
Điều này giải quyết vấn đề, rằng trước PHP 5.3, bất kỳ lớp nào mở rộng Singleton sẽ tạo ra một thể hiện của lớp cha thay vì lớp của nó.
Bây giờ bạn có thể làm:
class Foobar extends Singleton {};
$foo = Foobar::getInstance();
Và $ foo sẽ là một thể hiện của Foobar thay vì một thể hiện của Singleton.
"subclass should own its own static var. check this: echo get_class(Foobar::getInstance());echo get_class(Singleton::getInstance());"
.
$instance
cư trú tại Singleton, không phải là lớp con. Sau khi một số lớp con được khởi tạo, getInstance () sẽ trả về thể hiện đó cho tất cả các lớp con.
Thật không may câu trả lời của Inwdr bị phá vỡ khi có nhiều lớp con.
Đây là một lớp cơ sở Singleton kế thừa chính xác.
class Singleton
{
private static $instances = array();
protected function __construct() {}
protected function __clone() {}
public function __wakeup()
{
throw new Exception("Cannot unserialize singleton");
}
public static function getInstance()
{
$cls = get_called_class(); // late-static-bound class name
if (!isset(self::$instances[$cls])) {
self::$instances[$cls] = new static;
}
return self::$instances[$cls];
}
}
Mã kiểm tra:
class Foo extends Singleton {}
class Bar extends Singleton {}
echo get_class(Foo::getInstance()) . "\n";
echo get_class(Bar::getInstance()) . "\n";
Cách thực sự và hiện đại để tạo mẫu Singleton là:
<?php
/**
* Singleton Pattern.
*
* Modern implementation.
*/
class Singleton
{
/**
* Call this method to get singleton
*/
public static function instance()
{
static $instance = false;
if( $instance === false )
{
// Late static binding (PHP 5.3+)
$instance = new static();
}
return $instance;
}
/**
* Make constructor private, so nobody can call "new Class".
*/
private function __construct() {}
/**
* Make clone magic method private, so nobody can clone instance.
*/
private function __clone() {}
/**
* Make sleep magic method private, so nobody can serialize instance.
*/
private function __sleep() {}
/**
* Make wakeup magic method private, so nobody can unserialize instance.
*/
private function __wakeup() {}
}
Vì vậy, bây giờ bạn có thể sử dụng nó như thế nào.
<?php
/**
* Database.
*
* Inherited from Singleton, so it's now got singleton behavior.
*/
class Database extends Singleton {
protected $label;
/**
* Example of that singleton is working correctly.
*/
public function setLabel($label)
{
$this->label = $label;
}
public function getLabel()
{
return $this->label;
}
}
// create first instance
$database = Database::instance();
$database->setLabel('Abraham');
echo $database->getLabel() . PHP_EOL;
// now try to create other instance as well
$other_db = Database::instance();
echo $other_db->getLabel() . PHP_EOL; // Abraham
$other_db->setLabel('Priler');
echo $database->getLabel() . PHP_EOL; // Priler
echo $other_db->getLabel() . PHP_EOL; // Priler
Như bạn thấy nhận thức này linh hoạt hơn rất nhiều.
instance
chức năng $instance
nên null
khôngfalse
Bạn có thể nên thêm một phương thức __clone () riêng tư để không cho phép nhân bản một thể hiện.
private function __clone() {}
Nếu bạn không bao gồm phương pháp này, điều sau đây có thể
$inst1=UserFactory::Instance(); // to stick with the example provided above
$inst2=clone $inst1;
ngay bây giờ $inst1
! == $inst2
- chúng không còn là ví dụ nữa.
<?php
/**
* Singleton patter in php
**/
trait SingletonTrait {
protected static $inst = null;
/**
* call this method to get instance
**/
public static function getInstance(){
if (static::$inst === null){
static::$inst = new static();
}
return static::$inst;
}
/**
* protected to prevent clonning
**/
protected function __clone(){
}
/**
* protected so no one else can instance it
**/
protected function __construct(){
}
}
sử dụng:
/**
* example of class definitions using SingletonTrait
*/
class DBFactory {
/**
* we are adding the trait here
**/
use SingletonTrait;
/**
* This class will have a single db connection as an example
**/
protected $db;
/**
* as an example we will create a PDO connection
**/
protected function __construct(){
$this->db =
new PDO('mysql:dbname=foodb;port=3305;host=127.0.0.1','foouser','foopass');
}
}
class DBFactoryChild extends DBFactory {
/**
* we repeating the inst so that it will differentiate it
* from UserFactory singleton
**/
protected static $inst = null;
}
/**
* example of instanciating the classes
*/
$uf0 = DBFactoryChild::getInstance();
var_dump($uf0);
$uf1 = DBFactory::getInstance();
var_dump($uf1);
echo $uf0 === $uf1;
nghỉ ngơi
object(DBFactoryChild)#1 (0) {
}
object(DBFactory)#2 (0) {
}
Nếu bạn đang sử dụng PHP 5.4: đặc trưng là một tùy chọn, vì vậy bạn không phải lãng phí hệ thống phân cấp thừa kế để có mẫu Singleton
và cũng lưu ý rằng cho dù bạn sử dụng các đặc điểm hay mở rộng lớp Singleton, một kết thúc lỏng lẻo là tạo ra các singleton của các lớp con nếu bạn không thêm dòng mã sau:
protected static $inst = null;
trong lớp trẻ
kết quả bất ngờ sẽ là:
object(DBFactoryChild)#1 (0) {
}
object(DBFactoryChild)#1 (0) {
}
Phương thức này sẽ thực thi các singletons trên bất kỳ lớp nào bạn muốn, vì bạn phải làm là thêm 1 phương thức vào lớp bạn muốn tạo một singleton và điều này sẽ làm điều đó cho bạn.
Điều này cũng lưu trữ các đối tượng trong một lớp "SingleTonBase" để bạn có thể gỡ lỗi tất cả các đối tượng mà bạn đã sử dụng trong hệ thống của mình bằng cách đệ quy các SingleTonBase
đối tượng.
Tạo một tệp có tên SingletonBase.php và đưa nó vào thư mục gốc của tập lệnh của bạn!
Mã là
abstract class SingletonBase
{
private static $storage = array();
public static function Singleton($class)
{
if(in_array($class,self::$storage))
{
return self::$storage[$class];
}
return self::$storage[$class] = new $class();
}
public static function storage()
{
return self::$storage;
}
}
Sau đó, đối với bất kỳ lớp nào bạn muốn tạo một singleton chỉ cần thêm phương thức nhỏ này.
public static function Singleton()
{
return SingletonBase::Singleton(get_class());
}
Đây là một ví dụ nhỏ:
include 'libraries/SingletonBase.resource.php';
class Database
{
//Add that singleton function.
public static function Singleton()
{
return SingletonBase::Singleton(get_class());
}
public function run()
{
echo 'running...';
}
}
$Database = Database::Singleton();
$Database->run();
Và bạn chỉ có thể thêm hàm singleton này vào bất kỳ lớp nào bạn có và nó sẽ chỉ tạo 1 thể hiện cho mỗi lớp.
LƯU Ý: Bạn phải luôn đặt __construct ở chế độ riêng tư để loại bỏ việc sử dụng Class mới (); tức thời.
class Database{
//variable to hold db connection
private $db;
//note we used static variable,beacuse an instance cannot be used to refer this
public static $instance;
//note constructor is private so that classcannot be instantiated
private function __construct(){
//code connect to database
}
//to prevent loop hole in PHP so that the class cannot be cloned
private function __clone() {}
//used static function so that, this can be called from other classes
public static function getInstance(){
if( !(self::$instance instanceof self) ){
self::$instance = new self();
}
return self::$instance;
}
public function query($sql){
//code to run the query
}
}
Access the method getInstance using
$db = Singleton::getInstance();
$db->query();
Bạn không thực sự cần sử dụng mẫu Singleton vì nó được coi là một mẫu phản. Về cơ bản có rất nhiều lý do để không thực hiện mô hình này. Đọc phần này để bắt đầu: Thực hành tốt nhất trên các lớp đơn PHP .
Nếu sau tất cả, bạn vẫn nghĩ rằng bạn cần sử dụng mẫu Singleton thì chúng tôi có thể viết một lớp cho phép chúng tôi có được chức năng Singleton bằng cách mở rộng lớp trừu tượng SingletonClassVendor của chúng tôi.
Đây là những gì tôi đi kèm để giải quyết vấn đề này.
<?php
namespace wl;
/**
* @author DevWL
* @dosc allows only one instance for each extending class.
* it acts a litle bit as registry from the SingletonClassVendor abstract class point of view
* but it provides a valid singleton behaviour for its children classes
* Be aware, the singleton pattern is consider to be an anti-pattern
* mostly because it can be hard to debug and it comes with some limitations.
* In most cases you do not need to use singleton pattern
* so take a longer moment to think about it before you use it.
*/
abstract class SingletonClassVendor
{
/**
* holds an single instance of the child class
*
* @var array of objects
*/
protected static $instance = [];
/**
* @desc provides a single slot to hold an instance interchanble between all child classes.
* @return object
*/
public static final function getInstance(){
$class = get_called_class(); // or get_class(new static());
if(!isset(self::$instance[$class]) || !self::$instance[$class] instanceof $class){
self::$instance[$class] = new static(); // create and instance of child class which extends Singleton super class
echo "new ". $class . PHP_EOL; // remove this line after testing
return self::$instance[$class]; // remove this line after testing
}
echo "old ". $class . PHP_EOL; // remove this line after testing
return static::$instance[$class];
}
/**
* Make constructor abstract to force protected implementation of the __constructor() method, so that nobody can call directly "new Class()".
*/
abstract protected function __construct();
/**
* Make clone magic method private, so nobody can clone instance.
*/
private function __clone() {}
/**
* Make sleep magic method private, so nobody can serialize instance.
*/
private function __sleep() {}
/**
* Make wakeup magic method private, so nobody can unserialize instance.
*/
private function __wakeup() {}
}
Sử dụng ví dụ:
/**
* EXAMPLE
*/
/**
* @example 1 - Database class by extending SingletonClassVendor abstract class becomes fully functional singleton
* __constructor must be set to protected becaouse:
* 1 to allow instansiation from parent class
* 2 to prevent direct instanciation of object with "new" keword.
* 3 to meet requierments of SingletonClassVendor abstract class
*/
class Database extends SingletonClassVendor
{
public $type = "SomeClass";
protected function __construct(){
echo "DDDDDDDDD". PHP_EOL; // remove this line after testing
}
}
/**
* @example 2 - Config ...
*/
class Config extends SingletonClassVendor
{
public $name = "Config";
protected function __construct(){
echo "CCCCCCCCCC" . PHP_EOL; // remove this line after testing
}
}
Chỉ để chứng minh rằng nó hoạt động như mong đợi:
/**
* TESTING
*/
$bd1 = Database::getInstance(); // new
$bd2 = Database::getInstance(); // old
$bd3 = Config::getInstance(); // new
$bd4 = Config::getInstance(); // old
$bd5 = Config::getInstance(); // old
$bd6 = Database::getInstance(); // old
$bd7 = Database::getInstance(); // old
$bd8 = Config::getInstance(); // old
echo PHP_EOL."COMPARE ALL DATABASE INSTANCES".PHP_EOL;
var_dump($bd1);
echo '$bd1 === $bd2' . ($bd1 === $bd2)? ' TRUE' . PHP_EOL: ' FALSE' . PHP_EOL; // TRUE
echo '$bd2 === $bd6' . ($bd2 === $bd6)? ' TRUE' . PHP_EOL: ' FALSE' . PHP_EOL; // TRUE
echo '$bd6 === $bd7' . ($bd6 === $bd7)? ' TRUE' . PHP_EOL: ' FALSE' . PHP_EOL; // TRUE
echo PHP_EOL;
echo PHP_EOL."COMPARE ALL CONFIG INSTANCES". PHP_EOL;
var_dump($bd3);
echo '$bd3 === $bd4' . ($bd3 === $bd4)? ' TRUE' . PHP_EOL: ' FALSE' . PHP_EOL; // TRUE
echo '$bd4 === $bd5' . ($bd4 === $bd5)? ' TRUE' . PHP_EOL: ' FALSE' . PHP_EOL; // TRUE
echo '$bd5 === $bd8' . ($bd5 === $bd8)? ' TRUE' . PHP_EOL: ' FALSE' . PHP_EOL; // TRUE
Tất cả sự phức tạp này ("liên kết tĩnh muộn" ... harumph), đối với tôi, chỉ đơn giản là một dấu hiệu của mô hình đối tượng / lớp bị hỏng của PHP. Nếu đối tượng lớp là đối tượng hạng nhất (xem Python), sau đó "$ _instance" sẽ là một lớp dụ biến - một thành viên của đối tượng lớp, trái ngược với một thành viên / thuộc tính của các thể hiện của nó và trái ngược với chia sẻ bởi con cháu của nó. Trong thế giới Smalltalk, đây là sự khác biệt giữa "biến lớp" và "biến thể hiện lớp".
Trong PHP, có vẻ như tôi cần phải ghi nhớ hướng dẫn rằng các mẫu là hướng dẫn viết mã - có lẽ chúng ta có thể nghĩ về một mẫu Singleton, nhưng cố gắng viết mã kế thừa từ một lớp "Singleton" thực sự có vẻ sai lầm cho PHP (mặc dù tôi cho rằng một số linh hồn dám nghĩ dám làm có thể tạo ra một từ khóa SVN phù hợp).
Tôi sẽ tiếp tục chỉ mã riêng từng singleton, sử dụng một mẫu được chia sẻ.
Lưu ý rằng tôi hoàn toàn đứng ngoài cuộc thảo luận về những kẻ độc thân, cuộc sống quá ngắn ngủi.
Tôi biết điều này có thể sẽ gây ra một cuộc chiến nảy lửa không cần thiết, nhưng tôi có thể thấy bạn có thể muốn nhiều hơn một kết nối cơ sở dữ liệu như thế nào, vì vậy tôi sẽ thừa nhận rằng singleton có thể không phải là giải pháp tốt nhất cho điều đó ... tuy nhiên, có sử dụng khác của mẫu singleton mà tôi thấy cực kỳ hữu ích.
Đây là một ví dụ: Tôi quyết định tung công cụ tạo khuôn mẫu và MVC của riêng mình vì tôi muốn thứ gì đó thực sự nhẹ. Tuy nhiên, dữ liệu mà tôi muốn hiển thị chứa rất nhiều ký tự toán học đặc biệt như ≥ và và những gì bạn có ... Dữ liệu được lưu trữ dưới dạng ký tự UTF-8 thực tế trong cơ sở dữ liệu của tôi thay vì được mã hóa trước HTML vì ứng dụng của tôi có thể cung cấp các định dạng khác như PDF và CSV ngoài HTML. Vị trí thích hợp để định dạng cho HTML là bên trong mẫu ("chế độ xem" nếu bạn muốn) chịu trách nhiệm hiển thị phần trang đó (đoạn trích). Tôi muốn chuyển đổi chúng thành các thực thể HTML thích hợp của chúng, nhưng hàm get_html_translation_table () của PHP không phải là siêu nhanh. Nó có ý nghĩa tốt hơn để lấy dữ liệu một lần và lưu trữ dưới dạng một mảng, làm cho nó có sẵn cho tất cả mọi người sử dụng. Đây' sa mẫu tôi gõ cùng nhau để kiểm tra tốc độ. Có lẽ, điều này sẽ hoạt động bất kể các phương thức khác mà bạn sử dụng (sau khi lấy ví dụ) có tĩnh hay không.
class EncodeHTMLEntities {
private static $instance = null;//stores the instance of self
private $r = null;//array of chars elligalbe for replacement
private function __clone(){
}//disable cloning, no reason to clone
private function __construct()
{
$allEntities = get_html_translation_table(HTML_ENTITIES, ENT_NOQUOTES);
$specialEntities = get_html_translation_table(HTML_SPECIALCHARS, ENT_NOQUOTES);
$this->r = array_diff($allEntities, $specialEntities);
}
public static function replace($string)
{
if(!(self::$instance instanceof self) ){
self::$instance = new self();
}
return strtr($string, self::$instance->r);
}
}
//test one million encodings of a string
$start = microtime(true);
for($x=0; $x<1000000; $x++){
$dump = EncodeHTMLEntities::replace("Reference method for diagnosis of CDAD, but clinical usefulness limited due to extended turnaround time (≥96 hrs)");
}
$end = microtime(true);
echo "Run time: ".($end-$start)." seconds using singleton\n";
//now repeat the same without using singleton
$start = microtime(true);
for($x=0; $x<1000000; $x++){
$allEntities = get_html_translation_table(HTML_ENTITIES, ENT_NOQUOTES);
$specialEntities = get_html_translation_table(HTML_SPECIALCHARS, ENT_NOQUOTES);
$r = array_diff($allEntities, $specialEntities);
$dump = strtr("Reference method for diagnosis of CDAD, but clinical usefulness limited due to extended turnaround time (≥96 hrs)", $r);
}
$end = microtime(true);
echo "Run time: ".($end-$start)." seconds without using singleton";
Về cơ bản, tôi đã thấy kết quả điển hình như thế này:
Kiểm tra php Thời gian chạy: 27.842966794968 giây bằng singleton Thời gian chạy: 237.78191494942 giây mà không sử dụng singleton
Vì vậy, trong khi tôi chắc chắn không phải là chuyên gia, tôi không thấy một cách thuận tiện và đáng tin cậy hơn để giảm chi phí của các cuộc gọi chậm đối với một số loại dữ liệu, trong khi làm cho nó cực kỳ đơn giản (một dòng mã để làm những gì bạn cần). Cấp ví dụ của tôi chỉ có một phương thức hữu ích, và do đó không tốt hơn một hàm được xác định toàn cầu, nhưng ngay khi bạn có hai phương thức, bạn sẽ muốn nhóm chúng lại với nhau, phải không? Tôi có cách ra khỏi căn cứ không?
Ngoài ra, tôi thích các ví dụ thực sự LÀM một cái gì đó, vì đôi khi thật khó để hình dung khi một ví dụ bao gồm các câu như "// làm điều gì đó hữu ích ở đây" mà tôi thấy mọi lúc khi tìm kiếm hướng dẫn.
Dù sao, tôi thích bất kỳ phản hồi hoặc nhận xét nào về lý do tại sao sử dụng một singleton cho loại điều này là bất lợi (hoặc quá phức tạp).
Bài viết này bao gồm chủ đề khá rộng rãi: http://www.phptherightway.com/pages/Design-Potypes.html#singleton
Lưu ý những điều dưới đây:
- Hàm tạo
__construct()
được khai báo làprotected
để ngăn việc tạo một thể hiện mới bên ngoài lớp thông quanew
toán tử.- Phương thức ma thuật
__clone()
được tuyên bố làprivate
để ngăn chặn việc sao chép một thể hiện của lớp thông quaclone
toán tử.- Phương thức ma thuật
__wakeup()
được khai báo làprivate
để ngăn chặn việc hủy kích hoạt một thể hiện của lớp thông qua hàm toàn cụcunserialize()
.- Một phiên bản mới được tạo thông qua liên kết tĩnh muộn trong phương thức tạo tĩnh
getInstance()
với từ khóastatic
. Điều này cho phép phân lớp củaclass Singleton
ví dụ.
Tôi đã viết từ lâu đã nghĩ để chia sẻ ở đây
class SingletonDesignPattern {
//just for demo there will be only one instance
private static $instanceCount =0;
//create the private instance variable
private static $myInstance=null;
//make constructor private so no one create object using new Keyword
private function __construct(){}
//no one clone the object
private function __clone(){}
//avoid serialazation
public function __wakeup(){}
//ony one way to create object
public static function getInstance(){
if(self::$myInstance==null){
self::$myInstance=new SingletonDesignPattern();
self::$instanceCount++;
}
return self::$myInstance;
}
public static function getInstanceCount(){
return self::$instanceCount;
}
}
//now lets play with singleton design pattern
$instance = SingletonDesignPattern::getInstance();
$instance = SingletonDesignPattern::getInstance();
$instance = SingletonDesignPattern::getInstance();
$instance = SingletonDesignPattern::getInstance();
echo "number of instances: ".SingletonDesignPattern::getInstanceCount();
Tôi đồng ý với câu trả lời đầu tiên nhưng tôi cũng sẽ tuyên bố lớp là cuối cùng để nó không thể được mở rộng vì việc mở rộng một singleton vi phạm mẫu đơn. Ngoài ra biến cá thể phải ở chế độ riêng tư để không thể truy cập trực tiếp. Đồng thời đặt phương thức __clone ở chế độ riêng tư để bạn không thể sao chép đối tượng singleton.
Dưới đây là một số mã ví dụ.
/**
* Singleton class
*
*/
final class UserFactory
{
private static $_instance = null;
/**
* Private constructor
*
*/
private function __construct() {}
/**
* Private clone method
*
*/
private function __clone() {}
/**
* Call this method to get singleton
*
* @return UserFactory
*/
public static function getInstance()
{
if (self::$_instance === null) {
self::$_instance = new UserFactory();
}
return self::$_instance;
}
}
Cách sử dụng ví dụ
$user_factory = UserFactory::getInstance();
Điều này ngăn bạn làm gì (điều này sẽ vi phạm mẫu đơn ..
BẠN KHÔNG THỂ LÀM ĐIỀU NÀY!
$user_factory = UserFactory::$_instance;
class SecondUserFactory extends UserFactory { }
Đây phải là cách đúng đắn của Singleton.
class Singleton {
private static $instance;
private $count = 0;
protected function __construct(){
}
public static function singleton(){
if (!isset(self::$instance)) {
self::$instance = new Singleton;
}
return self::$instance;
}
public function increment()
{
return $this->count++;
}
protected function __clone(){
}
protected function __wakeup(){
}
}
Tôi thích phương pháp @ jose-segura sử dụng các đặc điểm nhưng không thích xác định một biến tĩnh trên các lớp con. Dưới đây là một giải pháp tránh nó bằng cách lưu trữ các thể hiện trong một biến cục bộ tĩnh cho phương thức nhà máy được lập chỉ mục theo tên lớp:
<?php
trait Singleton {
# Single point of entry for creating a new instance. For a given
# class always returns the same instance.
public static function instance(){
static $instances = array();
$class = get_called_class();
if( !isset($instances[$class]) ) $instances[$class] = new $class();
return $instances[$class];
}
# Kill traditional methods of creating new instances
protected function __clone() {}
protected function __construct() {}
}
Cách sử dụng giống như @ jose-segura chỉ không cần biến tĩnh trong các lớp con.
Lớp cơ sở dữ liệu kiểm tra nếu có bất kỳ trường hợp cơ sở dữ liệu hiện có nào, nó sẽ trả về thể hiện trước đó.
class Database {
public static $instance;
public static function getInstance(){
if(!isset(Database::$instance) ) {
Database::$instance = new Database();
}
return Database::$instance;
}
private function __cunstruct() {
/* private and cant create multiple objects */
}
public function getQuery(){
return "Test Query Data";
}
}
$dbObj = Database::getInstance();
$dbObj2 = Database::getInstance();
var_dump($dbObj);
var_dump($dbObj2);
/*
After execution you will get following output:
object(Database)[1]
object(Database)[1]
*/
Tham khảo http://www.phptechi.com/php-singleton-design-potypes-example.html
Đây là ví dụ về tạo singleton trên lớp Cơ sở dữ liệu
mẫu thiết kế 1) singleton
class Database{
public static $instance;
public static function getInstance(){
if(!isset(Database::$instance)){
Database::$instance=new Database();
return Database::$instance;
}
}
$db=Database::getInstance();
$db2=Database::getInstance();
$db3=Database::getInstance();
var_dump($db);
var_dump($db2);
var_dump($db3);
sau đó đưa ra là -
object(Database)[1]
object(Database)[1]
object(Database)[1]
chỉ sử dụng một thể hiện duy nhất không tạo ra 3 thể hiện
Ví dụ nhanh:
final class Singleton
{
private static $instance = null;
private function __construct(){}
private function __clone(){}
private function __wakeup(){}
public static function get_instance()
{
if ( static::$instance === null ) {
static::$instance = new static();
}
return static::$instance;
}
}
Mong mọi người giúp đỡ.
Đây là ví dụ của tôi cung cấp khả năng gọi là $ var = new Singleton () và cũng tạo 3 biến để kiểm tra nếu nó tạo đối tượng mới:
class Singleton{
private static $data;
function __construct(){
if ($this::$data == null){
$this->makeSingleton();
}
echo "<br/>".$this::$data;
}
private function makeSingleton(){
$this::$data = rand(0, 100);
}
public function change($new_val){
$this::$data = $new_val;
}
public function printme(){
echo "<br/>".$this::$data;
}
}
$a = new Singleton();
$b = new Singleton();
$c = new Singleton();
$a->change(-2);
$a->printme();
$b->printme();
$d = new Singleton();
$d->printme();