Bir PHP sınıfında CONST tanımlı olabilir miyim?


140

Bazı sınıflarda tanımlanmış birkaç CONST var ve bunların bir listesini almak istiyorum. Örneğin:

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

ProfileSınıfta tanımlanan CONST'lerin bir listesini almanın herhangi bir yolu var mı ? Anlayabildiğim kadarıyla, en yakın seçenek ( get_defined_constants()) hile yapmayacak.

Aslında ihtiyacım olan sabit isimlerin bir listesi - böyle bir şey:

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

Veya:

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

Ya da:

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

Bunu yansıma kullanarak yapabilirsiniz . Bir örnek görmek için o sayfada "Sınıf sabitlerini yazdır" ı arayın.
n3rd

Reflection ve Cl üzerindeki ReflectionClass öğelerini kullanarak
Tim Ebenezer

Yanıtlar:


245

Bunun için Yansıma kullanabilirsiniz . Bunu çok yapıyorsanız sonucu önbelleğe almak isteyebileceğinizi unutmayın.

<?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());

Çıktı:

Array
(
    'LABEL_FIRST_NAME' => 'First Name',
    'LABEL_LAST_NAME' => 'Last Name',
    'LABEL_COMPANY_NAME' => 'Company'
)

4
İki küçük NB: ilk olarak 5.3'te, Profiletırnak işaretleri olmadan (basit bir sınıf adı) reflektör yapıcısına argüman olarak kullanılabilir; ikincisi, tamamen açık olmak gerekirse, sonuçta elde edilen dizinin anahtarları dizelerdir, burada biçimlendirme önerileceği gibi sabit değildir. (Sadece fn belgelenmemiş olarak bahsetmeye değer .)
Benji XVI

11
@Benji XVI Açık bildirimler varsa 5.3'te Profile, aşağıdaki hatayı göstereceği için tırnak işaretleri olmadan kullanamazsınız : Uyarı: Tanımlanmamış sabit Profil kullanımı - 'Profil' olduğu varsayılır. Bu yüzden tırnak işaretlerini öneriyorum'Profile'
toneplex

10
Sınıf içindeki mantıkla ilgili sabitleri tanımlamak iyidir, bu nedenle yapıcı argümanını sabit kodlamanız gerekmez, __CLASS__bunun yerine kullanmanız gerekir .
Luke Adamczewski

7
new ReflectionClass(Profile::class)çok iyi çalışıyor
mtizziani

@mtizziani doğru, ancak ad alanlarının farkında olun! Diyelim ki Citysınıfla bir ad alanınız var B- B::classiyi çalışır, ancak örneğin ad alanında kullanacak olursanız Jungle- B::classdahil etmeden oraya çağırmak usesonuçlanır Jungle\B(Jungle hiç B olmasa bile!)
jave.web

22

Bu

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

1
+1 Sınıf sabitleri elde etmek için herhangi bir yerleşik yordamsal PHP işlevi bulamadığım için bu olurdu, ki bu biraz utanç verici.
BoltClock

1
Muhtemelen çok az ihtiyaç olduğu için. OP belirleyerek bir meta yapılandırmayı yapmak isteyebilirsiniz typesolarak all constants this class hasçoğu durumda, ve benim sağlanan sınırlı görüşüme göre muhtemelen daha iyi diğer anlamları olan sabitler yer bırakarak türleri ile (ya miras veya bir statik dizi değişkenle sunulduğu, / kullanımı).
Wrikken

16

Token_get_all () kullanın . Yani:

<?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";
}
?>

Çıktı:

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

1
+1, bu yansımayı diğer posterlerde belirtildiği gibi kullanmak için mükemmel bir zaman olsa da, "kaputun altında" olan çalışmaları anlamak ve onlarsız yapabilmek veya gerekirse çoğaltabilmek de önemlidir. İyi gösteri.
Dereleased

1
Sınıfınızın belleğe yüklenmesini istemiyorsanız, token_get_all harika bir alternatiftir. Yansımadan ÇOK daha hızlıdır ve bunu çok sayıda sınıfla yapmanız gerekiyorsa işlem belleğini karıştırmaz.
Harold

Jeton tabanlı çözüm için +1! Jeton tabanlı ayrıştırmayı anlamak, performansı göz önünde bulundurarak bir zevktir ... ve her zaman olduğu gibi, sabitleri token_get_all () yoluyla nasıl ayrıştıracağını gösteren harika bir kişi vardır. Çok teşekkür ederim!
mwatzer

Muhtemelen bu yalnızca tek bir dosya üzerinde çalışır ve üst sınıflardan herhangi bir sabit miras almaz. Aslında, bu teknik sınıfla bile ilgilenmez - dosyada, küresel kapsamda bile size tüm sabitleri verir. Yine de keşfetmek için harika bir araçtır.
Jason


13

ReflectionClass (PHP 5) kullanabiliyorsanız, PHP dokümanlarının yorumları uyarınca:

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

Kaynak burada.


9

ReflectionClass kullanarak ve getConstants()tam olarak ne istediğinizi verir:

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

Çıktı:

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

6

Statik yöntemle özellik - kurtarmaya

Sınıf işlevselliğini genişletmek için Statik işlevli Özellikleri kullanmak için iyi bir yer gibi görünüyor. Özellikler, aynı kodu tekrar tekrar yazmadan bu işlevselliği başka herhangi bir sınıfta uygulamamıza izin verecektir (DRY'de kalın).

Profil sınıfında özel 'ConstantExport' Özelliğimizi kullanın. Bu işlevselliğe ihtiyacınız olan her sınıf için yapın.

/**
 * 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;

}

KULLANIM ÖRNEĞİ

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

print_r($constList); // TEST

ÇIKTILAR:

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


4

Kendi sabitlerini döndürmek için sınıf içinde bir yönteme sahip olmak kullanışlıdır.
Bu şekilde yapabilirsiniz:

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());

3

Neden bir sınıf değişkenine bir dizi olarak başlamalısınız? Geçiş yapmayı kolaylaştırır.

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

2
Çünkü diziler sabit değil mi? Değişken olarak sabit olması gereken bir şeyi uygularsanız, istemeden değişme veya ayarlanmamış olma riskiyle karşı karşıya kalırsınız. Başka bir deyişle, sabit kalmalarına güvenemezsiniz.
GordonM

3

Sonunda ad alanlarıyla:

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());

1
class Qwerty 
{
    const __COOKIE_LANG_NAME__ = "zxc";
    const __UPDATE_COOKIE__ = 30000;

    // [1]
    public function getConstants_(){

        return ['__COOKIE_LANG_NAME__' => self::__COOKIE_LANG_NAME__, 
                '__UPDATE_COOKIE__' => self::__UPDATE_COOKIE__]; 
    }    

    // [2]
    static function getConstantsStatic_(){

        return ['__COOKIE_LANG_NAME__' => self::__COOKIE_LANG_NAME__, 
                '__UPDATE_COOKIE__' => self::__UPDATE_COOKIE__]; 
    } 
}

// [1]
$objC = new Qwerty();
var_dump($objC->getConstants_());

// [2]
var_dump(Qwerty::getConstantsStatic_());
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.