development

PHP에서 데이터베이스에 액세스 할 수있는 싱글 톤의 사용 사례가 있습니까?

big-blog 2020. 6. 24. 07:08
반응형

PHP에서 데이터베이스에 액세스 할 수있는 싱글 톤의 사용 사례가 있습니까?


PDO를 통해 MySQL 데이터베이스에 액세스합니다. 데이터베이스에 대한 액세스를 설정하고 있으며 첫 번째 시도는 다음을 사용하는 것입니다.

내가 생각한 첫 번째 것은 global:

$db = new PDO('mysql:host=127.0.0.1;dbname=toto', 'root', 'pwd');

function some_function() {
    global $db;
    $db->query('...');
}

이것은 나쁜 습관으로 간주됩니다. 약간의 검색 후, 나는 함께 결국 싱글 패턴 , 어떤

"클래스의 단일 인스턴스가 필요한 상황에 적용됩니다."

매뉴얼의 예에 따르면 다음과 같이해야합니다.

class Database {
    private static $instance, $db;

    private function __construct(){}

    static function singleton() {
        if(!isset(self::$instance))
            self::$instance = new __CLASS__;

        return self:$instance;
    }

    function get() {
        if(!isset(self::$db))
            self::$db = new PDO('mysql:host=127.0.0.1;dbname=toto', 'user', 'pwd')

        return self::$db;
    }
}

function some_function() {
    $db = Database::singleton();
    $db->get()->query('...');
}

some_function();

이것을 할 수 있는데 왜 비교적 큰 수업이 필요한가요?

class Database {
    private static $db;

    private function __construct(){}

    static function get() {
        if(!isset(self::$db))
            self::$db = new PDO('mysql:host=127.0.0.1;dbname=toto', 'user', 'pwd');

        return self::$db;
    }
}

function some_function() {
    Database::get()->query('...');
}

some_function();

이 마지막은 완벽하게 작동하며 $db더 이상 걱정할 필요가 없습니다.

더 작은 싱글 톤 클래스를 만들려면 어떻게해야합니까, 아니면 PHP에서 누락 된 싱글 톤에 대한 사용 사례가 있습니까?


알았어, 내가 처음 커리어를 시작할 때 한동안 궁금했어. 다른 방법을 구현하고 정적 클래스를 사용하지 않기로 결정한 두 가지 이유가 있었지만 꽤 큰 클래스입니다.

하나는 당신이 당신이 절대로 하나 이상의 인스턴스를 가질 수 없다는 것을 절대적으로 확신하는 것을 발견 할 것이라는 것입니다. 두 번째 모니터, 두 번째 데이터베이스, 두 번째 서버 등으로 끝날 수 있습니다.

이런 일이 발생하면 정적 클래스를 사용한 경우 싱글 톤을 사용하는 것보다 훨씬 더 나쁜 리팩터링이 필요합니다. 싱글 톤 자체는 iffy 패턴이지만, 지능적인 팩토리 패턴으로 쉽게 변환 할 수 있으며, 너무 많은 문제없이 의존성 주입을 사용하도록 변환 할 수도 있습니다. 예를 들어, 싱글 톤이 getInstance ()를 통해 얻은 경우 getInstance (databaseName)로 쉽게 변경하고 다른 코드 변경없이 여러 데이터베이스를 허용 할 수 있습니다.

두 번째 문제는 테스트입니다 (솔직히 이것은 첫 번째 문제와 동일합니다). 때로는 데이터베이스를 모의 데이터베이스로 바꾸려고합니다. 실제로 이것은 데이터베이스 오브젝트의 두 번째 인스턴스입니다. 정적 클래스는 싱글 톤보다 정적 클래스로 처리하기가 훨씬 어렵습니다. 정적 클래스의 모든 단일 메소드가 아닌 getInstance () 메소드 만 조롱하면됩니다 (일부 언어에서는 매우 어려울 수 있음).

사람들은 "글로벌 (Globals)"이 나쁘다고 말할 때 그럴만한 이유가 있지만, 문제를 직접 해결할 때까지 항상 분명하지는 않습니다.

당신이 할 수있는 최선의 방법은 (당신이 한 것처럼) 물어보고 결정을 내리는 결과를 관찰하는 것입니다. 시간이 지남에 따라 코드의 진화를 해석 할 수있는 지식을 갖는 것이 처음부터 올바르게 수행하는 것보다 훨씬 중요합니다.


싱글 톤은 PHP에서 거의 사용하지 않습니다.

