У меня есть класс под названием «Макет» для макета страницы, другой класс, называемый «Пользователь» для пользователя.
Каждая страница, которую я создаю, создаю новый макет.
Когда пользователь входит в систему, создается новый Пользователь.
Как получить экземпляр класса макета, чтобы узнать об инстанцированном пользователе? Я мог бы также сохранить весь экземпляр пользователя в переменной сеанса. Я предполагаю, что это плохая идея. Каковы наилучшие методы для этого?
class User { var $userid; var $email; var $username; function User($user) { $this->userid = $this->getUid($user); $this->email = $this->getEmail($user); $this->username = $user; } function getUid($u) { ... } function getEmail($u) { ... } } class Layout { var $var1; var $var2; var $var3; function Layout() { //defaults... } function function1() { echo "something"; } function function2() { echo "some other stuff"; } function function3() { echo "something else"; } }
поэтому в index.php, например, я бы сделал следующее:
include "user.php" include "layout.php" $homelayout = new Layout(); $homelayout->function1(); $homelayout->function2(); $homelayout->function3();
теперь скажем, что в login.php кто-то вошел в систему:
include "layout.php" include "user.php" if(userAuthSuccess) { $currentUser = new User($_POST['username']); }
какой лучший способ получить доступ к $ currentUser и его переменным-членам, таким как $ currentUser-> email и т. д. из всех php-файлов здесь, если пользователь не вышел из системы?
Поскольку для каждого запроса будет только один Пользователь, и, таким образом, для каждого запуска вашей программы, это будет случай, чтобы сделать «Пользователь» классом Singleton, как описано здесь:
http://php.net/manual/en/language.oop5.patterns.php
Это обеспечило бы один способ для других классов ссылаться на текущего пользователя без возможности доступа к неправильному экземпляру, поскольку есть только один.
ОТКАЗ ОТ ОТВЕТСТВЕННОСТИ: Да, я знаю, что Singeltons часто используются в неправильных местах для неправильной цели, и некоторые люди склонны обвинять эту проблему в шаблоне вместо людей, которые злоупотребляли им каким-то вонючим кодом. Это, однако, является очень хорошим вариантом использования шаблона Singelton.
Я думаю, что лучшее средство для решения, изложенное выше, предназначено для концепции под названием Dependency Injection, в которой вы пишете дополнительный класс, который будет вводить зависимость (объект в этом случае) к запрашивающему классу. Большинство современных разработчиков будут придерживаться этой технологии встраивания зависимостей в свои приложения, поскольку это позволит:
Программы с ограниченной связью. Поскольку зависимость вводится третьим классом, нет необходимости жестко кодировать зависимость в логике программы.
Поддерживаемый код. Это та особенность парадигмы ООП, которая привлекает больше всего. Это особенно актуально, когда речь идет о крупномасштабных программах.
Управление памятью. Как разработчик, вы можете управлять памятью в соответствии с вашими требованиями к спецификации.
«Глобализация» чего-либо, помещая его в переменную сеанса или cookie с единственной целью глобализации, это очень плохая привычка вступать, и это приводит к тесно связанным библиотекам, которые полагаются на произвольную переменную, устанавливаемую вне класса. Сессионные переменные в целом хороши, чтобы держаться подальше от других причин.
Лучший способ получить переменную в любом классе – передать ее в качестве аргумента. У вас есть метод в вашем классе Layout, который отображает (выводит) его? Вы можете добавить аргумент $ data к этому методу, который принимает ассоциативный массив данных, который можно использовать в макете.
Я лично использовал бы класс реестра (Singleton) и зарегистрировал там пользователя для доступа к макету. Таким образом, вам нужно передать экземпляр реестра в макет. Класс User не является неотъемлемой частью конструкции Layout, так как он должен быть связан только с макетом, поэтому я не передал бы это в конструкторе.
Другим методом было бы использование контроллера для организации этих взаимодействий между представлениями и моделями. Всякий раз, когда создается новый контроллер, буфера выводится. Затем, во время рендеринга, буферизуйте содержимое и назначьте его свойствам (или массиву свойств) представления, которые затем могут их отобразить. Вероятно, вам не нужен настоящий класс модели, который должен быть передан в View / Layout – просто его вывод.
Используйте шаблон реестра. Не нужно делать это синглом, все бросают это слово.
include "layout.php" include "user.php" if(userAuthSuccess) { $data['currentUser'] = new User($_POST['username']); } $data['nav'] = new nav('home'); $homelayout = new Layout( $data );
Теперь $homelayout
может получить доступ к $data
(который содержит все переменные, которые вы вкладываете в него) через массив данных.