Tracking an objects state - php

In PHP, what's the best way to track an objects state, to tell whether or not it has been modified? I have a repository object that creates new entities, they are then read/modified by other components and eventually given back to the repository. If the object has changed I want the repository to save the data back to the persistent storage (DB).
I can think of four options:
Use an internal boolean property called $_modified, which every setter updates when modifications are made (tedious if there are a lot of setters).
Some horrible ugly hack using serialize() and comparing the strings (I'm sure this is a very bad idea, but I thought I'd add it for completeness)
Something like the above but with a hash of the objects properties (not sure if it would work with objects that contain other objects)
Taking clones of the objects as they come out of the repo and comparing what comes in (more complicated than it sounds, because how do you know which clone to compare the object to?)
or...
Some other clever trick I'm not aware of?
Thanks,
Jack

Option 1 - using a boolean flag - is the best way. In terms of performance, as well as general usability and portability.
All the other options incur excessive overhead which is simply not needed in this case.

You might want to look into the Unit of Work pattern, as this is much the problem which it is designed to tackle. As objects are changed, they register themselves, or are passively registered, with the UoW, which is responsible for keeping track of which objects have been changed, and for figuring out what needs to be saved back to the database at the end of play.

First, I generally think a $modified or $dirty property is the best solution here.
But the reason I'm writing was your comment that it would be
tedious if there are a lot of setters
I'm wondering if you're not using PHP5?
If you are, this is a perfect use of the __set() magic method. You could even use it as-is, calling your existing setters from the __set() method.
For example:
class some_concept
{
private $x = 1;
private $y = 2;
private $dirty = false;
// This represents your existing setter methods
function set_y($i)
{
$this->y = $i;
}
function __set($name, $value)
{
if ($value != $this->{$name}) $this->dirty = true;
return $this->{'set_' . $name}($value);
}
function __get($name)
{
return $this->{$name};
}
}
However, there is some merit to your idea of comparing serialized strings. Serialization can be expensive. It's true.
But it is the most accurate solution on your list. Imagine loading the object above, setting $y to 0, then setting it back to 2, then saving. Is it dirty? It will say so, but in reality, it's in the same state it was when it was loaded.
The test I would use here is how expensive is your save(). If saving is a very expensive API call, DB transaction, etc, then you might find that it's worth the expense to serialize the object on-load and save an md5 hash of it.
If that op, which will take a fraction of a second, can save a multi-second transaction, then it could really be worth it.
Finally, I want to point out a contrarian opinion on this subject from Damien Katz. Katz is a talented developer who created CouchDb, and currently works for MySQL.
His Error Codes v Exceptions post is long but a very good read on this topic.
While it begins talking about the merits of returning an Error Code of throwing an Exception, he really ends up talking about how to write solid software.
Primarily, he talks about how to create classes that are atomic in the same way that SQL Transactions are. The general idea being that you make a copy of an object, modify it its state, and, only on the last step, if successful, do you swap that copy out for the primary object. That allows meaningful undo features. A pattern like this, while difficult to shim into an existing app, also provides a solution to this is_modified problem.

I think the first option is the best for more readable code and faster execution. I would also consider serializing the objects first(say to file) and then hashing the contents.
The same contents should produce the same hash value.

Related

How to handle passing data around internally within the app, in an PHP application?

