全局vs函数与静态类方法

Ale*_*lex 5 php global class function

假设你有一个独特的对象,它被所有其他类和函数使用......就像$application.

您将如何在函数中访问此对象?

  1. 在每个函数中使用全局变量:

    global $application;
    $application->doStuff();
    
    Run Code Online (Sandbox Code Playgroud)
  2. 创建一个函数,就像application()将对象实例化为静态变量并返回它一样; 然后在需要访问对象的任何地方使用此函数:

    application()->doStuff();
    
    Run Code Online (Sandbox Code Playgroud)
  3. 创建一个单例的东西,就像一个返回唯一实例的对象类中的静态方法,并使用此方法来访问该对象:

    Application::getInstance()->doStuff();
    
    Run Code Online (Sandbox Code Playgroud)
  4. KingCrunch&skwee:将应用程序对象作为参数传递给需要的每个函数/类

    ...
    public function __construct(Application $app, ...){
      ....
    
    Run Code Online (Sandbox Code Playgroud)

如果还有其他选择,请发布.我想知道哪些选项是最有效/被认为是"最佳实践".

Dmi*_*sev 4

我会将其传递给所有需要的方法。IE

function doFoo(Application $app) {
    $app->doStuff();
}
Run Code Online (Sandbox Code Playgroud)

全局和单例都被认为是不好的,并且将您的代码束缚得太多,这使得单元测试变得更加困难。如果您对以下语句回答“是”,则允许您使用单例时有一条规则:

我是否需要向我的应用程序引入全局状态并且我必须拥有给定对象的单个实例并且拥有多个实例将导致错误

如果您对所有 3 个部分的回答都是肯定的,那么您可以使用单例。在任何其他情况下,只需将所有实例传递给所有需要它们的方法即可。如果它们太多,请考虑使用诸如 Context 之类的东西

class Context {
    public $application;
    public $logger;
    ....
}
========
$context = new Context();
$context->application = new Application();
$context->logger = new Logger(...);
doFoo($context);
========
function doFoo(Context $context) {
    $context->application->doStuff();
    $context->logger->logThings();
}
Run Code Online (Sandbox Code Playgroud)

(如果您需要保护数据或操作数据,或者想要使用延迟启动等,则可以使用 getter/setter)。

祝你好运!