Php unserialize from file

Php unserialize from file

Функция serialize() возвращает строковое представление любого значения, которое может быть сохранено в PHP. Функция unserialize() может использовать эту строку для восстановления исходного значения переменной. Использование сериализации для сохранения объекта сохранит все его переменные. Методы в объекте не будут сохранены, только имя класса.

Для того, чтобы иметь возможность выполнить unserialize() для объекта, нужно, чтобы класс этого объекта был определён заранее. То есть, если у вас есть экземпляр класса А, и вы сделаете его сериализацию, вы получите его строковое представление, которое содержит значение всех переменных, содержащихся в нем. Для того, чтобы восстановить объект из строки в другом PHP-файле, класс A должен быть определён заранее. Это можно сделать, например, путём сохранения определения класса A в отдельный файл и подключить этот файл или использовать функцию spl_autoload_register() для автоматического подключения.

public function show_one () echo $this -> one ;
>
>

$a = new A ;
$s = serialize ( $a );
// сохраняем $s где-нибудь, откуда page2.php сможет его получить.
file_put_contents ( ‘store’ , $s );

// это нужно для того, чтобы функция unserialize работала правильно.
include( «classa.inc» );

$s = file_get_contents ( ‘store’ );
$a = unserialize ( $s );

// теперь можно использовать метод show_one() объекта $a.
$a -> show_one ();
?>

Если в приложении производится сериализация объектов для последующего использования, настоятельно рекомендуется подключать определение класса для этого объекта во всем приложении. Невыполнение этого требования может привести к тому, что объект будет десериализован без определения класса, что приведёт к тому, что PHP будет использовать для этого объекта класс __PHP_Incomplete_Class_Name , который не имеет методов и сделает объект бесполезным.

Читайте также:  Найти гласные буквы в строке python

Поэтому, если в приведённом выше примере $a стало частью сессии после запуска session_register(«a») , вы должны подключать файл classa.inc на всех ваших страницах, а не только page1.php и page2.php .

Обратите внимание, что, кроме вышеприведённого совета, также можно подключиться к событиям сериализации и десериализации объекта с помощью методов __sleep() и __wakeup(). Метод __sleep() также позволяет сериализовать лишь некоторое подмножество свойств объекта.

Источник

unserialize

unserialize() принимает одну сериализованную переменную и конвертирует ее обратно в значение PHP.

Список параметров

Если переменная, требующая десериализации, является объектом, то после успешного восстановления объекта PHP автоматически попытается вызвать магический метод __wakeup() (если он существует).

Замечание: Директива unserialize_callback_func

Существует возможность указать функцию обратного вызова, которая будет вызвана, если в процессе десериализации должен быть проинициализирован неопределенный класс. (для предотвращения получения неполного объекта object «__PHP_Incomplete_Class».) Используйте php.ini , ini_set() или .htaccess для определения функции ‘unserialize_callback_func‘. Данная функция будет вызываться каждый раз, когда должен быть проинициализирован неопределенный класс. Для отключения этой возможности просто оставьте значение директивы пустым.

Возвращаемые значения

Возвращается преобразованное значение, которое принимать один из типов boolean , integer , float , string , array или object .

В случае, если переданная строка не поддается десериализации, возвращается FALSE и генерируется E_NOTICE .

Список изменений

Версия Описание
5.6.0 Изменение сериализованных данных с заменой C: на O:, для принудительного создания объекта без вызова конструктора, теперь будет проходить успешно.

Примеры

Пример #1 Пример использования unserialize()

// Мы используем функцию unserialize() для загрузки сессионных данных в массив
// $session_data из строки, извлекаемой из базы данных.
// Данный пример дополняет пример, описывающий использование serialize().

$conn = odbc_connect ( «webdb» , «php» , «chicken» );
$stmt = odbc_prepare ( $conn , «SELECT data FROM sessions WHERE > );
$sqldata = array( $_SERVER [ ‘PHP_AUTH_USER’ ]);
if (! odbc_execute ( $stmt , $sqldata ) || ! odbc_fetch_into ( $stmt , $tmp )) // если процедура извлечения данных не удалась, то инициализируем пустой массив
$session_data = array();
> else // сейчас у нас должны быть сериализованные данные в $tmp[0].
$session_data = unserialize ( $tmp [ 0 ]);
if (! is_array ( $session_data )) // что-то пошло не так, инициализируем пустой массив
$session_data = array();
>
>
?>

