我正在使用一个 wordpress 测验插件,我想直接从数据库表中提取问题和答案,并用它来创建一个 pdf 文档。问题存储为易于提取的简单字符串,但答案(多项选择答案)存储在数据库列中,如下所示:
a:4:{i:0;O:27:"WpProQuiz_Model_AnswerTypes":7:{s:10:"*_answer";s:7:"Option1";s:8:"*_html";b:0;s:10:"*_points";i:1;s:11:"*_correct";b:1;s:14:"*_sortString";s:0:"";s:18:"*_sortStringHtml";b:0;s:10:"*_mapper";N;}i:1;O:27:"WpProQuiz_Model_AnswerTypes":7:{s:10:"*_answer";s:7:"Option2";s:8:"*_html";b:0;s:10:"*_points";i:1;s:11:"*_correct";b:0;s:14:"*_sortString";s:0:"";s:18:"*_sortStringHtml";b:0;s:10:"*_mapper";N;}i:2;O:27:"WpProQuiz_Model_AnswerTypes":7:{s:10:"*_answer";s:7:"Option3";s:8:"*_html";b:0;s:10:"*_points";i:1;s:11:"*_correct";b:0;s:14:"*_sortString";s:0:"";s:18:"*_sortStringHtml";b:0;s:10:"*_mapper";N;}i:3;O:27:"WpProQuiz_Model_AnswerTypes":7:{s:10:"*_answer";s:7:"Option4";s:8:"*_html";b:0;s:10:"*_points";i:1;s:11:"*_correct";b:0;s:14:"*_sortString";s:0:"";s:18:"*_sortStringHtml";b:0;s:10:"*_mapper";N;}}
这里的四个选项是“Option1”、“Option2”、“Option3”和“Option4”。如何将它们提取为四个字符串或字符串数组?
编辑------------------------------------
按照建议我使用反序列化函数如下:
$ser ='a:4:{i:0;O:27:"WpProQuiz_Model_AnswerTypes":7:{s:10:"*_answer";s:7:"Option1";s:8:"*_html";b:0;s:10:"*_points";i:1;s:11:"*_correct";b:1;s:14:"*_sortString";s:0:"";s:18:"*_sortStringHtml";b:0;s:10:"*_mapper";N;}i:1;O:27:"WpProQuiz_Model_AnswerTypes":7:{s:10:"*_answer";s:7:"Option2";s:8:"*_html";b:0;s:10:"*_points";i:1;s:11:"*_correct";b:0;s:14:"*_sortString";s:0:"";s:18:"*_sortStringHtml";b:0;s:10:"*_mapper";N;}i:2;O:27:"WpProQuiz_Model_AnswerTypes":7:{s:10:"*_answer";s:7:"Option3";s:8:"*_html";b:0;s:10:"*_points";i:1;s:11:"*_correct";b:0;s:14:"*_sortString";s:0:"";s:18:"*_sortStringHtml";b:0;s:10:"*_mapper";N;}i:3;O:27:"WpProQuiz_Model_AnswerTypes":7:{s:10:"*_answer";s:7:"Option4";s:8:"*_html";b:0;s:10:"*_points";i:1;s:11:"*_correct";b:0;s:14:"*_sortString";s:0:"";s:18:"*_sortStringHtml";b:0;s:10:"*_mapper";N;}}';
$un = unserialize($ser);
if(!is_array($un)){
echo $un;
}else{
foreach($un as $value){
echo $value."\n";
}
}
我收到以下错误:
PHP Notice: unserialize(): Error at offset 63 of 822 bytes in <path> on line 5
我该如何解决这个问题?
EDIT2----------------------------
当我自己设置变量 $ser 从 mysql 表复制值时,使用 str_replace() 代码工作。 现在当我通过 php 代码提取它时,变量 $ser 不再是一个字符串。我无法将其强制转换为字符串。所以 str_replace() 不起作用。所以我尝试了正则表达式函数preg_replace(),但它不能替换'*_'。所以我只替换了'*'。 这是代码:
$host="<>"; // Host name
$username="<>"; // Mysql username
$password="<>"; // Mysql password
mysql_connect("$host", "$username", "$password")or die("cannot connect");
mysql_select_db("<>")or die("cannot select DB");
$sql="<the query>";
$result = mysql_query($sql);
$row=mysql_fetch_array($result);
$ser = $row['answer_data'];
echo $ser.'<br/><br/>';
$pattern = '/\*/';
$replace = '_00';
$ser = preg_replace($pattern, $replace, $ser);
echo $ser.'<br/><br/>';
$un = unserialize($ser);
$un = json_decode(json_encode($un));
foreach($un as $obj){
echo $obj->_00_answer;
}
mysql_close();
这是输出:
a:4:{i:0;O:27:"WpProQuiz_Model_AnswerTypes":7:{s:10:"*_answer";s:7:"Option1";s:8:"*_html";b:0;s:10:"*_points";i:1;s:11:"*_correct";b:1;s:14:"*_sortString";s:0:"";s:18:"*_sortStringHtml";b:0;s:10:"*_mapper";N;}i:1;O:27:"WpProQuiz_Model_AnswerTypes":7:{s:10:"*_answer";s:7:"Option2";s:8:"*_html";b:0;s:10:"*_points";i:1;s:11:"*_correct";b:0;s:14:"*_sortString";s:0:"";s:18:"*_sortStringHtml";b:0;s:10:"*_mapper";N;}i:2;O:27:"WpProQuiz_Model_AnswerTypes":7:{s:10:"*_answer";s:7:"Option3";s:8:"*_html";b:0;s:10:"*_points";i:1;s:11:"*_correct";b:0;s:14:"*_sortString";s:0:"";s:18:"*_sortStringHtml";b:0;s:10:"*_mapper";N;}i:3;O:27:"WpProQuiz_Model_AnswerTypes":7:{s:10:"*_answer";s:7:"Option4";s:8:"*_html";b:0;s:10:"*_points";i:1;s:11:"*_correct";b:0;s:14:"*_sortString";s:0:"";s:18:"*_sortStringHtml";b:0;s:10:"*_mapper";N;}}
a:4:{i:0;O:27:"WpProQuiz_Model_AnswerTypes":7:{s:10:"_00_answer";s:7:"Option1";s:8:"_00_html";b:0;s:10:"_00_points";i:1;s:11:"_00_correct";b:1;s:14:"_00_sortString";s:0:"";s:18:"_00_sortStringHtml";b:0;s:10:"_00_mapper";N;}i:1;O:27:"WpProQuiz_Model_AnswerTypes":7:{s:10:"_00_answer";s:7:"Option2";s:8:"_00_html";b:0;s:10:"_00_points";i:1;s:11:"_00_correct";b:0;s:14:"_00_sortString";s:0:"";s:18:"_00_sortStringHtml";b:0;s:10:"_00_mapper";N;}i:2;O:27:"WpProQuiz_Model_AnswerTypes":7:{s:10:"_00_answer";s:7:"Option3";s:8:"_00_html";b:0;s:10:"_00_points";i:1;s:11:"_00_correct";b:0;s:14:"_00_sortString";s:0:"";s:18:"_00_sortStringHtml";b:0;s:10:"_00_mapper";N;}i:3;O:27:"WpProQuiz_Model_AnswerTypes":7:{s:10:"_00_answer";s:7:"Option4";s:8:"_00_html";b:0;s:10:"_00_points";i:1;s:11:"_00_correct";b:0;s:14:"_00_sortString";s:0:"";s:18:"_00_sortStringHtml";b:0;s:10:"_00_mapper";N;}}
这是日志文件记录:
[11-Aug-2016 04:01:42 Etc/GMT] PHP Notice: unserialize(): Error at offset 63 of 934 bytes in <path> on line 24
[11-Aug-2016 04:01:42 Etc/GMT] PHP Warning: Invalid argument supplied for foreach() in <path> on line 26
EDIT3--------------------
从数据库中提取时 echo json_encode($ser);
的输出:
"a:4:{i:0;O:27:\"WpProQuiz_Model_AnswerTypes\":7:{s:10:\"\u0000*\u0000_answer\";s:7:\"Option1\";s:8:\"\u0000*\u0000_html\";b:0;s:10:\"\u0000*\u0000_points\";i:1;s:11:\"\u0000*\u0000_correct\";b:1;s:14:\"\u0000*\u0000_sortString\";s:0:\"\";s:18:\"\u0000*\u0000_sortStringHtml\";b:0;s:10:\"\u0000*\u0000_mapper\";N;}i:1;O:27:\"WpProQuiz_Model_AnswerTypes\":7:{s:10:\"\u0000*\u0000_answer\";s:7:\"Option2\";s:8:\"\u0000*\u0000_html\";b:0;s:10:\"\u0000*\u0000_points\";i:1;s:11:\"\u0000*\u0000_correct\";b:0;s:14:\"\u0000*\u0000_sortString\";s:0:\"\";s:18:\"\u0000*\u0000_sortStringHtml\";b:0;s:10:\"\u0000*\u0000_mapper\";N;}i:2;O:27:\"WpProQuiz_Model_AnswerTypes\":7:{s:10:\"\u0000*\u0000_answer\";s:7:\"Option3\";s:8:\"\u0000*\u0000_html\";b:0;s:10:\"\u0000*\u0000_points\";i:1;s:11:\"\u0000*\u0000_correct\";b:0;s:14:\"\u0000*\u0000_sortString\";s:0:\"\";s:18:\"\u0000*\u0000_sortStringHtml\";b:0;s:10:\"\u0000*\u0000_mapper\";N;}i:3;O:27:\"WpProQuiz_Model_AnswerTypes\":7:{s:10:\"\u0000*\u0000_answer\";s:7:\"Option4\";s:8:\"\u0000*\u0000_html\";b:0;s:10:\"\u0000*\u0000_points\";i:1;s:11:\"\u0000*\u0000_correct\";b:0;s:14:\"\u0000*\u0000_sortString\";s:0:\"\";s:18:\"\u0000*\u0000_sortStringHtml\";b:0;s:10:\"\u0000*\u0000_mapper\";N;}}"
之前 echo json_encode($ser);
的输出,即从 phpmyadmin 复制粘贴值:
"a:4:{i:0;O:27:\"WpProQuiz_Model_AnswerTypes\":7:{s:10:\"*_answer\";s:7:\"Option1\";s:8:\"*_html\";b:0;s:10:\"*_points\";i:1;s:11:\"*_correct\";b:1;s:14:\"*_sortString\";s:0:\"\";s:18:\"*_sortStringHtml\";b:0;s:10:\"*_mapper\";N;}i:1;O:27:\"WpProQuiz_Model_AnswerTypes\":7:{s:10:\"*_answer\";s:7:\"Option2\";s:8:\"*_html\";b:0;s:10:\"*_points\";i:1;s:11:\"*_correct\";b:0;s:14:\"*_sortString\";s:0:\"\";s:18:\"*_sortStringHtml\";b:0;s:10:\"*_mapper\";N;}i:2;O:27:\"WpProQuiz_Model_AnswerTypes\":7:{s:10:\"*_answer\";s:7:\"Option3\";s:8:\"*_html\";b:0;s:10:\"*_points\";i:1;s:11:\"*_correct\";b:0;s:14:\"*_sortString\";s:0:\"\";s:18:\"*_sortStringHtml\";b:0;s:10:\"*_mapper\";N;}i:3;O:27:\"WpProQuiz_Model_AnswerTypes\":7:{s:10:\"*_answer\";s:7:\"Option4\";s:8:\"*_html\";b:0;s:10:\"*_points\";i:1;s:11:\"*_correct\";b:0;s:14:\"*_sortString\";s:0:\"\";s:18:\"*_sortStringHtml\";b:0;s:10:\"*_mapper\";N;}}"
所以现在确实有额外的字符。数据库中的排序规则是 'utf8_general_c'
最佳答案
序列化字符串在许多属性名称中都有空字节。当您 echo
时,这些不会显示他们。例如,您会看到:
*_answer
...而实际上原始字符串(未回显)有这个(其中 <NUL>
表示空字节):
<NUL>*<NUL>_answer
这些空字节表示这些属性受到保护,如 PHP documentation on serialize
中所述:
[...] protected members have a '*' prepended to the member name. These prepended values have null bytes on either side.
如果你只接受回显字符串,然后尝试 unserialize
那,你会得到你提到的错误,因为指示的字符串长度(如 s:10:
)将不再对应于随后的空字节剥离属性名称的长度。
如果另一方面你unserialize
原始字符串,它将生成数组,但随后元素将具有 protected 属性,这使得很难访问它们。
这是将空-星号-空序列替换为其他三个可读字符(我选择:“key”)的代码,同时保持长度不变。这样,unserialize
函数不会产生 protected 属性,您可以使用诸如“key_answer”之类的名称轻松访问它们:
// Replace two NUL bytes separated by an asterisk with three other characters: "key"
// Note that you need to use double quotes for the first argument.
// This will make it easier to access those properties:
$ser = str_replace("\0*\0_", 'key_', $ser);
// Now unserialize this:
$un = unserialize($ser);
// Avoid warnings about incomplete objects:
// turn specific class objects to standard associative arrays:
$un = json_decode(json_encode($un), true);
// Extract the answers:
$answers = array_column($un, 'key_answer');
// Output the answers (but you could also use a foreach loop):
echo implode(",", $answers);
如果您的 PHP 版本低于 5.5,则它不支持 array_column
.而只是写:
foreach($un as $row) {
$answers[] = $row['key_answer'];
}
关于php - 从 mysql 数据库中提取序列化数据并在 php 中反序列化和使用各个字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38882158/