Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

OOP Best Practices (specifically PHP)

Tags:

oop

php

I've been developing in PHP for a while now but only recently made the switch over to an OOP approach.

One question that keeps cropping up for me is 'how far' to go with the OOP stuff, specifically in terms of execution speed and memory resources etc.

For example, let's say I have 2 objects, User and Listing

Listings are always linked to a individual user. UserId is a property of Listing so I know which user it relates to. Once in a while, within a Listing method I need to access a single property of the related User.

As far as I can see (please advise if not) I have 3 options for how to accomplish this.

  1. Create a new user object and access the relevent propery via $user -> theProperty

  2. Make the required property a local property of Listing and populate this when Listing is initialised (e.g. via a sql join)

  3. Query the database directly to retrieve the property of User required via the user ID

It seems to me that options 1 & 2 obide by OOP rules more stringently, but have performance hits due to initialising a whole object simply to retrieve 1 property. Option 3 would be the least memory intensive but sidesteps OOP altogether.

In addition, in terms of populating objects at creation, most of my objects get most of their properties populated via one 'fill' method shortly after being initialised (hence requiring only 1 DB query). Would this generally be considered best practise, or would it be more advisable to use individual methods to get these properties, populating as and when they are needed?

I realise there may not be "correct" answers to this, but could anyone give an advice on best ways to approach this situation?

Many thanks Nick

like image 961
Nick Avatar asked Jun 01 '11 07:06

Nick


People also ask

Is OOP in PHP good?

OOP is faster and easier to execute. OOP provides a clear structure for the programs. OOP helps to keep the PHP code DRY "Don't Repeat Yourself", and makes the code easier to maintain, modify and debug. OOP makes it possible to create full reusable applications with less code and shorter development time.

What are OOP principles PHP?

Object-oriented programming in PHP helps developers build reusable and complex web applications. Object-oriented programming is a programming style that refers to the association of various components and revolves around the inheritance, polymorphism, encapsulation, and abstraction concepts.

Why PHP is not fully OOP?

Multiple inheritance is still not there in PHP So it not fully Object Oriented. If the basic language semantics allow for both paradigms, then it's commonly classified as an hybrid language. @Shakti Singh. Multiple inheritance is not a basic concept of OO.


2 Answers

I definitely prefer option 1. Option 2 does not follow the idea behind OOP because user information is not part of your listing, so keep it in a separate object.

Keep the following rules in mind:

  1. Load an object without its relationships at once.
  2. If you need a related object load it at the time you need it according to rule 1

Many ORMs work this way, for example Doctrine ( http://www.doctrine-project.org ). It's called lazy loading.

When you need one property of an object you will find yourself loading a second property of that same object some lines further. In many cases you will find yourself doing numerous database queries within a complete script for just one object.

like image 99
Rene Terstegen Avatar answered Oct 01 '22 13:10

Rene Terstegen


Option 1 is the prefered OOP way.

Alternatively, in php you could write a wrapper object which only contains the user_id and the properties you need.

And when a method is called or a other property is accessed you can load and initiate a real user object.

This can be achieved which the __get(), __set() and __call() methods.

That way you can optimize the query and memory usage of the Listing object while having access to all the OOP goodness from the user object, when needed.

Code should look something along the lines of:

class LazyObject {

  private 
    $propertySubset = array(),
    $realObject;


 function __call($method, $args) {
    if ($this->realObject === null) {
      $this->initRealObject();
    }
    return call_user_func_array(array($this->realObject, $method), $args);
  }

  // __get, __set and initRealObject implementation goes here

}

Caveats

  • You can use references: myMethod(&$ref) and $shortcut = &$object->prop wont work
  • You'll need to manually check if you filled the wrapper with enough properties. Not enough properties will result in allot of queries and the wrapper only slows thins down.
  • Usage of interfaces (like ArrayAccess) won't work unless you implement them in the lazyObject

PS.
This should be considered an optimalisation hack. So implement this only if the performance is becoming an issue;

like image 39
Bob Fanger Avatar answered Oct 01 '22 11:10

Bob Fanger