Why is singleton so bad in the PHP environment?

Possible duplicate:
Who needs singletones?

I was wondering what are the disadvantages of using singletones in php scripts. I use a lot of them, and sometimes I do not understand the criticisms of the developers. Some examples:

I have a Request class:

Sanitizing POST, GET, COOKIE inputdata and using it instead of global arrays - strictly and globally. how

$request = Request::getInstance(); $firstname = $request->post('firstname', $additionalFilters); 

There is always only one request per request. Why is using a singleton a bad idea in this case?

Same thing for $ _SESSION:

I have a Session (Singleton) class that represents an $ _SESSION array, because there is only one session, and I use it globally.

Database

 $mysql = DB::getInstance('mysql', 'dbname'); //pseudo $sqlite = DB::getInstance('sqlite', 'dbname'); //pseudo 

For each type of database, I want only one object and never again. In my opinion, there is a risk of chaos.

Unique strings

Also, I often use classes to represent / use a unique row of the db table.

 $article = Article::getInstance($id); $navigation = Navigation::getInstance($id); 

I see only the benefits of doing it this way. I never want the second object to represent a unique string. Why is there such a bad idea here?

In fact, most (almost all) of my classes do not have a common constructor, but always a static method such as getInstance ($ id) or create (), so the class itself handles possible instances (which does not mean that they are, by definition, all singleton)

So my question is: are there any flaws that I have not yet understood. And what is the specific scenario that singleton doubters think of when advised against singleton.

Edit:

Now you have a singleton that wraps around $ _POST, but what if you don't have $ _POST but want to use the file instead for input? In this case, it would be more convenient if you had an abstract input class and create an instance of POSTInput to control input through published data.

Good, real benefits. I did not realize this. This is especially true for the Request class.

Nevertheless, I have doubts about this approach. Suppose I have a "Functionality" class that performs a specific request (for example, a guestbook component). Inside this class I want to get the passed parameter. So I get an instance of Singleton request

 $req = Request::getInstance(); $message = $req->post('message'); 

Thus, only my functional object takes care of the Request class.

When I use the non-element approach, I need to somehow create an additional class / function to control that each request receives a valid request object. Thus, my Functionality class does not need to know about this control class, but, in my opinion, there is still a dependency / problem: every time I create a Functionality object object, there is a chance that I forget to set the request object.

Of course, I can define an optional parameter when creating functionality. But this leads to some redundant parameter for some time. Or not?

+6
source share
2 answers

Singletones (and static classes, to which basically the same story applies) are not bad in themselves, but they make dependencies that you don't need.

Now you have a singleton that wraps around $ _POST, but what if you don't have $ _POST, but want to use the file to enter instead? In this case, it would be more convenient if you had an abstract input class and created an instance of POSTInput to control input through published data.

If you want to get an input file or even (for some reason) want to imitate (or play) several queries based on input from a database table, you can still do this without changing any code except that it creates an instance of the class.

The same applies to other classes. You do not want your entire application to talk to this MySQL single. What if you need to connect to two MySQL databases? What if you need to switch to WhatEverSQL? .. Make abstracts for these classes and redefine them to implement certain technologies.

+4
source

I don’t think single player games should have the bad print they do in a query-based architecture such as PHP or ASP.NET (or whatever). Essentially, in a regular program the life of this singleton can be as many months or years as the program works:

 int main() { while(dont_exit) { // do stuff Singleton& mySingleton = Singleton::getInstance(); // use it } return 0; } 

Besides being just a global variable, it is very difficult to replace this singleton, perhaps with one single, which can be useful in unit testing. The amount of code that can depend on it, potentially hundreds of source files, are closely related to the use of this singleton code for the entire program.

However, in the case of query-based scripts such as your PHP page or ASP.NET page, all of your called codes are effectively wrapped in a function call. Again, they confuse the global variable (but in the context of the request) with protection against creating more than once.

Nevertheless, I oppose their use. What for? Because even in the context of your only request, everything depends and is closely connected with this instance. What happens when you want to test another script with a different request object? Assuming you have enabled encoding, you need to go and change each individual instance of this call. If you passed a link to the pre-built Request class, now you can do cool things, for example, provide a modular test version of your class by simply changing what is passed to other functions. You have also disconnected everything from using this universal Request object.

+3
source

Source: https://habr.com/ru/post/894044/


All Articles