草庐IT

php - Class::getInstance 的起源/解释?

coder 2024-04-22 原文

我对经典继承相当陌生,因为我主要处理 ECMAScript 和 Python,尽管我对 PHP 也有一定了解(不寒而栗)。我知道它深受 Java 和其他基于经典继承的语言的影响。

问题:

我正在查看框架中的几个类,并注意到没有调用(至少直接调用)“new”关键字来创建实例,而是使用公共(public) getInstance 方法来创建初始对象。

有人可以解释这背后的策略吗?我什么时候应该在自己的类(class)中使用它?

相关代码:

class FrontController {
    public static $_instance;

    public static function getInstance() {
        if ( !(self::$_instance instanceof self) ) {
            self::$_instance = new self();
        }
        return self::$_instance;
    }
}

$front = FrontController::getInstance();
$front->route();
echo $front->getBody();

完整代码:

class FrontController
{
    protected $_controller, $_action, $_params, $_body, $_url;

    public static $_instance;

    public static function getInstance()
    {
    if ( ! ( self::$_instance instanceof self) ) {
        self::$_instance = new self();
    }
    return self::$_instance;
    }

    private function __construct() {
    $this->uri = uri::getInstance();

    if ( $this->uri->fragment(0) ) {
        $this->_controller = $this->uri->fragment(0).'Controller';
    }
    else {
        $config = config::getInstance();
        $default = $config->config_values['application']['default_controller'].'Controller';
        $this->_controller = $default;
    }

    if ( $this->uri->fragment(1) ) {
        $this->_action = $this->_uri->fragment(1);
    } else {
        $this->_action = 'index';
    }
    }

    public function route() {
    $con = $this->getController();
    $rc = new ReflectionClass( $con );

    if ( $rc->implementsInterface( 'IController' ) ) {
        $controller = $rc->newInstance();

        if ( $rc->hasMethod( $this->getAction() ) ) {
        $method = $rc->getMethod( $this->getAction() );
        } else {
        $config = config::getInstance();
        $default = $config->config_values['application']['default_action'];
        $method = $rc->getMethod( $default );
        }
        $method->invoke( $controller );
    } else {
        throw new Exception('Interface iController must be implemented');
    }
    }

    public function getController() {
    if ( class_exists( $this->_controller ) ) {
        return $this->_controller;
    }
    else {
        $config = config::getInstance();
        $default = $config->config_values['application']['error_controller'].'Controller';
        return $default;
    }
    }

    public function getAction() {
    return $this->_action;
    }

    public function getBody() {
    return $this->_body;
    }

    public function setBody( $body ) {
    $this->_body = $body;
    }
}

最佳答案

这很简单。看起来,很像 Zend Framework 的想法?
无论如何,这实现了单例设计模式。它禁止程序员创建多个 Controller 实例。那么,您是否可以从代码中的任何位置访问您的 Controller ,而不是创建一个新的 FrontController 或类似的东西,您只是要求获得之前创建的 One 实例。

如果不存在实例,它会创建其他实例,它只会返回您之前创建的前端 Controller 。


希望对您有所帮助!

关于php - Class::getInstance 的起源/解释?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1449362/

