0

I have some variables and functions which need to be available for different classes. Hence, I put all definitions (Variables / functions) to some class:

class common_functions() {
    function __construct() {
        $this->define_variables();
        $this->connect_to_database();
        echo "EXEC";
    }
    function define_variables() {
        $this->var1 = "foo";
        $this->var2 = "bar";
    }
    function connect_to_database() {
        mysql_connect(...)
    }
    function do_something() {
        //...
    }
}

which is the parent of all the others:

class orders extends common_functions {

    private $order_item;

    function __construct() {
        parent::__construct()
        $order_item = new item();
    }
    function show_something() {
        echo $order_item->get_something()*$this->var1;
    }

}


class item extends common_functions {

    pivate $some_number;

    function __construct() {
        parent::__construct()
        $this->number = 123;
    }
    function get_something() {
        return $this->var2*$this->var1*$this->number;
    }

}


class some_other_class extends common_functions {

    function __construct() {
        parent::__construct()

    }

    // ..

}

However, as executing

$o = new order();
$o->show_something();

the output is

EXEC
EXEC

since the common_functions class is called twice. Especially also mysql-connection is established several times which is quite unefficient.

What I need is some technique so that all the functions and variables (and database-connections) from common_functions are available to all classes without the drawback that e.g. connect_to_database() is executed several times. Some ideas?

  • 1
    If two classes need a database connection, then it should be injected into their constructor as a dependency. To see a way for implementing that, take a look at [this example](http://stackoverflow.com/a/11369679/727208). Also, you should really stop using the ancient `mysql_*` functions. They are no longer maintained and shouldn't be used in any new codebase. It is being phased out in favor of newer APIs. Instead you should use [**prepared statements**](https://www.youtube.com/watch?v=nLinqtCfhKY) with either [PDO](http://php.net/pdo) or [MySQLi](http://php.net/mysqli). – tereško Nov 24 '13 at 20:19

2 Answers2

0

If I were you I'd redesign my implementation. Why? Well because it seems to me that neither some_other_class nor item is a common_functions. However they both have common_functions. Thus I'd create only one instance of that class and pass it into the constructor.

Something like this:

class Item {

    private $common_functions;

    public function __construct($common_functions) {
        $this->common_functions = $common_functions;
    }

}

class Order {

    private $common_functions;

    public function __construct($common_functions) {
        $this->common_functions = $common_functions;
    }

}

What happens now is that both the item and some_other_class objects has a dependency which we inject to common_functions. This obviously means that you have to pass some values to the methods in common_functions but that is a very small price to pay considering what you gain from not inheriting common_functions, like only one db-connection.

Inheritance is cool but in practice it isn't used all that much. It's often much better compose objects than to inherit a bunch of stuff. When designing OO-classes always consider wether an objects relation is an is a or has a relation.

So what you could do using the above example of the orders constructor is the following:

class orders {

    private $common_functions;

    public function __construct($common_functions) {
        $this->common_functions = $common_functions;
        $order_item = new Item($common_functions);
    }

}

That way both item and order will share the same common_functions object.

Daniel Figueroa
  • 9,573
  • 3
  • 38
  • 63
  • yes, thats the point that all the functions have a "has a"-relation. However, I don't see how your suggestion works? How to make functions available in classes item oder some_other_class? – user3027761 Nov 24 '13 at 17:46
-1

Assign a static null variable initially in parent class and check if its null or not.

class common_functions {

private static $dbInstance = null;

function __construct() {

    if(self::$dbInstance == null) {
      self::$dbInstance = $this->connect_to_database();

    }

} ...

return the the database connection handler or any other than the null value in $this->connect_to_database();

Khem
  • 184
  • 7
  • however, $dbInstance will not be available to other classes than the one called the constructor?! – user3027761 Nov 24 '13 at 18:25
  • which means that finally every class need to established a db-connection again, as at my present implementation. – user3027761 Nov 24 '13 at 18:28
  • class common_functions { private static $dbInstance = null; function __construct() { if(self::$dbInstance == null) { self::$dbInstance = $this->connect_to_database(); echo "EXEC"; } else { echo "NOEXEC"; } } function connect_to_database() { $dbh = mysql_connect("localhost", "root", ""); mysql_select_db('dbname', $dbh); return $dbh; } } As of your implementation $t = new item(); $o = new order(); outputs EXEC NOEXEC connect_to_database() function will not be executed several times. – Khem Nov 24 '13 at 18:39