unserialize()[function.unserialize]:偏移时出错 [英] unserialize() [function.unserialize]: Error at offset
问题描述
我在图片上传插件中使用Hotaru CMS,如果我尝试附加图片到帖子,我会收到此错误,否则没有错误。
违规代码(与**匹配的错误):
/ **
*检索提交步骤数据
*
* @param $ key - 设置
时为空* @return bool
* /
public function loadSubmitData($ h,$ key ='')
{
//删除此表中超过30分钟的所有内容:
$ this-> deleteTempData($ h-> db);
if(!$ key){return false; }
$ cleanKey = preg_replace('/ [^ a-z0-9] + /','',$ key);
if(strcmp($ key,$ cleanKey)!= 0){
return false;
} else {
$ sql =SELECT tempdata_value FROM。 TABLE_TEMPDATA。 WHERE tempdata_key =%s ORDER BY tempdata_updatedts DESC LIMIT 1;
$ submitted_data = $ h-> db-> get_var($ h-> db-> prepare($ sql,$ key));
** if($ submitted_data){return unserialize($ submitted_data); } else {return false; } **
}
}
表中的数据,注意到结束bit有图像信息,我不是PHP的专家,所以我想知道你们/ gals可能认为什么?
tempdata_value:
a:10:{s:16:submit_editorial; b:0; s:15:submit_orig_url; s:13:www.bbc。 co.uk; s:12:submit_title; s:14:找不到标题; s:14:submit_content; s:12:dnfsdkfjdfdf; s:15:submit_category; i:2 ; s:11:submit_tags; s:3:bbc; s:9:submit_id; b:0; s:16:submit_subscribe; i:0; s:15:submit_comments :4:open; s:5:image; s:19:C:fakepath100.jpg;}
编辑:我想我找到了序列化位...
/ **
*保存提交步骤数据
*
* @return bool
* /
public function saveSubmitData($ h)
{
// delete everything在此表中超过30分钟:
$ this-> deleteTempData($ h-> db);
$ sid = preg_replace('/ [^ a-z0-9] + / i','',session_id());
$ key = md5(microtime()。$ sid。rand());
$ sql =INSERT INTO。 TABLE_TEMPDATA。 (tempdata_key,tempdata_value,tempdata_updateby)VALUES(%s,%s,%d);
$ h-> db-> query($ h-> db-> prepare($ sql,$ key,serialize($ h-> vars ['submitted_data']),$ h- > currentUser-> id));
return $ key;
}
unserialize()[function.unserialize]:偏移处的错误
是由于长度无效而导致的无效序列化数据
快速修复
你可以做的是重新计算长度
序列化数组中的元素
您当前的序列化数据
$ data ='a:10:{s:16:submit_editorial; b:0; s:15:submit_orig_url; s:13:www.bbc.co.uk ; s:12:submit_title; s:14:找不到标题; s:14:submit_content; s:12:dnfsdkfjdfdf; s:15:submit_category; i:2; 11:submit_tags; s:3:bbc; s:9:submit_id; b:0; s:16:submit_subscribe; i:0; s:15:submit_comments open; s:5:image; s:19:C:fakepath100.jpg;}';
不重新计算的示例
var_dump(unserialize($ data));
输出
注意:unserialize()[function.unserialize]:在338字节的偏移337处出错
重新计算
: $ data = preg_replace('!s:(\d +): 。*?);! e','s:'。strlen('$ 2')。':\$ 2\;',$ data);
var_dump(unserialize($ data));
输出
array
'submit_editorial'=> boolean false
'submit_orig_url'=> string'www.bbc.co.uk'(length = 13)
'submit_title'=> string'No title found'(length = 14)
'submit_content'=> string'dnfsdkfjdfdf'(length = 12)
'submit_category'=> int 2
'submit_tags'=> string'bbc'(length = 3)
'submit_id'=> boolean false
'submit_subscribe'=> int 0
'submit_comments'=> string'open'(length = 4)
'image'=> string'C:fakepath100.jpg'(length = 17)
.. I
而不是使用这种快速修复...我建议你更新问题与
-
如何串行处理资料
-
如何储存资料
li>
========================== ====== EDIT 1 =============================
错误
错误是由于使用双引号而不是单引号
'
,这就是为什么 C:\fakepath\100.png
转换为 C:fakepath100.jpg
修复错误
您需要更改 $ h-> vars ['submitted_data']
>')
取代
$ h-> vars ['submitted_data'] ['image'] =C:\fakepath\100.png;
使用
$ h-> vars ['submitted_data'] ['image'] ='C:\fakepath\100.png';
其他过滤器
您还可以在调用serialize之前添加这个简单的过滤器
function satitize(& $ value,$ key)
{
$ value = addslashes($ value);
}
array_walk($ h-> vars ['submitted_data'],satitize);
如果您有UTF字符,也可以运行
$ h-> vars ['submitted_data'] = array_map(utf8_encode,$ h-> vars ['submitted_data']);
如何检测未来序列化数据中的问题 b
$ b
findSerializeError($ data1);
输出
Diffrence 9!= 7
- > ORD number 57!= 55
- >行号= 315
- > Section Data1 = pen; s:5:image; s:19:C:fakepath100.jpg
- > Section Data2 = pen; s:5:image; s:17:C:fakepath100.jpg
^ -------错误(元素长度)
findSerializeError
函数
function findSerializeError($ data1){
echo< pre>;
$ data2 = preg_replace('!s:(\d +):(。*?);! e','s:'。strlen('$ 2')。':\$ 2 \;',$ data1);
$ max =(strlen($ data1)> strlen($ data2))? strlen($ data1):strlen($ data2);
echo $ data1。 PHP_EOL;
echo $ data2。 PHP_EOL;
for($ i = 0; $ i
if(@ $ data1 {$ i}!== @ $ data2 {$ i}){
echoDiffrence,@ $ data1 {$ i},!=,@ $ data2 {$ i},PHP_EOL;
echo\t-> ORD number,ord(@ $ data1 {$ i}),!=,ord(@ $ data2 {$ i}),PHP_EOL;
echo\t-> Line Number = $ i。 PHP_EOL;
$ start =($ i - 20);
$ start =($ start< 0)? 0:$ start;
$ length = 40;
$ point = $ max - $ i;
if($ point< 20){
$ rlength = 1;
$ rpoint = - $ point;
} else {
$ rpoint = $ length - 20;
$ rlength = 1;
}
echo\t-> Section Data1 =,substr_replace(substr($ data1,$ start,$ length),< b style = \color :green\> {$ data1 {$ i}}< / b>,$ rpoint,$ rlength),PHP_EOL;
echo\t-> Section Data2 =,substr_replace(substr($ data2,$ start,$ length),< b style = \color:red\> {$ data2 {$ i}}< / b>,$ rpoint,$ rlength),PHP_EOL;
}
}
}
保存到数据库的更好方法
$ toDatabse = base64_encode ); //保存到数据库
$ fromDatabase = unserialize(base64_decode($ data)); //获取保存格式
I am using Hotaru CMS with the Image Upload plugin, I get this error if I try to attach an image to a post, otherwise there is no error.
The offending code (error points to line with **):
/**
* Retrieve submission step data
*
* @param $key - empty when setting
* @return bool
*/
public function loadSubmitData($h, $key = '')
{
// delete everything in this table older than 30 minutes:
$this->deleteTempData($h->db);
if (!$key) { return false; }
$cleanKey = preg_replace('/[^a-z0-9]+/','',$key);
if (strcmp($key,$cleanKey) != 0) {
return false;
} else {
$sql = "SELECT tempdata_value FROM " . TABLE_TEMPDATA . " WHERE tempdata_key = %s ORDER BY tempdata_updatedts DESC LIMIT 1";
$submitted_data = $h->db->get_var($h->db->prepare($sql, $key));
**if ($submitted_data) { return unserialize($submitted_data); } else { return false; }**
}
}
Data from the table, notice the end bit has the image info, I am not an expert in PHP so I was wondering what you guys/gals might think?
tempdata_value:
a:10:{s:16:"submit_editorial";b:0;s:15:"submit_orig_url";s:13:"www.bbc.co.uk";s:12:"submit_title";s:14:"No title found";s:14:"submit_content";s:12:"dnfsdkfjdfdf";s:15:"submit_category";i:2;s:11:"submit_tags";s:3:"bbc";s:9:"submit_id";b:0;s:16:"submit_subscribe";i:0;s:15:"submit_comments";s:4:"open";s:5:"image";s:19:"C:fakepath100.jpg";}
Edit: I think I've found the serialize bit...
/**
* Save submission step data
*
* @return bool
*/
public function saveSubmitData($h)
{
// delete everything in this table older than 30 minutes:
$this->deleteTempData($h->db);
$sid = preg_replace('/[^a-z0-9]+/i', '', session_id());
$key = md5(microtime() . $sid . rand());
$sql = "INSERT INTO " . TABLE_TEMPDATA . " (tempdata_key, tempdata_value, tempdata_updateby) VALUES (%s,%s, %d)";
$h->db->query($h->db->prepare($sql, $key, serialize($h->vars['submitted_data']), $h->currentUser->id));
return $key;
}
unserialize() [function.unserialize]: Error at offset
was dues to invalid serialization data
due to invalid length
Quick Fix
What you can do is is recalculating the length
of the elements in serialized array
You current serialized data
$data = 'a:10:{s:16:"submit_editorial";b:0;s:15:"submit_orig_url";s:13:"www.bbc.co.uk";s:12:"submit_title";s:14:"No title found";s:14:"submit_content";s:12:"dnfsdkfjdfdf";s:15:"submit_category";i:2;s:11:"submit_tags";s:3:"bbc";s:9:"submit_id";b:0;s:16:"submit_subscribe";i:0;s:15:"submit_comments";s:4:"open";s:5:"image";s:19:"C:fakepath100.jpg";}';
Example without recalculation
var_dump(unserialize($data));
Output
Notice: unserialize() [function.unserialize]: Error at offset 337 of 338 bytes
Recalculating
$data = preg_replace('!s:(\d+):"(.*?)";!e', "'s:'.strlen('$2').':\"$2\";'", $data);
var_dump(unserialize($data));
Output
array
'submit_editorial' => boolean false
'submit_orig_url' => string 'www.bbc.co.uk' (length=13)
'submit_title' => string 'No title found' (length=14)
'submit_content' => string 'dnfsdkfjdfdf' (length=12)
'submit_category' => int 2
'submit_tags' => string 'bbc' (length=3)
'submit_id' => boolean false
'submit_subscribe' => int 0
'submit_comments' => string 'open' (length=4)
'image' => string 'C:fakepath100.jpg' (length=17)
Recommendation .. I
Instead of using this kind of quick fix ... i"ll advice you update the question with
How you are serializing your data
How you are Saving it ..
================================ EDIT 1 ===============================
The Error
The Error was generated because of use of double quote "
instead single quote '
that is why C:\fakepath\100.png
was converted to C:fakepath100.jpg
To fix the error
You need to change $h->vars['submitted_data']
From (Note the singe quite '
)
Replace
$h->vars['submitted_data']['image'] = "C:\fakepath\100.png" ;
With
$h->vars['submitted_data']['image'] = 'C:\fakepath\100.png' ;
Additional Filter
You can also add this simple filter before you call serialize
function satitize(&$value, $key)
{
$value = addslashes($value);
}
array_walk($h->vars['submitted_data'], "satitize");
If you have UTF Characters you can also run
$h->vars['submitted_data'] = array_map("utf8_encode",$h->vars['submitted_data']);
How to detect the problem in future serialized data
findSerializeError ( $data1 ) ;
Output
Diffrence 9 != 7
-> ORD number 57 != 55
-> Line Number = 315
-> Section Data1 = pen";s:5:"image";s:19:"C:fakepath100.jpg
-> Section Data2 = pen";s:5:"image";s:17:"C:fakepath100.jpg
^------- The Error (Element Length)
findSerializeError
Function
function findSerializeError($data1) {
echo "<pre>";
$data2 = preg_replace ( '!s:(\d+):"(.*?)";!e', "'s:'.strlen('$2').':\"$2\";'",$data1 );
$max = (strlen ( $data1 ) > strlen ( $data2 )) ? strlen ( $data1 ) : strlen ( $data2 );
echo $data1 . PHP_EOL;
echo $data2 . PHP_EOL;
for($i = 0; $i < $max; $i ++) {
if (@$data1 {$i} !== @$data2 {$i}) {
echo "Diffrence ", @$data1 {$i}, " != ", @$data2 {$i}, PHP_EOL;
echo "\t-> ORD number ", ord ( @$data1 {$i} ), " != ", ord ( @$data2 {$i} ), PHP_EOL;
echo "\t-> Line Number = $i" . PHP_EOL;
$start = ($i - 20);
$start = ($start < 0) ? 0 : $start;
$length = 40;
$point = $max - $i;
if ($point < 20) {
$rlength = 1;
$rpoint = - $point;
} else {
$rpoint = $length - 20;
$rlength = 1;
}
echo "\t-> Section Data1 = ", substr_replace ( substr ( $data1, $start, $length ), "<b style=\"color:green\">{$data1 {$i}}</b>", $rpoint, $rlength ), PHP_EOL;
echo "\t-> Section Data2 = ", substr_replace ( substr ( $data2, $start, $length ), "<b style=\"color:red\">{$data2 {$i}}</b>", $rpoint, $rlength ), PHP_EOL;
}
}
}
A better way to save to Database
$toDatabse = base64_encode(serialize($data)); // Save to database
$fromDatabase = unserialize(base64_decode($data)); //Getting Save Format
这篇关于unserialize()[function.unserialize]:偏移时出错的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!