PDO проблем

teroristd

Registered
Здравейте, имам един проблем. Тествам фреймуорка на gatakka. Първо ще обясня, и после ще дам кодовете свързани с прблема. Значи правя си един модел в който имам заявка към базата данни. Модела наследява класа SimpleDB. В контролера си викам модела и получавам следната грешка Fatal error: Cannot use object of type PDO as array. Грешката е свързана по някакъв начин с конекцията към базата данни. Във фреймуорка има клас DBSession който, също използва конекцията към базата и също наследява класа SimpleDB. DBSession винаги се изпълнява първи защото го викаме в стартиращия клас. Конекцията определяме каква да бъде посредством функцията getDatabaseConnection() в класа Database защото може да имаме конекция към повече от една база данни. Цялата работа е че ако изключа сесията(демек DBSession което, става от конфигурацията или задам на сесията да не работи с базата данни) тогава не получавам грешката и модела си върши работата, но това не ме урежда защото ми трябва сесията в базата. Ето и кодовете.

Модел
Код:
namespace models;

class LoginModel extends \application\SimpleDB{
    
 public function __construct($dbConnection) {
     parent::__construct($dbConnection);
 }

public function do_something($dataEmail, $dataPass) {
        
        $this->prepare('INSERT INTO login (email,pass) VALUES(?,?)', array($dataEmail, $dataPass))->execute();
}

    }

SimpleDB
Код:
namespace application;

class SimpleDB{

    protected $_connection = 'default';
    private $_db = null;
    private $_stmt = null;
    private $_params = array();
    private $_sql = null;

    public function __construct($connection = null) {
        if ($connection instanceof \PDO) {
            $this->_db = $connection;
        } elseif ($connection != null) {
            $this->_db = \application\Database::getInstance()->getDatabaseConnection($connection);
            $this->_connection = $connection;
        } else {
            $this->_db = \application\Database::getInstance()->getDatabaseConnection($this->_connection);
        }
    }

    public function prepare($sql, $params = array(), $pdoOptions = array()) {
        $this->_stmt = $this->_db->prepare($sql, $pdoOptions);
        $this->_params = $params;
        $this->_sql = $sql;
        return $this;
    }

    public function execute($params = array()) {
        if ($params) {
            $this->_params = $params;
        }
        $this->_stmt->execute($this->_params);
        return $this;
    }

Database
Код:
namespace application;

class Database {

    private static $_instance = null;

    /**
     *
     * @var \application\Config 
     */
    private $_config;
    private $_dbConnection = array();

    private function __construct() {
        $this->_config = \application\Config::getInstance();
    }

    /**
     *
     * @return \application\Database 
     */
    public static function getInstance() {
        if (self::$_instance == null) {
            self::$_instance = new \application\Database();
        }
        return self::$_instance;
    }

    public function getDatabaseConnection($connection = 'default') {
        if (!$connection) {
            throw new \Exception('No indetificator', 500);
        }
        if ($this->_dbConnection[$connection]) {
            return $this->_dbConnection[$connection];
        }
        $cnf = $this->_config->db_config_file;
        if (!$cnf[$connection]) {
            throw new \Exception('No valid indetificator', 500);
        }
        $dbh = new \PDO($cnf[$connection]['host_and_dbName'], $cnf[$connection]['username'], $cnf[$connection]['password'], $cnf[$connection]['pdo_options']);
        $this->_dbConnection = $dbh;
        return $dbh;
    }

}

DBSession не пускам целия код защото няма общо с проблема
Код:
namespace application\sessions;

class DBSession extends \application\SimpleDB implements \application\sessions\ISession {

    public function __construct($dbConnection, $name, $tableName = 'session', $lifetime = 3600, $path = null, $domain = null, $secure = FALSE) {

        parent::__construct($dbConnection);
}
}

Контролера в който викам модела
Код:
namespace controllers;

class Login extends \application\BaseController {

 public function bar() {
 
        $model = new \models\LoginModel($dbConnection = 'default');
        $model->do_something($dataEmail, $dataPass);
    }
}
 
Ти подаваш конекция обект не масив. Тоест не подавай при викането обект а подай вече създадена конекция. :idea:
 
teroristd каза:
Тоест как да стане дай пример.
На кой ред в кой файл ти дава точно грешката!? Играл съм си доста с фрейма на гатака пренаписах си го по моите виждания. Остава ми само да преправя базата да е по-читава, визуализирането и работата с рутерите.
 
Грешката ми я дава когато викам модела в контролера
$model = new \models\LoginModel($dbConnection = 'default');
, но ако спра сесията от конфигурацията($cnf['session']['autostart'] = FALSE;) или я сменя с другата($cnf['session']['type'] = 'native'), понеже имаме два типа сесиии както знаеш, тогава кода си работи. Праща си заявката всичко е ток и жица :).
 
