Undefined variable: DBH in… (PDO include)

undefined variable: dbhИ так, давайте разберемся с ошибкой 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, рекомендую почитать мою предыдущую статью.

Есть 4 коммент.

  1. планшет пишет:

    Встречал такую ошибку. Пришлось создавать соединение в каждом месте, то есть копировать код. В случае с простым mysql драйвером можно было в одном месте установить соединение и выполнять SQL запросы.

    В общем тоже интересует более рациональное решение.

  2. koqep пишет:

    может стоило для начала прочитать в документации про область видимости переменных, а уже потом писать эту статью?

  3. admin пишет:

    По моему в статье про это указано

  4. helpix пишет:

    Использовать единый объект данного класса. У меня это было реализовано именно так. То есть для работы с бд используется класс экземпляр которого всего один. Функция через, который его получаем отслеживает данный момент. Везде где нужно используем вызов данной функции.

Написать комментарий

XHTML: Вы можете использовать эти теги: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

*

*