1

私は、アプリケーションのバックボーンの 1 つである大きなクラス内で作業しています。これを と呼びますmyClass。このクラスの新しいパブリック メソッドを作成し、作成中の関数の個々のメソッドを呼び出す変数配列を受け入れるようにするmy_new_iterative_function()必要があります: ... ある意味では、「クラス内にクラスが必要です。 " (javascript はこれに適しています ;) ... どうすれば次のことを達成できますか。$fallback_orderパラメーター配列を反復処理して、これらのメソッドが呼び出される順序を変更し、デフォルトの順序を設定します。$fallback_order定義されているように false の場合に実行されますデフォルトのパラメータ?

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>

編集:明らかに欠陥のあるロジックを修正

4

2 に答える 2

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に設定すると、致命的なエラーになります)

于 2012-10-15T17:10:37.830 に答える
1

私はあなたが受け入れた良い答えをすでに持っていることを認識しています。私はPHPをあまりよく知らないと言ってこれを警告する必要がありますが、これについて少し考えたので、関係なくチャイムを鳴らすかもしれないと思いました.

反復するメソッドのロジックを個別のコマンドに抽象化する方がすっきりするのではないかと思いました(反復コードに触れずにさらにメソッドを追加できるという明らかな利点があり、追加する追加コードの量を最小限に抑えることができます)大規模なクラス)。その後、デフォルトの順序配列を のプロパティとして設定できますが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()));
于 2012-10-16T00:28:18.907 に答える