【问题标题】:How do you stop a PHP class from executing?如何阻止 PHP 类执行?
【发布时间】:2010-09-27 19:18:01
【问题描述】:

我正在寻找类似 @​​987654321@ 的 for 循环。

这是一些示例代码(使用 Symfony 的石灰),其中 stop() 不会让课程继续,I_DONT_WANT_THIS_TO_RUN() 不会被执行。

$browser->isStatusCode(200)
  ->isRequestParameter('module', 'home')
  ->isRequestParameter('action', 'index')
  ->click('Register')
  ->stop()
  ->I_DONT_WANT_THIS_TO_RUN();
$browser->thenThisRunsOkay();

stop() 内部调用$this->__deconstruct(); 似乎没有奏效。有没有我可以在stop() 中调用的函数来实现这一点?

【问题讨论】:

    标签: php exception class


    【解决方案1】:

    你可以使用PHP exceptions:

    // This function would of course be declared in the class
    function stop() {
        throw new Exception('Stopped.');
    }
    
    try {
        $browser->isStatusCode(200)
          ->isRequestParameter('module', 'home')
          ->isRequestParameter('action', 'index')
          ->click('Register')
          ->stop()
          ->I_DONT_WANT_THIS_TO_RUN();
    } catch (Exception $e) {
        // when stop() throws the exception, control will go on from here.
    }
    
    $browser->thenThisRunsOkay();
    

    【讨论】:

    • 这是一个有趣的技术,我肯定没有想到。
    • 我了解到,lime 实际上会捕获任何异常并阻止它继续,就像我正在寻找的那样。
    【解决方案2】:

    只需返回另一个类,它将为每个调用的方法返回 $this。

    例子:

    class NoMethods {
        public function __call($name, $args)
        {
            echo __METHOD__ . " called $name with " . count($args) . " arguments.\n";
            return $this;
        }
    }
    
    class Browser {
        public function runThis()
        {
            echo __METHOD__ . "\n";
            return $this;
        }
    
        public function stop()
        {
            echo __METHOD__ . "\n";
            return new NoMethods();
        }
    
        public function dontRunThis()
        {
            echo __METHOD__ . "\n";
            return $this;
        }
    }
    
    $browser = new Browser();
    echo "with stop\n";
    $browser->runThis()->stop()->dontRunThis()->dunno('hey');
    echo "without stop\n";
    $browser->runThis()->dontRunThis();
    echo "the end\n";
    

    将导致:

    with stop
    Browser::runThis
    Browser::stop
    NoMethods::__call called dontRunThis with 0 arguments.
    NoMethods::__call called dunno with 1 arguments.
    without stop
    Browser::runThis
    Browser::dontRunThis
    the end
    

    【讨论】:

    • 我最终使用了它,这样我就可以跟踪没有运行的方法。它更明确地说明了它在做什么。非常感谢!
    【解决方案3】:

    OIS 的答案非常好,尽管我可以看到如果对象突然变成其他东西可能会让人感到困惑。也就是说,您希望在链的末端,您最终会得到相同的对象。为了避免这个问题,我会添加一个私有变量来告诉班级是否实际做任何事情。如果课程已停止,则每个课程都会立即返回$this。这为您提供了能够重新启动执行的额外好处。

    class MyClass {
        private $halt;
    
        function __call($func, $args) {
            if ($this->halt) {
                return $this;
            } else {
                return $this->$func($args);
            }
        }
    
        private function isRequestParameter() {
            // ...
        }
        public function stop() {
            $this->halt = true;
        }
        public function start() {
            $this->halt = false;
        }
    }
    

    这可以放入父类中,这样您就不必复制此代码。

    【讨论】:

    • 你必须调用 $browser->start()->method()->method2();每次。仅当您希望对其中一种方法返回的对象执行某些操作时,返回另一个类/对象的可链接性才是问题。但是你的方法也会失败。
    • 很明显你会初始化 $halt 为假。如果您执行类似 $a = $b->func1()->func2()->stop()->func3();... 之类的操作,您的解决方案将不是最好的,因为 $a 将是一个 NoMethod 对象.
    • 呃,$b 就是 $a 的样子,所以没有意义,你可以这样做 $a = $b = new Object();你的论点有缺陷。
    猜你喜欢
    • 1970-01-01
    • 2012-05-28
    • 1970-01-01
    • 2016-06-14
    • 2011-08-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多