Как создать свойство статического класса PHP во время выполнения (динамически)? - PullRequest
11 голосов
/ 23 марта 2012

Я бы хотел сделать что-то вроде этого:

public static function createDynamic(){
    $mydynamicvar = 'module'; 
    self::$mydynamicvar = $value;
}

и сможете получить доступ к свойству из класса с

$value = self::$module;

Ответы [ 4 ]

10 голосов
/ 23 марта 2012

Я не знаю точно, почему вы хотели бы сделать это, но это работает. Вы должны обращаться к динамическим «переменным» как функция, потому что в 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();
3 голосов
/ 15 июня 2015

статические переменные должны быть частью определения класса, поэтому вы не можете создавать их динамически .Даже с 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);
}
2 голосов
/ 23 марта 2012

Статические свойства должны быть определены в определении класса. Следовательно, реальные статические свойства нельзя создавать динамически, как обычные свойства.

Например, если вы запустите это:

<?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 (как можно было ожидать, если вы просто делали это неправильно и динамическое создание статических свойств было действительно возможно).

0 голосов
/ 06 июня 2019

Связанная проблема, которая возможна (в 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...