Sharing objects between multiple classes using base class - php

This article is similar to my needs, but I'm more curious about a specific solution to it, and if it's a good or bad idea to do it. Sharing objects between PHP classes
Say, like in the link above, I have an object I want to pass to multiple classes, say a $db object.
Instead of using dependency injection and passing it to each method's constructor, is it ever a good idea to let all the classes extend a Base class, that stores the $db object as a property?
For example:
abstract class Base {
protected static $_db;
public function setDatabase( Database $db ) {
$this->_db = $db;
}
public function getDatabase() {
return $this->_db;
}
}
class SomeClass extends Base {
public function doStuff() {
$result = $this->getDatabase()->query(.....);
}
}
Which would mean all classes that extend Base need not worry about grabbing/checking/setting the $db themselves, as they'd already have that object as a property as soon as the class is defined.
I know dependency injection is the usual way to go, but is this ever a viable solution?
Thanks!

You still have to set the db on each instance of the class - setting it on one instance doesnt set it on all instances... unless of course its a static property.

That is perfectly fine. I have used it before and never ran into any issues.

Related

Is it bad practice to instantiate classes inside of functions PHP

I'm in the process of re factoring a lot of code to make it more testable and I have a bunch of useful functions that rely on an instantiated database object.
Things like this:
function id_from_name($table, $name)
{
$db = get_database();
//code that returns an id
}
function username_from_user_id($id)
{
$db = get_database();
//code that returns a username
}
There are a bunch more like id_exists, id_active etc.
Now I'm thinking that this isn't the right thing to do as the object should probably be passed through as an argument? But then that means creating and sending in a new object into each of these functions every time i want to use one.
So really, my questions are: Should I be moving these functions into their own class/library that has access to the database object? and are the examples that I've shown above generally a bad way of doing things?
A better approach would be indeed to make classes. And you would be passing the database object to the constructor and make it an instance variable. That way every function would have access to the database object.
Now the reason why it is considered bad to instantiate e.g. your database object in every function, is because if you decide for example one day to change your datasource, you might need a huge refactor. If you pass your database object into the constructor, you can just pass/inject the right object into the class without any refactor.
...a bit more about DI below...
By passing your objects into the constructors, you also create a more clear API => you know which object depends on the other, you know exactly which class uses your DB object. If you start instantiating it or accessing it in a static way inside the functions like you did, I would have to look through all your classes to see where your DB object is used. One more point, dependency injection forces SRP (single responsibility principle) => if you start injecting too many objects (constructor gets many arguments), you should suspect your class is doing too much than what it should, and start refactoring.
You can create a class Table_Adapter and instantiate database object inside its constructor:
class Table_Adapter
{
protected $db;
public function __construct()
{
$db = get_database();
}
}
Then you create a child class Items_Table_Adapter' that extendsTable_Adapterand put their all methods related toItems` table.
class Items_Table_Adapter extends Table_Adapter
{
public function item_by_id($id)
{
}
}
Then you use it like:
$tableAdapter = new Items_Table_Adapter();
$item = $tableAdapter->item_by_id(1);
Try something like:
class YourClass{
public static function get_database(){
// your creation
return $db;
}
public function id_from_name($table, $name)
{
/* your code */
//code that returns an id
}
public function username_from_user_id($id)
{
/* your code */
}
}
so you could just use it this way:
$db = YourClass::get_database();
$result = $db->id_from_name($table, $name);
It is certainly recommended that you have the option to swap out your database connection.
Now, if your function get_database() looks like this:
function get_database() {
static $db;
if (!$db)
$db = new \mysqli(...);
return $db;
}
Then you really, really should change it to a wrapper around a class, looking like this:
function get_database_manager() {
static $dbmgr;
if (!$dbmgr)
$dbmgr = new DbManager;
return $dbmgr;
}
function get_database() {
return get_database_manager()->getCurrentConnection();
}
where DbManager has an instance attribute with the current connection that is returned with getCurrentConnection(). If you want to swapt out the connection, do something like get_database_manager()->setConnection($newConn). Problem solved :)
I'll leave the downsides of static programming here (it remains with many examples in this thread): http://kunststube.net/static/
as well as the common method to get rid of that (we have another approach here): http://en.wikipedia.org/wiki/Dependency_injection

