我想做这样的事情:
public static function createDynamic(){
$mydynamicvar = 'module';
self::$mydynamicvar = $value;
}
并且能够使用
从类中访问该属性$value = self::$module;
答案 0 :(得分:10)
我不知道你为什么要这样做,但这很有效。您必须像函数一样访问动态“变量”,因为PHP中没有__getStatic()魔术方法。
class myclass{
static $myvariablearray = array();
public static function createDynamic($variable, $value){
self::$myvariablearray[$variable] = $value;
}
public static function __callstatic($name, $arguments){
return self::$myvariablearray[$name];
}
}
myclass::createDynamic('module', 'test');
echo myclass::module();
答案 1 :(得分:3)
静态变量必须是类定义的一部分,因此您无法创建动态。甚至没有使用Reflection:
chuck at manchuck dot com 2 years ago
请务必注意,调用
ReflectionClass::setStaticPropertyValue
将不允许您向类中添加新的静态属性。
但这看起来非常像XY Problem。您可能不想在运行时向PHP类添加静态属性;你有一些用例可以通过这种方式实现也。或者那种方式是实现某些用例的最快方式。可能还有其他方式。
实际上,下面的用例再次成为某些更高级别问题的可能解决方案。重新审视高级问题并以不同的方式重构/重新思考它可能是值得的,可能完全不需要干涉静态属性。
trait HasDictionary {
private static $keyValueDictionary = [ ];
public static function propget($name) {
if (!array_key_exists($name, static::$keyValueDictionary) {
return null;
}
return static::$keyValueDictionary[$name];
}
public static function propset($name, $value) {
if (array_key_exists($name, static::$keyValueDictionary) {
$prev = static::$keyValueDictionary[$name];
} else {
$prev = null;
}
static::$keyValueDictionary[$name] = $value;
return $prev;
}
}
class MyClass
{
use Traits\HasDictionary;
...$a = self::propget('something');
self::propset('something', 'some value');
}
这实际上发生在我身上,我在调查这样做的过程中发现了这个问题。我需要在我的工作流程的B点看到,在某一点(" A")定义了一个给定的类,以及代码的其他部分。最后,我将该信息存储到由我的自动加载器提供的数组中,最后还能够在第一次加载时存储debug_backtrace()
。
// Solution: store values somewhere else that you control.
class ClassPropertySingletonMap {
use Traits\HasDictionary; // same as before
public static function setClassProp($className, $prop, $value) {
return self::propset("{$className}::{$prop}", $value);
}
public static function getClassProp($className, $prop) {
return self::propget("{$className}::{$prop}");
}
}
// Instead of
// $a = SomeClass::$someName;
// SomeClass::$someName = $b;
// we'll use
// $a = ClassPropertySingletonMap::getClassProp('SomeClass','someName');
// ClassPropertySingletonMap::setClassProp('SomeClass','someName', $b);
// Use Reflection. The property is assumed private, for were it public
// you could do it as Class::$property = $whatever;
function setPrivateStaticProperty($class, $property, $value) {
$reflector = new \ReflectionClass($class);
$reflector->getProperty($property)->setAccessible(true);
$reflector->setStaticPropertyValue($property, $value);
$reflector->getProperty($property)->setAccessible(false);
}
答案 2 :(得分:2)
必须在类定义中定义静态属性。因此,无法像常规属性那样动态创建实际静态属性。
例如,如果你运行它:
<?php
class MyClass
{
public static function createDynamic()
{
$mydynamicvar = 'module';
self::$mydynamicvar = $value;
}
}
MyClass::createDynamic();
var_dump(MyClass::$mydynamicvar);
var_dump(MyClass::$module);
...你会收到这个错误
Fatal error: Access to undeclared static property: MyClass::$mydynamicvar test.php on line 8
注意在尝试设置属性而不是第14行或第15行时如何在第8行发生错误(如果您只是做错了,并且实际上可以动态创建静态属性,可能会出现这种情况)。
答案 3 :(得分:0)
一个可能的相关问题(在PHP 5.4.0及更高版本中)是包括各种不同的静态变量或常量声明组,并将它们分组为一个类声明。
这里是一个例子:
trait Added1 // This can be located in one Include file
{
static
$x="hello"; // Can declare more variables here
}
trait Added2 // This can be located in another Include file
{
static
$y="world"; // Can declare more variables here
}
class G // Global constant and variable declarations class
{
use Added1, Added2; // Combines all variable declarations
}
echo G::$x." ".G::$y; // Shows "hello world" on the web page