PHP ООП синглтон, как правильно использовать статические методы?

Помогите разобраться. Делаю класс User. Как правильно организовать класс User и затем его использовать? Мне кажется, я что-то делаю не так.

namespace model;

use \core\DB; 

class User 
{        
 
    protected static $_instance; 
    private $user_data;     

    public function __construct($user_id) 
    {        
        DB::$sql_query = "SELECT * FROM `table_users` where `id_usr` = '".$user_id."' ";
        DB::sql_execute();                      
         $this->user_data = DB::fetch_assoc();     
    } 
  
    public function getUser() {
       return $this->user_data['name']; 
    }


Класс DB сделан в стиле синглтон инициализируется один раз
core\DB::getInstance();

Вот дальше я начинаю путаться. Как правильно организовать класс User и затем его использовать? Сейчас в модели я делаю так, но мне кажется что это как-то не правильно
function __construct() // конструктор в модели
    {                             
     $this->model = new \model\model_place();
     $this->view  = new \view\view_index();    
     $this->user =  new User('1234');
    }
    
    function action_index()
    {
     $data = $this->model->get_data(); 
        echo $this->user->getUser();   // для примера  
     $this->view->generate('view_index.php', 'html_page.htm', $data);  
    }


UPD: использовать синглтон в User ошибка, поправил.
  • Вопрос задан
  • 3562 просмотра
Решения вопроса 1
akubintsev
@akubintsev
Опытный backend разработчик
1) Глобальные сервисы лучше использовать посредством Dependency Injection, иначе будут проблемы с написанием тестов.
2) User, как и иные сущности предметной области, связанные с БД, лучше выполнить через шаблоны DataMapper или ActiveRecord
3) User у вас вряд ли должен быть один при выполнении кода, синглтон совсем не нужен.
Ответ написан
Пригласить эксперта
Ответы на вопрос 5
pavel_salauyou
@pavel_salauyou
Symfony2 & Angular разработчик
зачем огранизовывать класс User через синглтон, какие цели преследуете?
Ответ написан
jakulov
@jakulov
Когда столкнулся с готовым ORM, понял, что чего-то не понимаю, не в плане как ими пользоваться, а как они устроены. Не мудрено, ибо это была Doctrine2 вкупе с Symfony.
Решил после этого попробовать самому с нуля написать что-то похожее, в итоге вышел целый фреймворк. У меня в модуле Core есть несложный маппер объектов с репозиториями — весь фреймворк строил на Dependency Injection.
Сейчас решил перебрать по-косточкам что написал, покрыть тестами — завел блог, чтобы описать весь процесс.
Ответ написан
Комментировать
reffy
@reffy
Я молодец.
Попробуйте для начала какой-нибудь фреймворк толковый. Там вы на практике узнаете что и где надо использовать и как это работает.
Ответ написан
Комментировать
@kambur
Скорее всего синглтон вам действительно не нужен.
Для роботы ви можете просто создать клас User и в нем статические методы (например getUser()) - User::getUser()
Ответ написан
Комментировать
thestump
@thestump
программист PHP
Наверное вы хотели сказать что класс хороший, однако небольшой рефакторинг его улучшит. Вы правы - еще есть над чем поработать для завершения этого класса. Думаю что направлением рефакторинга может стать проработка предметной области. Например User содержит имя, фамилию, адрес, пр. думаю что такие поля должны быть в класс
class User 
{        
    public $name;
    public $family;
    public $address;
}

User что-то делает и оперирует с данными, значит у него должно быть поле data и в системе User может быть только один:
class User 
{        
    public $name;
    public $family;
    public $address;

    private $user_data;     
    
    private static $_instance; 
}

Поля могут быть и еще, но пока остановимся. Подумает что класс может делать!? Пользователь может быть загружен и может быть сохранен
class User 
{        
    public $name;
    public $family;
    public $address;

    private $user_data;     
    
    private static $_instance; 

    public function Load(){}
    public function Save(){}
}

Может загружать данные из БД и выгружать данные в БД:
class User 
{        
    public $name;
    public $family;
    public $address;

    private $user_data;     
    
    private static $_instance; 

    public function Load(){}
    public function Save(){}

    public function LoadData(){}
    public function SaveData(){}
}

И т.д. Потом рекомендуемо написать юнит-тест для одного из методов и с помощью тестирования и рефакторинга написать код этого метода, потом следующий и т.д. до завершения класса. Работу вынести в область ORM и пр.
Ответ написан
Комментировать
Ваш ответ на вопрос

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

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