Неправильное неполное имя класса PHP


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

Одной из таких ошибок является:

Main(): Скрипт пытался выполнить метод или получить доступ к свойству неполного объекта. Пожалуйста, убедитесь, что определение класса "Вход в систему" объекта, с которым вы пытаетесь работать, был загружен до того, как будет вызвана функция 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, обработчик сеанса по умолчанию.

Author: VexedPanda, 2011-09-01

10 answers

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

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

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

wrong: LoginLogging
right: ScormElement

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

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

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

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

<?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
}

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

 21
Author: hakre, 2014-01-10 08:28:18

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

 7
Author: gus, 2012-03-02 03:17:43

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

Вы можете использовать простые методы 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);

Это наверняка сработает.

 4
Author: Shiv Aggarwal, 2014-03-05 10:59:22

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

 3
Author: a sad dude, 2012-02-27 23:25:21

Включить класс до того, как session_start() отлично работает для меня. =)

 3
Author: Wellington Lorindo, 2013-11-12 19:10:26

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

register_shutdown_function('session_write_close');

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

 2
Author: VexedPanda, 2012-05-01 21:38:06

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

Удачи!

 1
Author: FerYepes, 2013-01-27 02:49:13

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

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

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

 0
Author: Dev, 2011-09-02 10:20:41

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

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

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

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

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

 0
Author: Ray, 2012-02-23 13:21:11

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

$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
Author: IT Sekuro, 2017-03-10 01:43:10