So if I need to pass data around the application internally is there nice predictable way to pass it around.
I want to be able to look at a function and know whats in the collection that is getting passed into the function.
An array is an unpredictable data structure, so you never know what you're getting.
I feel like it's better to have an object defined with named properties and pass that around the application instead of an array, because that way theres SOME sort of a definition available.
The issue with that is that there will just be an bunch of objects accumulating in some folder somewhere.
Was wondering anyone's opinion on this, and any other alternatives?
You might be having a larger (although - hidden) problem. A structure in your code should not cross more than one layer boundary.
If some structure (doesn't matter whether it is an array or an object) is crossing two layers, then, unless it is an intentional compromise, it is a sign, that there might be "architectural flaws" indicating fragility of your codebase. Such cross-cutting data structures become the fault-lines across witch your codebase exhibits none-trivial bugs.
If your have structures, that cross 3 or more layer boundaries, your codebase is fucked. It becomes one of those "kill it with fire, before it lays eggs" projects.
The solution that I use is this:
Instead of having dedicated "data structures" being passed around, focus your business logic around domain objects. You create it at some point in the layer, where you will be actually using it logic-related behaviour and inject it or return it to other layer only to affect it.
Kinda like this:
public function loginWithPassword(Entity\EmailIdentity $identity, string $password): Entity\CookieIdentity
{
if ($identity->matchPassword($password) === false) {
throw new PasswordMismatch;
}
$identity->setPassword($password);
$this->updateEmailIdentityOnUse($identity);
$cookie = $this->createCookieIdentity($identity);
return $cookie;
}
What is being passed in an out of this method is not some "data structure", but a fully formed logical entity, which contains specific, business-relate behaviour.

What is faster: an index-array or getters and variables? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 6 years ago.
Improve this question
I am trying to figure out what should be considered better for performance:
I have a bunch of objects that contain a lot of page-data.
A few examples of the data that an object can have:
filepath of PHP-file for includes
CSS filepath
JavaScript filepath
Meta data of the page
The object is specific for each type of content. I have an interface that defines the render-function. Each object implements this function differently.
Example:
class PhpFragment extends FragmentBase {
public function render() {
//... render output for this type of data
}
}
I am currently using a parent-object that contains variables that can contain multiple object of the type mentioned above. The object looks something like this:
class pageData {
protected $CSS;
protected $PHP;
protected $JS;
protected $Meta;
protected etc...
public function getCSS() {
return $this->CSS;
}
public function getPHP() {
return $this->PHP;
}
public function getJS() {
return $this->JS;
}
}
Whenever I load in a page, I walk through a template and render the data of each object that matches the tag in the template.
For example: If a template has a line where CSS is needed, I call the getCSS function of the pageData which returns an array of objects. Foreach of these objects I call the render function and add the data in the page.
What do I want?
I want to get rid of these fixed variables in the pageData object to be able to use my design as dynamically as possible. I want the pageData object to disappear and just have an array of different fragment-objects.
To achieve this, I need to replace the get-functions in the pageData with something clever?
My top priority is performance, so I thought I'd look through all the objects once to get all the different types, and put all the types as key in the array, the value of the array will then be a subarray that contains the correct key to the objects that match the type.
What I was wondering, before I start changing the design entirely, is this faster?
I don't know if this is the right place to ask this question (it's more a code-review question IMO). Anyway, here's a couple of thoughts I'd consider if I were you:
What are objects
Objects are units of functionality, or entities that represent a specific set of values. DTO's (like your pageData class) serves one purpouse: to group, and represent a set of values that belong together. The fact that a class has a type (type-hints) and an interface makes a code-base testable, easier to understand, maintain, debug, and document.
At first glance, a simple DTO isn't too different from a simple array, and yes, objects have a marginal performance cost.
The question you need to ask is whether or not you want to shave of those 1 or 2 ms per request at the cost of: increased development time, less testable, more error prone, and harder to maintain code. I'd argue that for this reason alone, DTO's make more sense than arrays
pre-declared properties are fast
If you want an object that is as dynamic as possible, then PHP offers you to possibility to add properties to instances on the fly:
Class Foo{}
$x = new Foo;
$x->bar = 'new property';
echo $x->bar;//echoes new property
So in essence, objects are just as flexible as arrays. However, properties that weren't declared beforehand are (again marginally) slower than predeclared properties.
When a class definition declares 3 properties, these properties are stored in a hash table. When accessing a member of an instance, this hashtable will be checked first. Internally, these hashtable lookups are O(1), If no properties were declared, any "dynamic" property is stored in a second hash table. Lookups on this fallback HT are O(n). Not terrible, but worse than they need be.
In addition to dynamic properties being less performant, they're also always public, so you have no control over their values (they can be reassigned elsewhere), and they are, of course, susceptible to human error (typo's):
$x = new Foo;
$x->foo = 'Set the value of foo';
echo $x->fo;//typo...
Getters and setters are good
The methods you have now don't do anything, true enough, but consider this:
class User
{
protected $email;
public function setEmail($email)
{
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
throw new \InvalidArgumentException('Invalid email');
}
$this->email = $email;
return $this;
}
}
A setter like this not only allows me to control/check when and where a property is set, but also to validate the data that someone is trying to assign to it. You can validate the data. You can ensure that, no matter what, if you receive an instance of User, the email will either be null, or a valid email address.
There are many more reasons why objects make more sense than arrays, but these alone, to me at least, outweigh the benefits of 2ms/req performance gain.
If performance is such an issue, why not write in a faster language?
If all you're after is performance, you might want to look into languages that outperform PHP to begin with. Don't get me wrong: I honestly like PHP, but it's just a fact that, for example, Go can do the same thing, only faster.
Pass by value, copy-on-write, and (almost) pass by reference
Arrays are, essentially, scalar values. Pass an array to a function, and any changes made to that array inside the function doesn't change the array you passed to that method. Objects are (sort-of) passed by reference. That's to say: objects are passed by identifier.
Say you have an instance of Foo. The Zend engine will assign a unique ID to that instance (eg 123). When you call a function and pass that instance, internally, you'll pass the identifier of that object to the method not the object itself.
This has several implications: When changing the state of the instance, PHP doesn't have to make a copy of the object: it just uses the ID to get the zval (internal representation of a PHP variable), and operates on the same piece of memory. The net result: you're passing a simple value (an int), and whatever happens to the object, wherever it happens, the state is shared throughout.
Arrays are different: Passing an array is (sort-of) passing a copy of that value. In reality, PHP is clever enough to pass a reference to the existing array, but once you start reassigning values, PHP does have to create a copy. This is the copy-on-write mechanism. Put simply, the idea is: do not create needless copies of values, unless you have to:
function foo(array $data)
{
$x = $data[0];//read, no copy of argument is required
$data[1] = $x * $data[3];//now, we're altering the argument, a copy is created
}
$data = [1, 2, 3, 4];
foo($data);//passes reference
Depending on how you use the arrays or objects you pass to functions, one might perform better than the other. On the whole: passing an array that you'll only use to read values will most likely outperform passing an object. However, if you start operating on the array/object, an object might turn out to outperform arrays...
TL;DR
Yes, arrays are generally faster than objects. But they're less safe, pretty much impossible to test, harder to maintain an non-communicative (public function doStuff(array $data) doesn't tell me as much as public function doStuff(User $data)).
Owing to the copy-on-write and the way instances are passed to functions, it's impossible to say which will be faster with absolute certainty. It really boils down to what you do: is the array fairly small, and are you only reading its values, then it's probably going to be faster than objects.
The moment you start operating on the data, it's entirely possible objects might prove to be faster.
I can't just leave it there without at least mentioning that old mantra:
Premature optimization is the root of all evil
Switching from objects to arrays for performance sake does smell of micro-optimization. If you have in fact reached the point that there's nothing else to optimize but these kinds of trivial things, then the project is either a small one; or you're the first person to actually work on a big project and actually finish it. In all other cases, you shouldn't really be wasting time on this kind of optimization.
Things that are far more important to profile, and then optimize are:
Caching (opcache, memcache, ...)
Disk IO (including files, autoloader mechanisms)
Resource management: open file pointers, DB connections (when to connect, when to close connections)
If you're using a traditional SQL DB: queries... The vast majority of PHP applications can benefit a lot by having a DBA look at the queries and actually optimize those
Server setup
...
Only if you've gone through this list, and more, could you perhaps consider thinking about some micro optimization. That is of course, if by then you haven't encountered any bugs...