객체가 공유 메모리에있는 언어에서는 싱글 톤을 사용하여 메모리 사용량을 낮출 수 있습니다. 두 개의 객체를 만드는 대신 전역 공유 응용 프로그램 메모리에서 기존 인스턴스를 참조합니다. PHP에는 그러한 응용 프로그램 메모리가 없습니다. 하나의 요청에서 생성 된 싱글 톤은 정확히 해당 요청에 대해 유효합니다. 동시에 수행 된 다른 요청에서 생성 된 싱글 톤은 여전히 ​​완전히 다른 인스턴스입니다. 따라서 Singleton의 두 가지 주요 목적 중 하나는 여기에 적용되지 않습니다.

또한 개념적으로 응용 프로그램에 한 번만 존재할 수있는 많은 개체에는이를 적용하기 위해 언어 메커니즘이 필요하지 않습니다. 이 경우 필요 하나 개의 인스턴스를, 다음 또 다른 인스턴스를하지 않습니다 . 다른 인스턴스 가 없을 때만 ( 예 : 두 번째 인스턴스를 만들 때 새끼 고양이가 죽는 경우) 싱글턴에 대한 유스 케이스가있을 수 있습니다.

다른 목적은 동일한 요청 내의 인스턴스에 대한 글로벌 액세스 포인트를 갖는 것입니다. 이것이 바람직하게 들릴지 모르지만 전역 범위 (예 : 전역 및 정적)에 대한 연결을 생성하기 때문에 실제로는 그렇지 않습니다. 따라서 단위 테스트가 어려워지고 일반적으로 응용 프로그램의 유지 관리 부담이 줄어 듭니다. 이를 완화 할 수있는 방법이 있지만 일반적으로 많은 클래스에서 동일한 인스턴스가 필요한 경우 Dependency Injection을 사용하십시오 .

PHP 에서 싱글 톤에 대한 내 슬라이드를 참조하십시오 -왜 나쁜지, 추가 정보 를 위해 응용 프로그램에서 제거하는 방법.

Singleton 패턴의 발명자 중 하나 인 Erich Gamma 조차도 오늘날이 패턴을 의심합니다.

"Singleton을 떨어 뜨리는 것을 선호합니다. 거의 항상 디자인 냄새입니다."

추가 자료

위의 후에도 여전히 결정에 도움이 필요한 경우 :

싱글 톤 결정 다이어그램


PHP에서 누가 싱글 톤을 필요로합니까?

싱글 톤에 대한 반대 의견의 대부분은 기술적 인 관점에서 비롯된 것입니다. 그러나 그 범위도 매우 제한적입니다. 특히 PHP의 경우. 먼저 싱글 톤을 사용하는 몇 가지 이유를 나열한 다음 싱글 톤 사용에 대한 이의를 분석합니다. 먼저, 필요한 사람들 :

-많은 다른 환경에서 사용될 큰 프레임 워크 / 코드베이스를 코딩하는 사람들은 기존의 다른 프레임 워크 / 코드베이스와 함께 작업해야하며, 클라이언트 / 보스의 많은 변화, 심지어 기발한 요청을 구현해야합니다. / 관리 / 단위 지도자들이합니다.

싱글 톤 패턴은 자체 포함 적입니다. 완료되면 싱글 톤 클래스는 포함 된 모든 코드에서 엄격하며 메소드와 변수를 작성하는 방식과 동일하게 작동합니다. 그리고 주어진 요청에서 항상 동일한 객체입니다. 두 개의 서로 다른 객체로 두 번 만들 수 없으므로 싱글 톤이 두 개, 세 개의 서로 다른 오래된 스파게티 코드베이스에 삽입 된 경우에도 코드에서 특정 지점에있는 단일 객체가 무엇인지 알 수 있습니다. 따라서 개발 목적면에서 더 쉬워집니다. 프로젝트에 많은 사람들이 참여하더라도 주어진 코드베이스에서 단일 지점이 한 지점에서 초기화되는 것을 볼 때 그것이 무엇인지, 어떻게하는지, 어떻게 알 수 있는지 기존 클래스 인 경우 해당 객체가 처음 작성된 위치를 추적해야합니다. 코드에서 특정 시점까지 호출 된 메소드 및 특정 상태 그러나 싱글 톤을 거기에 버리고, 코딩하는 동안 적절한 디버깅 및 정보 메소드와 추적을 싱글 톤에 버렸다면 정확히 무엇인지 알게됩니다. 따라서 다른 철학으로 수행했거나 접촉하지 않은 사람들이 수행 한 코드를 통합해야 할 필요가 있으므로 다른 코드베이스로 작업해야하는 사람들이 더 쉬워집니다. (즉, 더 이상 존재하지 않는 공급 업체 프로젝트 회사)는 아무것도 지원하지 않습니다. 다른 철학으로 수행했거나 접촉하지 않은 사람들이 수행 한 코드를 통합 할 필요가 있기 때문에 서로 다른 코드베이스로 작업해야하는 사람들이 더 쉬워집니다. (즉, 더 이상 존재하지 않는 공급 업체 프로젝트 회사)는 아무것도 지원하지 않습니다. 다른 철학으로 수행했거나 접촉하지 않은 사람들이 수행 한 코드를 통합 할 필요가 있기 때문에 서로 다른 코드베이스로 작업해야하는 사람들이 더 쉬워집니다. (즉, 더 이상 존재하지 않는 공급 업체 프로젝트 회사)는 아무것도 지원하지 않습니다.

