web-dev-qa-db-ja.com

PHPの動的クラス名を持つクラスから静的プロパティを取得する

私はこれを持っています:

  • クラス名($classname
  • プロパティ名($propertyname

そのクラスからプロパティを取得したいのですが、問題はプロパティが静的であり、その方法がわからないということです。

プロパティが静的でない場合、次のようになります。

$classname->$propertyname;

プロパティがメソッドの場合、call_user_functionを使用できた

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

しかし、私の場合、私はちょうど失われています。しかし、私はそれが可能であることを望んでいます。 PHPが持っている何千もの関数があるので、彼はこれのために何かを持っていたほうがいいでしょう。

ありがとう!

編集:

  • eval() ソリューションをお持ちの方へ:ありがとう、しかしそれは問題外です
  • get _class _vars() solutions:がありますが、 "指定されたクラスのデフォルトのプロパティ"(php.net)、そして、はい、その値を変更可能にしたいです(いくつかのケースで私を助けますが)
48
treznik

PHP 5.3.0以降を使用している場合、以下を使用できます。

_$classname::$$propertyname;
_

残念ながら、5.3.0より前のバージョンを使用している場合、 eval()get_class_vars() は機能しません。値が動的な場合)。

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

EDIT:先ほど言ったように get_class_vars() は値が動的な場合は機能しませんが、明らかに、変数の静的メンバーは "クラスのデフォルトプロパティ"の一部です。次のラッパーを使用できます。

_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
_

残念ながら、変数の値を設定したい場合は、まだ eval() を使用する必要がありますが、検証が行われているため、notとても悪

_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()この検証を使用すると、安全である必要があります。 _$className_および_$property_としてランダムなものを配置し始めると、既存のクラスまたはプロパティではないため、関数から終了します。 _$value_の時点では、実際にコードとして解析されることはないため、そこに何を入れてもスクリプトには影響しません。

74
Andrew Moore

私はこれが最も簡単だと思う:

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

呼び出す必要がある静的変数によって設定された変数値を返すには:

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

ドキュメントを確認してください:: PHP Constant Documentation

13
frodosghost

次のようなことができるはずです。

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

簡単なテストを行っただけで、これが機能しました。より良い方法があるかどうかはわかりませんが、見つけることができませんでした。

1
Steven Surowiec

「eval」は「evil」に非常に近いように見えます。私はそれを使用したり、コードで見たりするのが嫌いです。他の回答からのいくつかのアイデアを使用して、PHPが5.3以上ではない場合でも回避する方法があります。

コメントに基づくテストを反映するように変更されました。

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

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

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

echo $vars['foo'];

「baz」を出力します。

1
nilamo

私が気づいたことの1つは、eval()コマンドがクラス外のスコープで実行されるため、静的クラスで保護されている変数を設定できないことです。これを回避する唯一の方法は、eval()を実行するすべてのクラス内に静的メソッドを実装することです。 call_user_func()[setterメソッドを呼び出す]もクラス内から実行されるため、このメソッドを保護できます。

1
mbirth

get_class_varsget_object_varsと同じではありません。

get_clas_varsは元のプロパティ値を返すはずです。

0
firzen

evalは問題外だと言っても、以前のPHP 5.3で最も簡単な解決策はevalを使用することです:

eval("\$propertyval = $classname::\$propertyname;");
echo $propertyval;
0
Marco Demaio
0
Alex Weinstein

ReflectionClassを使用できます。

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

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