PHP dinamik sınıf adıyla bir sınıf statik özelliği Başlarken

11 Cevap php

Ben bu var:

  • sınıf adını ($ classname) tutan bir string değişken
  • ile bir string değişken özellik adı ($ özellikadı) tutar

Ben bu sınıfın o mülk almak istiyorum, sorun, mülkiyet statik ve ben bunu nasıl bilmiyorum.

Özelliği statik olmasaydı, o olurdu:

$classname->$propertyname;

özellik bir yöntem olsaydı, ben call_user_function kullanılmış olabilir

call_user_func(array($classname, $propertyname));

Ama benim durumumda, ben sadece kayboldum. Ancak bunun mümkün olduğunu umut ediyorum. PHP olan fonksiyonları binlerce, o da daha iyi bir şey bu olurdu. Belki de ben bir şey eksik?

Teşekkürler!

Edit:

  • eval () çözümleri ile olanlar için: teşekkürler, ama bu söz konusu değildir
  • get _class _VARS () çözümleri olanlar için: teşekkürler, ama o "belirli bir sınıfın varsayılan özelliklerini" (php.net) verir, ve evet, ben bana yardım yapsa bile (makinemizde olması için bu değer gibi gözüküyor Olguların bazı)

11 Cevap

PHP 5.3.0 veya daha kullanıyorsanız, aşağıdaki kullanabilirsiniz:

$classname::$$propertyname;

Unfortunately, if you are using a version lower than 5.3.0, you are stuck using eval() (get_class_vars() will not work if the value is dynamic).

$value = eval($classname.'::$'.$propertyname.';');


EDIT: Ben sadece söylediğim get_class_vars() wouldn't work if the value is dynamic, but apparently, variable static members are part of "the default properties of a class". Aşağıdaki sarıcı kullanabilirsiniz:

function get_user_prop($className, $property) {
  if(!class_exists($className)) return null;
  if(!property_exists($className, $property)) return null;

  $vars = get_class_vars($className);
  return $vars[$property];
}

class Foo { static $bar = 'Fizz'; }

echo get_user_prop('Foo', 'bar'); // echoes Fizz
Foo::$bar = 'Buzz';
echo get_user_prop('Foo', 'bar'); // echoes Buzz

Eğer değişkenin değerini ayarlamak istiyorsanız yazık ki, yine de kullanmak gerekir eval() , but with some validation in place, it's not so evil.

function set_user_prop($className, $property,$value) {
  if(!class_exists($className)) return false;
  if(!property_exists($className, $property)) return false;

  /* Since I cannot trust the value of $value
   * I am putting it in single quotes (I don't
   * want its value to be evaled. Now it will
   * just be parsed as a variable reference).
   */
  eval($className.'::$'.$property.'=$value;');
  return true;
}

class Foo { static $bar = 'Fizz'; }

echo get_user_prop('Foo', 'bar'); // echoes Fizz
set_user_prop('Foo', 'bar', 'Buzz');
echo get_user_prop('Foo', 'bar'); // echoes Buzz

set_user_prop() Bu doğrulama ile should güvenli olması. Insanlar $className gibi rastgele şeyler koyarak başlamak ve mevcut bir sınıf veya özellik olmayacak gibi $property, bu fonksiyonun dışarı çıkmak olacaktır. Itibariyle $value, aslında bu yüzden ne olursa olsun onlar oraya koymak komut etkilemez kodu olarak ayrıştırılır asla.

Ben bu basit olduğunu düşünüyorum:

$foo = new ReflectionProperty('myClassName', 'myPropertyName'); 
print $foo->getValue();

Aramanız gereken bir statik değişken tarafından belirlenen bir değişken değer döndürmek için:

$static_value = constant($classname.'::'.$propertyname);

Belgelerini kontrol edin :: PHP Constant Documentation

Ben fark bir şey sınıf dışında bir kapsamda eval () komutu çalıştırır gibi statik sınıflar korunmaktadır değişkenleri ayarlamak edemezler. Bunu aşmanın tek şey / eval çalışan her sınıf () içinde statik bir yöntem uygulamak olacaktır. Bu yöntem call_user_func () [ayarlayıcı yöntemi çağırmak için] Ayrıca sınıf içinde çalışır şekilde korunmuş olabilir.

Sen gibi bir şey yapmak mümkün olmalıdır:

eval("echo $classname::$propertyname;");

Ben sadece hızlı bir test yaptım ve benim için işe aldım. Orada daha iyi bir yol ya da değil, ama bulmak mümkün değildi emin değilim.

'Eval' şer 'çok yakın görünüyor ve bunu kullanarak ve / veya kod bunu görmekten nefret ediyorum. Diğer yanıtlar birkaç fikir ile, burada php 5.3 veya daha yüksek olmasa bile bunu önlemek için bir yol.

Bir Yorum dayalı test yansıtacak şekilde değiştirildi.

class A {
    static $foo = 'bar';
}

A::$foo = 'baz';
$a = new A;

$class = get_class($a);
$vars = get_class_vars($class);

echo $vars['foo'];

Çıktısı: 'baz'.

Potansiyel ilgili: PHP bağlayıcı geç statik tartışma - http://stackoverflow.com/questions/87192/when-would-you-need-to-use-late-static-binding.

get_class_vars get_object_vars olarak aynı değildir.

Bence get_clas_vars orijinal özellik değerlerini dönmelidir.

Dediğin için bile bile eval söz konusu değildir, önce PHP 5.3 kolay çözüm kullanarak hala eval:

eval("\$propertyval = $classname::\$propertyname;");
echo $propertyval;

Sen ReflectionClass kullanabilirsiniz:

class foo
{
    private static $bar = "something";
}

$class = "foo";
$reflector = new ReflectionClass($class);
$static_vars = $reflector->getStaticProperties();
var_dump($static_vars["bar"]);

Getting and setting both static and non static properties without using Reflection

Reflection kullanarak çalışır ama pahalı

İşte, ben bu amaç için kullanmak ne

Bunun için çalışan PHP 5 >= 5.1.0 because I'm using property_exist

function getObjectProperty($object, $property)
{
    if (property_exists(get_class($object), $property)) {
        return array_key_exists($property, get_object_vars($object))
            ? $object->{$property}
            : $object::$$property;
    }
}

function setObjectProperty($object, $property, $value)
{
    if (property_exists(get_class($object), $property)) {
        array_key_exists($property, get_object_vars($object))
            ? $object->{$property} = $value
            : $object::$$property = $value;
    }
}