В настоящее время я создаю систему блога, которая, как я надеюсь, превратится в полноценную CMS в будущем.
Есть два класса / объектов, которые были бы полезны для глобального доступа (соединение базы данных mysqli и пользовательский класс, который проверяет, вошел ли пользователь в систему).
Я ищу способ сделать это без использования глобальных объектов и, если возможно, не передавать объекты каждой функции при каждом вызове.
Вы можете сделать объекты Static, тогда у вас есть доступ к ним в любом месте. Пример:
myClass::myFunction();
Это будет работать в любом месте скрипта. Однако вы можете читать статические классы и, возможно, использовать класс Singleton для создания обычного класса внутри статического объекта, который можно использовать где угодно.
расширенный
Я думаю, что то, что вы пытаетесь сделать, очень похоже на то, что я делаю с моим классом DB.
class myClass { static $class = false; static function get_connection() { if(self::$class == false) { self::$class = new myClass; } return self::$class; } // Then create regular class functions. }
Что происходит после того, как вы получите соединение, используя $ object = myClass :: get_connection (), вы сможете делать что-либо регулярно.
$object = myClass::get_connection(); $object->runClass();
расширенный
После того, как вы сделаете эти статические объявления, вам просто нужно вызвать get_connection и присвоить возвращаемое значение переменной. Тогда остальные функции могут иметь такое же поведение, как класс, который вы вызывали с помощью $ class = new myClass (потому что это то, что мы сделали). Все, что вы делаете, это хранить переменную класса внутри статического класса.
class myClass { static $class = false; static function get_connection() { if(self::$class == false) { self::$class = new myClass; } return self::$class; } // Then create regular class functions. public function is_logged_in() { // This will work $this->test = "Hi"; echo $this->test; } } $object = myClass::get_connection(); $object->is_logged_in();
Вы можете передать глобальные объекты в настоящее время в конструктор.
<?php class Foo { protected $m_db; function __construct($a_db) { $this->m_db = $a_db; } } ?>
Недавно я обновил свою структуру в рамках подготовки ко второй версии CMS нашей компании. Я расстегнул огромное количество вещей, которые сделал статичным, чтобы заменить их обычными объектами. При этом я создал огромную гибкость, которая использовалась для того, чтобы полагаться на то, как я проходил и взламывал файлы ядра. Теперь я использую только статические конструкции, когда единственной альтернативой являются глобальные функции, которые связаны только с базовыми функциональными возможностями низкого уровня.
Я собираюсь показать несколько строк моего файла bootstrap.php (все мои запросы отправляются через этот файл, но вы можете добиться того же результата, включив его в начало каждого файла), чтобы показать вам, что я имею в виду. Это довольно внушительная версия того, что вы, вероятно, используете в своей ситуации, но, надеюсь, эта идея полезна. (Все это слегка изменено.)
//bootstrap.php ... // CONSTRUCT APPLICATION { $Database = new Databases\Mysql( Constant::get('DATABASE_HOST'), Constant::get('DATABASE_USER'), Constant::get('DATABASE_PASSWORD'), Constant::get('DATABASE_SCHEMA') ); $Registry = new Collections\Registry; $Loader = new Loaders\Base; $Debugger = new Debuggers\Dummy; // Debuggers\Console to log debugging info to JavaScript console $Application = new Applications\Base($Database, $Registry, $Loader, $Debugger); } ...
Как вы можете видеть, у меня есть все возможности для создания моего объекта приложения, который я могу предоставить в качестве аргумента в конструкторе другим объектам, чтобы дать им доступ к этим «глобальным» потребностям.
Объект базы данных не требует пояснений. Объект реестра действует как контейнер для объекта, который я могу получить в другом месте приложения. Загрузчик действует как утилита для загрузки других ресурсов, таких как файлы шаблонов. И отладчик должен обрабатывать вывод отладки.
Я могу, например, изменить класс базы данных, который я создаю, и, вуаля, у меня есть соединение с базой данных SQLite. Я могу изменить класс отладчика (как отмечено), и теперь вся моя информация об отладке будет записана на мою консоль JavaScript.
Хорошо, теперь вернемся к проблеме. Как вы даете другим объектам доступ ко всему этому? Вы просто передаете его аргументу конструктору.
// still bootstrap.php ... // DISPATCH APPLICATION { $Router = new Routers\Http($Application); $Router->routeUri($_SERVER['REQUEST_URI']); } ...
Не только это, но мой Маршрутизатор (или любой другой объект, который я строю с ним) также более гибкий. Теперь я могу просто создать экземпляр объекта приложения по-разному, и мой Router будет вести себя по-разному соответственно.
Ну, если у вас уже есть какой-то объект, по которому вы ссылаетесь на систему блога, вы можете скомпоновать эти объекты, чтобы они были $blog->db()
и $blog->auth()
или что-то еще.