-타사 API , 서비스 및 웹 사이트 와 협력해야하는 사람들 .

자세히 살펴보면, 이전의 경우와 크게 다르지 않습니다. 타사 API, 서비스, 웹 사이트는 제어 할 수없는 외부의 격리 된 코드베이스와 같습니다. 무슨 일이든 일어날 수 있습니다. 따라서 싱글 톤 세션 / 사용자 클래스를 사용하면 OpenID , Facebook , Twitter 등과 같은 타사 제공 업체의 모든 종류의 세션 / 권한 구현을 관리 할 수 있으며 SAME 싱글 톤 객체에서 동시에 모든 작업을 수행 할 수 있습니다. -어떤 코드에 연결해도 특정 지점에서 알려진 상태로 쉽게 액세스 할 수 있습니다. 자신의 웹 사이트 / 애플리케이션에서 SAME 사용자를위한 여러 개의 다른 타사 API / 서비스에 대한 여러 세션을 생성하고 원하는 작업을 수행 할 수도 있습니다.

물론,이 모든 것들은 일반적인 클래스와 객체를 사용함으로써 전통적인 방법으로 어조가 될 수 있습니다. 여기서 중요한 것은 싱글 톤이 더 깔끔하고 깔끔하기 때문에 그러한 상황에서 전통적인 클래스 / 오브젝트 사용에 비해 관리 가능하고 테스트하기가 더 쉽기 때문입니다.

-빠른 개발이 필요한 사람들

The global-like behavior of singletons make it easier to build any kind of code with a framework which has a collection of singletons to build on, because once you construct your singleton classes well, the established, mature and set methods will be easily available and usable anywhere, anytime, in a consistent fashion. It takes some time to mature your classes, but after that, they are rock solid and consistent, and useful. You can have as many methods in a singleton doing whatever you want, and, though this may increase the memory footprint of the object, it brings much more savings in time required for rapid development - a method you are not using in one given instance of an application can be used in another integrated one, and you can just slap a new feature which client/boss/project manager asks just by a few modifications.

당신은 아이디어를 얻습니다. 이제 싱글 톤에 대한 반대 의견과 유용한 것에 반대하는 부정한 성전을 살펴 보겠습니다 .

-가장 반대 의견은 테스트를 더 어렵게한다는 것입니다.

그리고 실제로 싱글 톤을 디버깅 할 것이라는 사실을 알고 적절한 예방 조치를 취하고 디버깅 루틴을 싱글 톤으로 코딩하여 쉽게 완화 할 수 있더라도 어느 정도까지는 가능합니다. 그러나 이것은 다른 코딩 철학 / 방법 / 패턴과 크게 다르지 않습니다. 단지, 싱글 톤은 비교적 새롭고 널리 보급되어 있지 않으므로 현재 테스트 방법은 비교할 수 없습니다. 그러나 이것은 프로그래밍 언어의 측면에서 다르지 않습니다. 스타일마다 스타일이 다릅니다.

One point this objection falls flat in that, it ignores the fact that the reasons applications developed is not for 'testing', and testing is not the only phase/process that goes into an application development. Applications are developed for production use. And as I explained in the 'who needs singletons' section, singletons can cut a GREAT deal from the complexity of having to make a code work WITH and INSIDE many different codebases/applications/third-party services. The time which may be lost in testing, is time gained in development and deployment. This is especially useful in this era of third-party authentication/application/integration - Facebook, Twitter, OpenID, many more and who knows what's next.

이해할 만하지 만 프로그래머는 경력에 따라 매우 다른 상황에서 일합니다. 정의 된 부서가 다른 방식으로 정의 된 소프트웨어 / 애플리케이션을 편안한 방식으로 그리고 예산 삭감 / 해고가 임박하지 않고 비교적 많은 다른 회사에서 일하는 사람들에게 싸고 / 빠르고 / 신뢰할 수있는 방식으로 싱글 톤은 그렇게 필요하지 않을 수도 있습니다. 그리고 그들은 이미 가지고있는 것에 방해가 될 수도 있습니다.