teroristd каза:
Грешката ми я дава когато викам модела в контролера
$model = new \models\LoginModel($dbConnection = 'default');
, но ако спра сесията от конфигурацията($cnf['session']['autostart'] = FALSE;) или я сменя с другата($cnf['session']['type'] = 'native'), понеже имаме два типа сесиии както знаеш, тогава кода си работи. Праща си заявката всичко е ток и жица :).
Викай така:
$model = new \models\LoginModel();
Защо да приравняваш променливата на дефаут? Този метод прави следното. Проверява дали си подал конекция инстанция на PDO ако ли не дали конекцията не е равна на нула, ако ли не директно ти подава дефаут ако е нула.
PHP:
 public function __construct($connection = null) {
        if ($connection instanceof \PDO) {
            $this->_db = $connection;
        } elseif ($connection != null) {
            $this->_db = \application\Database::getInstance()->getDatabaseConnection($connection);
            $this->_connection = $connection;
        } else {
            $this->_db = \application\Database::getInstance()->getDatabaseConnection($this->_connection);
        }
    }
 
Не става така, трябва да му подам конекцията като параметър иначе дава още една грешка Warning: Missing argument 1 for models\LoginModel::__construct()

В смисъл мога и така да подам но трябва да има параметър подаден $model = new \models\LoginModel($dbConnection); Просто за по четливо я приравнявам иначе няма разлика.
 
teroristd каза:
Не става така, трябва да му подам конекцията като параметър иначе дава още една грешка Warning: Missing argument 1 for models\LoginModel::__construct()

В смисъл мога и така да подам но трябва да има параметър подаден $model = new \models\LoginModel($dbConnection); Просто за по четливо я приравнявам иначе няма разлика.
Никак не е четливо така:
PHP:
 public function __construct($dbConnection = null) {
     parent::__construct($dbConnection);
 }
И реши проблема да извикаш както си е правилно така:
$model = new \models\LoginModel();
за да получиш дефаутовата конекция. Иначе в метода за проверка от предният ми пост щеше да има if($connection = 'defaut') което е глупаво защото ти ще трябва да подаваш адски излишни писаници както ги описа ти. Така ще ти е най-лесно и четливо. Все пак така
$model = new \models\LoginModel();
получаваш дефаутова конекция, а така
$model = new \models\LoginModel($dbconnection);
подаваш нещо и реално вече след време ще си гониш мнооого по-добре грешки ако има.
 
Ама не може така да го викам $model = new \models\LoginModel();
Дава освен първата грешка и още една за липсващ параметър.
Missing argument 1 for models\LoginModel::__construct()
 
teroristd каза:
Ама не може така да го викам $model = new \models\LoginModel();
Дава освен първата грешка и още една за липсващ параметър.
Missing argument 1 for models\LoginModel::__construct()
Нали затова ти написах:
PHP:
public function __construct($dbConnection = null) {
     parent::__construct($dbConnection);
 }
В LoginModel просто добавяш на конструктора по дефаут да е null ($dbConnection = null) и реши този проблем. :)
 
Да така мога да си викам само $model = new \models\LoginModel(); ама основната грешка си остава.
 
teroristd каза:
Да така мога да си викам само $model = new \models\LoginModel(); ама основната грешка си остава.
Ммм незнам какво правиш. Това се получава когато ако някъде си подал обект го ползваш като масив.
 
Накрая открих къде се чупи кода :P бъгчето не е в моя телевизор или поне така си мисля :D . Всичко идва от една проверка в метода getDatabaseConnection(). Ето тази проверка като я премахна и всичко почва да работи както се очаква. Пак си имам две връзки с базата, имам си и сесиии и всичко се записва коректно.

Код:
if ($this->_dbConnection[$connection]) {
            return $this->_dbConnection[$connection];
       }

Честно казано така и не разбирам тази проверка какво върши. _dbConnection е свойство и е масив. Не му присвояваме нищо преди проверката. Незнам :idea:
 
teroristd каза:
Накрая открих къде се чупи кода :P бъгчето не е в моя телевизор или поне така си мисля :D . Всичко идва от една проверка в метода getDatabaseConnection(). Ето тази проверка като я премахна и всичко почва да работи както се очаква. Пак си имам две връзки с базата, имам си и сесиии и всичко се записва коректно.

