0

Hey guys I'm doing this wrong again I'm sure, but I'm trying to instantiate a PDO database handler from my class Database from the file class.database.php inside my class AdminSession from class.admin.php, somethings a bit screwy with my dependancy injection, and it is not allowing me to use PDO's methods corretly; like fetch(), prepare() etcetra.

the class.database.php file

class Database
{
    public $db;   // handle of the db connection

    private static $dsn="mysql:host=server2.com;dbname=database";
    private static $user="user";
    private static $pass="pass";
    private static $instance;

    public function __construct () 
    {
        $this->db = new PDO(self::$dsn,self::$user,self::$pass,$self::$opts);
        $this->db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
        $this->db->setAttribute(PDO::MYSQL_ATTR_INIT_COMMAND, "SET NAMES 'utf8'");

        switch($_SERVER['ENVIRONMENT']) {
            case 'staging':
                self::$dsn="mysql:host=server1.com;dbname=database";
                self::$user="user";
                self::$pass="pass";
                break;
            default:
                self::$dsn="mysql:host=server2.com;dbname=database";
                self::$user="user";
                self::$pass="pass";
        }

    }

    public static function getInstance()
    {
        if(!isset(self::$instance))
        {
            $object= __CLASS__;
            self::$instance=new $object;
        }
        return self::$instance;
    }

}

and here's the topmost of my class.admin.php, and a method that is throwing an error. right now the errors I'm getting

PHP Fatal error: Call to undefined method line 230

If I use $this->db-prepare($sql)

or

PHP Fatal error: Call to a member function prepare() on a non-object line 230

If I use $db-prepare($sql)

require('library/class.database.php');

class AdminSession {
    static $abs_path;

    public function __construct(Database $db) {
        session_start();

        self::$abs_path = dirname(dirname(__FILE__));
        if($_SERVER['REQUEST_METHOD'] == 'POST') {

            $this->post = $_POST; // filter_input_array(INPUT_POST, FILTER_SANITIZE_STRING);

            if(get_magic_quotes_gpc ()) {
                //get rid of magic quotes and slashes if present
                array_walk_recursive($this->post, array($this, 'stripslash_gpc'));
            }
        }

        $this->get = $_GET; // filter_input_array(INPUT_GET, FILTER_SANITIZE_STRING);
        array_walk_recursive($this->get, array($this, 'urldecode'));
    }

// other methods

    private function checkDB($username, $password) {
        $sql = "SELECT * FROM users WHERE username=:username";
        try {

            $db             = Database::getInstance();
            $stmt           = $db->prepare($sql);

                $stmt->bindParam("username", $username);
                $stmt->execute();

            $user           = $stmt->fetchAll(PDO::FETCH_OBJ);

            $db = null;

            if($user) {
                //general return
                if(is_object($user[0]) && md5($user[0]->password) == $password) {
                    return true;
                } else {
                    return false;
                }
            } else {
                return false;
            }

        } catch(PDOException $e) {
            echo '{"error":{"text":'. $e->getMessage() .'}}';
        }

    }

}
1
  • I added an error, and also reworked my db class a bit into something more sensible. Commented Jul 19, 2012 at 19:02

1 Answer 1

1

You can't put logic into your class definition. Instead, determine the value of these variables within the constructor. The switch will work in a method, but not when defining members.

Edit: I actually feel silly for missing this. The connection was made before the switch statement. I don't know that it'll fix the second set of issues ... but it'll behave properly for the original question now.

class Database
{
    public $db;   // handle of the db connection

    private static $opts = array(PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8');
    private static $dsn="mysql:host=server2.com;dbname=database";
    private static $user="user";
    private static $pass="pass";
    private static $instance;

    public function __construct () 
    {
        switch($_SERVER['ENVIRONMENT']) {
            case 'staging':
                self::$dsn="mysql:host=server1.com;dbname=database";
                self::$user="user";
                self::$pass="pass";
                break;
            default:
                self::$dsn="mysql:host=server2.com;dbname=database";
                self::$user="user";
                self::$pass="pass";
        }

        $this->db = new PDO(self::$dsn,self::$user,self::$pass,$self::$opts);
        $this->db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    }

    public static function getInstance()
    {
        if(!isset(self::$instance))
        {
            $object= __CLASS__;
            self::$instance=new $object;
        }
        return self::$instance;
    }

}
Sign up to request clarification or add additional context in comments.

2 Comments

Close Robert, I did a little shuffling since private static options was acting weird, and get the error now Call to undefined method Database::prepare() when using $db->prepare($sql) or Call to a member function prepare() on a non-object if I try using $this->db-prepare($sql) any ideas?
This totally led me to the answer with the help of this thread: stackoverflow.com/questions/2047264/use-of-pdo-in-classes

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.