Intereting Posts
Не удалось подключиться к внешней базе данных SSL Postgres с Debian (ошибки разрешения сертификата) WooCommerce показывает два набора всех способов оплаты SQL ORDER BY с использованием подготовленных операторов Разница между row_array и result_array доктрина 2 много для многих (Продукты – Категории) Facebook PHP SDK 3 не будет работать на 32-битной системе, иидентификаторы facebook, обработанные как int, и могут быть> 2147483647, лучшее решение? Чтение текста с изображения с помощью PHP Создание изображений предварительного просмотра для файлов DOC, TXT и RTF Строковые числа в числовые числа в PHP Drupal и регулярная интеграция с PHP Загрузка PHP-расширения из скрипта с помощью dl () API-интерфейс PayPal REST: невозможно настроить целевую страницу для выставления счетов Является ли PHP универсальным во всех браузерах? Предупреждение move_uploaded_file Почему NSURLSession uploadTaskWithRequest: fromData: не удается загрузить на php-сервер?

Как динамически создавать новое свойство

Как я могу создать свойство из заданного аргумента внутри метода объекта?

class Foo{ public function createProperty($var_name, $val){ // here how can I create a property named "$var_name" // that takes $val as value? } } 

И я хочу иметь доступ к этому свойству:

 $object = new Foo(); $object->createProperty('hello', 'Hiiiiiiiiiiiiiiii'); echo $object->hello; 

Также возможно, что я мог бы сделать собственность открытой / защищенной / частной? Я знаю, что в этом случае он должен быть общедоступным, но я могу добавить некоторые методы magik, чтобы получить защищенные свойства и прочее 🙂


Думаю, я нашел решение:

  protected $user_properties = array(); public function createProperty($var_name, $val){ $this->user_properties[$var_name] = $val; } public function __get($name){ if(isset($this->user_properties[$name]) return $this->user_properties[$name]; } 

вы думаете, что это хорошая идея?

Для этого есть два метода.

Во-первых, вы можете напрямую создавать свойства динамически извне класса:

 class Foo{ } $foo = new Foo(); $foo->hello = 'Something'; 

Или, если вы хотите создать свойство с помощью метода createProperty :

 class Foo{ public function createProperty($name, $value){ $this->{$name} = $value; } } $foo = new Foo(); $foo->createProperty('hello', 'something'); 

Перегрузка объектов происходит очень медленно. Если можно, постарайтесь избежать этого. Также важно реализовать два других магических метода:

__isset (); __unset ();

Если позже вы не захотите найти некоторые распространенные ошибки при использовании этих атрибутов объекта,

Вот некоторые примеры:

http://www.php.net/manual/en/language.oop5.overloading.php#language.oop5.overloading.members

EDITED после комментария Alex:

Вы можете проверить себя разницу во времени между обоими решениями (изменить $ REPEAT_PLEASE)

 <?php $REPEAT_PLEASE=500000; class a {} $time = time(); $a = new a(); for($i=0;$i<$REPEAT_PLEASE;$i++) { $a->data = 'hi'; $a->data = 'bye'.$a->data; } echo '"NORMAL" TIME: '.(time()-$time)."\n"; class b { function __set($name,$value) { $this->d[$name] = $value; } function __get($name) { return $this->d[$name]; } } $time=time(); $a = new b(); for($i=0;$i<$REPEAT_PLEASE;$i++) { $a->data = 'hi'; //echo $a->data; $a->data = 'bye'.$a->data; } echo "TIME OVERLOADING: ".(time()-$time)."\n"; 

Используйте синтаксис: $ object -> {$ property}, где $ property – строковая переменная, а $ object может быть таким, если он находится внутри класса или любого объекта экземпляра

Пример: http://sandbox.onlinephpfunctions.com/code/108f0ca2bef5cf4af8225d6a6ff11dfd0741757f

  class Test{ public function createProperty($propertyName, $propertyValue){ $this->{$propertyName} = $propertyValue; } } $test = new Test(); $test->createProperty('property1', '50'); echo $test->property1; 

Результат: 50

Следующий пример предназначен для тех, кто не хочет объявлять целый класс.

 $test = (object) []; $prop = 'hello'; $test->{$prop} = 'Hiiiiiiiiiiiiiiii'; echo $test->hello; // prints Hiiiiiiiiiiiiiiii