Hello and welcome to our community! Is this your first visit?
Register
Enjoy an ad free experience by logging in. Not a member yet? Register.
Results 1 to 7 of 7
  1. #1
    Senior Coder djm0219's Avatar
    Join Date
    Aug 2003
    Location
    Wake Forest, North Carolina
    Posts
    1,294
    Thanks
    4
    Thanked 203 Times in 200 Posts

    Using a PDO object from an included file

    I am in the process of moving a 10+ year old application into the OO and PDO world. I have created a class for the PDO connection named repm_PDO.class. It contains:

    PHP Code:
    <?php
    class repm_DB {
        private 
    $hostname 'localhost';
        private 
    $database 'blah';
        private 
    $username 'blah';
        private 
    $password 'blah';
        public function 
    __construct() {
            new 
    PDO('mysql:host=' $this->hostname ';dbname=' $this->database,$this->username,$this->password,
                array(
    PDO::ATTR_PERSISTENT => true));
        }
    }
    ?>
    I use that class in, for testing purposes, index.php like so:

    PHP Code:
    <?php
    error_reporting 
    (E_ALL);
    require(
    'repm_DB.class');
    $ourdb = new repm_DB();
    include(
    'testinclude.php');
    exit;
    ?>
    That last include, testinclude.php, is where I'm attempting to use the PDO object and where things are failing. The test include contains:

    PHP Code:
    <?php
    $OrderStatQ 
    $ourdb->prepare("SELECT Order_Status,Description FROM repm_orderstatus ORDER BY Order_Status");
    $OrderStatQ->execute();
    $Status $OrderStatQ->fetchAll();
    print_r($Status);
    exit;
    ?>
    The error I'm getting is:

    Fatal error: Call to undefined method repm_DB :: prepare() in \public_html\Test\testinclude.php on line 3
    If I move the PDO declaration that is in repm_DB.class right now into index.php things work as expected. I'm at a loss as to what I'm doing wrong and why it is failing with the PDO declaration in a separate class file. If I add a print_r of $ourdb to testinclude.php it shows:

    repm_DB Object ( [hostname:repm_DB: private] => localhost [database:repm_DB: private] => blah [username:repm_DB: private] => blah [password:repm_DB: private] => blah )
    Any assistance/pointers/help would be greatly appreciated.
    Dave .... HostMonster for all of your hosting needs

  • #2
    New Coder
    Join Date
    Sep 2011
    Posts
    63
    Thanks
    0
    Thanked 7 Times in 7 Posts
    Looks like you are trying to call 'prepare', a PDO method, from your repm_DB class. The reason that it is not picking it up is because your PDO object belongs to your repm_DB class so your repm_DB class cannot access its methods or properties. One way you could solve this is to save the PDO to a property of the repm_DB class then access it that way.

    Or you might need to return the PDO. Not to sure on that one. I never return anything straight from a constructor.

    In a unrelated note you might find autoloading useful and making your database connection a singleton because after all you only want one connection to your database.

    Hope that helps

  • #3
    New Coder
    Join Date
    Jun 2013
    Location
    The Republic of Texas
    Posts
    29
    Thanks
    0
    Thanked 6 Times in 6 Posts
    You probably want to extend the PDO class. Not sure why you're using the class vars, but you can include a config file that defines those and pass them in:
    PHP Code:
    class repm_DB extends PDO {
       
        public function 
    __construct($hostname$dbname$username$password) {
            
    $dsn 'mysql:host=' $hostname ';dbname=' $dbname;
            
    parent::__construct($dsn$username$password, array(PDO::ATTR_PERSISTENT => true)); 

        } 

    At the start of the app you could create a config object and then fetch the db connection settings from there or just pass them manually:
    PHP Code:
    $ourdb = new repm_DB('localhost''dbname''username''password'); 

  • #4
    New Coder
    Join Date
    Dec 2011
    Posts
    80
    Thanks
    5
    Thanked 12 Times in 12 Posts
    Here's a slick way of doing it (well at least I think it is)

    File name: Database.php
    PHP Code:
    class Database {
     
        private 
    $_connection;
        
    // Store the single instance.
        
    private static $_instance;
     
        
    // Get an instance of the Database.
        // @return Database: 
        
    public static function getInstance() {
            if (!
    self::$_instance) {
                
    self::$_instance = new self();
            }
            return 
    self::$_instance;
        }
     
        
    // Constructor - Build the PDO Connection:
        
    public function __construct() {
            
    $db_options = array(
                
    PDO::ATTR_EMULATE_PREPARES => false                     // important! use actual prepared statements (default: emulate prepared statements)
                
    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION           // throw exceptions on errors (default: stay silent)
                
    PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC      // fetch associative arrays (default: mixed arrays)
            
    );
            
    $this->_connection = new PDO('mysql:host=localhost;dbname=cms;charset=utf8''username''password'$db_options);
        }
     
        
    // Empty clone magic method to prevent duplication:
        
    private function __clone() {
     
        }
     
        
    // Get the PDO connection:    
        
    public function getConnection() {
            return 
    $this->_connection;
        }
     

    file name: utilities.inc.php
    PHP Code:
    // Autoload classes from "classes" directory:
    function class_loader($class) {
        require(
    'classes/' $class '.php');
    }

    spl_autoload_register('class_loader');

    header('Content-Type: text/html; charset=utf-8');

    $db Database::getInstance();
    $pdo $db->getConnection(); 
    Then I would do this

    PHP Code:
    require('includes/utilities.inc.php');

    $OrderStatQ $pdo->prepare("SELECT Order_Status,Description FROM repm_orderstatus ORDER BY Order_Status");
    $OrderStatQ->execute();
    $Status $OrderStatQ->fetchAll();

    //....more code.... 
    If you do anything with the another Class that uses a PDO connection then you will have to put

    PHP Code:
    $db Database::getInstance();
    $pdo $db->getConnection(); 
    into that particular class.
    Last edited by Strider64; 07-18-2013 at 07:43 PM.
    True courage is about knowing not when to take a life, but when to spare one. PDO Tutorial

  • #5
    Senior Coder djm0219's Avatar
    Join Date
    Aug 2003
    Location
    Wake Forest, North Carolina
    Posts
    1,294
    Thanks
    4
    Thanked 203 Times in 200 Posts
    Quote Originally Posted by AbraCadaver View Post
    You probably want to extend the PDO class. Not sure why you're using the class vars, but you can include a config file that defines those and pass them in:
    Well that works but doesn't quite explain why it needs to be done that way. Also don't understand the comment about using class variables. I know those may be anywhere and passed but I was trying to narrow things down to the simplest test case possible.

    Thanks for your suggestion. Extending the PDO class allows things to work at least which is a step in the right direction
    Dave .... HostMonster for all of your hosting needs

  • #6
    New Coder
    Join Date
    Jun 2013
    Location
    The Republic of Texas
    Posts
    29
    Thanks
    0
    Thanked 6 Times in 6 Posts
    Quote Originally Posted by djm0219 View Post
    Well that works but doesn't quite explain why it needs to be done that way. Also don't understand the comment about using class variables. I know those may be anywhere and passed but I was trying to narrow things down to the simplest test case possible.
    In your code you have a class that creates a new PDO connection but you didn't assign it to an object, so when the constructor completes, the connection disappears. In my example your class extends PDO so any objects based on your class inherit all methods of the PDO class.

    In Strider's code a PDO connection is assigned to an object that is stored in your object.

  • Users who have thanked AbraCadaver for this post:

    djm0219 (07-18-2013)

  • #7
    Senior Coder djm0219's Avatar
    Join Date
    Aug 2003
    Location
    Wake Forest, North Carolina
    Posts
    1,294
    Thanks
    4
    Thanked 203 Times in 200 Posts
    OK that makes sense Able to take a few steps forward again now.
    Dave .... HostMonster for all of your hosting needs


  •  

    Posting Permissions

    • You may not post new threads
    • You may not post replies
    • You may not post attachments
    • You may not edit your posts
    •