how to call parent constructor just once in all child instances in php

I am trying to develop an object oriented PHP application in which whole php application will be extending from MyApplicationBase base class. But the problems is I want to create only single instance of MyApplicationBase. Below is the code which explains what I mean
class MyApplicationBase{
static $called=0;
public var $db;
function __construct()
{
self::$called++;
echo "<pre>MyApplicationBase Created ".self::$called." times</pre>";
$this->db=new DatabaseWrapper();
}
}
class ApplicationSecurity extends MyApplicationBase{
function is_logged_in()
{
$res=$this->db->query("user check db query goes here");
return ($res)?true:false;
}
//..... other methods related to ApplicationSecurity class
}
class ApplicationBusinessLogic extends MyApplicationBase{
// business logic methods here which may use base class vars like $db
// this may also use instance of ApplicationSecurity class
}
class ApplicationTemplating extends MyApplicationBase{
protected function outputHeader()
{
require_once('path/to/themes/header.php');
}
protected function outputSidebar()
{
require_once('path/to/themes/siderbar.php');
}
protected function outputMainbody()
{
require_once('path/to/themes/mainbody.php');
$app=new ApplicationBusinessLogic();
$app->initiate();
}
protected function outputFooter()
{
require_once('path/to/themes/footer.php');
}
public function outputTemplate()
{
$this->outputHeader();
$this->outputSidebar();
$this->outputMainbody();
$this->outputFooter();
}
}
//index.php file code starts here--------
$myPhpApplication = new ApplicationTemplating();
$myPhpApplication->outputTemplate();
My goal is when I create instance of my application then It only call the single instance of "MyApplicationBase" class instead of calling it multiple times. Please do tell me how can I achieve this. I am google for 5 hours but unable to find any solution yet.
I am trying to develop an object oriented PHP application in which whole php application will be extending from MyApplicationBase base class.
As PHP has single inheritance, this is by far the most worst idea to do object oriented PHP programming.
But the problems is I want to create only single instance of MyApplicationBase.
As every class is a MyApplicationBase you actually don't want that because it would mean you could instantiate exactly one class in your whole application.
What you're probably looking for is some kind of ApplicationClass which you pass along and of which just a single instance exists.
This would at least allow you in the future to throw such a "block in road" away more easily then if you would have got extended from there.
In any case you should program against an ApplicationInterface instead of an ApplicationClass to make this throwing away - as it will be necessary - easier.
The best thing for sure would be to not do anything in that direction and only write code you need in the first place.
To only write code you need, you need to develop test-driven. Why not start with that if you want to do object oriented programming?
Well I suppose that you want to avoid multiple connections to the database in this case. Solution is simple with Dependency injection, just initialize your database connection outside of MyApplicationBase class and then pass it as a constructor parameter (beware of constuctor hell though). Like this:
class MyApplicationBase{
static $called=0;
public $db;
function __construct($db)
{
self::$called++;
echo "<pre>MyApplicationBase Created ".self::$called." times</pre>";
$this->db= $d;
}
}
$db = new DatabaseWrapper();
$templating = new ApplicationTemplating($db);
$security = new ApplicationSecurity($db);
You could also take a look at some framework, they usually come with some dependency injection capabilities.

$this->class->function(): how does it work?

