我正在开发的其中一个项目使用第三方库。目前,我将这些对象存储在全局变量中(例如$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都是我真正使用的。
我正在评估:
我不会评估的内容:
欢迎任何第四种选择。
答案 0 :(得分:3)
你误解了OOP的含义。
您花在代码上的大部分时间都不会继续编写代码。花在代码库上的绝大部分时间用于维护它,使其正常工作。 OOP,测试,编码风格等都是减少维护时间的工具,可以减少您需要完成的大部分工作。
OOP不是为了“简化”事物,相反,OOP通常比函数式编程更难阅读和理解。 OOP的目的是允许轻松重构层,而不必影响应用程序的其余部分。
我们可以争论为什么全局变量整天都不好。但在底线,全球空间是一个很好的漏洞来源。依赖注入是一个很好的替代方案。
对于您的具体示例,传递HTML纯化库听起来是个好主意。如果明天你会找到一个更好的库,你可以使用它提供更好的功能或性能,你可以通过使用依赖注入相对容易地切换。
答案 1 :(得分:0)
我不会尝试和自制一个好的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 */
}
}