Примечание: Решение ниже для PHP 5.3 и ниже. Начиная с PHP 5.4, вы также можете использовать do it via Reflection as shown elsewhere on this page.
Это действительно возможно.
Измененный PHPUnit_Framework_MockObject_Generator
1 $myClass = unserialize(
2 sprintf(
3 'O:%d:"%s":0:{}',
4 strlen('MyClass'), 'MyClass'
5 )
6 );
Пожалуйста, имейте в виду, что код, как это все хорошо и оправдано в рамках как PHPUnit. Но если в вашем производственном коде должен быть такой код, вы, скорее всего, делаете что-то очень странное.
Поскольку вы попросили объяснения:
Когда вы serialize an Object вы получите строковое представление объекта. Например,
echo serialize(new StdClass) // gives O:8:"stdClass":0:{}
O
означает объект. 8
- длина строки имени класса. "stdClass"
- это, очевидно, название класса. Сериализованный объект имеет 0
набор свойств (подробнее к этому позже), обозначенный пустыми фигурными фигурными скобками. :
- это просто разделители.
Каждая серийная строка может быть воссоздана в исходное «живое» значение с помощью функции unserialize. Это позволит обойти конструктор. Как Чарльз правильно указал, что magic method __wakeup()
будет вызываться, если он определен (так же, как будет вызываться при сериализации).
В строке 3 вы видите строку, подготовленную для использования с sprintf (строка 2). Как вы можете видеть, длина строки имени класса задается как %d
, а имя класса указывается как %s
. Это означает, что sprintf должен использовать первый аргумент, переданный ему в строке 4, как цифру, а второй - как строку. Таким образом, результат вызова Sprintf является
'O:7:"MyClass":0:{}'
Вы бы заменить оба вхождения «MyClass» в строке 4 с нужным именем класса, чтобы создать последовательную строку класса, который вы хотите создать экземпляр без вызова контроллера.
Эта строка затем несериализуется в экземпляр MyClass в строке 1, минуя конструктор. Неэтериализованный экземпляр будет иметь все методы его класса, а также любые свойства. Если в MyClass есть свойства, они будут иметь значения по умолчанию, если вы не добавите разные значения в сериализованную фиктивную строку.
И это уже есть. Ничего слишком волшебного в этом нет.
Или, как указывали другие, статический метод может наилучшим образом удовлетворить ваши потребности в зависимости от того, что вы пытаетесь сделать. –
+1 для расширения класса. Возможно, это класс сторонней библиотеки, который не следует изменять ... –
+1 для хороших альтернативных решений. – Yacoby