2009-06-05 3 views
109

Ich habe mehrere CONSTs in einigen Klassen definiert und möchte eine Liste von ihnen erhalten. Zum Beispiel:Kann ich CONSTs in einer PHP-Klasse definiert bekommen?

class Profile { 
    const LABEL_FIRST_NAME = "First Name"; 
    const LABEL_LAST_NAME = "Last Name"; 
    const LABEL_COMPANY_NAME = "Company"; 
} 

Gibt es eine Möglichkeit, eine Liste des CONST des auf der Profile Klasse definiert zu bekommen? Soweit ich das beurteilen kann, wird die nächste Option (get_defined_constants()) nicht ausreichen.

Was ich wirklich brauchen, ist eine Liste der Namen von Konstanten - etwa so:

array('LABEL_FIRST_NAME', 
    'LABEL_LAST_NAME', 
    'LABEL_COMPANY_NAME') 

Oder:

array('Profile::LABEL_FIRST_NAME', 
    'Profile::LABEL_LAST_NAME', 
    'Profile::LABEL_COMPANY_NAME') 

Oder auch:

array('Profile::LABEL_FIRST_NAME'=>'First Name', 
    'Profile::LABEL_LAST_NAME'=>'Last Name', 
    'Profile::LABEL_COMPANY_NAME'=>'Company') 
+0

Mit Reflexion und ein Reflection auf Cl, können Sie die Funktion getConstants verwenden http://nz.php.net/manual /en/class.reflectionclass.php –

+0

