I have a few functions in PHP that read data from functions in a class
readUsername(int userId){
$reader = getReader();
return $reader->getname(userId);
}
readUserAddress(){
$reader = getReader();
return $reader->getaddress(userId);
}
All these make a call to
getReader()
{
require_once("Reader.php");
static $reader = new Reader();
return $reader;
}
An overview of Reader
class Reader{
getname(int id)
{
//if in-memory cache exists for this id return that
//else get from db and cache it
}
getaddress(int id)
{
$this->getname(int id);
//get address from name here
}
/*Other stuff*/
}
Why is class Reader needed The Reader class does some in-memory caching of user details. So, I need only one object of class Reader and it will cache the user details instead of making multiple db calls. I am using static so that it the object gets created only once. Is this the right approach or should I do something else?
3 Answers 3
static
keywords, represents that, the class methods or attribute can be accessed without having any object instantiated. Due to this reason, they exists separately to maintain their loosely coupled state.
The problem you are having can be solved, with an combination of factory and singleton pattern.
Your Reader class should be singleton, so that multiplexed instances of same class of same purpose will not be created.
For example:
class Reader {
private static $singletonObject = null;
function __construct() { }
public function static getInstance() {
if(!SELF::$singletonObject) { SELF::$singletonObject = new Reader(); }
return SELF::$singletonObject;
}
// Other
}
Now, whenever you are trying to access the Reader class,
$reader = Reader::getInstance();
Now, use $reader class as you need to. Now, you can create Factory and Singleton pattern to give you the instance of DB class and Cache Class.
Consider the Registry pattern, it provides a way of accessing global objects and avoids some drawbacks, that the Singleton has.
From your comment on the question:
Once the reader object is created it uses some in-memory caching. So if I call reader twice for getName and getAddress I will be doing many things twice.
Looks like Reader should be implemented roughly this way:
class Reader {
private $name;
public function getName() {
if (isset($this->name)) { return $this->name; }
$this->name = // Pull it from the database or wherever
return $this->name;
}
}
Usage is simple and straightforward, and getReader()
probably isn't even necessary anymore:
require_once("Reader.php");
getReader()
{
return new Reader();
}
-
how is getReader() not necessary?nischayn22– nischayn222012年05月31日 02:35:27 +00:00Commented May 31, 2012 at 2:35
-
@nischayn22 Well, look at the code there. The function is one single line. There isn't very much context for what
getReader()
is used for.Izkata– Izkata2012年05月31日 02:49:38 +00:00Commented May 31, 2012 at 2:49 -
say I use new Reader() for getName, and then again for getAddress() then I will be creating two objects. But getAddress() could simply use the $this->name set by getName initially if I had one object.nischayn22– nischayn222012年05月31日 03:06:14 +00:00Commented May 31, 2012 at 3:06
-
@nischayn22 Are
getAddress()
andgetName()
global functions or class functions?Izkata– Izkata2012年05月31日 03:25:54 +00:00Commented May 31, 2012 at 3:25 -
see my edit. Actually much more stuff is going on, so its difficult to explain no matter I tried my bestnischayn22– nischayn222012年05月31日 05:39:10 +00:00Commented May 31, 2012 at 5:39
Reader
is even necessary. DoesreadUsername()
just call$reader->getUsername()
, andgetUsername()
always returns the same value, or is something more going on?