【问题标题】:Static method that calls itself on an object在对象上调用自身的静态方法
【发布时间】:2014-09-02 11:15:11
【问题描述】:

我想要一个可以这样使用的类:

Thing::doThis()->doThat()->doImportantThing();

Thing::doThat()->doImportantThing();

Thing::doImportantThing();

但目前我只能这样使用:

$thing = new Thing();
$thing->doThis()->doThat()->doImportantThing();

我必须在课堂上进行哪些更改才能以我想要的方式使用它?我已经在每个函数调用中返回了一个 Thing 实例。

我想使用它的原因很简单,想象一个邮件类,在构造函数中定义默认的 from 和 to,但你可能想要更改它,所以你这样做 Mail::setFrom()->send()。如果要更改为,请使用Mail::setTo()->send()。如果它要被不同的人在不同的项目中使用,它只会更容易使用。

我希望通过调用Mail::{something} 来进行构造函数调用,然后运行{something} 函数。

【问题讨论】:

  • 我不禁想知道,为什么?
  • 也许this 会有所帮助
  • @Sami 谢谢,但这个问题部分有帮助,但我想通过这个例子实现的是避免getInstance() 调用。
  • 这个问题的真正答案是告诉你停止使用静态方法。
  • 好吧,因为你需要一个实例(在任何健全的设置中)。更重要的是,它很可能会产生紧密耦合的代码,隐藏依赖关系,是维护和调试的噩梦,并且会扼杀可测试性。

标签: php oop


【解决方案1】:

你可以这样做

class Thing {

    public static function __callStatic($name, $arguments){
        $thing = new self;
        return $thing->$name($arguments);
    }

    public function __call($name, $arguments){
        return $this->$name($arguments);
    }

    private function doThis(){
        echo 'this'.PHP_EOL;
        return $this;
    }

    private function doThat(){
        echo 'that'.PHP_EOL;
        return $this;
    }

    private function doImportantThing(){
        echo 'Important'.PHP_EOL;
        return $this;
    }
}

Thing::doThis()->doThat();
Thing::doThat()->doImportantThing();

不过,这是一个非常丑陋的解决方法。它使您无法拥有私有方法。

DEMO

【讨论】:

  • 我想使用它的原因很简单,想象一个邮件类,在构造函数中定义默认的fromto,但你可能想要更改它,所以你这样做@ 987654325@。如果要更改为,请使用Mail::setTo()->send()。如果它要被不同的人在不同的项目中使用,它只会更容易使用。
  • 所以你想做方法链,还是只是静态调用?
  • @MichelTomé 为什么不将可选参数传递给send() 方法?
  • 两者,这有点难以解释...我想通过调用Mail::{something} 来进行构造函数调用,然后运行{something} 函数
  • @MichelTomé 更新了答案。
【解决方案2】:

静态方法的一大优点是它们可以在对象上下文中工作,并且可以这样调用:$instance->staticMethod()

在这里(即使您在 ide 中完成代码,并且可以按照您的预期工作):

class Mail
{   
    public static $from;
    public static $to;
    public static $subject;
    public static $message;

    protected static $onlyInstance;

    protected function __construct () 
    {
        // disable creation of public instances 
    }

    protected static function getself()
    {
        if (static::$onlyInstance === null) 
        {
            static::$onlyInstance = new Mail;
        }

        return static::$onlyInstance;
    }

    /**
     * set from 
     * @param string $var
     * @return \Mail
     */
    public static function from($var) 
    {
        static::$from = $var;
        return static::getself();
    }

    /**
     * set to
     * @param string $var
     * @return \Mail
     */
    public static function to($var) 
    {
        static::$to = $var;
        return static::getself();
    }

    /**
     * set subject
     * @param string $var
     * @return \Mail
     */
    public static function subject($var) 
    {
        static::$subject = $var;
        return static::getself();
    }

    /**
     * set message
     * @param string $var
     * @return \Mail
     */
    public static function message($var) 
    {
        static::$message = $var;
        return static::getself();
    }

    public static function send()
    {
        echo "<pre><b>Hurrah mail sent</b>"
                . "\nFrom:\t ".static::$from.""
                . "\nTo:\t ".static::$to." "
                . "\nSubject: ".static::$subject.""
                . "\nMessage: ".static::$message;
        echo "</pre>";
    }
}

使用示例:

Mail::from('george@garcha')
        ->to('michel@tome')
        ->subject('hehe works')
        ->message('your welcome')
        ->send();

输出

Hurrah mail sent
From:    george@garcha
To:      michel@tome 
Subject: hehe works
Message: your welcome

示例 2(这也有效):

    Mail::from('george@garcha')
        ->to('michel@tome');

    Mail::subject('hehe works')
        ->message('your welcome')
        ->send();

【讨论】:

    猜你喜欢
    • 2023-03-16
    • 2016-09-13
    • 1970-01-01
    • 2014-11-30
    • 1970-01-01
    • 1970-01-01
    • 2011-06-19
    • 2021-12-10
    • 2011-06-26
    相关资源
    最近更新 更多