6

I've started learning OOP in PHP. I managed to write code where subclass would extend the superclass which contains connection to database. Now instead of extending or using subclass, is there a way where I can make this connection class global so that any class could use it's object without having to extend it?

Please note below, I have to use $this->pdo to regard the instance of the class. Is there a way where I can instantiate an object within this class like $pdo=new PDO(); and use this object as $pdo wherever I want?

Will static class help in this scenario?

class connection
{
    public $servername = "localhost";
    public $username = "root";
    public $password = "";
    public $dbname = "carrental";
    public $port="3306";
    public $pdo;

    function addConnection()
    {
      try {
          $this->pdo = new PDO("mysql:host=$this->servername;port=$this->port;dbname=$this->dbname", $this->username, $this->password);
          $this->pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
      } catch(PDOException $e) {
          echo 'ERROR: ' . $e->getMessage();
      }

      $this->pdo->query("use $this->dbname");
    }
}

Tried Singleton like below but can advise what's wrong as I get fatal error and warning.

( ! ) Fatal error: in C:\wamp\www\carRental\index.php on line 20 ( ! )
PDOException: in C:\wamp\www\carRental\index.php on line 20 Call Stack

Time Memory Function Location 1 0.0012 143752 {main}( )
..\index.php:0 2 0.0012 144296 car->__construct( ) ..\index.php:50

3 0.0013 144272 connection->addConnection( ) ..\index.php:39
4 0.0989 150800 query ( ) ..\index.php:20

<?php
class connection
{
    public $servername = "localhost";
    public $username = "root";
    public $password = "";
    public $dbname = "carrental";
    public $port="3306";
    public static $pdo;

    function addConnection()
    {
      try {
          self::$pdo = new PDO("mysql:host=$this->servername;port=$this->port;dbname=$this->dbname", $this->username, $this->password);
          self::$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
      } catch(PDOException $e) {
          echo 'ERROR: ' . $e->getMessage();
      }

      self::$pdo->query("use $this->dbname");
      return self::$pdo;
    }
}
class car 
{
    public $name;
    public $maker;
    public $type;
    public $colour;
    public $passanger;

    public function __construct($param1,$param2,$param3,$param4,$param5)
    {
        $this->name=$param1;
        $this->maker=$param2;
        $this->type=$param3;
        $this->colour=$param4;
        $this->passanger=$param5;
        connection::addConnection();
    }
    public function addCar()
    {
        $sql="INSERT INTO car(car_name,car_maker,car_type,car_colour,num_passanger)VALUES('{$this->name}','{$this->maker}', '{$this->type}','{$this->colour}','{$this->passanger}')";
        $stmt = $this->$pdo->prepare($sql);
        $stmt->execute();
        echo "Data inserted!";
    }
}

$car1=new car("Honda Accord","Honda","5 wheeler","Red",8);
$car1->addCar();

?>
112233
  • 2,406
  • 3
  • 38
  • 88
  • 2
    Google "Dependency Injection" – Mark Baker Jul 07 '15 at 09:38
  • 3
    Read about the Singleton pattern. – Barmar Jul 07 '15 at 09:42
  • ...and when you read about the singleton pattern also note the criticism, e.g. here: http://stackoverflow.com/questions/137975/what-is-so-bad-about-singletons . I second dependency injection over singleton for database connections, https://en.wikipedia.org/wiki/Dependency_injection – VolkerK Jul 07 '15 at 09:44
  • @Barmar, thanks for your suggestion..I studied about Singleton and tried it (posted above).But could you help me identify what's wrong in there that emits error please? – 112233 Jul 07 '15 at 11:22
  • @Barmar The Singleton pattern is considered bad, for a good reason: It makes it hard write independent tests. I would create the database connection object at an early stage of the application and pass it forward to the components which need it during their creation. – hek2mgl Jul 07 '15 at 11:33
  • @hek2mgl - but somehow You have to ensure that you pass only this only connection to all components. So i think that singleton+DI is best solution - pass connection object in constructor, but first, get it from some sort of factory, which will return singleton pattern thingie. I can't find any other solution. If You have some other idea - please, share it with me. I'm curious about it :) – Warzyw Jul 07 '15 at 12:55

1 Answers1

1

As i can see this line cause problems connection::addConnection();
You are trying to call addConnection like static method.
Static function means that you don't need to create instance of class to call this function. !But! when you call this method static, You can't use non-static properties or function of this class. So all of fields should be marked as static, because otherwise you will not have any of db password, login and so on.
TL:DR
Just mark "addConnection()" as
public static function addConnection()
and you can use static property/function of class.

Warzyw
  • 329
  • 3
  • 11
  • I did make the function static and called it connection::addConnection(); but it emits error.Fatal error: Call to a member function prepare() on a non-object in C:\wamp\www\carRental\index.php on line 44 – 112233 Jul 07 '15 at 14:07
  • This error is caused becouse You added "$" before "pdo" in "$this->$pdo->prepare($sql);" When You add extra dollar mark($), which is not required PHP will do some "magic" - it will cast variable to string, then will try to trigger member which have name as te string. Eg. we have variable "$string = "pdo"". Now, when you write like in Your code - "$this->$string->something" the code that will be parsed would look like "$this->pdo->something". When You dont use the dollar sign before "$string" - "$this->string->something" - it will cause error because car dont have member "string". – Warzyw Jul 07 '15 at 20:48
  • And if You remove second "$" from this line - $this->$pdo->prepare($sql); it will cause error too. Becouse "pdo" member variable is null. And null is not a object and dont have function "prepare".You have to write something like this; connection::pdo->prepare($sql) – Warzyw Jul 07 '15 at 20:50