2010-05-12 12 views
20

Próbuję utworzyć obiekt PHP (5), który może iterować przez jego właściwości, budując zapytanie SQL oparte tylko na jego właściwościach publicznych, a nie prywatnych.Wykryj, czy właściwość obiektu jest prywatna w PHP

Ponieważ ta metoda obiektu nadrzędnego ma być używana przez obiekty podrzędne, nie można po prostu pominąć właściwości prywatnych według nazwy (nie będę wiedział, jakie są one w obiektach potomnych).

Czy istnieje prosty sposób wykrywania wewnątrz obiektu, który z jego właściwości jest prywatny?

Oto uproszczony przykład tego, co mam do tej pory, ale wynik ten zawiera wartość $ bar:

class testClass { 

    public $foo = 'foo'; 
    public $fee = 'fee'; 
    public $fum = 'fum'; 

    private $bar = 'bar'; 

    function makeString() 
    { 
     $string = ""; 

     foreach($this as $field => $val) { 

      $string.= " property '".$field."' = '".$val."' <br/>"; 

     } 

     return $string; 
    } 

} 

$test = new testClass(); 
echo $test->makeString(); 

daje wyjście:

property 'foo' = 'foo' 
property 'fee' = 'fee' 
property 'fum' = 'fum' 
property 'bar' = 'bar' 

bym się podoba nie uwzględniać "paska".

Jeśli istnieje lepszy sposób na powtórzenie tylko właściwości publicznych obiektu, to też by tu zadziałało.

Odpowiedz

9

Możesz użyć Reflection, aby sprawdzić właściwości klasy. Aby uzyskać tylko publiczne i chronione właściwości, należy profilować odpowiedni filtr do metody ReflectionClass::getProperties.

Oto krótki przykład zastosowania Twojej metody makeString.

public function makeString() 
{ 
    $string = ""; 
    $reflection = new ReflectionObject($this); 
    $properties = $reflection->getProperties(ReflectionProperty::IS_PUBLIC); 
    foreach ($properties as $property) { 
     $name = $property->getName(); 
     $value = $property->getValue($this); 
     $string .= sprintf(" property '%s' = '%s' <br/>", $name, $value); 
    } 
    return $string; 
} 
+0

Dzięki - myślę, że pokonac cię do tego przez około 30 sekund, ale tak, działa dokładnie tak, jak potrzeba. – Hippyjim

+0

Tak, wydaje mi się, że za dużo czasu poświęcono na zrobienie ładnej odpowiedzi z czystymi i uporządkowanymi linkami do dokumentów. Lekcja, szybkie i brudne odpowiedzi od teraz! :-) – salathe

1
foreach (get_class_vars(get_class($this)) .... 
+0

Istnieje również klasa odbicia i metoda magiczna __get() – powtac

+0

Masz rację, zwraca vary z bieżącego zakresu -> $ to znaczy wszystko ... – powtac

+0

Obawiam się, że jestem nieświadomy Klasa refleksji - Będę potrzebować ciężkiego Googlinga. Dzięki za wskaźnik. – Hippyjim

1

Możesz użyć tablicy do przechowywania właściwości publicznych, dodać metodę owijania i użyć tablicy do wstawienia danych do SQL.

2

Jeśli rzutować obiektu do tablicy przed iteracji nad nim, prywatne i chronionych członkowie będą mieć specjalne przedrostki:

class Test{ 
    public $a = 1; 
    private $b = 1; 
    protected $c = 1; 
} 
$a = new Test(); 
var_dump((array) $a); 

wyświetla to:

array(3) { 
    ["a"]=> 
    int(1) 
    ["Testb"]=> 
    int(1) 
    ["*c"]=> 
    int(1) 
} 

Są tam również ukryte postacie, które nie zostaną wyświetlone. Ale możesz napisać kod, aby je wykryć. Na przykład wyrażenie regularne /\0\*\0(.*)$/ dopasuje chronione klucze, a /\0.*\0(.*)$/ będzie pasować do prywatnych. W obu przypadkach pierwsza grupa przechwytująca pasuje do nazwy elementu.

4

Szybszym rozwiązaniem, które znalazłem:

class Extras 
{ 
    public static function get_vars($obj) 
    { 
     return get_object_vars($obj); 
    } 
} 

a następnie wywołać wewnątrz swoich TestClass:

$vars = Extras::get_vars($this); 

additional reading in PHP.net

0

Można użyć API Reflection sprawdzić widoczność właściwości:

$rp = new \ReflectionProperty($object,$property); 
if($rp->isPrivate) { 
    // Run if the property is private 
} else { 
    // Run if the property is Public or Protected 
} 
Powiązane problemy