I've been programming in PHP for several years and I've only just recently begun to look at object oriented code. Now I understand classes and such:
class Myclass {
public function __construct() {
}
}
and all that good stuff... I also understand creating functions and calling in my index.php:
$someVar = new Myclass;
One thing I've been trying to understand, being that i've recently looked at codeigniter and I like one thing about it and want to try and accomplish the same thing without actually using codeigniter.
in code igniter they have the variable $this appear to be their class variable. But by using that, you're able to call from multiple classes all at once.. such as:
$this->load->module(); which is in one class file..
$this->db->query(); which is in another class file.
I've searched google for the last few days trying to figure out how to do this same thing where each class would have the correlation between them all allowing me to run $this->class_name->function_name in my projects instead of creating a new variable for each class or for the sake of a clean index file, having every function in a single class file.
Any information (aside from buy this book - as that isn't an option for me) is greatly appreciated and I will thank you now (and will probably thank you again later just for good measure).
I've been reading you and Phil's comments. First off, you can't use $this on index.php. $this can only be used in the context of an object. So you could do,
$someVar = new Myclass;
...
$someVar->db->something();
...instead.
I'm not entirely sure what you mean by "read classes," but you can assign members to MyClass exactly as Phil indicates:
class MyClass {
private $inj;
function __construct(Injected $inj) {
$this->injected = $inj;
}
}
Note that the private $inj declaration is not mandatory, but skipping it is dangerous. Any non-declared members added are automatically public, and this can potentially screw with you if you rely on magical get. I would declare the properties you need.
Finally, you either need to include all class definitions you will use, use a function like load_class(), or use autoloading. If Injected above is not a declared class, you will get an error when trying to create one. load_class() almost certainly includes the class definition somehow.
The load and db references are class properties which are themselves other objects with public module() and query() methods respectively. For example
class MyClass
{
/**
* #var CI_DB
*/
private $db;
/**
* #var Loader
*/
private $load;
public function __construct(CI_DB $db, Loader $load)
{
$this->db = $db;
$this->load = $load;
// PHP also allows you to add arbitrary object properties
// that receive a "public" visibility
// Please note, this is not a good practice
$this->foo = new Foo;
}
public function someMethod()
{
$this->load->module();
$this->db->query();
// You can also use foo even though it is not defined
// in the class properties
$this->foo->something();
}
}
See http://www.php.net/manual/en/language.oop5.properties.php
Adding the foo property like we did is dangerous. Because it receives the public visibility, it may be altered externally to the class.
$class = new MyClass($db, $load);
$class->foo = new Bar;
$class->someMethod(); // will break if Bar does not contain a something() method

Understanding PHP Inheritance

I understand the basic principles of inheritance in OOP, but I have a specific thing I am trying to do and want advice on how best to do it.
Lets say I have a core class:
class Core {
....
}
and I also have 2 or more other classes that extend this functionality
class MyClass1 extends Core {
....
}
class MyClass2 extends Core {
....
}
and I also have a database class in which I perform my queries, I want to pass an instantiated object of the database class (possibly by reference) to each one of my classes. One of the reasons for this would be to store a list or count of the queries that page as executed.
How should / can I go about this?
You could pass your instance of your database object to a constructor for your classes :
class Core
protected $db;
public function __construct(Your_Db_Class $database) {
$this->db = $database;
}
}
And, then, from your methods, work with $this->db, to access your database.
Of course, when instanciating your classes, you'll have to specify the database object :
// somewhere, instanciate your DB class
$db = new Your_Db_Class();
// And, then, when instanciating your objects :
$obj = new MyClass1($db);
Another way would be to use the Singleton design pattern, so there can be only one instance of your database class.
Probably a bit easier to setup ; but less easy to unit-test, after.
You could pass the database object as a parameter to the __construct function of your class, and then in said function assign the db object to member of the class, for instance $this->database_handler.
Another possibility is to work with a global variable that is your database object, but global variables are evil for many reasons, so let's disregard that.
Another note: By default, all objects are passed by reference, so you don't need to worry about that.

Static classes in PHP via abstract keyword?