How can I ensure that an object only belongs to one collection, while maintaining the DRY principle?

I'm trying to solve a problem in my PHP code, but this is also something I've been unable to solve in other code as well.
I have an object that must belong to one and only one collection. And I will primarily be accessing these objects from the perspective of the collection. Other code wouldn't be expected to find the Object without going through the Collection.
So, how I've handled this in the past would be to give the Object a reference to the Collection. In this way, we attempt satisfy that the Object can only belong to one Collection. Then I would add the Object to the Collection.
public function __construct(Collection $c)
{
$this->setCollection($c);
}
public setCollection(Collection $c)
{
$this->collection = $c;
$c->addObject($this);
}
This is an obvious contradiction to "Don't Repeat Yourself". And comes about because the requirements of, needing easy access to the collection of objects and requiring objects only belong in one collection, are at odds with each other. The Object knows it's in the Collection and the Collection knows the Object is in it the collection. If either gets out of sync the system is broken.
And the problems become obvious when you start trying to make code to move an object from one collection to another. Or when deleting an object.
So, has anyone found a solution to this kind of problem? Is there something I should try? In the end I can make it work with a lot of double checking, but it seems like there has to be a better way.
I'm not sure I follow your line of reasoning to the end game of 'double checking'... but what's wrong with code like this?
class Collection {
public function AddMember(Member $m) {
$m->SetCollection($this);
// add to underlying data structure
}
public function RemoveMember(Member $m) {
// remove from underlying data structure
}
}
class Member {
private $collection = null;
public function SetCollection(Collection $c) {
if($this->collection)
$this->collection->RemoveMember($this);
$this->collection = $c;
}
public __destruct() {
if($this->collection)
$this->collection->RemoveMember($this);
}
}
Syntax is probably off, treat it as psuedo-code, not tested, use references where needed, other disclaimers etc.
This is a great design pattern where friend classes/methods would be useful for proper encapsulation, to prevent anyone other than a collection object from setting or removing a member from its collection. You will also want to think long and hard about which methods you want to be used as the entry points and do the right thing in those cases without falling into a recursion loop. For a framework/library class like this, unit tests will make your life much easier.
Yeah, I can see where you may be worried about having to do an if check before basically doing anything with adding, removing or destroying. But that's the nature of a smart & safe pointer/reference pattern. The DRY principle isn't so much about avoiding redundancy of safety checks as it is about avoiding having multiple copies of data or redundant implementations of algorithms. Yes, each of those methods in my pseudo code is technically an algorithm, but here's a few things to chew on (okay, they're really the same-ish thing, stated from different perspectives):
They run in constant time (provided you avoid the recursion pitfalls I mentioned).
Seriously: shortest algorithm ever.
If you're worried about optimizing out half of your if statements in a library, you're missing the forest for the (a single) tree. Optimization time is better spent on making the code easier to use, easier to maintain, and reducing the complexity of algorithms. It doesn't get any less complex than a constant time algorithm.
You're not going to peg your processor by doing an extra if statement on every add or remove. You peg your processor by running an O(n^2) algorithm on a large n.
To sum up, no there really isn't a better way to implement a safe, doubly-linked data structure. You have to check the safety on each link and that's the the way it's going to be.

