Должен был спросить кто-то это давным-давно.
Что лучший способ состоит в том, чтобы использовать другие классы в другом классе?
Например, позволяет, говорят, что у меня есть класс приложений:
class Application
{
public function displayVar() {
echo 'hello world';
}
}
и класс базы данных
class Database
{
// connects to db on construct
public function query() {
// queries db
}
}
теперь, я хочу добавить функцию к своему классу приложений, который использует функцию от класса дб
class Application
{
public function displayVar() {
echo 'hello world';
}
public function getVar() {
global $db;
$sql = foo;
$db->query($sql);
}
}
таким образом я имею
$db = new Database();
$app = new Application();
$app->getVar('var');
Существует ли лучший способ сделать это? Действительно то, что я ищу, является стандартным способом сделать его, не другой способ подстроить его.
Есть пара способов сделать это. Глобальные переменные - это, безусловно, один из способов, и на большинство из них тоже смотрят свысока. Можно создать Singleton , и все другие классы, которым нужен доступ к базе данных, будут обращаться к этому Singleton.
final class Database {
private static $connection;
public static function getInstance() {
if(self::$connection == NULL) {
self::$connection = // init your database connection
}
return self::$connection;
}
}
И использовать этот объект подключения к БД в любом классе, который в этом нуждается.
class Application {
public function displayVar() {
echo 'hello world';
}
public function getVar() {
$db = Database::getInstance();
$sql = foo;
$db->query($sql);
}
}
Это все хорошо для начала и большой шаг за пределы использования глобальных переменных, но вы можете сделать это лучше с помощью Dependency Injection. Dependency Injection - это простая концепция, которая заключается в том, что если класс имеет какие-либо внешние зависимости, такие как подключение к базе данных в вашем примере, то вы явно передаете их нужному классу в его конструкторе или методе. Таким образом, новый код будет выглядеть как решение Джонатана. Основное преимущество использования инъекции зависимостей заключается в юнит-тестировании, где вы можете легко заменить этот реальный объект БД на имитирующий объект и передать его тому, кому он нужен.
class Application {
private $db;
public function __construct(Database $db) {
$this->db = $db;
}
public function displayVar() {
echo 'hello world';
}
public function getVar() {
$sql = foo;
$this->db->query($sql);
}
}
Для небольших проектов вы можете легко сделать это самостоятельно. Для больших проектов доступны различные DI-фреймворки для PHP
$db
может быть свойством вашего класса Application
. Любая ссылка на него из экземпляра Application
будет сделана через $this
- $this->db
class Application {
private $db = null;
public function setDB($name) {
$this->db = new Database($name);
}
}
Включите файл класса (или настройте автоиндикатор) в каждый PHP-файл, которому нужен данный класс. Затем выполните его инстанцирование по мере необходимости.
Если вам нужен "общий" экземпляр объекта, вы можете посмотреть на Singleton and Factory patterns: