简体   繁体   English

unserialize()函数不能对新服务器上的MySQL表中的变量起作用

[英]unserialize() function does not work on a variable from the MySQL table on new server

We just switched our website over to a new server. 我们刚刚将网站切换到新服务器。 There is a part of my PHP software that pulls out a serialized data value from the MySQL table, and puts it into a variable, and then it's supposed to unserialize(). 我的PHP软件中有一部分从MySQL表中提取序列化数据值,并将其放入变量中,然后它应该是unserialize()。

I never had this issue on any other servers (and this exact code is used on many different servers..), but I'm getting an issue where the value fails to unserialize - it returns false (blank). 我从来没有在任何其他服务器上出现此问题(这个确切的代码在许多不同的服务器上使用..),但我遇到的问题是值无法反序列化 - 它返回false(空白)。

HOWEVER, if I copy the exact value, put it into another $var, and then unserialize($var) it, it works perfectly fine into an array... they are the exact same values. 但是,如果我复制确切的值,将其放入另一个$ var,然后反序列化($ var)它,它可以很好地处理数组...它们是完全相同的值。 One works, the other doesn't. 一个有效,另一个没有。

Check out the following link to visualize what I mean.. 看看以下链接,想象我的意思..

http://paulmasoumi.com/admin/test.php http://paulmasoumi.com/admin/test.php

And the PHP code on this page is: 此页面上的PHP代码是:

<?
include 'start.php';

$var = 'a:8:{i:0;s:0:"";i:1;s:11:"New Listing";i:2;s:11:"Just Listed";i:3;s:9:"New Price";i:4;s:17:"Exclusive Listing";i:5;s:12:"Just Reduced";i:6;s:31:"Great Price!;Showroom Condition";i:7;s:42:"Featured In;Dream Homes of Canada Magazine";}';


echo 'Echoing $var:<br />';
echo $var;
echo '<br />';


echo 'Echoing $settings[\'remarksdisplay\'] retrieved from mysql database field:<br />';
echo $settings['remarksdisplay'];
echo '<br />';

echo '<br />';

echo 'When you run print_r(unserialize($var)):<br />';
print_r(unserialize($var));
echo '<br />';

echo 'When you run print_r(unserialize($settings[\'remarksdisplay\'])):<br />';
print_r(unserialize($settings['remarksdisplay']));

echo '<br />';
echo '<br />';

echo 'When you run IF statement to see if $settings[\'remarksdisplay\']==$var:<br />';
if($settings['remarksdisplay']==$var) {echo "EQUAL";} else {echo 'not equal';}
?>

I've also checked the server settings regarding the serialize() and unserialize() functions... 我还检查了有关serialize()和unserialize()函数的服务器设置......

Check out these two settings: http://www.paulmasoumi.com/admin/phpinfo.php http://demo.brixwork.com/admin/phpinfo.php 看看这两个设置: http//www.paulmasoumi.com/admin/phpinfo.php http://demo.brixwork.com/admin/phpinfo.php

Settings involving serialization of strings, magic quotes etc. are all identical. 涉及字符串序列化,魔术引号等的设置都是相同的。

What am I missing??? 我错过了什么?

The strings are not identical. 字符串不相同。 Viewing the source of your page the one coming out of the database has a linebreak: 查看页面的来源,数据库中出现的内容有一个换行符:

a:8:{i:0;s:0:"";i:1;s:11:"New Listing";i:2;s:11:"Just Listed";i:3;s:9:"New Price";i:4;s:17:"Exclusive Listing";i:5;s:12:"Just Reduced";i:6;s:31:"Great 
Price!;Showroom Condition";i:7;s:42:"Featured In;Dream Homes of Canada Magazine";

As you can see after Great. 正如你所看到的那样伟大。 But, it should handle the new line characters just fine. 但是,它应该处理新的行字符就好了。 When I copied the database serialized string and tried to unserialize it I received a: 当我复制数据库序列化字符串并尝试反序列化时,我收到了:

PHP Notice: unserialize(): Error at offset 176 of 234 bytes in php shell code on line 1 PHP注意:unserialize():第1行的php shell代码中234字节的偏移量176出错

Which means something funky is happening, not sure what. 这意味着发生了一些时髦的事情,不确定是什么。 I am going to keep digging, but just posting what I found out. 我将继续挖掘,但只是张贴我发现的东西。 If you want a true test, however, add a newline after Great. 但是,如果您想要真正的测试,请在Great之后添加换行符。

UPDATE UPDATE

<?php
$var = 'a:8:{i:0;s:0:"";i:1;s:11:"New Listing";i:2;s:11:"Just Listed";i:3;s:9:"New Price";i:4;s:17:"Exclusive Listing";i:5;s:12:"Just Reduced";i:6;s:31:"Great' . "\n" .  
'Price!;Showroom Condition";i:7;s:42:"Featured In;Dream Homes of Canada Magazine";}';

$settings['remarksdisplay'] = 'a:8:{i:0;s:0:"";i:1;s:11:"New Listing";i:2;s:11:"Just Listed";i:3;s:9:"New Price";i:4;s:17:"Exclusive Listing";i:5;s:12:"Just Reduced";i:6;s:31:"Great
Price!;Showroom Condition";i:7;s:42:"Featured In;Dream Homes of Canada Magazine";}';

echo 'Echoing $var:' . PHP_EOL;
echo $var;
echo "\n\n";


echo 'Echoing $settings[\'remarksdisplay\'] retrieved from mysql database field:' . PHP_EOL;
echo $settings['remarksdisplay'];

echo "\n\n";

echo 'When you run print_r(unserialize($var)):' . PHP_EOL;
print_r(unserialize($var));
echo "\n";

echo 'When you run print_r(unserialize($settings[\'remarksdisplay\'])):' . PHP_EOL;
print_r(unserialize($settings['remarksdisplay']));

echo "\n\n";

echo 'When you run IF statement to see if $settings[\'remarksdisplay\']==$var:' . PHP_EOL;
if($settings['remarksdisplay']==$var) {echo "EQUAL";} else {echo 'not equal';}
echo PHP_EOL;

?>

Sorry, I changed the Linebreaks to NewLine characters cause I tested it in CLI. 抱歉,我将Linebreaks更改为NewLine字符,因为我在CLI中对其进行了测试。 The above code has the extra space after Great removed and it works just fine. 上面的代码在Great删除有额外的空间,它工作得很好。

So what was happening was basically that extra space threw off the count, as you can see the s:XX the number indicates how long the string is, that extra space made it 32 instead of 31 for the "Great Price" statement, since serialize needs to be accurate, it was throwing a Notice error, which most people do not show and why there were no errors coming through. 所以发生的事情基本上就是额外的空间从计数中消失了,因为你可以看到s:XX数字表示字符串有多长,额外的空格使得32为“Great Price”语句而不是31,因为序列化需要准确,它是一个通知错误,大多数人没有显示,为什么没有错误通过。

Use substr to remove quotes like 使用substr删除引号

$str = substr( $data['str'], 1, -1 );

and then unserialize your data. 然后反序列化您的数据。

reason is mysql return quoted string 原因是mysql返回引用的字符串

Just guessing, maybe the database returns some kind of object that doesn't play well with unserialize? 只是猜测,也许数据库会返回一些与unserialize不能很好匹配的对象? Try: 尝试:

$str = (string) $settings['remarksdisplay'];
print_r(unserialize($str));

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM