Обычно это делается в отдельном методе, наподобие
Save.
У пользователя, которого нет в базе,
$this->id будет нулевым.
И для загрузки данных лучше сделать отдельный метод -
Load.
public function __construct($id = NULL)
{
$this->id = $id;
$this->Load();
}
public function Load()
{
// идентификатор не указан, загружать данные не нужно
if (!isset($this->id) || (int)$this->id == 0)
{
return false;
}
// указан идентификатор, загружаем данные в текущий экземпляр класса
$mysqli = db_connect();
$req = 'SELECT u.ID, u.name, u.age, u.city_id, c.city_name FROM users AS u '.
'INNER JOIN cities AS c ON (c.city_id = u.city_id) '.
'WHERE u.ID = '.$this->id; // опасно так передавать в запрос данные
$res = $mysqli->query($req);
if ($res !== false){
if ($res->num_rows == 1 )
{
// смысла в цикле нет, ожидается ведь одна строка данных
while ($row = $res->fetch_assoc())
{
$this->id = $row['ID'];
$this->username = $row['name'];
$this->city_name = $row['city_name'];
$this->city_id = $row['city_id'];
$this->age = $row['age'];
}
}
else
{
return false;
}
}
else
{
return false;
}
}
public function Save()
{
$sql = '';
$params = [];
if (!isset($this->id) || (int)$this->id == 0)
{
// запрос на добавление данных в базу
$sql = 'INSERT INTO users (name, city_id, age) VALUES (?, ?, ?)';
// параметры запроса
$params = [$this->username, $this->city_id, $this->age];
}
else
{
// запрос на обновление данных в базе
$sql = 'UPDATE users SET name = ?, city_id = ?, age = ? WHERE ID = ?';
// параметры запроса
$params = [$this->username, $this->city_id, $this->age, $this->id];
}
// код выполнения запроса
// не могу быть уверен в коде, давно не писал и проверять лень
// должно быть что-то типа такого:
$mysqli = db_connect(); // лучше сделать отдельный метод для создания и закрытия соединений
// подготавливаем запрос
$s = $mysqli->prepare($sql);
// выполняем запрос с указанными параметрами
$s->execute($params);
// тут еще неплохо бы закрыть все соединения :-)
}
Можно пойти дальше и сделать базовый класс, который будет содержать готовые методы
Load и
Save.
Либо сделать отдельный класс, который будет получать данные и заполнять экземпляры классов этими данными, сохранять и удалять данные. В таком случае классы таблиц (сущности) будут просто описывать структуру данных в базе и не будут выполнять никаких действий. Этот вариант мне нравится больше, т.к. он чище (проще) и более гибкий.
Придется придумать, как сопоставлять данные, если имена свойств не соответствую именам полей в базе. Скорее всего интерфейсы нужно будет использовать. Также учесть свойства, которые не определены в базе (которые следует игнорировать).
Для работы со структурой классов потребуется использовать
Reflection.
В общих чертах примерно следующим образом:
// создаем экземпляр класса User
$instance = new User();
// получаем информацию об экземпляре класса
$r = new \ReflectionClass($instance);
// получаем список публичных свойств
$propeties = $r->getProperties(\ReflectionProperty::IS_PUBLIC);
// перебираем все свойства
foreach ($propeties as $property)
{
// получаем имя свойства
$propertyName = $property->getName();
// получаем значение свойства
$propertyValue = $property->getValue();
// и далее можно использовать полученную информацию
// для формирования динамических запросов к базе
// полученные из базы данные можно передать в нужные свойства
$property->setValue("значение из базы");
}
Готовое решение
найти будет проще :-)