Is there a use-case for singletons with database access in PHP?

I access my MySQL database via PDO. I'm setting up access to the database, and my first attempt was to use the following:
The first thing I thought of is global:
$db = new PDO('mysql:host=127.0.0.1;dbname=toto', 'root', 'pwd');
function some_function() {
global $db;
$db->query('...');
}
This is considered a bad practice. After a little search, I ended up with the Singleton pattern, which
"applies to situations in which there needs to be a single instance of a class."
According to the example in the manual, we should do this:
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();
Why do I need that relatively large class when I can do this?
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();
This last one works perfectly and I don't need to worry about $db anymore.
How can I create a smaller singleton class, or is there a use-case for singletons that I'm missing in PHP?
Singletons have very little - if not to say no - use in PHP.
In languages where objects live in shared memory, Singletons can be used to keep memory usage low. Instead of creating two objects, you reference an existing instance from the globally shared application memory. In PHP there is no such application memory. A Singleton created in one Request lives for exactly that request. A Singleton created in another Request done at the same time is still a completely different instance. Thus, one of the two main purposes of a Singleton is not applicable here.
In addition, many of the objects that can conceptually exist only once in your application do not necessarily require a language mechanism to enforce this. If you need only one instance, then don't instantiate another. It's only when you may have no other instance, e.g. when kittens die when you create a second instance, that you might have a valid Use Case for a Singleton.
The other purpose would be to have a global access point to an instance within the same Request. While this might sound desirable, it really isnt, because it creates coupling to the global scope (like any globals and statics). This makes Unit-Testing harder and your application in general less maintainable. There is ways to mitigate this, but in general, if you need to have the same instance in many classes, use Dependency Injection.
See my slides for Singletons in PHP - Why they are bad and how you can eliminate them from your applications for additional information.
Even Erich Gamma, one of the Singleton pattern's inventors, doubts this pattern nowadays:
"I'm in favor of dropping Singleton. Its use is almost always a design smell"
Further reading
How is testing the registry pattern or singleton hard in PHP?
What are the disadvantages of using a PHP database class as a singleton?
Database abstraction class design using PHP PDO
Would singleton be a good design pattern for a microblogging site?
Modifying a class to encapsulate instead of inherit
How to access an object from another class?
Why Singletons have no use in PHP
The Clean Code Talks - Singletons and Global State
If, after the above, you still need help deciding:
Okay, I wondered over that one for a while when I first started my career. Implemented it different ways and came up with two reasons to choose not to use static classes, but they are pretty big ones.
One is that you will find that very often something that you are absolutely sure that you'll never have more than one instance of, you eventually have a second. You may end up with a second monitor, a second database, a second server--whatever.
When this happens, if you have used a static class you're in for a much worse refactor than if you had used a singleton. A singleton is an iffy pattern in itself, but it converts fairly easily to an intelligent factory pattern--can even be converted to use dependency injection without too much trouble. For instance, if your singleton is gotten through getInstance(), you can pretty easily change that to getInstance(databaseName) and allow for multiple databases--no other code changes.
The second issue is testing (And honestly, this is the same as the first issue). Sometimes you want to replace your database with a mock database. In effect this is a second instance of the database object. This is much harder to do with static classes than it is with a singleton, you only have to mock out the getInstance() method, not every single method in a static class (which in some languages can be very difficult).
It really comes down to habits--and when people say "Globals" are bad, they have very good reasons to say so, but it may not always be obvious until you've hit the problem yourself.
The best thing you can do is ask (like you did) then make a choice and observe the ramifications of your decision. Having the knowledge to interpret your code's evolution over time is much more important than doing it right in the first place.
Who needs singletons in PHP?
Notice that almost all of the objections to singletons come from technical standpoints - but they are also VERY limited in their scope. Especially for PHP. First, I will list some of the reasons for using singletons, and then I will analyze the objections to usage of singletons. First, people who need them:
- People who are coding a large framework/codebase, which will be used in many different environments, will have to work with previously existing, different frameworks/codebases, with the necessity of implementing many different, changing, even whimsical requests from clients/bosses/management/unit leaders do.
See, the singleton pattern is self inclusive. When done, a singleton class is rigid across any code you include it in, and it acts exactly like how you created its methods and variables. And it is always the same object in a given request. Since it cannot be created twice to be two different objects, you know what a singleton object is at any given point in a code - even if the singleton is inserted to two, three different, old, even spaghetti codebases. Therefore, it makes it easier in terms of development purposes - even if there are many people working in that project, when you see a singleton being initialized in one point in any given codebase, you know what it is, what it does, how it does, and the state it is in. If it was the traditional class, you would need to keep track of where was that object first created, what methods were invoked in it until that point in the code, and its particular state. But, drop a singleton there, and if you dropped proper debugging and information methods and tracking into the singleton while coding it, you know exactly what it is. So therefore, it makes it easier for people who have to work with differing codebases, with the necessity of integrating code which was done earlier with different philosophies, or done by people who you have no contact with. (that is, vendor-project-company-whatever is there no more, no support nothing).
- People who need to work with third-party APIs, services and websites.
If you look closer, this is not too different than the earlier case - third-party APIs, services, websites, are just like external, isolated codebases over which you have NO control. Anything can happen. So, with a singleton session/user class, you can manage ANY kind of session/authorization implementation from third-party providers like OpenID, Facebook, Twitter and many more - and you can do these ALL at the same time from the SAME singleton object - which is easily accessible, in a known state at any given point in whatever code you plug it into. You can even create multiple sessions to multiple different, third-party APIs/services for the SAME user in your own website/application, and do whatever you want to do with them.
Of course, all of this also can be tone with traditional methods by using normal classes and objects - the catch here is, singleton is tidier, neater and therefore because of that manageable/testable easier compared to traditional class/object usage in such situations.
- People who need to do rapid development
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.
You get the idea. Now lets move on to the objections to singletons and
the unholy crusade against something that is useful:
- Foremost objection is that it makes testing harder.
And really, it does to some extent, even if it can be easily mitigated by taking proper precautions and coding debugging routines into your singletons WITH the realization that you will be debugging a singleton. But see, this isnt too different than ANY other coding philosophy/method/pattern that is out there - it's just that, singletons are relatively new and not widespread, so the current testing methods are ending up comparably incompatible with them. But that is not different in any aspect of programming languages - different styles require different approaches.
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.
Though it is understandable - programmers work in very different circumstances depending on their career. And for people who work in relatively big companies with defined departments tending different, defined software/applications in a comfortable fashion and without the impending doom of budget cuts/layoffs and the accompanying need to do a LOT of stuff with a lot of different stuff in a cheap/fast/reliable fashion, singletons may not seem so necessary. And it may even be nuisance/impediment to what they ALREADY have.
But for those who needs to work in the dirty trenches of 'agile' development, having to implement many different requests (sometimes unreasonable) from their client/manager/project, singletons are a saving grace due to reasons explained earlier.
- Another objection is that its memory footprint is higher
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.
You are not missing anything, as far as I can see. The example is pretty flawed.
It would make difference, if the singleton class had some non-static instance variables.

