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