Home >Backend Development >PHP Tutorial >Let's talk about the singleton pattern in PHP

Let's talk about the singleton pattern in PHP

青灯夜游
青灯夜游forward
2021-07-26 19:05:244171browse

In the previous article "In-depth analysis of the template method pattern in PHP" we introduced the template method pattern in PHP. The following article will take you to understand the singleton in the PHP design pattern. model.

Let's talk about the singleton pattern in PHP

#The singleton pattern is definitely ranked first among commonly used and frequently asked interview design patterns. On the one hand, it is simple enough and can be explained in a few words. On the other hand, it is complex enough. Its implementation is not only in one form, but also needs to consider the issue of multi-thread locking in asynchronous languages ​​such as Java. So during the interview, don't think that the interviewer will relax when he asks the question about the singleton model. This model can really be deep or shallow, and it can extremely reflect the level of a developer. Because as long as you work for a period of time, you will inevitably come into contact with this model.

Gof class diagram and explanation

GoF definition: Ensure that a class has only one instance and provide a global access point to access it.

GoF class diagram

Lets talk about the singleton pattern in PHP

##Code implementation

class Singleton
{
    private static $uniqueInstance;
    private $singletonData = '单例类内部数据';

    private function __construct()
    {
        // 构造方法私有化,外部不能直接实例化这个类
    }

    public static function GetInstance()
    {
        if (self::$uniqueInstance == null) {
            self::$uniqueInstance = new Singleton();
        }
        return self::$uniqueInstance;
    }

    public function SingletonOperation(){
        $this->singletonData = '修改单例类内部数据';
    }

    public function GetSigletonData()
    {
        return $this->singletonData;
    }

}

Yes, the core is such a singleton class, nothing else. Let the static variable save itself after instantiation. When this object is needed, call the GetInstance() method to obtain the globally unique object.

$singletonA = Singleton::GetInstance();
echo $singletonA->GetSigletonData(), PHP_EOL;

$singletonB = Singleton::GetInstance();

if ($singletonA === $singletonB) {
    echo '相同的对象', PHP_EOL;
}
$singletonA->SingletonOperation(); // 这里修改的是A
echo $singletonB->GetSigletonData(), PHP_EOL;

When called by the client, we will find that

singletonB is exactly the same object. Lets talk about the singleton pattern in PHP

    Yes, as you can see from the code, the biggest use of singletons is to make our objects globally unique.
  • So what are the benefits of global uniqueness? The creation of some classes is very expensive, and we do not need to use new objects every time. They can be reused as one object. They have no attributes or states that need to be changed, but only provide some public services. For example, database operation classes, network request classes, log operation classes, configuration management services, etc.
  • An interviewer once asked, is a singleton the only one in PHP? If it is under one process, that is, under one fpm, it is of course unique. That is definitely not the only one among the multiple fpms that nginx pulls up simultaneously. One process per process!
  • Advantages of the singleton pattern: controlled access to unique instances; narrowed namespace; allows refinement of operations and presentation; allows variable number of instances; more flexible than class operations.
  • Laravel uses the singleton mode in the IoC container part. We will explain the content of the container part in a future series of articles on Laravel. We can find the singleton method in the Illuminate\Container\Container class. It calls the getClosure method in the bind method. If you continue to track, you will find that they will eventually call the make or build method of the Container to instantiate the class. Regardless of the make or build method, they will have a singleton judgment, that is, to judge whether the class has been instantiated or already exists in the container. . if (!$reflector->isInstantiable()) in build.

The company is getting bigger and bigger, but we only have one copy (single instance class) of all company rosters, which is stored in our OA system. What I'm afraid of is that confusion will arise after each department has its own roster. For example, if the update is not timely, newly joined or resigned employees from other departments will be missed. Other departments can view the entire roster when needed, or create and modify their own department's sections based on the entire roster. But in the OA system, what they actually modify is the contents of the general roster. What everyone maintains is actually the only real roster stored in the OA system server

Full code: https://github.com/zhangyue0503/designpatterns-php/blob/master/21.singleton/source/singleton.php

Example

Since it was said above that both database operation classes and network request classes like to use the singleton mode, then we will implement the development of a singleton mode for the Http request class. I remember that when I was working on Android a long time ago, there were not as many frameworks as there are now. Http requests were all encapsulated by themselves, and most of the online tutorials adopted the singleton mode.

Cache class diagram

Lets talk about the singleton pattern in PHP
##Full source code: https://github.com/ zhangyue0503/designpatterns-php/blob/master/21.singleton/source/singleton-http.php

<?php 

class HttpService{
    private static $instance;

    public function GetInstance(){
        if(self::$instance == NULL){
            self::$instance = new HttpService();
        }
        return self::$instance;
    }

    public function Post(){
        echo &#39;发送Post请求&#39;, PHP_EOL;
    }

    public function Get(){
        echo &#39;发送Get请求&#39;, PHP_EOL;
    }
}

$httpA = new HttpService();
$httpA->Post();
$httpA->Get();

$httpB = new HttpService();
$httpB->Post();
$httpB->Get();

var_dump($httpA == $httpB);

Description

  • Is it still very simple? I won’t talk more about this form of singleton here. Let’s talk about several other forms of singletons
  • In static languages ​​such as Java , static variables can be directly new objects, in the declaration Lets talk about the singleton pattern in PHP

    instance = new HttpService();. In this way, the GetInstance() method can be omitted, but this static variable will be directly instantiated and occupy memory regardless of whether it is used or not. This kind of singleton is called the hungry Chinese singleton pattern.

  • Our code and examples are obviously not Hungry Man style, this form is called Lazy Man style. You have to actively use GetInstance() to get it, and then I will create the object.
  • Lazy style In multi-threaded applications, such as Java multi-threading or after using swoole in PHP, there will be a problem of repeated creation, and the objects created multiple times are not the same object. At this time, double detection is generally used to ensure that there is only one global object. You can find the specific code yourself. There will be no problem with the Hungry Han style. The Hungry Han style itself has already assigned a value to the static attribute and will not change again.
  • Another way is to create static inner classes. This is rarely seen, and its resource utilization rate is high. Put the static variable inside the method so that the static variable becomes a variable within the method instead of a variable in the class. It allows a singleton object to call its own static methods and properties.

Original address: https://juejin.cn/post/6844903990585458702

Author: Hardcore Project Manager

Recommended learning: "PHP Video Tutorial"

The above is the detailed content of Let's talk about the singleton pattern in PHP. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:juejin.cn. If there is any infringement, please contact admin@php.cn delete