我正在使用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'和'选项4'。如何将它们作为四个字符串或字符串数组提取?
EDIT ------------------------------------
如我所知,我使用了unserialize函数,如下所示:
$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 ---------------------------
使用str_replace()代码时,我设置变量$ ser自己从mysql表中复制值。 现在当我通过php代码提取它时,变量$ ser不再是一个字符串。我不能把它强制转换成字符串。所以str_replace()不起作用。所以我尝试了正则表达式函数preg_replace(),但它无法替换&#39; * _&#39;一起来。所以我更换了&#39; *&#39;。 这是代码:
$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&#39;
”答案 0 :(得分:1)
序列化字符串在许多属性名称中都有空字节。当您echo
时,这些不会显示。你会看到这样的:
*_answer
...实际上原始字符串(不是echo-ed)有这个(其中<NUL>
代表一个空字节):
<NUL>*<NUL>_answer
这些空字节表示这些属性受到保护,如PHP documentation on serialize
:
[...]受保护的成员在成员名称前加上“*”。这些前置值在任一侧都有空字节。
如果你只是接受echo-ed字符串,然后尝试unserialize
那你就会得到你提到的错误,因为指示的字符串长度(如s:10:
)将不再对应到后面的null-byte-stripped属性名称的长度。
另一方面,如果您unserialize
原始字符串,它将生成数组,但元素将具有受保护的属性,这使得很难访问它们。
这里的代码将用其他三个可读字符(我选择:“key”)替换null-asterisk-null序列,保持长度不变。这样,unserialize
函数将不会生成受保护的属性,您可以使用“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'];
}