dav*_*ave 38 php session class object
我有一个站点设置,在页面加载时,将所有用户提交的字符串转换为SafeString对象.对于那些不熟悉SafeString的人来说,它基本上迫使用户回应清理过的数据,防止XSS等等.
无论如何,有一个问题.我的$ _SESSION数组正在填充__PHP_Incomplete_Class Object.从我读过的,这是因为没有在会话之前初始化类,然后在会话中存储类对象.
这是我的代码:
require_once __WEBROOT__ . '/includes/safestring.class.php';
$temp = array
(
&$_SERVER, &$_GET, &$_POST, &$_COOKIE,
&$_SESSION, &$_ENV, &$_REQUEST, &$_FILES,
&$HTTP_SERVER_VARS, &$HTTP_GET_VARS,
&$HTTP_POST_VARS, &$HTTP_COOKIE_VARS,
&$HTTP_POST_FILES, &$HTTP_ENV_VARS
);
function StringsToSafeString(&$array)
{
foreach ($array as $key => $value)
{
if (is_string($array[$key]))
{
$array[$key] = new SafeString($value);
}
if (is_array($array[$key]))
{
StringsToSafeString($array[$key]);
}
}
}
StringsToSafeString($temp);
unset($temp);
Run Code Online (Sandbox Code Playgroud)
我想不出一种方法来重写这个可以解决问题的方法:/
有任何想法吗?
bob*_*nce 63
当您访问时$_SESSION,您不仅要更改当前脚本从会话中读取的数据副本,而且还要将SafeString对象写回活动会话.
但是在会话中放置自定义对象是狡猾的,我通常会尽量避免.为了能够做到这一点,你必须在调用之前定义有问题的类session_start; 如果你不这样做,PHP的会话处理程序将不知道如何反序列化该类的实例,你最终会得到__PHP_Incomplete_Class Object.
所以避免擦拭会话.如果必须采用此方法,请将数据副本复制$_SESSION到本地$mysession数组中.但是,我不得不说,我认为SafeString的整个想法是危险的,不可行的; 我不认为这种做法永远不会是水密的.一串原始文本是否"安全"与其来源无关,它是如何为目标上下文编码的属性.
如果从另一个源(例如数据库或文件)获取另一个文本字符串,或者在脚本本身中计算,则它需要与来自用户的字符串完全相同的处理:它需要被htmlspecialchars编辑.无论如何,你将不得不写下那个逃脱; 安全绳让你什么都没有.如果需要将字符串发送到其他目标格式,则需要使用不同的转义.
您无法将所有字符串处理问题封装到一个方便的框中,也不会再考虑它们; 这不是字符串的工作方式.
Ste*_*ain 25
我知道这已被问过多年了,但是我发布了答案,因为上面的答案都没有向OP解释实际上是错的.
PHP使用内置serialize和unserialize方法序列化其会话.serializePHP能够序列化PHP对象(也就是类实例)并将它们转换为字符串.当你使用unserialize这些字符串时,它会将这些字符串转换回那些相同的类.具有一些私有属性并希望对其进行编码/解码或在序列化/反序列化中执行复杂操作的Serializable类实现类,并向类添加serialize和unserialize方法.
当PHP unserialize尝试反序列化一个类对象,但没有声明/要求类名时,它不会发出警告或抛出一个Exception,而是将其转换为一个对象__PHP_Incomplete_Class.
如果您不希望将会话对象转换为__PHP_Incomplete_Class,则可以通过在调用之前要求类文件session_start或通过注册自动加载功能来执行此操作.
当您想要从变量中读取SafeString对象时,您只需要safestring.class.php在调用之前包含它:session_start()$_SESSION
<?php
require_once __WEBROOT__ . '/includes/safestring.class.php';
session_start();
print_r($_SESSION);
Run Code Online (Sandbox Code Playgroud)
是的,如果您正在使用(最有可能)session_start()内部调用的PHP框架,请require_once事先确保您的类文件(使用钩子或框架提供的任何机制).