Php unserialize error at offset

unserialize

(PHP 4, PHP 5, PHP 7, PHP 8)

unserialize — Создаёт PHP-значение из хранимого представления

Описание

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

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

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

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

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

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

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

Любые опции unserialize() в виде ассоциативного массива.

Корректные опции

Имя Тип Описание
allowed_classes mixed Массив имён классов, которые должны быть приняты, false для указания не принимать никаких классов или true для приёма всех. Если эта опция задана и unserialize() обнаружит объект неприемлемого класса, то он не будет принят, а вместо этого инстанцируется как объект класса __PHP_Incomplete_Class . Если опция не задана, то она будет считаться установленной в true : PHP будет пытаться инстанцировать объекты любого класса.
max_depth int Максимальная глубина структур, допустимая при десериализации и предназначенная для предотвращения переполнения стека. По умолчанию ограничение глубины составляет 4096 и может быть отключено установкой max_depth значения 0 .

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

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

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

Ошибки

Объекты могут выбрасывать Throwable в своих обработчиках десериализации.

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

Версия Описание
7.4.0 Добавлен элемент max_depth в параметр options для установки максимальной глубины структур, разрешённых при десериализации.
7.1.0 Теперь элемент allowed_classes параметра options строго типизирован, то есть если передано что-либо, кроме array и bool , unserialize() вернёт false и вызовет ошибку E_WARNING .

Примеры

Пример #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

ini_set ( ‘unserialize_callback_func’ , ‘mycallback’ ); // определяем свою callback-функцию

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

Примечания

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

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

User Contributed Notes 24 notes

Just some reminder which may save somebody some time regarding the `$options` array:

Say you want to be on the safe side and not allow any objects to be unserialized. My first thought was doing the following:

= unserialize ( $string , false );
// This will generate:
// Warning: unserialize() expects parameter 2 to be array, boolean given
?>

The correct way of doing this is the following:
= unserialize ( $string , [ ‘allowed_classes’ => false ]);
?>

Hope it helps somebody!

For the people who are getting the error

PHP Notice: unserialize(): Error at offset 191 of 285 bytes in .

and are getting the data from a database, Make sure that you have the database set the the correct encoding, I had the database set as latin1_swedish_ci and all of the data looked perfect, Infact when i copied it into a online unserialize it worked fine. I changed the collation to utf8mb4_unicode_ci and all worked fine.

Here’s a simple function to get the class of a serialized string (that is, the type of object that will be returned if it’s unserialized):

function get_serial_class ( $serial ) <
$types = array( ‘s’ => ‘string’ , ‘a’ => ‘array’ , ‘b’ => ‘bool’ , ‘i’ => ‘int’ , ‘d’ => ‘float’ , ‘N;’ => ‘NULL’ );

$parts = explode ( ‘:’ , $serial , 4 );
return isset( $types [ $parts [ 0 ]]) ? $types [ $parts [ 0 ]] : trim ( $parts [ 2 ], ‘»‘ );
>
?>

I use this when saving a serialized object to a cookie, to make sure it is the right type when I go to unserialize it.

The type names are the same format/case as you would see if you did a var_dump().

In the Classes and Objects docs, there is this: In order to be able to unserialize() an object, the class of that object needs to be defined.

Prior to PHP 5.3, this was not an issue. But after PHP 5.3 an object made by SimpleXML_Load_String() cannot be serialized. An attempt to do so will result in a run-time failure, throwing an exception. If you store such an object in $_SESSION, you will get a post-execution error that says this:

Fatal error: Uncaught exception ‘Exception’ with message ‘Serialization of ‘SimpleXMLElement’ is not allowed’ in [no active file]:0 Stack trace: #0

thrown in [no active file] on line 0

The entire contents of the session will be lost. Hope this saves someone some time!

// RAY_temp_ser.php
error_reporting ( E_ALL );
session_start ();
var_dump ( $_SESSION );
$_SESSION [ ‘hello’ ] = ‘World’ ;
var_dump ( $_SESSION );

// AN XML STRING FOR TEST DATA
$xml = ‘

// MAKE AN OBJECT (GIVES SimpleXMLElement)
$obj = SimpleXML_Load_String ( $xml );

// STORE THE OBJECT IN THE SESSION
$_SESSION [ ‘obj’ ] = $obj ;

As mentioned in the notes, unserialize returns false in the event of an error and for boolean false. Here is the first solution mentioned, without using error handling:

function isSerialized ( $str ) <
return ( $str == serialize ( false ) || @ unserialize ( $str ) !== false );
>

var_dump ( isSerialized ( ‘s:6:»foobar»;’ )); // bool(true)
var_dump ( isSerialized ( ‘foobar’ )); // bool(false)
var_dump ( isSerialized ( ‘b:0;’ )); // bool(true)
?>

__PHP_Incomplete_Class Object Demystified

1. First take note of the output. A simple example:

__PHP_Incomplete_Class Object (
[__PHP_Incomplete_Class_Name] => SomeObject1
[obj1property1] => somevalue1 [obj1property2] => __PHP_Incomplete_Class Object ( [__PHP_Incomplete_Class_Name] => SomeObject2 [obj2property1] => somevalue1 [obj2property2] => Array (
[‘key1’] => somevalue3, [‘key2’] => somevalue4 ) ) )

