Последствия инстанцирования объектов с динамическими переменными в PHP

Как будто вы пытаетесь получить доступ к объекту, который является null. Рассмотрим ниже пример:

TypeA objA;

. В это время вы только что объявили этот объект, но не инициализировали или не инициализировали. И всякий раз, когда вы пытаетесь получить доступ к каким-либо свойствам или методам в нем, он будет генерировать NullPointerException, что имеет смысл.

См. Также этот пример:

String a = null;
System.out.println(a.toString()); // NullPointerException will be thrown
11
задан Anant Singh---Alive to Die 5 June 2015 в 17:45
поделиться

9 ответов

Одна из проблем с разрешением во время выполнения - то, что Вы делаете его действительно трудно для кэшей кода операции (как APC). Однако, на данный момент выполнение чего-то как Вы описывает в Вашем вопросе, допустимый путь, если Вам нужно определенное количество косвенности, когда instanciating наполняют.

Пока Вы не делаете чего-то как

$classname = 'SomeClassName';
for ($x = 0; $x < 100000; $x++){
  $object = new $classname;
}

Вы, вероятно, в порядке :-)

(мое точка быть: Динамично поиск класса здесь и затем не причиняет боль. Если Вы будете часто делать это, то это будет).

Кроме того, убедитесь, что $classname никогда не может устанавливаться с внешней стороны - Вы хотели бы иметь некоторый контроль над тем, какого точного класса Вы будете инстанцировать.

8
ответ дан 3 December 2019 в 03:19
поделиться

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

<?php

class Test {
    function __construct($x) {
        echo $x;
    }
}

$class = 'Test';
$object = new $class('test'); // echoes "test"

?>

Именно это Вы имели в виду, правильно?

Так единственная другая проблема Вы упомянули и что я могу думать, безопасность его, но не должно быть слишком трудно заставить его защитить, и это, очевидно, намного более безопасно, чем использование оценки ().

8
ответ дан 3 December 2019 в 03:19
поделиться

Я добавил бы, что Вы можете также instanciate он с динамическим количеством использования параметров:

<?php

$class = "Test";
$args = array('a', 'b');
$ref = new ReflectionClass($class);
$instance = $ref->newInstanceArgs($args);

?>

Но конечно Вы добавляете еще некоторые, служебные путем выполнения этого.

О проблеме безопасности я не думаю, что она имеет значение очень, по крайней мере, это - ничто по сравнению с оценкой (). В худшем случае неправильный класс получает instanciated, конечно, это - потенциальное нарушение защиты, но намного тяжелее использовать, и легко отфильтровать использование массива позволенных классов при реальной необходимости во вводе данных пользователем для определения имени класса.

5
ответ дан 3 December 2019 в 03:19
поделиться

Я использую динамическое инстанцирование в своей пользовательской платформе. Мой контроллер приложения должен инстанцировать подконтроллера на основе запроса, и было бы просто смешно использовать гигантский, постоянно меняющийся оператор переключения для управления загрузкой тех контроллеров. В результате я могу добавить контроллер после контроллера к моему приложению, не имея необходимость изменять контроллер приложения для вызова их. Пока мои URIs придерживаются конвенций моей платформы, контроллер приложения может использовать их, не имея необходимость знать что-либо до времени выполнения.

Я использую эту платформу в производственном приложении корзины покупок прямо сейчас, и производительность довольно благоприятна, также. Однако я только использую динамический выбор класса в одном или двух местах в целом приложении. Интересно, при каких обстоятельствах необходимо было бы часто использовать его, и являются ли те ситуации, которые страдают от требования программиста сверхабстрагировать приложение (я был виновен в этом прежде).

0
ответ дан 3 December 2019 в 03:19
поделиться

@coldFlame: IIRC можно использовать call_user_func(array($className, 'someStaticMethod') и call_user_func_array() передать параметрические усилители

0
ответ дан 3 December 2019 в 03:19
поделиться
class Test {
    function testExt() {
    print 'hello from testExt :P';
    }
    function test2Ext()
    {
    print 'hi from test2Ext :)';
    }
}


$class = 'Test';
$method_1 = "testExt";
$method_2 = "test2Ext";
$object = new $class(); // echoes "test"
$object->{$method_2}(); // will print 'hi from test2Ext :)'
$object->{$method_1}(); // will print 'hello from testExt :P';

этот прием работы и в php4 и в php5 :D обладает..

0
ответ дан 3 December 2019 в 03:19
поделиться

Одна проблема состоит в том, что Вы не можете обратиться к статическим участникам как этот, например

<?php
$className = 'ClassName';

$className::someStaticMethod(); //doesn't work
?>
0
ответ дан 3 December 2019 в 03:19
поделиться

Может действительно быть хит производительности для того, чтобы иметь необходимость разрешить название переменной перед поиском определения класса. Но, не объявляя классы динамично у Вас нет реального способа сделать программирование "dyanmic" или "meta". Вы не смогли бы записать программы генерации кода или что-либо как проблемно-ориентированная конструкция языка.

Мы используем эту конвенцию повсеместно в некоторых базовых классах нашей внутренней платформы для создания URL к работе отображений контроллера. Я также видел его во многих коммерческих приложениях с открытым исходным кодом (я попытаюсь вырыть для примера и отправить его). Так или иначе точка моего ответа - то, что кажется определенно стоящим того, что является, вероятно, небольшим снижением производительности, если это делает более гибкий, динамический код.

Другой компромисс, который я должен упомянуть, тем не менее, - то, что производительность в стороне, это действительно делает код немного менее очевидным и читаемым, если Вы не очень осторожны со своими именами переменной. Большая часть кода написана однажды, и перечитана и много раз изменяется, таким образом, удобочитаемость важна.

4
ответ дан 3 December 2019 в 03:19
поделиться

Alan, нет ничего неправильно с динамической инициализацией класса. Эта техника присутствует также на языке Java, где можно преобразовать строку в использование класса Class.forClass('classname') метод. Также довольно удобно задержать сложность алгоритма к нескольким классам вместо того, чтобы иметь список если-условий. Динамические имена классов особенно хорошо подходят в ситуациях, где Вы хотите, чтобы Ваш код остался открытым для расширения без потребности в модификациях.

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

Вы не должны быть обеспокоены производительностью. Это не имеет почти никаких издержек, и сами объекты супер быстры в PHP. Если необходимо породить тысячи одинаковых объектов, используйте шаблон разработки В наилегчайшем весе для сокращения объема потребляемой памяти. Особенно, Вы не должны жертвовать своим временем как разработчик только для сохранения миллисекунд на сервере. Также оптимизаторы кода операции работают беспрепятственно с этой техникой. Сценарии, скомпилированные с Оптимизатором Зенда, не неправильно себя вели.

2
ответ дан 3 December 2019 в 03:19
поделиться
Другие вопросы по тегам:

Похожие вопросы: