__PHP_Incomplete_Class_Name неправильно - PullRequest
12 голосов
/ 01 сентября 2011

Мы случайно получаем очень странные журналы ошибок.Они не происходят при каждом обращении к странице, даже при одинаковых параметрах / действиях / и т. Д., И они не кажутся повторяемыми, каждый из них отличается по месту аварийного завершения и контексту.Но почти все имеют неверную __PHP_Incomplete_Class_Name в качестве причины.

Одна из таких ошибок:

main (): скрипт пытался выполнить метод или получить доступ к свойству незавершенного объекта.Убедитесь, что определение класса «LoginLogging» объекта, с которым вы пытаетесь работать, было загружено до вызова unserialize () или предоставьте функцию __autoload () для загрузки определения класса

Проблема в том, что нет класса "LoginLogging".Объект, на который он ссылается, имел тип ScormElement, когда он был сохранен в сеансе.Выполнение дампа переменной дает:

__PHP_Incomplete_Class::__set_state(array(
 '__PHP_Incomplete_Class_Name' => 'LoginLogging',
 'intUserId' => '64576',
 '__intUserId' => '64576',
 'intScormId' => '665',
 '__intScormId' => '665',
 'intScoId' => '9255',
 '__intScoId' => '9255',
 'strElement' => 'cmi.core.lesson_location',
 '__strElement' => 'cmi.core.lesson_location',
 'strValue' => '1',
 'dttTimeModified' => QDateTime::__set_state(array(
   'blnDateNull' => false,
   'blnTimeNull' => false,
   'strSerializedData' => '2011-08-31T08:05:22-0600',
   'date' => '2011-08-31 08:05:22',
   'timezone_type' => 1,
   'timezone' => '-06:00',
 )),
 '__strVirtualAttributeArray' => array (),
 '__blnRestored' => true,
 'objUser' => NULL,
 'objScorm' => NULL,
)

Все свойства сохраняются правильно и соответствуют определению класса для ScormElement.Но имя класса неверно.Там есть нет класса с именем LoginLogging.

Что вызывает это и как мы можем это исправить ???

Редактировать : Это простопример.Другие ошибки очень похожи по структуре, но влияют на другие типы классов и имеют разные неполные имена.Однако ВСЕ неполные имена имеют одинаковую строку длина правильного имени класса.

Редактировать 2011-10-27 : я все еще вижу эти журналы ошибок,и не имели успеха в поиске решения.Буду признателен за любую помощь.

PHP 5.3.3, APC, обработчик сеанса по умолчанию.

Ответы [ 10 ]

23 голосов
/ 26 февраля 2012

Как написано в цитате в вашем вопросе __PHP_Incomplete_Class_Name - это специальное имя класса в PHP, которое используется всякий раз, когда определение класса не может быть найдено при десериализации (unserialize() ).

Рекомендуется либо убедиться, что определение класса доступно, либо предоставить некоторую автозагрузку для отсутствующего класса.

Вы прокомментировали, что PHP ищет здесь неправильное имя класса:

wrong: LoginLogging
right: ScormElement

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

Таким образом, варианты ограничены некоторыми общими предложениями:

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

Кроме того, существует unserialize_callback_func Ini-Directive , которую можно использовать для дальнейшего отслеживания проблемы.

<?php
$serialized_object='O:1:"a":1:{s:5:"value";s:3:"100";}';

// unserialize_callback_func directive available as of PHP 4.2.0
ini_set('unserialize_callback_func', 'mycallback'); // set your callback_function

function mycallback($classname) 
{
    // just include a file containing your classdefinition
    // you get $classname to figure out which classdefinition is required
}

Когда вы пишете, проблема больше не возникает, я подозреваю, что в какой-то момент сериализация на вашем сайте была прервана с сохранением неверных данных. Какие рамки / библиотеки / приложения вы используете? Какой компонент заботится о сериализации?

9 голосов
/ 25 февраля 2012

Если вы пытаетесь получить доступ к методу свойства объекта или сериализованного значения, которое вы сохранили в переменной $ _SESSION, и вы включили класс после , вызывая session_start (), попробуйте включить класс перед вызов session_start ();

4 голосов
/ 05 марта 2014

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

Вы можете просто использовать методы json в PHP

json_encode для этого массива и снова json_decode для этого массива и сохранение его в переменной, а затем распечатка этой переменной. вы получите простой массив.

например.

$array = array(); // this is your array variable to whom you are trying to save in a session
$encode = json_encode($array);
$decode = json_decode($encode);
echo '<pre>';
print_r($decode);

это будет работать наверняка.

3 голосов
/ 12 ноября 2013

Включить класс перед session_start () у меня нормально работает.=) * * Тысяча одна

3 голосов
/ 28 февраля 2012

Вы случайно не используете какой-либо кэш кода операции (например, APC, XCache) или какой-либо отладчик? Иногда они вызывают странные вещи. Если в вашем проекте нет и никогда не было класса LoginLogging, но ваш проект не единственный на сервере, я бы сделал ставку на кеш.

2 голосов
/ 27 января 2013

Когда вы пытаетесь десериализовать переменную, php должен знать структуру объекта. Попробуйте включить свой класс, прежде чем десериализовать. Какой класс? тот, который содержит эти свойства, показанные в вашем коде. include ('pathtoyourclass / classname.php') или include_once ('pathtoyourclass / classname.php').

Удачи!

2 голосов
/ 02 мая 2012

Предложение Хакре взглянуть на session_write_close привело меня к тому, что кажется надежным исправлением:

register_shutdown_function('session_write_close');

Это вынуждает записывать сеанс до очистки памяти и выгрузки классов.Это важно из-за изменения в PHP, которое может привести к состязанию между APC, удаляющим ссылки на класс, и PHP, записывающим данные сеанса: http://news.php.net/php.internals/46999

1 голос
/ 10 марта 2017

Я использую эту функцию для решения этой проблемы

$user = $_SESSION['login'];
$auth_user= fixObject($user);
function fixObject(&$object) {
   if (!is_object($object) && gettype($object) == 'object')
      return ($object = unserialize(serialize($object)));
   return $object;
}
0 голосов
/ 23 февраля 2012

Получаете ли вы этот сериализованный объект из службы / потока или читаете его из файла?Я видел, как это происходит в настройке клиент-сервер, устанавливающей объект на стороне клиента, и объекты на стороне сервера отличаются незначительно ... возможно, имеют свойство, которого нет у другого.Это также происходит, когда вы сериализуете объект, сохраняете его в файл, затем реорганизуете код, который удаляет класс, а затем пытается десериализовать объект.

Затем, когда он десериализуется и пытается создать экземпляры необходимых классов, которые они не 't существует.

Ошибка ясна и понятна: вы создаете объект, для которого класс не был загружен.

Я бы выполнил поиск по вашему коду, выяснил, где находится нужный класс, и сделал бы простой автозагрузчик (или просто необработанное включение / требуется) файла.Просто загрузите необходимый ему класс.

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

0 голосов
/ 02 сентября 2011

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

Просто проверьте ваш код, правильно инициализируйте ваши объекты.

Проверьте, используете ли вы метод serialize () / unserialize ().

...