Я думаю, что у меня есть проблема в понимании того, как работает ООП. Я уже изменил код, который он работает, но это не тот способ, который я считаю. Следующий сценарий (Нет, я не создаю userlogin самостоятельно, его действительно просто для локального разработчика, чтобы лучше понять ООП):
У меня есть файл database.php:
class Database { /* Properties */ private $conn; private $dsn = 'mysql:dbname=test;host=127.0.0.1'; private $user = 'root'; private $password = ''; /* Creates database connection */ public function __construct() { try { $this->conn = new PDO($this->dsn, $this->user, $this->password); } catch (PDOException $e) { print "Error!: " . $e->getMessage() . ""; die(); } return $this->conn; } }
Итак, в этом классе я создаю соединение с базой данных, и я возвращаю соединение (объект?)
Тогда у меня есть второй класс, известный класс User (на самом деле я не использую autoload, но знаю об этом):
include "database.php"; class User { /* Properties */ private $conn; /* Get database access */ public function __construct() { $this->conn = new Database(); } /* Login a user */ public function login() { $stmt = $this->conn->prepare("SELECT username, usermail FROM user"); if($stmt->execute()) { while($rows = $stmt->fetch()) { $fetch[] = $rows; } return $fetch; } else { return false; } } }
Так что это мои два класса. Как видите, ничего большого. Теперь не надо смириться с именем login
функции – на самом деле я просто пытаюсь выбрать некоторые имена пользователей и usermails из базы данных и отображать их. Я пытаюсь добиться этого путем:
$user = new User(); $list = $user->login(); foreach($list as $test) { echo $test["username"]; }
И здесь возникает проблема. Когда я выполняю этот код, появляется следующее сообщение об ошибке:
Uncault Error: вызов неопределенного метода Database :: prepare ()
И я не уверен, что я действительно понимаю, что вызывает эту ошибку.
Код работает хорошо, когда я изменяю следующие вещи:
Измените $conn
в database.php на public, а не на private (я думаю, что это плохо …? Но когда он закрыт, я могу выполнять запросы внутри класса Database, я прав? Так что я должен поместить все эти запросы в класс базы данных? Я думаю, что это плохо, потому что в большом проекте это станет действительно большим ..)
И второе изменение, которое мне нужно сделать: Изменить $this->conn->prepare
к $this->conn->conn->prepare
в файле user.php. И здесь у меня действительно нет идеи, почему.
Я имею в виду, что в конструкторе user.php у меня есть $this->conn = new Database()
и поскольку новая база данных вернет мне объект соединения из класса DB, я действительно не знаю, почему должны быть второе conn->
Я был бы очень благодарен, если кто-нибудь сможет мне это объяснить. Я знаю о видимости переменных, и я много читал об этом, но думаю, что я не понял его прямо сейчас, иначе у меня не было бы этой проблемы.
Спасибо за каждый совет! 🙂
database.php:
<?php $host = '127.0.0.1'; $db = 'test'; $user = 'root'; $pass = ''; $charset = 'utf8'; $dsn = "mysql:host=$host;dbname=$db;charset=$charset"; $opt = [ PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, PDO::ATTR_EMULATE_PREPARES => false, ]; $pdo = new PDO($dsn, $user, $pass, $opt);
user.php
<?php class User { /* Properties */ private $conn; /* Get database access */ public function __construct($pdo) { $this->conn = $pdo; } /* List all users */ public function get_users() { return $this->conn->query("SELECT username, usermail FROM user")->fetchAll(); } }
app.php
include 'database.php'; $user = new User($pdo); $list = $user->get_users(); foreach($list as $test) { echo $test["username"]; }
вывод:
username_foo username_bar username_baz
Проверьте (только правильное) руководство PDO для получения дополнительных сведений о PDO.