Код:
if ($this->_dbConnection[$connection]) {
            return $this->_dbConnection[$connection];
       }

Честно казано така и не разбирам тази проверка какво върши. _dbConnection е свойство и е масив. Не му присвояваме нищо преди проверката. Незнам :idea:
Ако в масива имаш вече сетната такава конекция ти връща тази конекция. Примерно:
PHP:
$test[0] = false;
$test[1] = true;
if($test[1]){//Влиза при истина!}

Виж къде сетваш конекцията и при какви условия във $_dbConnection.
:)
 
Аз единственото място където това свойство е използвано е тук.
Код:
private $_dbConnection = array();

public function getDatabaseConnection($connection = 'default') {
        if (!$connection) {
            throw new \Exception('No indetificator', 500);
        }
        if ($this->_dbConnection[$connection]) {
            return $this->_dbConnection[$connection];
        }
        $cnf = $this->_config->db_config_file;
        if (!$cnf[$connection]) {
            throw new \Exception('No valid indetificator', 500);
        }
        $dbh = new \PDO($cnf[$connection]['host_and_dbName'], $cnf[$connection]['username'], $cnf[$connection]['password'], $cnf[$connection]['pdo_options']);
        $this->_dbConnection = $dbh;
        return $dbh;
    }

На предпоследния ред му присвояваме конекцията но той идва след проверката.
 
teroristd каза:
Аз единственото място където това свойство е използвано е тук.
Код:
private $_dbConnection = array();

public function getDatabaseConnection($connection = 'default') {
        if (!$connection) {
            throw new \Exception('No indetificator', 500);
        }
        if ($this->_dbConnection[$connection]) {
            return $this->_dbConnection[$connection];
        }
        $cnf = $this->_config->db_config_file;
        if (!$cnf[$connection]) {
            throw new \Exception('No valid indetificator', 500);
        }
        $dbh = new \PDO($cnf[$connection]['host_and_dbName'], $cnf[$connection]['username'], $cnf[$connection]['password'], $cnf[$connection]['pdo_options']);
        $this->_dbConnection = $dbh;
        return $dbh;
    }

На предпоследния ред му присвояваме конекцията но той идва след проверката.
Така ако няма конекция при първият if то веднага трещи грешка. Винаги е подаден дефаут тъй че тази проверка е малко винаги излишна освен ако не е подаден false тъй че нека си я има. Следва описаната от теб проверка. Проверяваш дали $this->_dbConnection['defaut'] e true и ако е така връщаш тази стойност на конекцията. (затова те попитах дали някъде другаде не се сетва $this->_dbConnection['defaut'] = на нещо ) Вика се конфигурацията вади се от там и се правят проверки. За най-лесно изгледай видеото където правеше тези конекции към базата за да ти стане по-ясно защо го прави.
 
Гледах ги 300 пъти видията. Казва по повод проверката че ако имаме вече конекция я връща, защото няма смисъл да се прави втора инстанция. Обаче явно PDO не мисли така и цепи грешка :D. Видеото е Database(3), ако искаш гледай го пък може да разбереш повече от мене.
 
teroristd каза:
Гледах ги 300 пъти видията. Казва по повод проверката че ако имаме вече конекция я връща, защото няма смисъл да се прави втора инстанция. Обаче явно PDO не мисли така и цепи грешка :D. Видеото е Database(3), ако искаш гледай го пък може да разбереш повече от мене.
Явно има малка грешка ето тук:
$dbh = new \PDO($cnf[$connection]['host_and_dbName'], $cnf[$connection]['username'], $cnf[$connection]['password'], $cnf[$connection]['pdo_options']);
$this->_dbConnection = $dbh;
return $dbh;

Би трябвало да е
$dbh = new \PDO($cnf[$connection]['host_and_dbName'], $cnf[$connection]['username'], $cnf[$connection]['password'], $cnf[$connection]['pdo_options']);
$this->_dbConnection[$connection] = $dbh;
return $dbh;

За да има някакъв смисъл от горната проверка и това което е казал.
 
Веднага пробвах и ти казвам че си прав :?: . Аз не можах да го измисля въпреки че, сега като го гледам ми се набива в очите. Ама от толкова взиране по кодовете се омотах напълно :D . Евала Дака железо си :) .
 
teroristd каза:
Веднага пробвах и ти казвам че си прав :?: . Аз не можах да го измисля въпреки че, сега като го гледам ми се набива в очите. Ама от толкова взиране по кодовете се омотах напълно :D . Евала Дака железо си :) .
Ако знаеш и аз колко съм го благославял по темата :D :D :D
 

Back
Горе