PHP coding standards at work: Insane, or am I?

I prefer coding standards to be logical. This is my argument for why the following set of standards are not.
I need to know one of two things: (1) why I'm wrong, or (2) how to convince my team to change them.
camelCase: Functions, class names, methods, and variables must be camelCase.
Makes it hard to differentiate between variables and classes
Goes against PHP's lowercase/underscored variables/functions and UpperCamelCase classes
Example:
$customerServiceBillingInstance = new customerServiceBillingInstance(); // theirs
$customer_service_billing_instance = new CustomerServiceBillingInstance();
Functions/methods must always return a value (and returned values must always be stored).
This appears on hundreds of our php pages:
$equipmentList = new equipmentList();
$success = $equipmentList->loadFromDatabase(true, '');
$success = $equipmentList->setCustomerList();
$success = $equipmentList->setServerList();
$success = $equipmentList->setObjectList();
$success = $equipmentList->setOwnerList();
$success = $equipmentList->setAccessList();
The return value is rarely used but always stored. It encourages the use of copy-and-paste.
No static methods
Lines like the following appear thousands of times in the codebase:
$equipmentList = new equipmentList();
$success = $equipmentList->loadFromDatabase();
I would prefer:
$equipmentList = equipmentList::load();
What reason is there to not use static methods or properties? Aren't static methods responsible for non-instance-specific logic? Like initializing or populating a new instance?
Your code is not OOP unless everything returns an object
There's a piece of code that performs a query, checks it several ways for errors, and then processes the resulting array. It is repeated (copied+pasted) several times, so I put it in the base class. Then I was told returning an array is not OOP.
How do you defend these practices? I really do need to know. I feel like I'm taking crazy pills.
If you can't defend them, how do you convince the adamant author they need to be changed?
I would suggest trying to list down the goals of your coding standards, and weigh them down depending on which goals is the most important and which goals are less important.
PS: I don't speak PHP, so some of these arguments may contain blatantly incorrect PHP code.
camelCase: Functions, class names, methods, and variables must be camelCase.
Workplace's Apparent Reason: "consistency" at the cost of "information density in name".
Argument:
1) Since 'new' keyword should always be followed by a class, then you can easily spot illegal instantiation, e.g.:
$value = new functionName();
$value = new local_variable();
$value = new GLOBAL_VARIABLE();
would raise an alarm, because 'new' should be followed by a TitleCase name.
$value = new MyClass(); // correct
Relying on Case makes it easy to spot these errors.
3) Only functions can be called, you can never call variables. By relying on Case Rule, then we can easily spot fishy function calls like:
$value = $inst->ClassName();
$value = $inst->instance_variable();
$value = $GLOBAL_VARIABLE();
3) Assigning to a function name and global variables is a huge deal, since they often lead to behavior that is difficult to follow. That's why any statement that looks like:
$GLOBAL = $value;
$someFunction = $anotherFunction;
should be heavily scrutinized. Using Case Rule, it is easy to spot these potential problem lines.
While the exact Case Rule may vary, it is a good idea to have different Case Rule for each different type of names.
Functions/methods must always return a value (and returned values must always be stored).
Workplace's Apparent Reason: apparently another rule born out of blind consistency. The advantage is that every line of code that isn't a flow control (e.g. looping, conditionals) is an assignment.
Argument:
1) Mandatory assignment makes unnecessary long lines, which harms readability since it increases the amount of irrelevant information on screen.
2) Code is slightly slower as every function call will involve two unnecessary operation: value return and assignment.
Better Convention:
Learn from functional programming paradigm. Make a distinction between "subroutine" and "functions". A subroutine does all of its works by side-effect and does not return a value, and therefore its return value never need to be stored anywhere (subroutine should not return error code; use exception if it is really necessary). A function must not have any side-effect, and therefore its return value must be used immediately (either for further calculations or stored somewhere). By having side-effect free function policy, it is a waste of processor cycle to call a function and ignoring its return value; and the line can therefore be removed.
So, there is three type of correct calls:
mySubroutine(arg); // subroutine, no need to check return value
$v = myFunction(arg); // return value is stored
if (myFunction(arg)) { ... } // return value used immediately
you should never have, for example:
$v = mySubroutine(arg); // subroutine should never have a return value!
myFunction(arg); // there is no point calling side-effect free function and ignoring its return value
and they should raise warning. You can even create a naming rule to differentiate between subroutine and functions to make it even easier to spot these errors.
Specifically disallow having a "functiroutine" monster that have both a side-effect and return value.
No static methods
Workplace Apparent Reason: probably someone read somewhere that static is evil, and followed blindly without really doing any critical evaluation of its advantages and disadvantages
Better Convention:
Static methods should be stateless (no modifying global state). Static methods should be a function, not subroutine since it is easier to test a side-effect-free function than to test the side-effects of a subroutine. Static method should be small (~4 lines max) and should be self-contained (i.e. should not call too many other static methods too deeply). Most static methods should live in the Utility class; notable exceptions to this is Class Factories. Exceptions to this convention is allowed, but should be heavily scrutinized beforehand.
Your code is not OOP unless everything returns an object
Workplace Apparent Reason: flawed understanding of what is OOP.
Argument:
Fundamental datatypes is conceptually also an object even if a language's fundamental datatype doesn't inherit from their Object class.
If you can't defend them, how do you
convince the adamant author they need
to be changed?
By giving strong/valid arguments! Still I think you should only change them when your arguments are really strong! Because most of the programmers at work are used to these coding standards which is a big point why to use them.
==
Like others told before this is pretty subjective, but these are mine opinions/arguments.
1. camelCase: Functions, class names, methods, and variables must be camelCase.
I would use the PHP style if I code in PHP and the Camelcase style if I code in Java. But it does not matter which style you choose as long as you stay consistent.
2. Functions/methods must always return a value (and returned values must always be stored).
This is nonsense in my opinion. In almost all programming languages you have some sort of 'void' type. But from a testing point of view most of the times it is useful if your function are side effect free. I don't agree that your production code should always use the return value especially if it does not have any use.
3. No static methods
I would advice you to read static methods are death to testability from misko
During the instantiation I wire the
dependencies with mocks/friendlies
which replace the real dependencies.
With procedural programing there is
nothing to “wire” since there are no
objects, the code and data are
separate.
Although PHP is a dynamic language so it is not really a big problem. Still the latest PHP does support typing so that I still think most of times static methods are bad.
4. Your code is not OOP unless everything returns an object
I believe(not 100% sure) a truly OOP language should do this(return an object), but I don't agree with this like a of like languages like for example Java(which I believe is not trully OOP). A lot of the times your methods should just return primitives like String/Int/Array/etc. When you are copying and pasting a lot of code it should be a sign that something is not totally right with your design. You should refactor it(but first have a tests(TDD) ready so that you don't break any code).
Many of these coding standards are very subjective, but some important things to consider are:
Get a single set of code naming and style rules, and follow them. If you don't have already defined rules, make sure to get rules figured out. Then work at refactoring the code to follow them. This is an important step in order to make it easier for new developers to jump on board, and keep the coding consistent among developers.
It takes time and effort to change the coding standards your company puts in place. Any change to the rules means that the code really has to be gone through again to update everything to be consistent with the new standards.
Keeping the above in mind, and looking more along the lines of specific PHP coding standards. The first thing to look at is if your company uses any sort of framework, look at the coding standards for that framework as you may want to stick with those in order to stay consistent across all the code. I have listed links to a couple of the popular PHP frameworks below:
Zend Framework Naming Conventions and Zend Framework Code Style
Pear Code Standards
My personal preference in regards to your specific coding styles:
1. camelCase: Functions, class names, methods, and variables must be camelCase
Class names should be Pascal Case (Upper Camel Case).
So in your example:
class CustomerServiceBillingInstance
{
// Your class code here
}
Variables and functions I generally feel should be camel case.
So either one of these, depending on your preference in terms of underscores:
$customerServiceBillingInstance = whatever;
$customer_service_billing_instance = whatever;
2. Functions/methods must always return a value (and returned values must always be stored).
This one seems like extra code and like you could end up using extra resources. If a function doesn't need to return anything, don't return anything. Likewise, if you do not care about what a function returns, don't store it. There is no point in using the extra memory to store something you are never going to look at.
An interesting thing you may want to try on this one, is running some benchmarks. See if it takes extra time to return something and store it even though you are not looking at it.
3. Your code is not OOP unless everything returns an object
In this instance, I feel you have to draw the line somewhere. Performance wise, it is faster for you to do:
return false;
Than to do:
return new Boolean(false); // This would use up unnecessary resources but not add very much to readability or maintainability in my opinion.
Defending a coding standard
To defend a coding standard that you feel is right (or showing why another is not as good), you really are going to have to bring up one of two points.
Performance. If you can show that a particular coding standard is adversely affecting performance, you may want to consider switching.
Maintainability/Readability. Your code should be easy to read/understand.
The goal is to find the happy median between performance and the maintainability/readability. Sometimes it is an easy decision because the most maintainable option is also the best performing, other times there is a harder choice to be made.
Standards and conventions exist for many reasons, but most of these reasons boil down to "they make code easier to write and maintain." Instead of asking "is this the correct way to do X?" just cut right to the chase and ask if this criterion is met. The last point in particular is simply a matter of definition. OOP is a means, not an end.
Many of those are matters of taste. You can argue for or against camelCase all day.
However, the storing of return values that are never used is Wrong. There is no value to the code. The code is not executed. You might as well sprinkle $foo = 47 * 3; around the code.
Any code that is not doing something useful must be removed.
The bigger issue is, if you're working for a clueless manager, it may be time to move.
The one aspect of this that I don't see anybody else commenting on is the "2. Functions/methods must always return a value (and returned values must always be stored)."
If you're not using exceptions, then any function that can fail does have to return a value. The last clause is misworded; return values don't always need to be STORED, but they do always need to be CHECKED. Again, that's IF you're not using exceptions, which isn't common these days, but it's still worth mentioning.
As far as I know quite a few of the conventions you posted are encouraged by the Zend PHP Framework as well. You're not alone, I'm a Codeigniter user and my work is pretty big on using Zend Framework. These kind of naming conventions are absolutely ridiculous and I honestly can only see an advantage of using camelCase for variable names, not function names as it makes things confusing.
Read this: http://framework.zend.com/manual/en/coding-standard.naming-conventions.html
Do these coding conventions look familiar to you?

Categories