Yes, I see that now.
And thanks for completely owning me on my PHP knowledge lastcraft.
I think I've found it. http://www.sitepoint.com/forums/show...43&postcount=7Originally Posted by lastcraft
Annotations support for PHP5
TC/OPT™ Group Leader
hi guys, I must say that this is a very interesting discussion. really. i got the expected answer (don't use globals, they are evil ) and a few solutions to work around this problem.
thanks a lot for the link Marcus, it really answers most of my questions.
just one last thing about the Singleton (as in the above example (c.f beginning of the thread)). Should the bit of code shown above be used in the constructor of classes dealing with a db or in each method?
I read this thread with much interest, and particularly enjoyed this post by Marcus. However I've been thinking about the above quote quite a lot, and it has me both confused and a little concerned about my understanding of how database connections work in PHP.Originally Posted by lastcraft
Since PHP (unlike say Java) can't use true singleton objects that are accessible in multiple simultaneous processes/requests, wouldn't the simultaneous requests mentioned above actually be handled by different database connection objects? If so, how is there a risk that a transaction would get garbled?
This also got me thinking about persistent connections, which I've always used as a matter of course. I would think that any risk posed by the above scenario would be ten times as dangerous with the use of persistent connections, since there's a pool of open connections that any script/request/process can use. Again, my understanding was that this was handled automatically, and that the same connection couldn't be used by more than one client at the same time. Am I mistaken in this point as well?
Sorry if this is all a bit noobish for this forum, but I wanted to post in the context of this discussion since it seems relevant.
Thanks for any enlightenment you can provide.
If the data is critical and/or the potential for collisions high then transactions are necessary. But the majority of websites database accesses are reads and if writes are light, such as adding a occasional record to a mailing list or adminstrative updates, then most sites can go forever and never get a write error using modern databases.A web server has many, many simultaneous requests. Please, please don't tell me you build database driven web sites without using transactions.
With PHP a single request/response cycle is everything. When the script ends and the connection is closed then the commit would occur. There is no such thing as a transaction running across two requests. You are thinking of long running apps such as desktop applications or application servers.If the connection is global, who begins the transaction? Who commits it? These are synchonisation issues. Issues that you drive a horse and cart through by using a global.
I wonder why there seems to be an insistance on singleton patterns (particularly in PHP4) for cases where a static class is much easier to implement, conceptualize and use. Why instance the object when its class code is all you really want? I have a (static) connection class that holds a static array of connection resources. There is no need to wrap each resource in an object -- that is wasteful. As all classes are in the global namespace, there is no issue with accessing it from anywhere and at anytime. It is uniform, it is fast and it is always available. When I switched my codebase to PHP5, I merely re-implemented the function/static var as a real class static var (even though it continued to work as is).
OOP patterns are both useful and fashionable, to be sure. That doesn't change the fact that procedural patterns are also useful even if they are not as fashionable at the moment. Use the simplest solution possible (but no simpler). Always.
OOP is rather more than just a fashion, I think.
Surely that is true -- and it is also what I said. Never-the-less, it is only one technique from a myriad of possible techniques. Use the one that is most appropriate for your problem and your toolchain. Sometimes an OOP pattern is the best, sometimes not. That's all I meant to imply.Originally Posted by McGruff
Out of interest, why do you need to instanciate the database object at all? This might be bad practise but PHP falls back to the last opened database connection regardless of any issue of scope. Furthermore everything else in a database specific abstraction should be fairly static? I appreciate that multi-database setups would have a scope issue.
Please don't confuse object-oriented programming with software design-patterns. They may have spawned from the same place, but they deal with different abstration-levels. Most design-patterns can be implemented in whatever you want, though admittedly a few are pretty much tied in to object-oriented languages. (Such as the Singleton)Originally Posted by jayboots
Singleton has advantages over a static class. For one thing it can have properties, so it may hold state (A connection-id for example).Originally Posted by jayboots
A lot of the problems with using globals for database connections result from threaded applications, which are hardly ever done in php. Simultaneous requests are handled by different db-connetions usually. The way that most (popular) php based software does it, is it first creates a db-connection or otherwise dies. If during the course of the execution of the script the db becomes unavailable the script dies as well. The Connection is then closed at the very end of the script. Everything done in the script is sequential.Originally Posted by hennagaijin
Now using transactions or not, is whole other issue. Obviously if you are not using transactions, and the script dies after having done only half of the necessary updates, you will likely have a problem (inconsisten data); or if a simultaneous request respectively overwrite parts of the the newly made changes. This is basic database theory - and it has nothing to do with wether you use a global db-variable or a singleton (except maybe in very special circumstances).
A persistent connection is only used by one instance at any time. Or to quote from the manual:I would think that any risk posed by the above scenario would be ten times as dangerous with the use of persistent connections, since there's a pool of open connections that any script/request/process can use. Again, my understanding was that this was handled automatically, and that the same connection couldn't be used by more than one client at the same time. Am I mistaken in this point as well?
Their benefit is on a "different level" that has nothing to do with global var vs singleton. If you are using transactions with pconnects there are some caveats (due to side-effects), which are explained in the above link.In fact, to be extremely clear about the subject, persistent connections don't give you any functionality that wasn't possible with their non-persistent brothers.
But a static class may have static properties, which means it can hold a state.Originally Posted by kyberfabrikken
Basically, a class that has only static members represents an application wide single object instance. The only difference is that the singleton makes it impossible to spawn multiple instances via the "new Class()" mechanism. With singleton, you can even do this:
and still be using the same, unique instance.PHP Code:
$aVariable = new SingletonClass();
*sigh* I don't mean to be rude but that really doesn't say much, does it? Further, I don't think it fairly characterizes my comments. Remember, I'm not arguing against OOP or OOP patterns nor am I trying to suggest that there is a one-size-fits-all coding style. My opinion is that in this specific case, a singleton, while it will do the job, is not as straight-forward as a static class. Looking back at my post I realize that I could and should have expressed my premise in a less confrontational style. For that, I apologize.Originally Posted by kyberfabrikken
Nothing prevents even a PHP4 static class from implementing private data in static function vars. It is much simpler with PHP5 since it does indeed support static class members. Again, I'm not arguing against singleton's in-general--I'm musing as to the benefit of them in this case. In my experience, singleton usage often occurs as a by-product of the fact that the language being used does not support non OOP styles. This is not the case for PHP. Still, I don't mean to be argumentative -- I have had my say so I will be good and be quite now.Originally Posted by kyberfabrikken
I heard recently of someone who defined a constant with the database handle resource to provide global access through the application. Seems like this would work as long as you wanted to use the native API calls.
The main benefit to using a Singleton pattern is guaranteeing the setup is done correctly on your single connection object instance. That said, if you don't really want an object, it may not be the way to go. Also, Singletons are effectivly stealth global variables, and can introduce testing headaches if you want to replace your connection object with a MockObject version during testing.
The idea behind the Singleton is not about the scope of the instance, but the scope of the class. It is true that Singletons are by default global, but the pattern was introduced to be used when you need to ensure that a class may at any time have no more instances than one.Originally Posted by sweatje
Database connection is not necessarily the best candidate for singleton, because we may imagine a scenario where an application might have several database connections open at the same time (even in PHP, if we pulled the data from several db's, but especially in memory-resident applications) -- they can be singletons (but only if they belong to different classes), statics, globals, passed around as references or even instantiated anew on each call. A better example might be a HTTPRequest class representing the incoming request in a Web application: for each request -- which in PHP means for each run of the application -- there should be only a single request shared among all other classes.