그러나 고객 / 관리자 / 프로젝트로부터 많은 다른 요청 (때로는 불합리한)을 구현해야하는 '민첩한'개발의 불참 한 트렌치에서 일해야하는 사람들을 위해 싱글 톤은 앞에서 설명한 이유 때문에 절약의 은혜입니다.

-또 다른 반대는 메모리 풋 프린트가 더 높다는 것입니다

Because a new singleton will exist for each request from each client, this MAY be an objection for PHP. With badly constructed and used singletons, the memory footprint of an application can be higher if many users are served by the application at any given point.

Though, this is valid for ANY kind of approach you can take while coding things. The questions which should be asked are, are the methods, data which are held and processed by these singletons unnecessary? For, if they ARE necessary across many of the requests application is getting, then even if you don't use singletons, those methods and data WILL be present in your application in some form or another through the code. So, it all becomes a question of how much memory will you be saving, when you initialize a traditional class object 1/3 into the code processing, and destroy it 3/4 into it.

See, when put this way, the question becomes quite irrelevant - there should not be unnecessary methods, data held in objects in your code ANYway - regardless of you use singletons or not. So, this objection to singletons becomes really hilarious in that, it ASSUMES that there will be unnecessary methods, data in the objects created from the classes you use.

- Some invalid objections like 'makes maintaining multiple database connnections impossible/harder'

I can't even begin to comprehend this objection, when all one needs to maintain multiple database connections, multiple database selections, multiple database queries, multiple result sets in a given singleton is just keeping them in variables/arrays in the singleton as long as they are needed. This can be as simple as keeping them in arrays, though you can invent whatever method you want to use to effect that. But let's examine the simplest case, use of variables and arrays in a given singleton:

Imagine the below is inside a given database singleton:

$this->connections = array(); (wrong syntax, I just typed it like this to give you the picture - the proper declaration of the variable is public $connections = array(); and its usage is $this->connections['connectionkey'] naturally )

You can set up, and keep multiple connections at any given time in an array in this fashion. And same goes for queries, result sets and so forth.

$this->query(QUERYSTRING,'queryname',$this->connections['particulrconnection']);

Which can just do a query to a selected database with a selected connection, and just store in your

$this->results

array with the key 'queryname'. Of course, you will need to have your query method coded for this - which is trivial to do.

This enables you to maintain a virtually infinite number of (as much as the resource limits allow of course) different database connections and result sets as much as you need them. And they are available to ANY piece of code in any given point in any given codebase into which this singleton class has been instantiated.

OF COURSE, you would naturally need to free the result sets, and connections when not needed - but that goes without saying, and it's not specific to singletons or any other coding method/style/concept.

At this point, you can see how you can maintain multiple connections/states to third-party applications or services in the same singleton. Not so different.

Long story short, in the end, singleton patterns are just another method/style/philosophy to program with, and they are as useful as ANY other when they are used in the correct place, in the correct fashion. Which is not different from anything.

You will notice that in most of the articles in which singletons are bashed, you will also see references to 'globals' being 'evil'.

Let's face it - ANYthing that is not used properly, abused, misused, IS evil. That is not limited to any language, any coding concept, any method. Whenever you see someone issuing blanket statements like 'X is evil', run away from that article. Chances are very high that it's the product of a limited viewpoint - even if the viewpoint is the result of years of experience in something particular - which generally ends up being the result of working too much in a given style/method - typical intellectual conservatism.

Endless examples can be given for that, ranging from 'globals are evil' to 'iframes are evil'. Back around 10 years ago, even proposing the use of an iframe in any given application was heresy. Then comes Facebook, iframes everywhere, and look what has happened - iframes are not so evil anymore.

There are still people who stubbornly insist that they are 'evil' - and sometimes for good reason too - but, as you can see, there is a need, iframes fill that need and work well, and therefore the entire world just moves on.

The foremost asset of a programmer/coder/software engineer is a free, open and flexible mind.


Singletons are considered by many to be anti-patterns as they're really just glorified global variables. In practice there are relatively few scenarios where it's necessary for a class to have only one instance; usually it's just that one instance is sufficient, in which case implementing it as a singleton is completely unnecessary.

To answer the question, you're right that singletons are overkill here. A simple variable or function will do. A better (more robust) approach, however, would be to use dependency injection to remove the need for global variables altogether.


In your example you're dealing with a single piece of seemingly unchanging information. For this example a Singleton would be overkill and just using a static function in a class will do just fine.

