0

Hi i am using PDO DB class to connect to database. But i really wonder if i am doing it correct or not. All connection set up is fine but i get error when i run a query

My Directory Structure is

/root
 /dbops <-- Directory contains `config.php` -->
   /dbfunctions <-- Directory contains `DBclass.php` & `DBFuncts.php` -->

Now contents of config.php are:

define( 'DB_HOST', 'localhost' );
define( 'DB_USERNAME', 'root');
define( 'DB_PASSWORD', '');
define( 'DB_NAME', 'testDB');
define('DB_CHAR', 'utf8');

function __autoload($class){
   $parts = explode('__', $class);
   $path = implode(DIRECTORY_SEPARATOR,$parts);
   require_once $path . '.php';
}

DBclass.php contains:

class dbdunctions__DBclass{
  public $instance = null;
  public function __construct() {}
  final private function __clone() {}

   public static function instance()
   {
        if (self::$instance === null)
        {
          $opt  = array(
            PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,
            PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
            PDO::ATTR_EMULATE_PREPARES   => TRUE,
            PDO::ATTR_STATEMENT_CLASS    => array('myPDOStatement'),
           );
            $dsn = 'mysql:host='.DB_HOST.';dbname='.DB_NAME.';
            charset='.DB_CHAR;
            self::$instance = new PDO($dsn, DB_USERNAME, DB_PASSWORD, 
            $opt);
        }
        return self::$instance;
   }
   public static function __callStatic($method, $args) {
    return call_user_func_array(array(self::instance(), $method), $args);
   }
}

class myPDOStatement extends PDOStatement
{
   function execute($data = array())
    {
       parent::execute($data);
       return $this;
    }
}

DBFuncts.php contains below:

class dbfunctions__DBFuncts
{
  protected $_con;
  public function __construct()
  {
    $db = new dbfunctions__DBclass();
    $this->_con = $db->con;
  }

  function gotodb(array $data){
    $result = 
  $this->_con::instance()->prepare($qry)->execute(array(/*parameters*/));
  }
}

Now when query is fired with $result then i get following error

Parse error: syntax error, unexpected '::' (T_PAAMAYIM_NEKUDOTAYIM) in dbops/dbfunctions/DBFuncts.php on line 12

Please guide. I have already spent 2 hrs on this issue and googling around.

Gags
  • 3,759
  • 8
  • 49
  • 96
  • How it can be a duplicate. My problem is way different.. – Gags Nov 05 '15 at 15:53
  • Why are you placing a wrapper around PDO? – SpacePhoenix Nov 05 '15 at 19:05
  • This pdo works when i simply include this file but when i am trying through classes then i am facing issues. So wrapper around PDO did not give problem. If you are aware of sol then kindly let me know – Gags Nov 06 '15 at 01:52

3 Answers3

0

Instead of

$this->_con::instance()

You should be able to just do

$this->_con->instance()->prepare($qry)->execute(array(/*parameters*/));

Not sure if it's a typo for when you put the code in - but I did notice that in the DBclass.php you have class dbdunctions__DBclass - surely this should be class dbfunctions__DBclass() ?

Also there seems to be some other errors in your example code ... But lets tackle them one at a time :)

