2012-05-09 9 views
0

私は、クラスツリーの中で多くのクラスがハイレベルになっている、つまり多くの親クラスを持っているPHPプロジェクトに取り組んでいます。いくつかのレベルではクラスとそのサブクラスのインスタンスの間のサブクラスのパスを見つける方法は?

、私は私につながるすべてのサブクラスの配列を与えるクラスFoodのメソッドgetFoodClasses()を実装するサブクラスとサブサブクラスなどのかなり多くを持つクラスFoodがある考えます現在のインスタンス、つまり、クラスFoodのツリーと、現在のインスタンス(後者を含む)のクラスです。 Foodクラス自体とそのすべてのスーパークラスを結果に含めないでください。

例:Foodのサブクラスは、次にサブクラスBananaを有するサブクラスFruitを有するVegetable、あろう場合には、(Banana) $b->getFoodClasses()上の結果は、 `アレイ(「野菜」、「果物」をもたらすことが必要であり、 'バナナ')。

ので、その結果

class Food extends SomeBaseClass 
{ 
    public function getFoodClasses() 
    { 
    /* Here goes the magic! */ 
    } 

} 

class Vegetable extends Food  {} 
class Fruit  extends Vegetable {} 
class Banana extends Fruit  {} 

$b = new Banana; 
print_r($b->getFoodClasses()); 

:リフレクションを使用しない

Array 
(
    [0] => Vegetable 
    [1] => Fruit 
    [2] => Banana 
) 

答えて

2

私はこの機能に終わりました。

/** 
* Calculates the widget path between this class and the current instance. 
* @return array An array with all subclasses in the path between this class and the current instance. 
*/ 
public function getFoodClasses() 
{ 
    $reflClass = new ReflectionClass(get_class($this)); 
    $classes = array(); 

    while ($reflClass->getName() != __CLASS__) 
    { 
     $classes[] = $reflClass->getName(); 
     $reflClass = $reflClass->getParentClass(); 
    } 

    return $classes; 
} 
1

は、あなたはまだこれを達成するためにいくつかの単純なPHPの関数を使用することができます。

class Food 
{ 
    public function getFoodClasses() 
    { 
    $class = get_class($this); 

    $classes = array($class); 
    while (($parentClass = get_parent_class($class)) && $parentClass != "Food") 
    { 
     array_unshift($classes, $parentClass); // Push onto the beginning because your example shows parents before children. 
     $class = $parentClass; 
    } 
    return $classes; 
    } 
} 
+0

PHP組み込み関数も同様にこれを実現できることは非常にうれしいです。現時点ではSPLの使い方は好きではありませんが、あなたのコードを見れば、まさにそれがやるべきことをするようです。パフォーマンスの面でどれが好ましいかを知るには、両方の実装でベンチマークを行うのが理想的です。 –

0

今後の予定です。このコードは実際に動作します(バナナから出発して、Foodに行く)。

<?php 
class Food 
{ 
    public function getFoodClasses() 
    { 

    } 
} 

class Vegetable extends Food  {} 
class Fruit  extends Vegetable {} 
class Banana extends Fruit  {} 

$banana = new Banana; 

$class = new ReflectionClass(get_class($banana)); 

$parents = array(); 

while($parent = $class->getParentClass()) { 
    $parents[] = $parent->getName(); 
    $class = $parent; 
} 

var_dump($parents); 
+0

それは、現在のクラスでも停止しません。 :)(私の例でもっと正確に言及しておきたいのは、Foodに親クラスもある私の更新を見てください)そして、あなたの例では、 'Food'エントリも含まれています。それは起こるべきではありません。 –

+0

少し不明です。上記の私の言いたいことは、Foodのスーパークラスが結果に表示されないようにすることです。 –

関連する問題