According to the PHP manual, a class like this:
abstract class Example {}
cannot be instantiated. If I need a class without instance, e.g. for a registry pattern:
class Registry {}
// and later:
echo Registry::$someValue;
would it be considered good style to simply declare the class as abstract? If not, what are the advantages of hiding the constructor as protected method compared to an abstract class?
Rationale for asking: As far as I see it, it could a bit of feature abuse, since the manual refers to abstract classes more as like blueprints for later classes with instantiation possibility.
Update: First of all, thanks for all the answers! But many answers sound quite alike: 'You cannot instantiate an abstract class, but for a registry, why not using a singleton pattern?'
Unfortunately, that was more or less exactly a repeat of my question. What is the advantage of using a singleton pattern (a.k.a. hiding __construct()) compared to just declaring it abstract and not having to worry about that? (Like, e.g., it is a strong connotation between developers, that abstract classes are not actually used or so.)
If your class is not meant to define some super-type, it should not be declared as abstract, I'd say.
In your case, I would rather go with a class :
That defines __construct and __clone as private methods
so the class cannot be instanciated from outside
And, this way, your class could create an instance of itself
See the Singleton design pattern, about that, btw
Now, why use a Singleton, and not only static methods ? I suppose that, at least a couple of reasons can be valid :
Using a singleton means using an instance of the class ; makes it easier to transform a non-singleton class to a singleton one : only have to make __construct and __clone private, and add some getInstance method.
Using a singleton also means you have access to everything you can use with a normal instance : $this, properties, ...
Oh, a third one (not sure about that, but might have its importance) : with PHP < 5.3, you have less possibilities with static methods/data :
__callStatic has only been introduced in PHP 5.3
There is no __getStatic, __setStatic, ...
Same for a couple of other Magic methods !
Late Static Binding has only been added with PHP 5.3 ; and not having it often makes it harder, when working with static methods/classes ; especially when using inheritance.
This being said, yes, some code like this :
abstract class MyClass {
protected static $data;
public static function setA($a) {
self::$data['a'] = $a;
}
public static function getA() {
return self::$data['a'];
}
}
MyClass::setA(20);
var_dump(MyClass::getA());
Will work... But it doesn't feel quite natural... and this is a very simple example (see what I said earlier with Late Static Binding, and magic methods).
What you describe is permitted by the PHP language, but it's not the intended usage of an abstract class. I wouldn't use static methods of an abstract class.
Here's the downside of doing that: Another developer could extend your abstract class and then instantiate an object, which is what you want to avoid. Example:
class MyRegistry extends AbstractRegistry { }
$reg = new MyRegistry();
True, you only need to worry about this if you're handing off your abstract class to another developer who won't comply with your intended usage, but that's why you would make the class a singleton too. An uncooperative developer can override a private constructor:
class Registry
{
private function __construct() { }
}
class MyRegistry extends Registry
{
public function __construct() { } // change private to public
}
If you were using this class yourself, you would simply remember not to instantiate the class. Then you wouldn't need either mechanism to prevent it. So since you're designing this to be used by others, you need some way to prevent those people from circumventing your intended usage.
So I offer these two possible alternatives:
Stick with the singleton pattern and make sure the constructor is also final so no one can extend your class and change the constructor to non-private:
class Registry
{
private final function __construct() {
}
}
Make your Registry support both static and object usage:
class Registry
{
protected static $reg = null;
public static function getInstance() {
if (self::$reg === null) {
self::$reg = new Registry();
}
return self::$reg;
}
}
Then you can call Registry::getInstance() statically, or you can call new Registry() if you want an object instance.
Then you can do nifty things like store a new registry instance inside your global registry! :-)
I implemented this as part of Zend Framework, in Zend_Registry
As other guys said, you cannot instantiate an abstract class. You could use static methods in your class to prevent instantiating, but I'm not really a fan of doing so unless I have a proper reason.
I might be little bit off-topic now, but in your example you said you wanted this for Registry pattern class. What is the reason you don't want to instantiate it? Wouldn't it better to create an instance of Registry for each registry you want to use?
Something like:
class Registry {
private $_objects = array( );
public function set( $name, $object ) {
$this->_objects[ $name ] = $object;
}
public function get( $name ) {
return $this->_objects[ $name ];
}
}
I wouldn't even use Singleton in this case.
Setting a class to abstract that only defines static properties/methods won't have a real effect. You can extend the class, instantiate it, and call a method on it and it would change the static class properties. Obviously very confusing.
Abstract is also misleading. Abstract is ment to define an class that implements some functionality, but needs more behaviour (added via inheritance) to function properly. On top of that it's usually a feature that shouldn't be used with static at all. You are practically inviting programmers to use it wrong.
Short answer: A private constructor would be more expressive and fail safe.
There are patterns in OO that are common and well-recognized. Using abstract in an unconventional way may cause confusion (sorry, my some examples are in Java instead of PHP):
abstract class - a class meant to conceptualize a common ancestor, but of which actual instances are not meant to exist (e.g. shape is an abstract superclass for rectangle and triangle).
Commonly implemented by:
use abstract modifier on class to prevent direct instantiation, but allow deriving from the class
utility class - a class that does not represent an object in the solution space, but rather is a collection of useful static operations/methods, e.g. Math class in Java.
Commonly implemented by:
make class non-derivable, e.g. Java uses the final modifier on class, and
prevent direct instantiation - provide no constructors and hide or disable any implicit or default constructors (and copy constructors)
singleton class - a class that does represent an object in the solution space, but whose instantiation is controlled or limited, often to insure there is only one instance.
Commonly implemented by:
make class non-derivable, e.g. Java uses the final modifier on class, and
prevent direct instantiation - provide no constructors and hide or disable any implicit or default constructors (and copy constructors), and
provide a specific means to acquire an instance - a static method (often getInstance()) that returns the only instance or one of the limited number of instances
abstract really is meant to indicate a "blueprint", as you call it, for class inheritance.
Registries generally follow a singleton pattern, which means they it would instantiate itself in a private variable. Defining it as abstract would prevent this from working.
I wouldnt use an abstract class. Id use something more akin to a singleton with a protected/private constructor as you suggest. There should be very few static properties other than $instance which is the actual registry instance. Recently ive become a fan of Zend Frameworks typical pattern which is something like this:
class MyRegistry {
protected static $instance = null;
public function __construct($options = null)
{
}
public static function setInstance(MyRegistry $instance)
{
self::$instance = $instance;
}
public static function getInstance()
{
if(null === self::$instance) {
self::$instance = new self;
}
return self::$instance;
}
}
This way you get a singleton essentially but you can inject a configured instance to use. This is handy for testing purposes and inheritance.
The purpose of an abstract class is to define methods that are 1) meaningful to other classes and 2) not meaningful when not in the context of one of those classes.
To paraphase some of the php docs, imagine you are connecting to a database. Connecting to a database doesn't make much sense unless you have a particular kind of database to connect to. Yet connecting is something you will want to do regardless of the kind of database. Therefore, connecting can be defined in an abstract database class and inherited, and made meaningful by, say, a MYSQL class.
From your requirements, it sounds like you don't intend to do this but instead simply require a class without an instance. Whilst you could use an abstract class to enforce this behaviour, this seems hacky to me because it abuses the purpose of abstract classes. If I encounter an abstract class, I should be able to reasonably expect that this will have some abstract methods, for example, but your class will have none.
Therefore, a singleton seems like a better option.
However, if the reason you wish to have a class without an instance is simply so that you can call it anywhere then why do you even have a class at all? Why not just load every variable as a global and then you can just call it directly rather than through the class?
I think the best way to do this is to instantiate the class and then pass it around with dependency injection. If you are too lazy to do that (and fair enough if you are! Its your code, not mine.) then don't bother with the class at all.
UPDATE: It seems like you are conflicted between 2 needs: The need to do things quickly and the need to do things the right way. If you don't care about carrying a ton of global variables for the sake of saving yourself time, you will assumedly prefer using abstract over a singleton because it involves less typing. Pick which need is more important to you and stick with it.
The right way here is definitely not to use a Singleton or an abstract class and instead use dependency injection. The fast way is to have a ton of globals or an abstract class.
From my understanding, a class without instance is something you shouldn't be using in an OOP program, because the whole (and sole) purpose of classes is to serve as blueprints for new objects. The only difference between Registry::$someValue and $GLOBALS['Registry_someValue'] is that the former looks 'fancier', but neither way is really object-oriented.
So, to answer your question, you don't want a "singleton class", you want a singleton object, optionally equipped with a factory method:
class Registry
{
static $obj = null;
protected function __construct() {
...
}
static function object() {
return self::$obj ? self::$obj : self::$obj = new self;
}
}
...
Registry::object()->someValue;
Clearly abstract won't work here.
I would say it's a matter of coding habbits. When you think of an abstract class it is usually something you need to subclass in order to use. So declaring your class abstract is counter-intuitive.
Other than that is it just a matter of using self::$somevar in your methods if you make it abstract, rather than $this->somevar if you implement it as a singleton.

Categories