2012-05-02 3 views
1

Я довольно новичок как для PDO, так и для OOP. Я пытаюсь написать класс, который подключается к базе данных и обновляет вставки и изменяет его. У меня есть несколько вопросов:PHP класс PDO класс

  1. Это хорошая практика для подключения к базе данных в конструкторе?

  2. Следует ли обновлять, вставлять, модифицировать и подключать один класс или делиться на несколько классов?

  3. Почему runQuery не работает? Я предполагаю, потому что $ pdo определен в другой области. Как мне это сделать?

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

Извинения за перегрузку вопросов. Заранее благодарим за любые ответы.

<?php 
class Login{ 

private $_username; 
private $_password; 
private $_host; 
private $_database; 
private $_driver; 

//Connect to the database 

function __construct($configFile){ 

    $connectionDetails = parse_ini_file($configFile); 

    $this->_username = $connectionDetails['username']; 
    $this->_password = $connectionDetails['password']; 
    $this->_host = $connectionDetails['host']; 
    $this->_database = $connectionDetails['database']; 
    $this->_driver = $connectionDetails['driver']; 

    $pdo = new PDO("$this->_driver:host=$this->_host;dbname=$this->_database", $this->_username, $this->_password); 

} 

public function loginAllowed($user, $pw){ 

    $sth = $pdo->setFetchMode(PDO::FETCH_ASSOC); 
    print_r($sth); 
} 

public function runQuery($query, $params){ 
    $sth = $this->pdo->prepare($query); 
    $sth->execute($params); 
} 
} 

ответ

7

Поскольку $pdo является локальной переменной в конструкторе и ваш метод loginAllowed. Вы должны сделать это переменной экземпляра (private $pdo), чтобы вы могли позвонить через $this->pdo. Я также предлагаю использовать здесь type hinting, указать класс PDO в качестве параметра в конструкторе.

Пример

<?php 
class Login { 
    private $pdo; 
    // Your other instance variables 

    public function __construct(PDO $pdo) 
    { 
     $this->pdo = $pdo; 
    } 

    // Your other methods 
} 

$pdo = new PDO("..."); 
$login = new Login($pdo); 

Вы не должны беспокоить вашего класса с настройками чтения и инициализации соединения с базой данных (обязательно читать о separation of concerns), держать его из класса. Просто дайте объект PDO в качестве параметра (я использовал type hinting, таким образом вы вынуждены предоставить объект типа PDO). Еще одно преимущество заключается в том, что теперь вы можете убедиться, что у вас есть только одно активное соединение с базой данных (вы можете управлять этим в своей базе кода), создание нескольких соединений не является необходимым и, безусловно, нежелательным (с точки зрения производительности).

Также используйте require_once, чтобы включить определение вашего класса. В противном случае вы получите много ошибок об обновлении (и вы хотите этого избежать).

+0

Спасибо за замечательный ответ, надели все ваши предложения на практике. У меня небольшая проблема с типом hinting (без этого он отлично работает), когда я передаю объект $ pdo, я получаю следующую ошибку: _Catchable fatal error: Аргумент 1 передан Login :: __ construct() должен быть экземпляр PDO, строка given_ Я использовал gettype, чтобы гарантировать, что передача переменной im фактически является объектом. Я озадачен ..... – Shane

+0

Вы задаете строку как параметр. Что вам нужно сделать, так это создать экземпляр PDO вне вашего класса и предоставить этот экземпляр в качестве параметра. (Тип hinting очень силен, потому что теперь вы можете принуждать параметры к типу (классы только в этот момент).) – Styxxy

+0

Я делаю это '$ pdo = new PDO (« $ driver: host = $ host; dbname = $ database ", $ username, $ password);' (вне класса), затем этот '$ login = new Login ($ pdo);' и когда я пытаюсь распечатать переменную, которую я передаю ($ pdo), я получаю this: _Object класса PDO не может быть преобразован в string_ – Shane

1
  1. Подключитесь к DB, где вам будет удобно. Просто попробуйте убедиться, что есть только одно соединение. Больше подключений к одному и тому же БД - пустая трата времени и ресурсов.

  2. Класс, на который вы ссылаетесь, называется моделью в архитектуре MVC. Он обычно выполняет все операции над данной таблицей. Я не вижу ничего плохого в использовании одного класса для всех ваших потребностей - до тех пор, пока код доступен для чтения и обслуживания.

  3. Это не работает, потому что $pdo является локальной переменной. В ctor создайте вместо него $this->pdo.

  4. Включение класса не эквивалентно его экземпляру. Новый экземпляр сделает другое соединение. Включая его несколько раз, вы получите только несколько ошибок объявления :). Вместо этого используйте require_once. Если вы хотите использовать экземпляр в нескольких файлах, я настоятельно рекомендую вам выполнить быстрый поиск по шаблону Singleton.Использование объекта singleton гарантирует, что у вас всегда будет только один экземпляр объекта модели.

0

1) Является ли хорошей практикой подключение к базе данных в конструкторе?

Нет good.just не подключить Befor запрос

if($this->pdo == null) { 
$this->pdo = new PDO("...."); 

}

2) В случае, если один класс будет обновление, вставка, изменение и подключение или она должна быть разделена на несколько классов? Добавить методы для класса

3) Почему runQuery не работает? Я предполагаю, потому что $ pdo определен в другой области. Как мне это сделать? использовать $ this-> pdo вместо

4) Если класс включен в верхней части каждой страницы, это означает, что он будет повторно подключаться к базе данных каждый раз при загрузке новой страницы и вызовет ли это проблемы безопасности? использовать статические $ п.д.о. затем самостоятельно :: $ PDO будет только один разъем

if(self::$pdo == null) { 
self::$pdo = new PDO("...."); 

}

1

Не беспокоить со всей случайной вещи, просто replacethis в вашей конструкции:

$pdo = new PDO("$this->_driver:host=$this->_host;dbname=$this->_database", $this->_username, $this->_password); 

с

$this->pdo = new PDO("$this->_driver:host=$this->_host;dbname=$this->_database", $this->_username, $this->_password); 

и ссылки я t от $ this-> pdo отныне. Так просто!!

Смежные вопросы