2. We analyze this and break it down.
__PHP_Incomplete_Class Object tells you there is an object that needs to be declared somehow.
__PHP_Incomplete_Class_Name simply tells you the expected class name. It is just one of the properties for now.

So we have:
a) an unknown object that has a class name SomeObject1 (first class)
b) it has 2 properties, namely obj1property1 and obj2property2
c) obj2property2 is itself an object whose class name is SomeObject2 (the second class)
d) SomeObject2 has two properties, obj2property1 and obj2property2
e) obj2property2 is an array that contains two elements

3. Now that we have an idea of the structure, we shall create class definitions based from it. We will just create properties for now, methods are not required as a minimum.

class SomeObject1 <
public $obj1property1 ;
public $obj1property2 ;
>
class SomeObject2 <
public $obj2property1 ;
public $obj2property2 ;
>
?>

4. Have that accessible to your script and it will solve the __PHP_Incomplete_Class Object problem as far as the output is concerned. Now you will have:

SomeObject1 ( [obj1property1] => somevalue1 [obj1property2] => SomeObject2 ( [obj2property1] => somevalue1 [obj2property2] => Array ( [‘key1’] => somevalue3, [‘key2’] => somevalue4 ) ) )

As you will notice, __PHP_Incomplete_Class Object is gone and replaced by the class name. The property __PHP_Incomplete_Class_Name is also removed.

5. As for the array property obj2property2, we can directly access that and just assume that it is an array and loop through it:

// this will be SomeObject1
$data = unserialize ( $serialized_data );

// this will be SomeObject2
$data2 = $data -> obj1property2 ();

foreach( $data2 -> obj2property2 as $key => $value ):
print $key . ‘ : ‘ . $value . ‘
‘ ;
endforeach;

?>

Outputs:
key1 : somevalue3
key2 : somevalue4

That’s it. You can add more methods on the class declarations for the given properties, provided you keep your original output as basis for the data types.

Источник

ErrorException: unserialize(): Error at offset 0 in AbstractPhpProcess.php #3141

Comments

Q A
PHPUnit version 7.1
PHP version 7.2
Installation Method Composer

from vendor packages installed with composer.

It was working on PhPUnit 6 i think, so before upgrade

Without processIsolation we got

And that is it, result of test

I am not sure is it doctrine, some settings, symfony or PhPUnit, i missed time when some changes were made and broke it. Other tests are passed well.

Thanks for help.

The text was updated successfully, but these errors were encountered:

Thank you for your report.

Please provide a minimal, self-contained, reproducing test case that shows the problem you are reporting.

Without such a minimal, self-contained, reproducing test case I will not be able to investigate this issue.

That was from our side. Issue can be closed. Thank you.

Hi guys. I have the same problem.

@BonBonSlick What’s the modification you’ve done to do it works ?

Hello, the same thing is happening to me. Soon I share more information.

@BonBonSlick how did you fix it? Please share your knowledge.

OK finally we found the problem. While the error message ErrorException: unserialize(): Error at offset. seemed to point a problem in PHPUnit code. The problem over here was that the assertion we used was wrong / failed. The test itself did run but the assertion failed. So in our case our test first looked like this (Laravel 4.2):

But status code we recived was 301 — so we fixed this:

Finally the error message went away. Unfortunately, when running @runInSeparateProcess PHPUnit seems not recognizing the correct error message thrown by the assertion we used. Instead this ends up in a PHP error.

I hope this will help others. Take a look at your tests and ensure the assertions are valid.

@linslin problems mostly because of your code. It is not related to phpunit. You are doing something wrong, i do not remmber already how solved it, but it was not phpunit issue.

I just stumbled upon this thread searching for «phpunit errorexception unserialize error at offset 0» as one of the few results.

For me the solution was to disable XDebug since it polluted the output of php when phpunit was running its tests.
Same thing seems to be the case with the original author’s problem where you can see in the stack trace that it begins with unserialize(‘Doctrine\\Common. ‘) which is definitely not valid serialized data.

I was scratching my head over this ticket and comment chain since it sounded unlikely that phpunit would just fail this hard on an unexpected return value because it should just mark the test as failed in this case.

The actual issue seems to be either polluted php output or uncaught exceptions in the code which is being tested.

Any dd(), dump(), var_dump(), print_r() of these functions called in your test case will throw that error exception now.
is this intentional?

in my case, this is what I have in that test case, note its not even the first test case in that there are several others before that works but this one

And I still get that error. Really dont know what to do. The tests is existing test I cannot remove it. (I intentionally removed the actual content of the test and reduced to just a dd)

in my case, this is what I have in that test case, note its not even the first test case in that there are several others before that works but this one

And I still get that error. Really dont know what to do. The tests is existing test I cannot remove it. (I intentionally removed the actual content of the test and reduced to just a dd)

Holy cow. There happens to be a missing migration digging further. It was a painful digging tho. So instead of just erroring out as usual I’m met with that error that tells me nothing but cause PTSD. Glad I was able to figure this out. So like something said earlier, its likely something in the code it may just be too hard or painful to find.

Источник

Читайте также:  Error x ink кто это
Smartadm.ru
Adblock
detector