Я хотел бы сделать что-то вроде этого:
public static function createDynamic(){
$mydynamicvar = 'module';
self::$mydynamicvar = $value;
}
и иметь возможность доступа к свойству из класса с помощью
$value = self::$module;
Я хотел бы сделать что-то вроде этого:
public static function createDynamic(){
$mydynamicvar = 'module';
self::$mydynamicvar = $value;
}
и иметь возможность доступа к свойству из класса с помощью
$value = self::$module;
Я не знаю, почему вы хотели бы это сделать, но это работает. Вы должны получить доступ к динамическим "переменным", как к функции, потому что в 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();
static переменные должны быть частью определения класса, поэтому вы не можете создавать динамически . Даже с Reflection:
chuck at manchuck dot com 2 years ago
Важно отметить, что вызов
ReflectionClass::setStaticPropertyValue
не позволит вам добавлять новые статические свойства в класс.
Но это очень похоже на проблему XY. Вероятно, вы не хотите добавлять статические свойства в класс 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);
}
Статические свойства должны быть определены в определении класса. Поэтому реальные статические свойства не могут создаваться динамически, как обычные свойства.
Например, если вы запустите это:
<?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
Обратите внимание, как ошибка возникает в строке 8 при попытке установить свойство вместо строки 14 или 15 (как и следовало ожидать, если бы вы просто делали это неправильно и динамически создавали статические свойства, было возможно).
Связанная проблема, которая возможна (в 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