И так, давайте разберемся с ошибкой 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, рекомендую почитать мою предыдущую статью.
Покупай дешевые, со скидкой 5 евро! видеокарты, компьютерное и другое оборудование
Встречал такую ошибку. Пришлось создавать соединение в каждом месте, то есть копировать код. В случае с простым mysql драйвером можно было в одном месте установить соединение и выполнять SQL запросы.
В общем тоже интересует более рациональное решение.
может стоило для начала прочитать в документации про область видимости переменных, а уже потом писать эту статью?
По моему в статье про это указано
Использовать единый объект данного класса. У меня это было реализовано именно так. То есть для работы с бд используется класс экземпляр которого всего один. Функция через, который его получаем отслеживает данный момент. Везде где нужно используем вызов данной функции.