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() .'}}';
        }

    }

}
ehime
  • 8,025
  • 14
  • 51
  • 110

1 Answers1

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;
    }

}
Robert K
  • 30,064
  • 12
  • 61
  • 79
  • 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? – ehime Jul 19 '12 at 19:55
  • This totally led me to the answer with the help of this thread: http://stackoverflow.com/questions/2047264/use-of-pdo-in-classes – ehime Jul 19 '12 at 20:27