И так, давайте разберемся с ошибкой Undefined variable: DBH in… или DB Fatal error: Call to a member function prepare() on a non-object in…, у кого как обозначено соединение с базой данных, которая возникла например у меня. Сам файл с функцией коннекта к базе данных у меня расположен в отдельном файле. И в другом файле я делаю include этого файла, и далее пытаюсь выбрать данные из базы воспользовавшись $DBH объектом PDO. Но вместо нормального срабатывания, которое было например при использовании функций mysql_ я получаю такую вот ошибку. Давайте разберемся в чем дело.
И так, прошерстив интернет я нашел несколько ответов. Предлагаю взглянуть на них.
Для начала что у нас находится в файле, который мы хотим подключить:
//db.php try { $DBH = new PDO('mysql:host='.HOST.';dbname='.DATABASE,USERNAME,PASSWORD); } catch(PDOException $e) { echo $e->getMessage(); }
Подключаем файл и хотим получить какие то данные используя функцию:
//function.php include('db.php'); function getName() { $STH = $DBH->query('SELECT * FROM name'); $STH->setFetchMode(PDO::FETCH_ASSOC); $name = array(); while($row = $STH->fetch()) { $name[] = $row['name']; return $name; } } getName();
И так, проблема в том, что $DBH не находится в области действия в момент вызова $DBH->query (). $DBH это в глобальном масштабе, а вызов приходится внутри функции (getName). В отличие от других языков, глобальные переменные не доступны в функции, если вы специально их не объявите.
Первое решение этой проблемы – использование глобальных объявлений $DBH в функции:
function getName() { global $DBH; ...
Однако, это не очень хорошая идея, потому что вы теперь заперлись на конкретном способе обработки соединений с базой данных. Было бы лучше передать объект базы данных в качестве параметра в конструктор, хранить его в переменной объекта, и получить его, когда вам нужно его использовать.
class myData { protected $dbh; public function __construct($dbh) { $this->dbh = $dbh; } public function getName() { $STH = $this->dbh->query('SELECT * FROM name'); ... } }
Затем вам необходимо будет инициализировать ваш класс с объектом DB, переданном в качестве параметра:
$property = new myData($DBH); echo $property->getName();
Второй совет:
Попытайтесь передать дескриптор $DBH в конструктор класса и зарезервируйте имена переменных в верхнем регистре только для глобальных переменных и констант. Избегайте использования глобальных переменных в классе.
class myData { protected $dbh; public function __construct($dbhandle) { $this->dbh = $dbhandle; } public function getName() { $sth = $this->dbh->query('SELECT * FROM name'); $sth->setFetchMode(PDO::FETCH_ASSOC); $name = array(); while($row = $sth->fetch()) { $countries[] = $row['name']; } return $name; } } $data = new myData($DBH); echo $data->getName();
Вот такие вот ответы я получил на вопрос об ошибке Undefined variable: DBH in… Fatal error: Call to a member function prepare() on a non-object in… Если кто сталкивался с этим, буду признателен если вы поделитесь своим опытом в комментариях! Для тех кто хочет понять основы работы с PDO, рекомендую почитать мою предыдущую статью.
Встречал такую ошибку. Пришлось создавать соединение в каждом месте, то есть копировать код. В случае с простым mysql драйвером можно было в одном месте установить соединение и выполнять SQL запросы.
В общем тоже интересует более рациональное решение.
может стоило для начала прочитать в документации про область видимости переменных, а уже потом писать эту статью?
По моему в статье про это указано
Использовать единый объект данного класса. У меня это было реализовано именно так. То есть для работы с бд используется класс экземпляр которого всего один. Функция через, который его получаем отслеживает данный момент. Везде где нужно используем вызов данной функции.