Ben php kendi statik değişkenleri aramak için sınıfları bir dizi toplamak gerekir

5 Cevap php

I açıklamak için kolay bir soru değil, bu yüzden kafa karıştırıcı gibi görünüyor eğer sabırlı olun lütfen söylemek istediğim ilk şey.

Ben bu gibi sınıfların bir dizi var

class Product {

   public static $static_type = 'product';
   public static $static_table = 'product_table';

   public function __construct($params) { //do some }
}

ve daha sonra sınıfları Haberler, Etkinlikler vb vardır

Başka bir sınıf i tekrarlayıcı bir şekilde bu sınıflar içinde bu statik değişkenlere erişmek için gerekir. Gibi bir şey:

//...
if (Product::$static_type) { //do some }
else if (News::$static_type) { //do other }
//...

Ben (bu doğru değil ama benim soruya mantıklı) böyle bir şekilde foreach gibi, bir döngü içinde trasform istiyorum

foreach ($classes as $class) {
  echo $class::$static_type; //brrrr, just to render the idea :)
}

Yani ben benim sınıfları bir dizi dönen statik bir yöntem (örneği değil) olan bir tekil / statik sınıf düşünüyorum. Bu gibi:

class Conf {

    public function __construct() {
          //nothing
        }

    public static function get_class_array () {

       //how to do this???
    }
}

ve daha sonra

foreach (Conf::get_class_array() as $class) {
  echo $class::$static_type; //brrrr, just to render the idea :)
}

Nasıl bu ulaşabilir? Bu durumda ürün, Haberler veya başkalarını örneğini istemiyorum.

Edit: eval kötülük, ben kullanmak istemiyorum. (: get_declared_class ile hile yok, çözmek için hiçbir şekilde varsa ben o sözü arasında daha şık bir yol olduğunu düşünüyorum, yansıma kullanır.

Edit: Bu arada ben bu şekilde conf :: get_class_array () yapacağım

public static function get_class_array () {
   return array(new ReflectionClass('Prodotto'), new ReflectionClass('News'));
}

ve daha sonracall it here:

foreach (Conf::get_class_array() as $class) {
  echo $class->getStaticPropertyValue('static_type');
}

5 Cevap

Ben bunu yapabileceğimi sanmıyveyaum. Ancak bunlardan birini yapabilirsiniz:

$properties = get_class_vars('Product');
echo $properties['static_type'];

veya

$class = new ReflectionClass('product');
echo $class->getStaticPropertyValue('static_type');

Note that in PHP 5.3 echo $class::$static_type; will wveyak (http://php.net/manual/en/language.oop5.static.php)

5.3.0 kadar, bu yöntemi deneyebilirsiniz. Senin önerdiğin gibi (biz ne vardı sopa ile Konf arayacağım) bir konteyner sınıf oluşturmak ve üzerinde yineleme yapmak istiyorsanız geçerli sınıfları ayarlamak ve almak için iki yöntem sunar:

<?php

class Conf {
    private static $instance;
    private $classes = array();

    public static function getInstance() {
    	if ( is_null(self::$instance) ) {
    		self::$instance = new self();
    	}

    	return self::$instance;
    }

    public function registerClass($className) {
    	// Use associative index to maintain uniqueness
    	$this->classes[$className] = $className;
    }

    public function getRegisteredClasses() {
    	return $this->classes;
    }
}

Bazı örnek sınıfları ve onları nasıl kayıt:

class X {
    public static $a = "catus";
    public static $b = "pants";
}

class Y {
    public static $a = "apples";
    public static $b = "bananers";
}

$conf = Conf::getInstance();
$conf->registerClass("X");
$conf->registerClass("Y");

Şimdi, statik üyelere erişmek ve / veya değiştirmek için, size (tom Haigh işaret olarak RefelectionClass kullanarak) aşağıdaki gibi bir şey yapabilirsiniz:

$conf = Conf::getInstance();

echo "<pre>";
foreach ( $conf->getRegisteredClasses() as $class ) {
    $reflection = new ReflectionClass($class);

    echo "<hr/>Class: $class\n";

    // Access example
    print_r( $reflection->getStaticProperties() );

    // Alter example
    $reflection->setStaticPropertyValue("a", 
         $reflection->getStaticPropertyValue("a") . "-modified"
    );
    print_r( $reflection->getStaticProperties() );

}

Eğer Com_Example_Static_X ve (bunu arzu eğer statik bir yöntem yapmak bile ve) Com_Example_Static_Y, sen gibi yaparak basitleştirmek Conf->getRegisteredClasses() edebilirsiniz gibi bir sınıf adlandırma kuralı varsa N3rd önerdi:

class Conf {
    // ....

    static public function getMatchingClasses($pattern="/^Com_Example_Static_.+$/") {
    	$response = array();
    	foreach ( get_declared_classes() as $className ) {
    		if ( preg_match($pattern, $className, $m) ) {
    			$response[] = $className;
    		}
    	}

    	return $response;
    }
}

Ve, elbette, foreach güncellemek

foreach ( Conf::getMatchingClasses() as $class ) {
    // ...
}

Bu yardımcı oldu umuyoruz.

Sınıfların bir listesini almak için, kullanabileceğiniz get_declared_classes. Sonra işlemek isteyen sınıfların belirlemek gerekir.

Sen is_subclass_of ile ortak bir taban sınıf arıyor, ya da ilgilendiğiniz statik üye değişkenler olup olmadığını görmek için ReflectionClass kullanarak bunu yapabilirdi

Bunu yapmak için kolay bir yolu var sanmıyorum. İşte bunu hakkında gitmek nasıl kafamın üst kapalı bir kaç öneri:

  • get_declared_classes() Onlar bir arabirim uygulamak olsun tüm tanımlanmış sınıfların bir listesini almak ve adlandırma düzeni karşı onları kontrol edin (örneğin, MyNamespace_*) veya kullanın (örneğin, MyStaticEnumerable).
  • Kinda üstünde, ama biraz daha karmaşık gibi: senin üstünde yazmak class loader ve yüklü bir sınıfı numaralandırmak istediğiniz olanlardan biri olup olmadığını kontrol ettirin. Eğer öyleyse, bazı yönetici sınıfa bilinen olun.
  • Sınıflar elle bütün sınıfları numaralandırmak tanımlandığı dizini kontrol edin.