2009-05-07 7 views
0

我々は問題を抱えているPHP:内部から「動的」コールバック/クラスの外

私は変数のparamのベースに、クラス内で動的にコールバックを割り当てる必要があります[CITを。]:私の目標は持っていることですクラスが1つ(メインクラスではなく、多くのエクステンダサブクラス)であり、値がXの場合はこの関数内でfuncitonXを使用しなければなりません。私はうまく説明カント知っ

は、私は私の例が行うことを願っています:

class plzComplicateMyLife{ 
    public $vehicle; 
    public $kindVehicle; 
    public $dynamicFunction; 
    public function __construct($vehicle, $kindVehicle){ 
    $this->kindVehicle = $kindVehicle; 
    $this->vehicle = $vehicle; 
    switch($kindVehicle){ 
     case 'cycle': 
      $this->dynamicFunction = "isACycle"; 
      break; 
     case 'car': 
      $this->dynamicFunction = "isACar"; 
      break; 
    } 
    //here come the problem, i need to call the callback store in dynamicFunction. 
    //i tried: 
    //call_user_func($this->$this->dinamicFunction, $this->vehicle); 
    //error: Catchable fatal error: Object of class plzComplicateMyLife could not be converted to string in [...] 
    //call_user_func("plzComplicateMyLife::".$this->dynamicFunction); 
    //Warning: call_user_func(plzComplicateMyLife::isACar) [function.call-user-func]: First argument is expected to be a valid callback in [...] 
    //$this->dynamicFunction(); 
    //Fatal error: Call to undefined method plzComplicateMyLife::dynamicFunction() in [...] 
    //so, how can i do that? 
    } 
    public function isACycle($vehicle){ 
     echo 'im a cycle, model: '.$vehicle.'<br />'; 
    } 
    public function isACar($vehicle){ 
     echo 'im a car, model: '.$vehicle.'<br />'; 
    } 
    //i know this has no sense, in this example at least. 
    public function printKind(){ 
     //call_user_func($this->$this->dinamicFunction, $this->vehicle); 
     //call_user_func("plzComplicateMyLife::".$this->dynamicFunction); 
     //then? 
    } 
} 

$maserati = new plzComplicateMyLife('maserati4', 'car'); 

//then, maybe, outside the class i'll need to recover the callback: 

$maserati->printKind(); 

EDIT:ロブが言ったように

は、多型が本当に良い解決策になります。

しかし、問題は、例えば...この場合には、私は本当に必見はパラメータのみを変更し、すべてのクラスのインスタンスで同じ宣言を持っている、ということである:

$maserati = new plzComplicateMyLife('maserati4', 'car'); 
$ducati = new plzComplicateMyLife('maserati4', 'cycle'); 
//is good 
//becose i cant have: 
$maserati = new plzComplicateMyLifeWithACar('maserati4'); 
$ducati = new plzComplicateMyLifeWithACycle('maserati4'); 

答えて

1

あなたの編集に応じて、代わりにこのようなことをすることはできませんか?

abstract class MethodOfTransport { 
    protected $model; 

    public function __construct($model) { 
     $this->model = $model; 
    } 

    abstract public function printKind(); 

    public static function create($model, $type) { 
     $object = new $type($model); 
     return $object; 
    } 
} 

class cycle extends MethodOfTransport { 
    public function printKind() { 
     echo 'im a cycle, model: '.$this->model.'<br />'; 
    } 
} 

class car extends MethodOfTransport { 
    public function printKind() { 
     echo 'im a car, model: '.$this->model.'<br />'; 
    } 
} 

$maserati = MethodOfTransport::create('maserati4', 'car'); 
$maserati->printKind(); 

$ducati = MethodOfTransport::create('maserati4', 'cycle'); 
$ducati->printKind(); 
+0

はい、それは私のやることです。ありがとう、仲間! – Strae

+0

私は試していませんでしたが、これらのクラスが別々のソースファイルで定義されている場合、基本クラスには拡張クラス定義ファイルを含める必要がありますが、同時に拡張クラス基本クラスを含める必要がありますか? (私が確信している唯一の理由は 'new $ type($ model) 'の使用のためです。 – grantwparks

+0

拡張クラスは、まだ含まれていなければ基本クラスを含む必要があります。拡張クラスのファイルをインスタンス化する前にそれを行う必要があります。また、spl_autoload_register() –

1

PHPでは、指定し使用することができます

array($object, $methodName); 

ですから、この

を行うことができます。たとえば、コールバック変数( see here)として配列を使用して、メソッドコールバック10
$callback = array($this, $this->dynamicFunction); 
call_user_func($callback, $this->vehicle); 
1

なぜ、ではないあなたはここで簡単な継承構造を使いたいですか?モデル化されたオブジェクトに応じて異なる動作が必要な場合は、多態性の正式な記述です。

あなたは本当に、あなたは2つのいずれかを行う必要があります、同じオブジェクトへのコールバックでの耕し化したいなら:

  1. は彼らがプライベートに、あなたのコールバックから$vehicleパラメータを削除するか、または保護され、通常それらを呼び出す、すなわち

    call_user_func(array($this, 'isACycle'));

  2. マークコールバックなどの静的、彼らはプライベートまたは保護作り、次のようにそれらを呼び出す:

    01非静的コールバック内

    call_user_func(array(__CLASS__, 'isACycle'), $this);

、通常の方法で$thisを介してオブジェクトのプロパティにアクセスします。また、不要な外部発信者を防ぐために、コールバックをプライベートまたは保護されたものとしてマークすることをお勧めします。おそらく、あなたはそれぞれのタイプに対して間違ったメソッドを実行することを望まないでしょう。

+0

は、私はちょうど私はポリモーフィズムを使用傾ける理由で記事を編集しました。.. – Strae

2

多型は、ここに行くための方法ですが、今後の参考のために、あなたもこれを行うことができます。

public function printKind() { 
    $this->{$this->dynamicFunction}($this->vehicle); 
} 
関連する問題