Один из проектов, который я разрабатываю, использует сторонние библиотеки. На данный момент я храню эти объекты в глобальной переменной (например, $GLOBALS['_HTMLPurifier']
).
Я знаю, что все говорят «не используйте $GLOBALS
в объектно-ориентированном коде используйте внедрение зависимости «. Проблема в том, что большинство этих классов предназначены для упрощения для разработчиков. Например:
<?php
namespace Sarciszewski\MyProject\Security;
$GLOBALS['_HTMLPurifier'] = new \HTMLPurifier(
\HTMLPurifier_Config::createDefault()
);
class XSS
{
/* blah */
public static function clean($input, $context)
{
/* logic here */
$input = $_GLOBALS['_HTMLPurifier']->purify($input);
/* other things here depending on $context */
}
}
Идея в том, что любой, кто использует этот проект, буквально просто должен сделать это:
<?php
namespace \Otherdev\HelloWorld;
use \Sarciszewski\MyProject as MyP;
$x = isset($_GET['url']) ? $_GET['url'] : '';
echo "<input type=\"text\" name=\"url\" value=\"".MyP\Security\XSS::clean($x, 'attribute')."\" />";
Я не хочу заставлять людей вводить зависимости. Я бы предпочел оставить один глобальный экземпляр этих объектов. Уместны ли здесь синглтоны? Или есть другой шаблон дизайна, которому нужно следовать?
(Наихудший сценарий: я просто говорю, прикрути это и делай так, потому что он выполняет свою работу.)
УТОЧНИТЬ: Я не делаю библиотеку, которую другие люди могли бы использовать в своих рамках, я делаю структуру, которая называет библиотеки других людей.
Я хочу явно скрыть все внедрения зависимостей, кроме авторов модульных тестов, в подходе «пиши меньше, делай больше». Пользователь никогда не должен передавать объект чему-либо.
Юзабилити важнее, чем правильность (которая все еще имеет значение, но не так много). Кроме того, я хотел бы минимизировать дополнительные сторонние зависимости. PHPUnit, HTMLPurifier и Twig — все, что я действительно использую.
Что я оцениваю:
Что я не буду оценивать:
Любые четвертые варианты приветствуются.
Вы неправильно понимаете, что такое ООП.
Большую часть времени вы тратите на код, а не пишете его. Подавляющее большинство времени, потраченного на кодовую базу, тратится на его поддержку, заставить его работать правильно. ООП, тесты, стиль кодирования и т. Д. — все это инструменты, позволяющие сократить количество времени, затрачиваемое на его обслуживание, и сократить большую часть работы, которую вам необходимо выполнить.
ООП не предназначен для «упрощения» вещей, напротив, ООП часто труднее читать и понимать, чем, скажем, функциональное программирование. Смысл ООП состоит в том, чтобы обеспечить легкую рефакторинг слоев, не влияя на остальную часть приложения.
Мы можем спорить о том, почему глобальные переменные плохи весь день. Но суть в том, что Global space — отличный источник ошибок. Инъекция зависимости является хорошей альтернативой этому.
Для вашего конкретного примера прохождение библиотеки очистки HTML звучит как хорошая идея. Если завтра вы найдете лучшую библиотеку, которую вы можете использовать, которая обеспечивает лучшие функции или производительность, вы можете относительно легко переключаться с помощью Dependency Injection.
Вместо того, чтобы пытаться найти хорошее решение для DI, я бы сказал, использовать библиотеку, которая уже существует.
PHP DI действительно приятно, так как это позволит вам просто напечатать подсказку для любого класса, который вы хотите внедрить в другой класс в __construct
метод, и он будет автоматически включен!
Может показаться, что это не ответ, но вопрос основан на мнениях. Лично я бы сказал, что использование глобальных переменных — очень плохая идея, потому что это сбивает с толку и может привести к появлению некоторых действительно трудных для отслеживания ошибок в коде. Я бы на 100% рекомендовал использовать очень упрощенный DI для решения подобных ситуаций.
В вашем случае (используя PHP-DI) вы можете сделать следующее:
class XSS
{
/**
* @Inject
* @var HTMLPurifier
*/
public static $purifier;
public static function clean($input, $context)
{
/* logic here */
$input = self::$purifier->purify($input);
/* other things here depending on $context */
}
}