discuz7.2升级discuz!X2中polloptions.php和pollvoter.php不能正常运行的解决方案
使用转换程序convert把论坛从版本discuz!7.2升级到discuz!X2的过程中,polloptions.php和pollvoter.php报错。我把升级过程分步骤描述如下:polloptions.php程序的修改:
一、为了减少转换程序的压力,把每次转换数据的数量从1000减小为100.
二、把forum_polloption表的插入操作拿到数据库中完成,运行一下SQL语句:
TRUNCATE `ultrax2`.pre_forum_polloption;
REPLACE INTO `ultrax2`.pre_forum_polloption (polloptionid,tid,votes,displayorder,polloption,voterids)(SELECT polloptionid,tid,votes,displayorder,polloption,voterids FROM `discuz`.cdb_polloptions);
三、修改以下程序,见程序中注释。注意:在对$voterids遍历循环操作中(修改后的第46行)添加is_numeric的判断,因为原discuz!7.2中$voterids有很多是IP地址,并不全都是uid,这时要把ip地址的投票者进行过滤。
四、把polloptions.php修改前第38行的调用members表赋值forum_pollvoter表username的操作取消,放到转换程序运行之后再用sql语句完成。
update pre_forum_pollvoter set pre_forum_pollvoter.username= (SELECT pre_common_member.username from pre_common_member WHERE pre_common_member.uid = pre_forum_pollvoter.uid)
\convert\source\d7.2_x2.0\table\polloptions.php的修改前是这样的,可以跟修改后的做比较:
<?php
/**
* DiscuzX Convert
*
* $Id: polloptions.php 19528 2011-01-05 09:12:03Z liulanbo $
*/
$curprg = basename(__FILE__);
$table_source = $db_source->tablepre . 'polloptions';
$table_target = $db_target->tablepre . 'forum_polloption';
$table_pollvoter = $db_target->tablepre . 'forum_pollvoter';
$limit = $setting['limit']['polloptions'] ? $setting['limit']['polloptions'] : 1000;
$nextid = 0;
$start = getgpc('start');
$continue = false;
if(!$start) {
$db_target->query("TRUNCATE $table_target");
$db_target->query("TRUNCATE $table_pollvoter");
}
$query = $db_source->query("SELECT * FROM $table_source WHERE polloptionid>'$start' LIMIT $limit");
while($row = $db_source->fetch_array($query)) {
$nextid = $row['polloptionid'];
$row = daddslashes($row, 1);
$data = implode_field_value($row, ',', db_table_fields($db_target, $table_target));
$db_target->query("INSERT INTO $table_target SET $data");
$voterids = trim($row['voterids']);
$voterids = explode("\t", $voterids);
foreach($voterids as $voterid) {
$count = $db_target->result_first("SELECT COUNT(*) FROM $table_pollvoter WHERE tid='{$row['tid']}' AND uid='$voterid' LIMIT 1");
if(!$count) {
$username = daddslashes($db_source->result_first("SELECT username FROM {$db_source->tablepre}members WHERE uid='$voterid'"), 1);
$db_target->query("INSERT INTO $table_pollvoter SET tid='{$row['tid']}', uid='$voterid', username='$username', options='', dateline='0'");
}
}
}
if($nextid) {
showmessage("继续转换数据表 ".$table_source." polloptionid > $nextid", "index.php?a=$action&source=$source&prg=$curprg&start=$nextid");
}
?>
\convert\source\d7.2_x2.0\table\polloptions.php的修改后:
<?php
/**
* DiscuzX Convert
*
* $Id: polloptions.php 19528 2011-01-05 09:12:03Z liulanbo $
*/
$curprg = basename(__FILE__);
$table_source = $db_source->tablepre . 'polloptions';
$table_target = $db_target->tablepre . 'forum_polloption';
$table_pollvoter = $db_target->tablepre . 'forum_pollvoter';
$limit = $setting['limit']['polloptions'] ? $setting['limit']['polloptions'] : 1000;
$limit = 100;//修改处一:这个数值改小一点比较好,以免数据量过大而导致程序运行超时。
$nextid = 0;
$start = getgpc('start');
$continue = false;
if(!$start) {
//$db_target->query("TRUNCATE $table_target");//这里要注释掉,在这里不进行forum_polloption表的操作
$db_target->query("TRUNCATE $table_pollvoter");
}
$query = $db_source->query("SELECT * FROM $table_source WHERE polloptionid>'$start' LIMIT $limit");
while($row = $db_source->fetch_array($query)) {
$nextid = $row['polloptionid'];
$row = daddslashes($row, 1);
/*修改处二:
//对于forum_polloption表的插入操作,在这里不执行,直接用mysql语句来完成。
TRUNCATE `ultrax2`.pre_forum_polloption;
REPLACE INTO `ultrax2`.pre_forum_polloption (polloptionid,tid,votes,displayorder,polloption,voterids)(SELECT polloptionid,tid,votes,displayorder,polloption,voterids FROM `discuz`.cdb_polloptions);
以上SQL语句可以在执行本程序之前来执行也可以在本程序完毕后再执行,但要在执行pollvoter之前。
*/
//$data = implode_field_value($row, ',', db_table_fields($db_target, $table_target));
//$db_target->query("INSERT INTO $table_target SET $data");
$voterids = trim($row['voterids']);
$voterids = explode("\t", $voterids);
foreach($voterids as $voterid) {
if(is_numeric($voterid))//需要判断一下,因为有的voterid值是ip地址
{
$count = $db_target->result_first("SELECT COUNT(*) FROM $table_pollvoter WHERE tid='{$row['tid']}' AND uid='$voterid' LIMIT 1");
if(!$count) {
/*修改处三:
//这一步操作也放到后边直接在mysql中执行下面的sql语句,减少转换程序的压力。
update pre_forum_pollvoter set pre_forum_pollvoter.username= (SELECT pre_common_member.username from pre_common_member WHERE pre_common_member.uid = pre_forum_pollvoter.uid)
以上SQL语句放在执行本程序完毕后再执行,但要在执行pollvoter之前。
*/
//$username = daddslashes($db_source->result_first("SELECT username FROM {$db_source->tablepre}members WHERE uid='$voterid'"), 1);
$username='';//把$username设置为空
$db_target->query("INSERT INTO $table_pollvoter SET tid='{$row['tid']}', uid='$voterid', username='$username', options='', dateline='0'");
}
}
}
}
if($nextid) {
showmessage("继续转换数据表 ".$table_source." polloptionid > $nextid", "index.php?a=$action&source=$source&prg=$curprg&start=$nextid");
}
?>
对pollvoter.php程序的修改:
文件路径:\convert\source\d7.2_x2.0\pollvoter.php
操作步骤:
1.同样是把$limit值改为100.
2.在程序第30行处对$voterid进行数字判断“if(is_numeric($voterid))”。
3.该程序有一处错误。程序源码的第33行:把$options[] = $row['polloptionid'];修改为$options[] .= $row['polloptionid'];//这个地方少了一个点,应该是.=。
4.把第35、36行拿到第32行的if语句之内,因为当polloptionid值在数据中已经存在时就没必要再重复一遍了。
pollvoter.php程序修改前后的代码如下:
修改前:
<?php
/**
* DiscuzX Convert
*
* $Id: pollvoter.php 19528 2011-01-05 09:12:03Z liulanbo $
*/
$curprg = basename(__FILE__);
$table_source = $db_source->tablepre . 'polloptions';
$table_target = $db_target->tablepre . 'forum_pollvoter';
$limit = 1000;
$pstep = getgpc('pstep');
$pstep = intval($pstep);
$total = getgpc('total');
$total = intval($total);
$offset = $pstep * $limit;
$continue = false;
$query = $db_source->query("SELECT * FROM $table_source ORDER BY polloptionid LIMIT $offset, $limit");
while($row = $db_source->fetch_array($query)) {
$voterids = trim($row['voterids']);
$voterids = explode("\t", $voterids);
foreach($voterids as $voterid) {
$options = $db_target->result_first("SELECT options FROM $table_target WHERE tid='{$row['tid']}' AND uid='$voterid'");
$options = explode("\t", $options);
if(!in_array($row['polloptionid'], $options)) {
$options[] = $row['polloptionid'];
}
$options_str = trim(implode("\t", $options));
$db_target->query("UPDATE $table_target SET options='$options_str' WHERE tid='{$row['tid']}' AND uid='$voterid'");
}
$continue = true;
$total ++;
}
$nextpstep = $pstep + 1;
if($continue) {
showmessage("继续转换数据表 ".$table_source.",已转换 $total 条记录。", "index.php?a=$action&source=$source&prg=$curprg&pstep=$nextpstep&total=$total");
}
?>
修改后:
<?php
/**
* DiscuzX Convert
*
* $Id: pollvoter.php 19528 2011-01-05 09:12:03Z liulanbo $
*/
$curprg = basename(__FILE__);
$table_source = $db_source->tablepre . 'polloptions';
$table_target = $db_target->tablepre . 'forum_pollvoter';
$limit = 100;//这个数值改小一点比较好,以免数据量过大而导致程序运行超时。
$pstep = getgpc('pstep');
$pstep = intval($pstep);
if(!$pstep) {
$db_target->query("update $table_target set options=''");
}
$total = getgpc('total');
$total = intval($total);
$offset = $pstep * $limit;
$continue = false;
$query = $db_source->query("SELECT * FROM $table_source ORDER BY polloptionid LIMIT $offset, $limit");
while($row = $db_source->fetch_array($query)) {
$voterids = trim($row['voterids']);
$voterids = explode("\t", $voterids);
foreach($voterids as $voterid) {
if(is_numeric($voterid))//需要判断一下,因为有的voterid值是ip地址
{
$options = $db_target->result_first("SELECT options FROM $table_target WHERE tid='{$row['tid']}' AND uid='$voterid'");
$options = explode("\t", $options);
if(!in_array($row['polloptionid'], $options)) {
$options[] .= $row['polloptionid'];//这个地方少了一个点,应该是.=
$options_str = trim(implode("\t", $options));//这一行和下面的这一行一起拿到if语句之内来,因为如果polloptionid已经存在了就不要再执行一遍update了
$db_target->query("UPDATE $table_target SET options='$options_str' WHERE tid='{$row['tid']}' AND uid='$voterid'");
}
}
}
$continue = true;
$total ++;
}
$nextpstep = $pstep + 1;
if($continue) {
showmessage("继续转换数据表 ".$table_source.",已转换 $total 条记录。", "index.php?a=$action&source=$source&prg=$curprg&pstep=$nextpstep&total=$total");
}
?>
查看完整版本: discuz7.2升级discuz!X2中polloptions.php和pollvoter.php不能正常运行的解决方案
Tags: discuz