PHP方法的最佳DRY方法在类中有2个级别?

时间:2012-10-15 16:53:49

标签: php class methods syntax

我在一个大型类中工作,这是一个应用程序的主干之一,我们称之为myClass。我需要创建一个这个类的新公共方法,并让它接受一个变量数组,该数组调用我正在编写的函数的各个方法:my_new_iterative_function() ...从某种意义上说,我需要一个“类中的类”(javascript对此很好;)...如何实现以下内容,我遍历$fallback_order参数数组以更改调用这些方法的顺序,然后具有默认顺序,如果$fallback_order为默认参数中定义的假,则执行?

class myClass {
    public function existing_app_method_1() {
        // other code
    }
    public function existing_app_method_2() {
        // other code
    }
    // large app-centric class with many more methods

    public function my_new_iterative_function( array $fallback_order = false ) {
        method_foo() {
            // do stuff
        }
        method_bar() {
            // do stuff
        }
        method_more_methods() {
            // there are at least 5 of them in total
        }

        if ( $fallbackorder == false ):
            method_foo();
            method_bar();
        else:
            foreach ( $fallback_order as $index => $this_fallback ) {
                $name = $this_fallback;
                if ( $this_fallback == $name ):
                    $this->$name();
                endif;
            }
        endif;
    }
}

目标将在视图模板中进行以下操作:

<div><?php $myClass->my_new_iterative_function( array( 'method_more_methods', 'method_bar', 'method_foo', ) ); ?></div>

编辑:修正了一些明显错误的逻辑

2 个答案:

答案 0 :(得分:3)

您可以将方法作为匿名函数放在方法内的数组中,并使用输入索引这些数组,如下所示:

class Foo {
    private $stuff = 'tickle me elmo';        

    public function my_new_iterative_function(array $fallback_order = array('method_foo', 'method_bar')) {

        $self = $this; // this acts as a keyword, you can't use in the `use ()` part

        $order_functions = array(
            'method_foo' => function() use ($self) {
                print "im in foo: {$self->stuff}<br>";
            },
            'method_bar' => function(){
                print "im in bar<br>";
            },
        );

        foreach ( $fallback_order as $index => $this_fallback ) {
            $order_functions[$this_fallback]();
        }
    }
}
(new Foo)->my_new_iterative_function(); // look, one-line `new` and method call, since php 5.4
(new Foo)->my_new_iterative_function([ 'method_bar', 'method_foo', ]); // and even [] for array literals too!

我还在默认参数中嵌入了默认顺序。 (当你将它键入数组时将其设置为false是一个致命的错误)

答案 1 :(得分:1)

我意识到你已经接受了一个很好的答案,我应该通过说我并不是非常了解PHP,但我想我可能会因为我已经给了这个有点想法。

我想知道将你迭代的方法中的逻辑抽象为单独的commands是否更为简洁(明显的优点是你可以在不触及迭代代码的情况下添加更多方法,并且你可以最小化数量)您添加到大班的其他代码)。然后,您可以将默认订单数组设置为myClass的属性,但如果需要,可以在my_new_iterative_function方法的参数中覆盖它(或者,可能更好,通过myClass上的设置器覆盖它)。

请原谅代码,但是这样:

class myClass 
{

    // override default order via class setter if required
    protected $fallback_order = array(new FooCommand(), new BarCommand(), new ANOtherCommand());

    public function my_new_iterative_function(  ) {

            foreach ( $this -> fallback_order as $value ) {
                $value -> execute();
            }
    }
}

或者也许是这样:

class MyClass 
{

    // override default order in method invokation if required
    protected $default_fallback_order = array(new FooCommand(), new BarCommand(), new ANOtherCommand());

    public function my_new_iterative_function( $fallback_order = null ) {

            // Use default fallback order if an override has not been 
            // specified in method parameter
            if (is_null($fallback_order))
                $fallback_order = $this -> default_fallback_order;

            foreach ( $fallback_order as $value ) {
                $value -> execute();
            }
    }
}

$myClass = new MyClass();
$myClass -> my_new_iterative_function(); // use default fallback order
$myClass -> my_new_iterative_function(array(new ANOtherCommand(), new BarCommand(), new FooCommand()));