G.H
  • 317
  • 1
  • 7
  • I thought of this and changed to this and now error is `Fatal error: Call to a member function instance() on a non-object ` – Gags Nov 05 '15 at 06:56
  • $this->_con = $db->con; try just setting $this->_con = $db in the DBFuncts.php – G.H Nov 05 '15 at 06:57
  • Now it is `Fatal error: Access to undeclared static property: Clws__DBclass::$instance` .. i m messing on it for 2 3 hrs :( – Gags Nov 05 '15 at 07:01
0

Try adjusting this way. I have it working on my server with some adjustments. Notably instantiating the connection in the __construct() of the dbdunctions__DBclass() class and assigning $this->_con to the self::$instance (dbdunctions__DBclass::$instance;):

class dbdunctions__DBclass
    {
        // Make the instance static
        public  static  $instance = null;

        public  function __construct()
            {
                // Create the static connection in the construct
                $this->init();
            }

        private function init()
            {
                if (self::$instance === null) {
                    $opt  = array(
                                PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,
                                PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
                                PDO::ATTR_EMULATE_PREPARES   => TRUE,
                                PDO::ATTR_STATEMENT_CLASS    => array('myPDOStatement'),
                               );

                    self::$instance =   new PDO('mysql:host='.DB_HOST.';dbname='.DB_NAME.'; charset='.DB_CHAR, DB_USERNAME, DB_PASSWORD, $opt);
                }
            }

        final private function __clone()
            {
            }

        public  static  function __callStatic($method, $args)
            {
                return call_user_func_array(array(self::instance(), $method), $args);
            }
    }

class myPDOStatement extends PDOStatement
    {
        public  function execute($data = array())
            {
                parent::execute($data);
                return $this;
            }
    }

class dbfunctions__DBFuncts
    {
        protected $_con;

        public function __construct()
            {
                // Create instance of database
                $database   =   new dbdunctions__DBclass();
                // Assign the connection to the $this->_con
                $this->_con =   dbdunctions__DBclass::$instance;
            }

        public  function gotodb($statement = false,$bind = false)
            {
                // Incase the statement or bind is empty, return 0
                if(empty($statement) || empty($bind))
                    return 0;
                // Create the query with method chain
                $query  =   $this   ->_con->prepare($statement)
                                    ->execute($bind);
                // Fetch results
                while($row = $query->fetch())
                    $result[]   =   $row;
                // If results return array else return 0 for consistency
                return (!empty($result))? $result : 0;
            }
    }

// Instantiate
$dbFunc =   new dbfunctions__DBFuncts();
// Use whatever you use to return a result here. This statement happens
// to work for my database...but likely not yours
print_r($dbFunc->gotodb("select * from `users` where `ID` = :ID",array(":ID"=>"29")));
Rasclatt
  • 12,498
  • 3
  • 25
  • 33
  • But this approach will fail when i have insert query... – Gags Nov 05 '15 at 07:51
  • Why is that? What would fail? – Rasclatt Nov 05 '15 at 07:53
  • i think 2 functions will do job.. one is to insert and other to select – Gags Nov 05 '15 at 07:53
  • Oh, yeah you would need to make a select and insert function, but the connection should work fine – Rasclatt Nov 05 '15 at 07:54
  • because insert statement will return 0 always – Gags Nov 05 '15 at 07:54
  • I only made the function return an array because it would show you for testing purposes that the connection was working and not receiving an error anymore. I am not suggesting you keep that feature, I don't know how you want to insert and select (query in general, really)... – Rasclatt Nov 05 '15 at 07:55
  • and you want me to create a class with select and insert functions in same Connection setup file? – Gags Nov 05 '15 at 07:58
  • You can do what you like in that regard. I personally use a class that builds queries for me so something like: `$query->select("*")->from("table")->where(array("ID"=>"29"))->Fetch();` and then the same class I would use: `$query->insert("table")->columns(array("col1","col2"))->values(array("val1","val2"))->write()` – Rasclatt Nov 05 '15 at 08:01
0
class dbfunctions__DBFuncts
{
  protected $_con;
  public function __construct()
  {
    $db = new dbfunctions__DBclass();
    $this->db = $db;
  }

  function gotodb(array $data){
    $result = 
  $stmt = $this->db->prepare($qry);
$stmt->execute(array(/*parameters*/));
  }

The PDO object gets created then made into a "member object". The gotodb object uses the "member object" PDO instance. Below is a sample of code from a site I'm working on which should help explain it better:

    try {
                $sql="
                    SELECT
                          id
                        , name
                        , description
                    FROM    
                        ue_bug_project                  
                ";
// $stmt objected created by preparing the SQL query for execution, using the PDO object, which in this case is $this->db
                $stmt = $this->db->prepare($sql);
// The execute method of the $stmt object is run executing the query, in this case no query data is bound as there is no user submitted data being used
                $stmt->execute();
// The result set is grabbed in one hit and placed into the projects array (I really should have set up the $projects variable as an empty array beforehand)
                $projects = $stmt->fetchAll(PDO::FETCH_ASSOC);
                return $projects;
            }
// If the query fails with an error, the catch block is run, in this case i log the error.
            catch (PDOException $e) {
                error_log('Error when getting the list of projects!');
                error_log(' Query with error: '.$sql);
                error_log(' Reason given:'.$e->getMessage()."\n");
                return false;
            }

}

From the looks of your code there's probably no real need to place your own wrapper around the PDO class

SpacePhoenix
  • 607
  • 1
  • 5
  • 15