Обучение/Помощь новичкам | Не пойму
У меня в инфраструктуре игрок обёрнут в отдельный класс, который сам управляет своей сериализацией/десериализацией, умеет в кэширование и финализирует все закэшированные объекты в конце обработки.
class Player
{
/* @var Player[] */
private static $cache = array();
const AUTH_OK = 0;
const AUTH_NOUSER = 1;
const AUTH_PASSWORDMISMATCH = 2;
private $ignoreFinalization;
public static function Exists($name)
{
$q = Database::GetInstance()->Query("SELECT * FROM players WHERE name = '%0%'", array($name));
return Database::GetInstance()->GetRowCount() > 0;
}
public static function Get($name)
{
if(Player::Exists($name))
{
foreach(Player::$cache as $cached)
{
if($cached->name == $name)
return $cached;
}
$player = new Player($name);
Player::$cache[] = $player;
return $player;
}
return null;
}
public static function Authorized()
{
return isset($_SESSION["name"]);
}
public static function Logout()
{
if(Player::Authorized())
unset($_SESSION["name"]);
}
public static function Create($name, $password)
{
Database::GetInstance()->Query("INSERT INTO players(`name`, `password`) VALUES('%0%', '%1%')", array($name, md5($password)));
return Database::GetInstance()->GetAffectedRows() > 0;
}
public static function Authorize($name, $password)
{
if(!Player::Exists($name))
return Player::AUTH_NOUSER;
$player = Player::Get($name);
if($player->password == md5($password))
{
$_SESSION["name"] = $name;
$player->lastLogin = time();
return Player::AUTH_OK;
}
return Player::AUTH_PASSWORDMISMATCH;
}
/*
* All instantiated objects are saved at script end.
* If we don't want to save object, we should exclude them from finalization using Player::IgnoreFinalization()
*/
public static function Finalize()
{
foreach(Player::$cache as $cached)
{
if(!$cached->ignoreFinalization)
$cached->Save();
}
}
protected function __construct($name)
{
$ret = Database::GetInstance()->Fetch("SELECT * FROM players WHERE name = '%0%'", array($name));
$this->ignoreFinalization = false;
if(sizeof($ret) > 0)
{
foreach($ret[0] as $field => $value)
$this->$field = $value;
}
}
public function GetLastVisitTime()
{
return date("d.m.y H:i", $this->lastLogin);
}
public function IsOnline()
{
return time() - $this->lastLogin < 300;
}
public function IgnoreFinalization()
{
$this->ignoreFinalization = true;
}
public function Save()
{
$fields = get_object_vars($this);
$setter = "";
foreach($fields as $field => $val)
{
// HACK
if(!is_numeric($field) && $field != "ignoreFinalization")
$setter .= ", `$field` = '" . $val . "'";
}
$setter = substr($setter, 1);
Database::GetInstance()->Query("UPDATE players SET $setter WHERE uid = '%0%'", array($this->uid));
}
}
if(isset($_SESSION["name"]))
{
if(Player::Exists($_SESSION["name"]))
{
$player = Player::Get($_SESSION["name"]);
$player->lastLogin = time();
$player->ua = $_SERVER["HTTP_USER_AGENT"];
}
else
{
unset($_SESSION["name"]);
Utils::Notify("#internalError");
}
}
register_shutdown_function("Player::Finalize");
[xrystalll] , а тут не процедурный, тут линейный код. В процедурном все выполняется в процедуре функции, как пример можно взять волдпресс сносная процедурка.
monobogdan , да, вот примерно так, когда уже не думаешь про запросы и куда что вставить а просто вызываешь метод обработки, плюс все в одном месте а не 100500 раз один и тот же ког в каждом файле
Эх так и знал что надо было на PDO писать
monobogdan , я бы создал интерфейс на самом деле , и не грузил бы так класс + использовал бы конструктор . А так у тебя обычный класс
Trec80 , как раз таки это частный случай не нагруженного класса. Ещё юзаю собственный универсальный сериализатор/десериализатор из БД, реализующий ArrayAccess, виртуальные геттеры/сеттеры, query builder, ну и само собой финализацию. Касательно приведенного примера, Player::Get управляет кэшированием, чтобы не плодить кучу инстансов.
________
посл. ред. 20.01.2019 в 14:32; всего 2 раз(а); by monobogdan
________
посл. ред. 20.01.2019 в 14:32; всего 2 раз(а); by monobogdan
monobogdan , Используешь MVC?
Trec80 , нет, не сторонник ни MVC, ни ECS.
monobogdan (20.01.2019 в 14:32)
Trec80 , нет, не сторонник ни MVC, ни ECS.
Trec80 , нет, не сторонник ни MVC, ни ECS.
Тогда сойдет , для MVC это было бы грубо
Стр.: 1, 2