[Reflection wird dein Retter] (http://se2.php.net/manual/en/reflectionclass.getconstants.php). –

+0

Sie können dies mit [reflection] (http://nz.php.net/oop5.reflection) tun. Suchen Sie nach "Klassenkonstanten drucken" auf dieser Seite, um ein Beispiel zu sehen. – n3rd

Antwort

191

Sie können verwenden dafür. Beachten Sie, dass Sie das Ergebnis zwischenspeichern möchten, wenn Sie dies häufig tun.

<?php 
class Profile { 
    const LABEL_FIRST_NAME = "First Name"; 
    const LABEL_LAST_NAME = "Last Name"; 
    const LABEL_COMPANY_NAME = "Company"; 
} 


$refl = new ReflectionClass('Profile'); 
print_r($refl->getConstants()); 

Ausgang:

Array 
(
    ['LABEL_FIRST_NAME'] => First Name 
    ['LABEL_LAST_NAME'] => Last Name 
    ['LABEL_COMPANY_NAME'] => Company 
) 
+4

Zwei kleinere NBs: zuerst, in 5.3, kann 'Profile' als Argument für den Reflektorkonstruktor verwendet werden, ohne Anführungszeichen (ein einfacher Klassenname); zweitens, um völlig klar zu sein, sind die Schlüssel des resultierenden Arrays Strings, keine Konstanten, da die Formatierung hier vorgeschlagen werden könnte. (Erwähnenswert ist nur, dass die FN [undokumentiert] ist (http://www.php.net/manual/en/reflectionclass.getconstants.php).) –

+11

@Benji XVI In 5.3, wenn Sie Benachrichtigungen aktiviert haben, haben Sie gewonnen ' Ich kann 'Profile' ohne die Anführungszeichen verwenden, da der folgende Fehler angezeigt wird: Hinweis: Verwendung von undefiniertem konstantem Profil - angenommenes 'Profil'. Also schlage ich vor, die Anführungszeichen '' Profil '' zu behalten – toneplex

+9

Es ist gut, Konstanten Logik innerhalb der Klasse zu definieren, so dass Sie nicht Konstruktorargument hartcodieren müssen, sondern '__CLASS__' stattdessen verwenden. –

4

Ja, du reflection verwenden. Betrachten Sie die Ausgabe von

<? 
Reflection::export(new ReflectionClass('YourClass')); 
?> 

Das sollte Ihnen die Idee von dem, was Sie sehen werden.

14

Verwendung token_get_all(). Nämlich:

<?php 
header('Content-Type: text/plain'); 

$file = file_get_contents('Profile.php'); 
$tokens = token_get_all($file); 

$const = false; 
$name = ''; 
$constants = array(); 
foreach ($tokens as $token) { 
    if (is_array($token)) { 
     if ($token[0] != T_WHITESPACE) { 
      if ($token[0] == T_CONST && $token[1] == 'const') { 
       $const = true; 
       $name = ''; 
      } else if ($token[0] == T_STRING && $const) { 
       $const = false; 
       $name = $token[1]; 
      } else if ($token[0] == T_CONSTANT_ENCAPSED_STRING && $name) { 
       $constants[$name] = $token[1]; 
       $name = ''; 
      } 
     } 
    } else if ($token != '=') { 
     $const = false; 
     $name = ''; 
    } 
} 

foreach ($constants as $constant => $value) { 
    echo "$constant = $value\n"; 
} 
?> 

Ausgang:

LABEL_FIRST_NAME = "First Name" 
LABEL_LAST_NAME = "Last Name" 
LABEL_COMPANY_NAME = "Company" 
+0

token_get_all ist großartig –

+1

+1, obwohl ich sagen würde, dass dies eine ausgezeichnete Zeit ist, Reflection zu verwenden, wie von anderen Plakaten erwähnt, ist es auch wichtig Verstehen Sie die Abläufe "unter der Haube" und können Sie darauf verzichten oder sie bei Bedarf replizieren. Gute Show. – Dereleased

+1

Wenn Sie nicht möchten, dass Ihre Klasse in den Speicher geladen wird, ist token_get_all eine fantastische Alternative. Es ist VIEL schneller als Reflection und stört den Prozessspeicher nicht, wenn Sie dies mit vielen Klassen tun müssen. – Harold

7

Mit Reflection und getConstants() gibt genau das, was Sie wollen:

<?php 
class Cl { 
    const AAA = 1; 
    const BBB = 2; 
} 
$r = new ReflectionClass('Cl'); 
print_r($r->getConstants()); 

Ausgang:

Array 
(
    [AAA] => 1 
    [BBB] => 2 
) 
12

Per die PHP-Dokumente Kommentare, wenn du bist der Lage, die Reflection (PHP 5) zu verwenden:

function GetClassConstants($sClassName) { 
    $oClass = new ReflectionClass($sClassName); 
    return $oClass->getConstants(); 
} 

Source is here.

2

Warum nicht steckte sie in eine Klassenvariable als Array zu beginnen? Erleichtert das Durchschleifen.

private $_data = array("production"=>0 ...); 
+3

im Array werden keine Code-Vervollständigungshinweise angezeigt ... –

+1

Weil Arrays keine Konstanten sind? Wenn Sie etwas implementieren, das eine Konstante als Variable sein soll, riskieren Sie, dass es versehentlich geändert oder unscharf wird. Mit anderen Worten, Sie können nicht davon ausgehen, dass sie konstant bleiben. – GordonM

18

This

$reflector = new ReflectionClass('Status'); 
var_dump($reflector->getConstants()); 
+1

+1 Dies wäre es, da ich keine eingebauten prozeduralen PHP-Funktionen zum Abrufen von Klassenkonstanten finden kann, was ein wenig schade ist. – BoltClock

+1

Wahrscheinlich, weil es wenig Bedarf dafür gibt. Das OP möchte vielleicht eine Meta-Konfiguration machen, indem es 'types' als' alle Konstanten, die diese Klasse hat' definiert, was in den meisten Fällen, und in meiner begrenzten Meinung, wahrscheinlich besser mit Vererbung oder einer statischen Array-Variable mit der Typen (lassen Raum für Konstanten mit anderen Bedeutungen/Verwendung). – Wrikken

2

eventuell mit Namensräume:

namespaces enums; 
class enumCountries 
{ 
    const CountryAustria   = 1 ; 
    const CountrySweden   = 24; 
    const CountryUnitedKingdom = 25; 
} 

namespace Helpers; 
class Helpers 
{ 
    static function getCountries() 
    { 
    $c = new \ReflectionClass('\enums\enumCountries'); 
    return $c->getConstants(); 
    } 
} 

print_r(\Helpers\Helpers::getCountries()); 
3

Es ist praktisch, eine Methode innerhalb der Klasse zu haben, die ihre eigenen Konstanten zurückgibt.
Sie können auf diese Weise tun:

class Profile { 
    const LABEL_FIRST_NAME = "First Name"; 
    const LABEL_LAST_NAME = "Last Name"; 
    const LABEL_COMPANY_NAME = "Company"; 


    public static function getAllConsts() { 
     return (new ReflectionClass(get_class()))->getConstants(); 
    } 
} 

// test 
print_r(Profile::getAllConsts()); 
0

Trait mit statischer Methode - zur Rettung

es sieht aus wie ein schöner Ort Traits mit einer statischen Funktion verwenden Klasse Funktionalität zu erweitern. Traits ermöglichen uns auch, diese Funktionalität in jeder anderen Klasse zu implementieren, ohne den gleichen Code immer wieder neu schreiben zu müssen (DRY bleiben).

Verwenden Sie unsere benutzerdefinierte Eigenschaft 'ConstantExport' mit der Profilklasse. Tun Sie es für jede Klasse, für die Sie diese Funktionalität benötigen.

/** 
* ConstantExport Trait implements getConstants() method which allows 
* to return class constant as an assosiative array 
*/ 
Trait ConstantExport 
{ 
    /** 
    * @return [const_name => 'value', ...] 
    */ 
    static function getConstants(){ 
     $refl = new \ReflectionClass(__CLASS__); 
     return $refl->getConstants(); 
    } 
} 

Class Profile 
{ 
    const LABEL_FIRST_NAME = "First Name"; 
    const LABEL_LAST_NAME = "Last Name"; 
    const LABEL_COMPANY_NAME = "Company"; 

    use ConstantExport; 

} 

Anwendungsbeispiel

// So simple and so clean 
$constList = Profile::getConstants(); 

print_r($constList); // TEST 

AUSGÄNGE:

Array 
(
    [LABEL_FIRST_NAME] => First Name 
    [LABEL_LAST_NAME] => Last Name 
    [LABEL_COMPANY_NAME] => Company 
) 
Verwandte Themen