有关php - Class::getInstance 的起源/解释?的更多相关文章

  1. ruby - 有人可以帮助解释类创建的 post_initialize 回调吗 (Sandi Metz) - 2

    我正在阅读SandiMetz的POODR,并且遇到了一个我不太了解的编码原则。这是代码:classBicycleattr_reader:size,:chain,:tire_sizedefinitialize(args={})@size=args[:size]||1@chain=args[:chain]||2@tire_size=args[:tire_size]||3post_initialize(args)endendclassMountainBike此代码将为其各自的属性输出1,2,3,4,5。我不明白的是查找方法。当一辆山地自行车被实例化时,因为它没有自己的initialize方法

  2. Ruby - 如何处理子类意外覆盖父类(super class)私有(private)字段的问题? - 2

    假设您编写了一个类Sup,我决定将其扩展为SubSup。我不仅需要了解你发布的接口(interface),还需要了解你的私有(private)字段。见证这次失败:classSupdefinitialize@privateField="fromsup"enddefgetXreturn@privateFieldendendclassSub问题是,解决这个问题的正确方法是什么?看起来子类应该能够使用它想要的任何字段而不会弄乱父类(superclass)。编辑:equivalentexampleinJava返回"fromSup",这也是它应该产生的答案。 最佳答案

  3. ruby - 解释为局部变量会覆盖方法名称吗? - 2

    如thisquestion,当在其自己的赋值中使用未定义的局部变量时,它的计算结果为nil。x=x#=>nil但是当局部变量的名称与现有的方法名称冲突时,就比较棘手了。为什么下面的最后一个示例返回nil?{}.instance_eval{a=keys}#=>[]{}.instance_eval{keys=self.keys}#=>[]{}.instance_eval{keys=keys}#=>nil 最佳答案 在Ruby中,因为可以在没有显式接收器和括号的情况下调用方法,所以在局部变量引用和无接收器无参数方法调用之间存在语法歧义:f

  4. ruby - 无法理解 `puts{}.class` 和 `puts({}.class)` 之间的区别 - 2

    由于匿名block和散列block看起来大致相同。我正在玩它。我做了一些严肃的观察,如下所示:{}.class#=>Hash好的,这很酷。空block被视为Hash。print{}.class#=>NilClassputs{}.class#=>NilClass为什么上面的代码和NilClass一样,下面的代码又显示了Hash?puts({}.class)#Hash#=>nilprint({}.class)#Hash=>nil谁能帮我理解上面发生了什么?我完全不同意@Lindydancer的观点你如何解释下面几行:print{}.class#NilClassprint[].class#A

  5. 语法类似于 GitHub Flavored Markdown 的 Ruby markdown 解释器? - 2

    我使用Jekyll运行博客,并认为我会解决RedcarpetMarkdown解释器,因为它是developedandusedbyGitHub.好吧,我只是碰巧遇到了一个错误,去检查问题,然后foundthis.Maintainersays,"Asyouprobablyhavenoticed(harharharhar)Idon'thavetimetomaintainRedcarpetanymore.It'snotapriorityforme(IfindMarkdownthoroughlyboring)andit'snotapriorityforGitHub,becausewenolong

  6. ruby - 使用 Class.new 时访问外部范围 - 2

    是否有可能以某种方式访问​​Class.new范围内的a?a=5Class.new{defb;aend}.new.b#NameError:undefinedlocalvariableormethod`a'for#:0x007fa8b15e9af0>#:in`b' 最佳答案 即使@MarekLipka的回答是正确的——改变变量范围总是有风险的。这是可行的,因为每个block都带有创建它的上下文,因此您的局部变量a突然变得不那么局部了——它变成了一个“隐藏的”全局变量:a=5object=Class.new{define_method(

  7. ruby - 有人可以解释一下在 Ruby 中注入(inject)的真实、通俗易懂的用法吗? - 2

    我正在学习Ruby,遇到了inject。我正处于理解它的风口浪尖,但当我是那种需要真实世界的例子来学习一些东西的人时。我遇到的最常见的例子是人们使用inject来添加一个(1..10)范围的总和,我不太关心这个。这是一个任意的例子。在实际程序中我会用它做什么?我正在学习,所以我可以继续使用Rails,但我不必有一个以Web为中心的示例。我只需要一些我可以全神贯注的目标。谢谢大家。 最佳答案 inject有时可以通过它的“其他”名称reduce更好地理解。它是一个对Enumerable进行操作(迭代一次)并返回单个值的函数。它有许多有

  8. ruby - 模块中的 instance_eval 与 class_eval - 2

    classFooincludeModule.new{class_eval"deflab;puts'm'end"}deflabsuperputs'c'endendFoo.new.lab#=>mc======================================================================classFooincludeModule.new{instance_eval"deflab;puts'm'end"}deflabsuperputs'c'endend注意这里我把class_eval改成了instance_evalFoo.new.labresc

  9. ruby-on-rails - Rails - 父类(super class)不匹配 - 2

    玩转Rails和Controller继承。我创建了一个名为AdminController的Controller,其中一个名为admin_user_controller的子类位于/app/controllers/admin/admin_user_controller.rb这是我的routes.rbnamespace:admindoresources:admin_user#Havetheadminmanagethemhere.endapp/controllers/admin/admin_user_controller.rbclassAdminUserController应用程序/Contr

  10. ruby-on-rails - ApplicationController :Class 的未定义方法 `caches_action' - 2

    我正在尝试升级到Rails4beta1,但遇到了一些问题。简而言之,这就是我的应用程序Controller的样子。classApplicationControllercaches_action在Rails4中移到了它自己的gem中,因此包含gem应该可以解决问题。gem"actionpack-action_caching",github:"rails/actionpack-action_caching"但是当我运行我的请求规范或在浏览器中访问该应用程序时,我收到此错误。app/controllers/application_controller.rb:3:in`':undefinedm

随机推荐