php - unserialize() 函数不适用于新服务器上 MySQL 表中的变量

标签 php mysql apache string serialization

我们刚刚将网站切换到新服务器。我的 PHP 软件有一部分从 MySQL 表中提取一个序列化的数据值,并将其放入一个变量中,然后它应该是 unserialize()。

我从来没有在任何其他服务器上遇到过这个问题(并且这个确切的代码在许多不同的服务器上使用..),但是我遇到了一个问题,即值无法反序列化 - 它返回 false(空白)。

但是,如果我复制确切的值,将其放入另一个 $var,然后反序列化($var)它,它在数组中工作得很好......它们是完全相同的值。一个有效,另一个无效。

查看以下链接以形象化我的意思..

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

而这个页面的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';}
?>

我还检查了有关 serialize() 和 unserialize() 函数的服务器设置...

检查这两个设置: http://www.paulmasoumi.com/admin/phpinfo.php http://demo.brixwork.com/admin/phpinfo.php

涉及字符串序列化、魔术引号等的设置都是相同的。

我错过了什么???

最佳答案

字符串不相同。查看您页面的源代码,从数据库中出来的页面有一个换行符:

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";

正如您在 Great 之后看到的那样。但是,它应该可以很好地处理换行符。当我复制数据库序列化字符串并尝试反序列化它时,我收到了:

PHP Notice: unserialize(): Error at offset 176 of 234 bytes in php shell code on line 1

这意味着发生了一些奇怪的事情,不确定是什么。我将继续挖掘,但只是发布我发现的内容。但是,如果您想要真正的测试,请在 Great 之后添加一个换行符。

更新

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

?>

抱歉,我将换行符更改为换行符,因为我在 CLI 中对其进行了测试。上面的代码删除了 after Great 的额外空格,并且工作正常。

所以发生的事情基本上是额外的空间打乱了计数,正如您所看到的 s:XX 数字表示字符串的长度,额外的空间使它成为 32 而不是“Great Price”声明的 31 ,因为序列化需要准确,它抛出了一个通知错误,大多数人都没有显示这个错误,这也是为什么没有错误出现的原因。

关于php - unserialize() 函数不适用于新服务器上 MySQL 表中的变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3688442/

相关文章:

php - 如何从最小值获取关联的行数据

php - 在 php 中集成 payfort api 时遇到问题

java - 错误 : in JAR with mysql-connector-java-5. 0.7-bin

php - 使用 apache 2.2.17 安装 PHP 5.3.5 时出现问题(apache 崩溃)

php - 带有 Web 浏览器的空白页面(错误 500),可以使用 php 命令

PHP:计算一个 stdClass 对象

php - 在 laravel 5 中使用 pingpong sky 模块

php - 如何正确使用 PDO 对象进行参数化 SELECT 查询

php - 从mysql表中删除不匹配记录的最佳方法

apache - .htaccess 规则,将不存在的旧地址重定向到新地址