More thoughts: You might be experiencing a case of implementing patterns for the sake of patterns and your gut is telling you "no, you don't have to" for the reasons you spelled out.

BUT: We have no idea of the size and scope of your project. If this is simple code, perhaps throw away, that isn't likely to need to change then yes, go ahead and use static members. But, if you think that your project might need to scale or be prepped for maintenance coding down the road then, yes, you might want to use the Singleton pattern.


First, I just want to say that I don't find much uses to the Singleton pattern. Why would one want to keep a single object thorough the whole application? Especially for databases, what if I want to connect to another database server? I have to disconnect and reconnect every time...? Anyway...

There are several drawbacks to using globals in an application (which is what the traditional use of the Singleton pattern does):

  • Difficult to unit test
  • Dependency injection issues
  • Can create locking issues (multi-threaded application)

Use static classes instead of a singleton instance provides some of the same drawbacks as well, because the biggest problem of singleton is the static getInstance method.

You can limit the number of instances a class can have without using the traditional getInstance method:

class Single {

    static private $_instance = false;

    public function __construct() {
        if (self::$_instance)
           throw new RuntimeException('An instance of '.__CLASS__.' already exists');

        self::$_instance = true;
    }

    private function __clone() {
        throw new RuntimeException('Cannot clone a singleton class');
    }

    public function __destruct() {
        self::$_instance = false;
    }

}

$a = new Single;
$b = new Single; // error
$b = clone($a); // error
unset($a);
$b = new Single; // works

This will help on the first the points mentioned above: unit testing and dependency injection; while still making sure a single instance of the class exist in your application. You could, per example, just pass the resulting object to your models (MVC pattern) for them to use.


Consider simply how your solution differs from the one presented in the PHP docs. In fact, there is just one "small" difference: your solution provides callers of the getter with a PDO instance, while the one in the docs provides callers of Database::singleton with a Database instance (they then use the getter on that to get a PDO instance).

So what conclusion do we reach?

  • In the documentation code, callers get a Database instance. The Database class may expose (in fact, it should expose if you 're going to all this trouble) a richer or higher-level interface than the PDO object it wraps.
  • If you change your implementation to return another (richer) type than PDO, then the two implementations are equivalent. There's no gain to be had from following the manual implementation.

On the practical side, Singleton is a pretty controversial pattern. This is mainly because:

  • It's overused. Novice programmers grok Singleton much easier than they grok other patterns. They then go on to apply their newfound knowledge everywhere, even if the problem at hand can be solved better without Singleton (when you 're holding a hammer, everything looks like a nail).
  • Depending on the programming language, implementing a Singleton in an airtight, non-leaky manner can prove to be a titanic task (especially if we have advanced scenarios: a singleton depending on another singleton, singletons that can be destroyed and re-created, etc). Just try to search for "the definitive" Singleton implementation in C++, I dare you (I own Andrei Alexandrescu's groundbreaking Modern C++ Design, which documents much of the mess).
  • It imposes additional workload both when coding the Singleton and when writing code to access it, workload which you can do without by following a few self-imposed constraints on what you try to do with your program variables.

So, as a final conclusion: your singleton is just fine. Not using Singleton at all is just fine most of the time as well.


Your interpretation is correct. Singletons have their place but are overused. Often, accessing static member functions is sufficient (notably, when you do not need to control time-of-construction in any way). Better, you can just put some free functions and variables in a namespace.


When programming there is not "right" and "wrong"; there is "good practice" and "bad practice".

Singletons are generally created as a class to be reused later. They need to be created in such a way that the programmer doesn't accidentally instantiate two instances while drunkenly coding at midnight.

If you have a simple little class that shouldn't be instantiated more than once, you don't need to make it a singleton. It's just a safety net if you do.

it's not always bad practice to have global objects. If you know that you're going to use it globally/everywhere/all the time, it may be one of the few exceptions. However, globals are generally considered "bad practice" in the same way that goto is considered bad practice.


I don't see any point to this at all. If you implemented the class in such a way that the connection string was taken as a parameter to the constructor and maintained a list of PDO objects (one for each unique connection string) then maybe there would be some benefit, but the implementation of singleton in this instance seems like a pointless exercise.


내가 볼 수있는 한, 당신은 아무것도 빠지지 않았습니다. 예는 꽤 결함이 있습니다. 싱글 톤 클래스에 비 정적 인스턴스 변수가 있으면 차이가 있습니다.

참고 URL : https://stackoverflow.com/questions/4595964/is-there-a-use-case-for-singletons-with-database-access-in-php

반응형