Пример #2 Пример использования unserialize_callback_func

// директива unserialize_callback_func доступна с PHP 4.2.0
ini_set ( ‘unserialize_callback_func’ , ‘mycallback’ ); // определяем свою функцию обратного вызова

function mycallback ( $classname )
// просто подключаете файл, содержащий определение класса
// $classname указывает, для какого класса требуется определение
>
?>

Примечания

FALSE возвращается как в случае ошибки, так и в случае, если десериализуется сериализованное значение FALSE . Этот особый случай можно отловить, используя сравнение str со значением serialize(false), или перехватив сгенерированную ошибку E_NOTICE .

Не передавайте непроверенные пользовательские данные в unserialize() . Десериализация может создать код, который выполнится при создании объекта или при автоматической загрузке кода, чем могут воспользоваться недобросовестные пользователи. Лучше использовать более безопасные стандартные форматы обмена данными, такие как JSON (с помощью функций json_decode() и json_encode() ), если вам нужно передать сериализованные данные пользователю.

Смотрите также

Источник

serialize

Генерирует пригодное для хранения представление переменной.

Это полезно для хранения или передачи значений PHP между скриптами без потери их типа и структуры.

Для превращения сериализованной строки обратно в PHP-значение, используйте функцию unserialize() .

Список параметров

Значение, которое необходимо сериализовать. serialize() обрабатывает все типы, кроме resource и некоторых типов object (смотрите примечание ниже). Возможно также сериализовать массивы, которые содержат ссылки на себя. Циклические ссылки внутри сериализуемого массива/объекта также сохраняются. Любые другие ссылки будут потеряны.

При сериализации объекта PHP пытается вызвать магические методы __serialize() или __sleep() перед сериализацией. Это делается для того, чтобы позволить объекту в последний момент произвести очистку и тому подобные операции перед сериализацией. Аналогично, когда объект восстанавливается функцией unserialize() , вызывается магический метод __unserialize() или __wakeup().

Замечание:

Начало имён закрытых членов объекта дополняются именем класса, а начало имён защищённых членов символом ‘*’. Эти дополненные значения окружаются нулевым байтом (0x00) с обеих сторон.

Возвращаемые значения

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

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

Примеры

Пример #1 Пример использования serialize()

// $session_data содержит многомерный массив с сессионной
// информацией о текущем пользователе. Мы используем serialize() для сохранения
// этой информации в базе данных в конце запроса.

$conn = odbc_connect ( «webdb» , «php» , «chicken» );
$stmt = odbc_prepare ( $conn ,
«UPDATE sessions SET data = ? WHERE > );
$sqldata = array ( serialize ( $session_data ), $_SERVER [ ‘PHP_AUTH_USER’ ]);
if (! odbc_execute ( $stmt , $sqldata )) $stmt = odbc_prepare ( $conn ,
«INSERT INTO sessions (id, data) VALUES(?, ?)» );
if (! odbc_execute ( $stmt , array_reverse ( $sqldata ))) /* Код, выполняемый в случае возникновения ошибки.. */
>
>
?>

Примечания

Замечание:

Обратите внимание, что много встроенных в PHP объектов не может быть сериализовано. Однако, те из них, которые поддерживают эту возможность, реализуют или интерфейс Serializable , или магические методы __serialize()/__unserialize() или __sleep()/__wakeup(). Если встроенный класс не удовлетворяет этим требованиям, он не может быть надёжно сериализован.

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

При сериализации объектов функцией serialize() , ведущий обратный слеш не будет включён в имя класса с указанным пространством имён для наилучшей обратной совместимости.

Смотрите также

  • unserialize() — Создаёт PHP-значение из хранимого представления
  • var_export() — Выводит или возвращает интерпретируемое строковое представление переменной
  • json_encode() — Возвращает JSON-представление данных
  • Сериализация объектов
  • __sleep()
  • __wakeup()
  • __serialize()
  • __unserialize()

User Contributed Notes 33 notes

