Как использовать PDO в других классах?

Как я вижу: пишу класс соединения с БД, подряжаю его в методах других классов и там уже работаю.
Как реализую:
Класс подключения

class qpdo {
	public function __construct() {
		$host = 'localhost'; $port = '3306'; $base = 'cm'; $char = 'utf8';
		$dsn = 'mysql:host=' . $host . ';port=' . $port . ';dbname=' . $base . ';charset=' . $char . '';
		$user = 'root'; $pass = 'root';
		$opts = [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, PDO::ATTR_CASE => PDO::CASE_NATURAL, PDO::ATTR_ORACLE_NULLS => PDO::NULL_EMPTY_STRING];

		  try                        {
			new PDO($dsn, $user, $pass, $opts);
		} catch(PDOexception $error) {
			echo 'Ошибка подключения к БД MySQL: ' . $error->getMessage() . ''; die;
		}
	}
}


Подрубаю в другом класса

class somethingClass {
	public $key

	function __construct() {
		$db = new qpdo();
	}

	function somethingFunction(string $key) {
		$query = $this->db->prepare("SELECT `key` FROM `table` WHERE `key` = :key");
		$query->execute(array(':key' => $key));
		$result = $query->fetch(PDO::FETCH_COLUMN);
		return $result;
	}
}



Получаю же я:
Fatal error: Uncaught Error: Call to undefined method qpdo::prepare() in C:\OpenServer\domains\localhost\core.php:254 Stack trace: #0 C:\OpenServer\domains\localhost\app\index.php(18): somethingClass->somethingFunction() #1 {main} thrown in C:\OpenSerever\domains\localhost\core.php on line 254


Раньше подключался к БД просто, без использования классов, а в каждом методе классов, в которых надо использовать подключение, прописывал global $qpdo;, но говорят, что это говнокод и неправильно.

Что ж делать, господа?
  • Вопрос задан
  • 349 просмотров
Пригласить эксперта
Ответы на вопрос 1
FanatPHP
@FanatPHP
Чебуратор тега РНР
Вопрос хороший и правильный. Всё остальное - не очень.
К сожалению, то что у тебя сейчас - это тоже говнокод и неправильно.

Тут надо понимать одну очень простую, но очень неприятную вещь: ООП, в отличие от ПХП - это сложная тема. Явочным порядком, там подглядев, тут скопипастив - ООП изучить нельзя.
Максимум что у тебя получится - это та же процедурщина, вид сбоку. Неподдерживаемый говнокод, просто по-обезьяньи обернутый в классы.

Но учиться все равно надо.
Главное что надо понимать про ООП - оно не про сами классы, а про их взаимодействие.
именно поэтому то самое жлобал и является говнокодом. Потому что никакого взаимодействия нет ,и класса тоже нет - есть функция, которую если вынуть из класса, то НИЧЕГО не изменится.

Но и то что у тебя сейчас - это не ООП.
Каждый раз создавать новое подключение можно и без всякого ООП. Вот только оно убьёт тебе сервер БД.
Чтобы было ООП, надо передать уже созданный инстанс класса для работы с БД как параметр конструктора.

Кроме того, класс qpdo - это какой-то анекдот, бессмыслица. Обезьяна увидела как человек носит очки, напялила на нос ложку и ходит с гордым видом. Внешне вроде то же самое, но смысла никакого.
Ты можешь объяснить, ЗАЧЕМ тебе класс qpdo? Чтобы настройки прописать? А ты подумал что настройки бывают РАЗНЫЕ? Что дома у тебя логин рут и пароль пустота, а на хостинге это не прокатит. И что - будешь код переписывать, каждый раз заливая из дома на сервер? Серьёзно?
Настройки должны всегда лежать отдельно. А больше ни для чего твой класс не нужен.

Поэтому,

1. qpdo выкинуть на помойку, по крайней мере до тех пор, пока не поймешь, для чего тебе свой класс, и как с ним обращаться.
2. Создать один раз инстанс класса для работы с БД (в простейшем случае - PDO) и передавать в другие классы через констркутор
3. в конструкторе присваивать его переменной класса, которую использовать для доступа к БД.

В итоге возвращаемся к исходному вопросу, как передать соединение в другой класс:
class somethingClass {
  function __construct($db) {
    $this->db = $db;
  }

  function somethingFunction(string $key) {
    $query = $this->db->prepare("SELECT `key` FROM `table` WHERE `key` = :key");
    $query->execute(array(':key' => $key));
    return $query->fetchColumn();
  }
}


Бонус
echo 'Ошибка подключения к БД MySQL: ' . $error->getMessage() . ''; die;
- это ад и говнокод.
Да, в прошлом веке так писали. С тех про прошло уже 20 чертовых лет. 20, Карл! Тебя небось еще в проекте не было.
Сайт, который вываливает вот это всё на всеобщее обозрение - это позор.
Все ошибки сайт должен всегда держать при себе. И никому не показывать. И поэтому никогда не надо лезть руками в ту ошибку, которую выбрасывает РНР. Надо дать ей спокойно пойти туда, куда идут все остальные ошибки.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы