__PHP_Incomplete_Class_Name 错误
我们随机收到一些非常奇怪的错误日志。即使使用相同的参数/操作/等,它们也不会在每次页面点击时发生,而且它们似乎不可重复,每个页面的崩溃位置和上下文都不同。但几乎所有的原因都是 __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、默认会话处理程序。
We're randomly getting some very strange error logs. They don't happen on every page hit, even with the same parameters/actions/etc, and they don't seem repeatable, each one is different in its crash location, and context. But almost all have incorrect __PHP_Incomplete_Class_Name as the cause.
One such error is:
main(): The script tried to execute a method or access a property of an incomplete object. Please ensure that the class definition "LoginLogging" of the object you are trying to operate on was loaded before unserialize() gets called or provide a __autoload() function to load the class definition
The problem being, there is no "LoginLogging" class. The object it's referring to was of type ScormElement when it was saved into the session.
Doing a dump of the variable gives:
__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,
)
All the properties are retained correctly, and match the class definition for ScormElement. But the class name is wrong. There is no class named LoginLogging.
What is causing this and how do we fix it???
Edit: This is just an example. Other errors are very similar in structure, but affect other class types, and have different incomplete names. However, ALL incomplete names have the same string length of the correct class name.
Edit 2011-10-27: I'm still seeing these error logs, and have had no success in finding a solution. Any help would be appreciated.
PHP 5.3.3, APC, default session handler.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(11)
如果您尝试访问存储在 $_SESSION 变量中的对象或序列化值的属性方法,并且您在调用 session_start() after 后包含了类,请尝试在 before 中包含类强> 调用 session_start();
If your trying to access a property method of an object or serialized value you've stored in a $_SESSION variable and you included the class after calling session_start() try including the class before calling session_start();
当我们尝试在加载要保存到会话中的对象的类定义之前初始化会话时,就会发生这种情况。
您可以在 PHP 中简单地使用 json 方法
json_encode 该数组,然后再次 json_decode 该数组并将其保存在变量中,然后打印该变量。你会得到一个简单的数组。
例如。
它肯定会起作用。
This happens when we try to initialize the session before loading the class definitions for the object we are trying to save into the session.
you can use simply json methods in PHP
json_encode that array and again json_decode that array and save it in a variable and than print that variable. you will get a simple array.
eg.
it will work surely.
您是否有机会使用某些操作码缓存(例如 APC、XCache)或某些调试器?它们有时会导致奇怪的事情发生。如果您的项目中没有且从未有过 LoginLogging 类,但您的项目不是服务器上唯一的项目,那么我将对缓存进行竞标。
Are you, by any chance, using some opcode cache (e.g. APC, XCache) or some debugger? They sometimes cause weird things to happen. If there isn't and never was a LoginLogging class in your project, but yours is not the only project on the server, I would bid on the cache.
在 session_start() 之前包含该类对我来说效果很好。 =)
To include the class before the session_start() works fine for me. =)
Hakre 建议查看 session_write_close ,这让我找到了一个似乎可靠的修复方法:
这会强制在发生任何内存清理和类卸载之前将会话写出。这一点很重要,因为 PHP 中的更改可能会导致 APC 删除类引用和 PHP 写出会话数据之间出现竞争条件: http://news.php.net/php.internals/46999
Hakre's suggestion to look at session_write_close led me to what appears to be a reliable fix:
This forces the session to be written out before any memory cleanup and class unloading occurs. This is important due to a change in PHP that can result in a race condition between APC removing class references and PHP writing out the session data: http://news.php.net/php.internals/46999
当您尝试反序列化变量时,php 必须知道该对象的结构。尝试在反序列化之前包含您的类。哪一堂课?保存代码中显示的那些属性的那个。 include('pathtoyourclass/classname.php') 或 include_once('pathtoyourclass/classname.php')。
祝你好运!
When you try to unserialize a variable, php must know the structure of the object. Try to include your class before unserialize. Which class? the one that holds those properties shown in your code. include('pathtoyourclass/classname.php') or include_once('pathtoyourclass/classname.php').
Good luck!
我用这个函数来解决这个问题
I use this function to solve this problem
这是代码中的序列化问题。可能是您的代码由于某种原因无法初始化对象,并且在代码的下一部分中尝试将该对象转换为字符串或其他数据类型。
只需检查您的代码,正确初始化您的对象。
检查您是否使用了serialize()/unserialize()方法。
It is the serialization issue in your code.It may be your code for some reason could not initialize the object and in next part of your code tries to convert that object to string or some other data type.
Just inspect your code, properly initialize your objects.
Check if you are using serialize()/unserialize() method.
您是从服务/流接收此序列化对象还是从文件中读取它?我已经看到它发生在客户端-服务器设置中,客户端对象和服务器端对象略有不同......可能具有另一个没有的属性。当您序列化一个对象,将其保存到文件,然后重构删除类的代码,然后尝试反序列化该对象时,也会发生这种情况。
然后,当它被反序列化并尝试实例化所需的类时,它们并不存在。
错误很清楚且简单,您正在创建一个尚未加载类的对象。
我会对您的代码进行字符串搜索,找到所需类的位置,并制作一个简单的文件自动加载器(或只是原始包含/需要)。只需以某种方式加载它需要的类即可。
如果该类确实不存在于任何地方,请尝试检查早期版本(我假设您有某种类型的版本控制)是否存在该类。如果您要反序列化另一个系统生成的对象,请同时检查该系统。
Are you receiving this serialized object from a service/stream or reading it from a file? I've seen it happen in a client-server setting the client side object and the server side objects differ very slightly... maybe have a property that the other doesn't have. This also happens when you serialize an object, save it to file, then refactor code that removes a class and then try's to deserialize the object.
Then when it gets deserialized and tries to instantiate the needed classes they don't exist.
The error is clear and straightforward, you're creating a object for which the class has not been loaded.
I'd do a string search on your code, find where the needed class is located, and make a simple autoloader (or just a raw include/require) of the file. Just get the class it needs loaded somehow.
If the class really doesn't exist anywhere, try checking earlier revisions (I'm assuming you have version control of some type) for existence of the class. If you're deserializing an object generated by another system check that system out as well.
我所需要的只是清除缓存(对我来说这是临时环境)
您的临时服务器上可能存在过时的缓存数据,从而导致序列化问题。例如,如果缓存损坏,会话中缓存的 Eloquent 模型可能会导致 __PHP_Incomplete_Class_Name 错误。
修复:清除暂存环境中的所有缓存(路由、配置、视图和数据缓存):
重新启动应用程序以确保清除所有缓存数据。
All I needed was to clear cache (for me it was staging environment)
It’s possible that there’s stale cached data on your staging server, causing serialization issues. Eloquent models cached in the session, for example, may result in the __PHP_Incomplete_Class_Name error if the cache becomes corrupted.
Fix: Clear all caches (route, config, view, and data caches) in the staging environment:
Restart the application to ensure that all cached data is cleared.
正如问题中的引用中所写的
__PHP_Incomplete_Class_Name
是 PHP 中的一个特殊类名称,每当反序列化时找不到类定义时就会使用它(unserialize()
)。建议确保类定义可用或为缺失的类提供一些自动加载。
您评论说 PHP 在这里寻找错误的类名:
很难用给出的信息来说明为什么在序列化/反序列化时更改类名。您在问题中提供的信息(尤其是转储)不完整。
因此,这些选项仅限于一些一般性建议:
您可以检查其中给出的类名的序列化字符串,这样您至少可以说它是否发生在序列化或反序列化中。您可以使用 序列化 PHP 库 轻松检查序列化数据,该库具有用于调试目的的文本转储器。
另外还有
unserialize_callback_func
Ini -Directive 您可以使用它来进一步追踪问题。当您编写时,问题不再发生,我怀疑您网站上的序列化在某些时候被破坏,存储了无效数据。您使用哪个框架/库/应用程序?哪个组件负责序列化?
As written in the quote in your question
__PHP_Incomplete_Class_Name
is a special class name in PHP that is used whenever the class definition could not be found when unserializing (unserialize()
).It's suggested to either ensure the class definition is available or to provide some autoloading for the missing class.
You commented that PHP is looking for the wrong classname here:
It's hard to say with the information given why the classname is being changed on serialization/unserialization. The information you've given (especially the dump) in your question is incomplete.
So the options are limited to some general suggestions:
You could inspect the serialized string which classname is given in there so you could at least say if it happens with serialization or unserialization. You can easily inspect serialized data with the Serialized PHP Library which has a text-dumper for debug purposes.
Additionally there is the
unserialize_callback_func
Ini-Directive you can use to further trace the problem.As you write the problem does not occur any longer, I suspect that at some point the serialization on your site was broken storing invalid data. Which framework/libraries/application are you using? Which component takes care about serialization?