/*
Anatomy of a serialize()’ed value:

Boolean
b:value; (does not store «true» or «false», does store ‘1’ or ‘0’)

Object
O:strlen(object name):object name:object size:

String values are always in double quotes
Array keys are always integers or strings
«null => ‘value'» equates to ‘s:0:»»;s:5:»value»;’,
«true => ‘value'» equates to ‘i:1;s:5:»value»;’,
«false => ‘value'» equates to ‘i:0;s:5:»value»;’,
«array(whatever the contents) => ‘value'» equates to an «illegal offset type» warning because you can’t use an
array as a key; however, if you use a variable containing an array as a key, it will equate to ‘s:5:»Array»;s:5:»value»;’,
and
attempting to use an object as a key will result in the same behavior as using an array will.
*/
?>

Please! please! please! DO NOT serialize data and place it into your database. Serialize can be used that way, but that’s missing the point of a relational database and the datatypes inherent in your database engine. Doing this makes data in your database non-portable, difficult to read, and can complicate queries. If you want your application to be portable to other languages, like let’s say you find that you want to use Java for some portion of your app that it makes sense to use Java in, serialization will become a pain in the buttocks. You should always be able to query and modify data in the database without using a third party intermediary tool to manipulate data to be inserted.

I’ve encountered this too many times in my career, it makes for difficult to maintain code, code with portability issues, and data that is it more difficult to migrate to other RDMS systems, new schema, etc. It also has the added disadvantage of making it messy to search your database based on one of the fields that you’ve serialized.

That’s not to say serialize() is useless. It’s not. A good place to use it may be a cache file that contains the result of a data intensive operation, for instance. There are tons of others. Just don’t abuse serialize because the next guy who comes along will have a maintenance or migration nightmare.

I did some testing to see the speed differences between serialize and json_encode, and my results with 250 iterations are:

PHP serialized in 0.0651714730263 seconds average
JSON encoded in 0.0254955434799 seconds average
json_encode() was roughly 155.62% faster than serialize()
Test took 27.2039430141 seconds with 300 iretations.

PHP serialized in 0.0564563179016 seconds average
JSON encoded in 0.0249140485128 seconds average
json_encode() was roughly 126.60% faster than serialize()
Test took 24.4148340225 seconds with 300 iretations.

From all my tests it looks like json_encode is on average about 120% faster (sometimes it gets to about 85% and sometimes to 150%).

Here is the PHP code you can run on your server to try it out:

// fillArray function myde by Peter Bailey
function fillArray ( $depth , $max ) static $seed ;
if ( is_null ( $seed )) $seed = array( ‘a’ , 2 , ‘c’ , 4 , ‘e’ , 6 , ‘g’ , 8 , ‘i’ , 10 );
>
if ( $depth < $max )$node = array();
foreach ( $seed as $key ) $node [ $key ] = fillArray ( $depth + 1 , $max );
>
return $node ;
>
return ’empty’ ;
>

function testSpeed ( $testArray , $iterations = 100 )

$json_time = array();
$serialize_time = array();
$test_start = microtime ( true );

for ( $x = 1 ; $x $start = microtime ( true );
json_encode ( $testArray );
$json_time [] = microtime ( true ) — $start ;

$start = microtime ( true );
serialize ( $testArray );
$serialize_time [] = microtime ( true ) — $start ;
>

$test_lenght = microtime ( true ) — $test_start ;
$json_average = array_sum ( $json_time ) / count ( $json_time );
$serialize_average = array_sum ( $serialize_time ) / count ( $serialize_time );

$result = «PHP serialized in » . $serialize_average . » seconds average
» ;
$result .= «JSON encoded in » . $json_average . » seconds average
» ;

if ( $json_average < $serialize_average )$result .= "json_encode() was roughly " . number_format ( ( $serialize_average / $json_average - 1 ) * 100 , 2 ). "% faster than serialize()
» ;
> else if ( $serializeTime < $jsonTime )$result .= "serialize() was roughly " . number_format ( ( $json_average / $serialize_average - 1 ) * 100 , 2 ). "% faster than json_encode()
» ;
> else $result .= «No way!
» ;
>

$result .= «Test took » . $test_lenght . » seconds with » . $iterations . » iterations.» ;

// Change the number of iterations (250) to lower if you exceed your maximum execution time
echo testSpeed ( fillArray ( 0 , 5 ), 250 );

Источник

Оцените статью