由于前一段时间很多使用国外代理的服务器来攻击,故当务之急是将所有国外IP段封掉。要nginx可以识别的allow/deny格式。

网上找到一个python脚本,从网络上得到一个IP对应国家列表,然后找出中国的IP段,提取出来。
原版的地址是http://ftp.apnic.net/apnic/dbase/data/country-ipv4.lst,发现已经404了,于是找到了可用的地址http://iiccms.googlecode.com/svn-history/r156/trunk/soft/country-ipv4.lst

以下是python程序:

#!/usr/bin/python
import urllib2
#request = urllib2.urlopen(“http://ftp.apnic.net/apnic/dbase/data/country-ipv4.lst”)
request = urllib2.urlopen(“http://iiccms.googlecode.com/svn-history/r156/trunk/soft/country-ipv4.lst”)
contents = request.read()
lines = contents.split(“\n”)
for line in lines:
 temp = line.split(“:”)
 if len(temp) is not 5: continue
 if temp[2].strip() == “cn”:
  block_range = temp[1].strip().split(“/”)[0]
  while len(block_range.split(“.”)) is not 4:
   block_range += “.0″
  block_range += “/” + temp[1].strip().split(“/”)[1]
  open(‘block.conf’,'a’).write(‘allow %s; \n’%(block_range))
  print(‘allow %s; \n’%(block_range))

(缩进用的是全角空格)
附带nginx语法的中国IP段列表:

block

其实这个东西是一把双刃剑,用好了可以在各个论坛定时发送有用的东西,用不好可以作为灌水机。

之前搞过一个专门给我们自己论坛发帖的机器人,那是从数据库直接灌数据的方式工作的。
由于这个是向别的论坛发数据,而且每天只发一条。所以可以用模拟用户提交表单的方式来发帖。

主攻discuz论坛,发布一篇帖子需要以下步骤:
获取登陆页面,分析到其中的formhash
将用户名密码等信息提交,得到登陆成功后的cookie
获取发布帖子页面的fromhash
提交帖子内容

需要注意的问题有:
discuz和discuzX的识别formhash的正则有区别,需要分开对待
网站编码问题,gbk编码首先需要用iconv转换成utf-8
referer问题,让referer连起来
header,gzip等也需要注意
有些论坛必须签到后才能发帖,那么需要首先签到

接下来是编码……………………
程序运行后会在page里面生成所有页面,往log里面添加记录,我可以根据page和log来判断这个程序是否正常运行。

程序写完后,我又用面向对象把代码重构了一遍。

前一段时间由于百度的收录一下子掉了很多,不知道什么问题,于是想到sitemap可能有问题。
于是写了一个自动生成sitemap的小程序,把主页和每个地区的列表页纳入sitemap中。

sitemap是xml文件

开头是
$sitemap_begin=”<?xml version=\”1.0\” encoding=\”UTF-8\”?>\n<urlset xmlns=\”http://www.sitemaps.org/schemas/sitemap/0.9\” xmlns:xsi=\”http://www.w3.org/2001/XMLSchema-instance\” xsi:schemaLocation=\”http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd\”>\n”;

结尾是
$sitemap_end=”</urlset>\n”;

中间的每条是
$sitemap_single=”  <url><loc>”.HOST.”%s/uni-%d/after/hold/page-%d/</loc><priority>%f</priority><lastmod>”.date(‘Y-m-d’).”</lastmod><changefreq>daily</changefreq></url>\n”;

从数据库中得到每个地区信息的条数,算出页数,然后写下对应页数的条数的记录,每条记录的权重:$pri = 0.5/ceil($count/30)*(ceil($count/30)+1-$i)+0.4;

每天更新,所以以后百度的快照都是昨天的了。

由于推广需要,需要群发一些邮件,邮件中带有图片,经过一番研究,写出了以下程序:注:需要phpmailer模块

# cat sendad.php
<html>
<head>
<title>send mail via smtp</title>
</head>
<body>

<?php
@set_magic_quotes_runtime(0);
require_once(‘./phpmailer/class.phpmailer.php’);

$mailliststr=file_get_contents(“email_list.txt”);
$maillist=explode(“\n”,$mailliststr);
foreach($maillist as $mailaddress)
{
echo “Sending mail to $mailaddress … “;
$mail = new PHPMailer(true);
$mail->IsSMTP(); // telling the class to use SMTP
try {
$mail->Host       = “smtp.exmail.qq.com”; // SMTP server
$mail->SMTPDebug  = 2;                     // enables SMTP debug information (for testing)
$mail->SMTPAuth   = true;                  // enable SMTP authentication
$mail->Port       = 25;                    // set the SMTP port for the GMAIL server
$mail->Username   = “admin@xxx.com”; // SMTP account username
$mail->Password   = “PASSWORD”;        // SMTP account password
//$mail->AddReplyTo(‘name@yourdomain.com’, ‘First Last’);
$mail->AddAddress($mailaddress, $mailaddress);
$mail->SetFrom(‘admin@xxx.com’, ‘admin’);
//$mail->AddReplyTo(‘name@yourdomain.com’, ‘First Last’);
$mail->CharSet     = ‘gb2312′;
$mail->Subject = ‘Subject’

$mail->AltBody = ‘To view the message, please use an HTML compatible email viewer!’; // optional – MsgHTML will create an alternate automatically
$body = file_get_contents(‘content/content.htm’);

preg_match_all(‘/<img.*?>/’, $body, $matches);
if (!isset($matches[0])) return;
// foreach tag, create the cid and embed image
$i = 1;
foreach ($matches[0] as $img)
{
// make cid
$id = ‘img’.($i++);
// replace image web path with local path
preg_match(‘/src=”(.*?)”/’, $img, $m);
// add
$mail->AddEmbeddedImage(‘./content/’.$m[1], $id, $m[1], ‘base64′, ‘image/jpeg’);
$body = str_replace($img, ‘<img alt=”" src=”cid:’.$id.’” style=”border: none;” />’, $body);
}
$mail->MsgHTML($body);

$mail->Send();
echo “OK! <br />\n”;
}
catch (phpmailerException $e) {
echo $e->errorMessage(); //Pretty error messages from PHPMailer
}
catch (Exception $e) {
echo $e->getMessage(); //Boring error messages from anything else!
}
}

function getFile() {
$fileArray=array();
if (false != ($handle = opendir ( ‘./content’ ))) {
$i=0;
while ( false !== ($file = readdir ( $handle )) ) {
if ($file != “.” && $file != “..” && $file != “content.htm” && strpos($file,”.”)) {
$fileArray[$i]=”./content/”.$file;
if($i==100){
break;
}
$i++;
}
}
closedir ( $handle );
}
return $fileArray;
}

?>

</body>
</html>

运行一次sendad.php,系统将会把content/content.htm以及其中附带的图片发送给email_list.txt中的所有地址。

慎用!

由于Linux命令比较复杂,一些初学者不容易掌握一些命令,于是搞一套用浏览器查看服务器信息的程序。

首先,服务器需要支持CGI脚本:http://blog.csdn.net/superwlg/article/details/6637859

以下是几个比较常用的功能脚本。

功能:显示连接服务器的最多的几个IP地址。

# cat view_connection.cgi

#!/bin/sh
echo
netstat -ntu | awk ‘{print $5}’ | cut -d: -f1 | sort | uniq -c | sort -rn | head
echo

———–

功能:显示最近的错误日志

# cat view_errorlog.cgi

#!/bin/sh
echo
tail -100 /home/wwwlogs/nginx_error.log

——-

功能:压缩内存

# cat mem_empty.cgi

#!/bin/sh
echo
freemem=$(cat /proc/meminfo | grep “MemFree” | awk ‘{print $2}’)
if [ $freemem -le 409600 ]
then
date  >> /var/log/mem.log
free -m >> /var/log/mem.log
sync
sync
echo 3 > /proc/sys/vm/drop_caches
free -m >> /var/log/mem.log
free
fi

———–

功能:查看网络连接

# cat net_status.cgi

#!/bin/sh
echo
netstat -n | awk ‘/^tcp/ {++state[$NF]} END {for(key in state) print key,”\t”,state[key]}’
echo -en “FAST-CGI \t ”
netstat -anpo | grep “php-cgi” | wc -l

———–

功能:重启nginx

# cat nginx_reload.cgi

#!/bin/sh
echo
/etc/init.d/nginx reload

————-

功能:重启mysql

# cat mysql_restart.cgi

#!bin/sh
echo
/etc/init.d/mysql restart

————–

功能:清空某个目录下的临时文件

# cat clearcache.cgi

#!/bin/sh
echo
rm -rfv /DIR/PATH/*
echo “!!! END !!!”

这个程序就像Windows的任务管理器的CPU和内存的性能使用记录似的,可以在浏览器中动态显示近20分钟的服务器资源使用状况。在CentOS平台上测试通过。
程序有一些BUG,当网络延迟比较大的时候,显示的图形不准确。
另外由于测试服务器的流量比较大,网络流量的量程比较大。

程序由两个文件组成,除此之外,还需要jQuery支持。

# cat resviewer.php

<html>
<head>
<script src=”/jquery.js” type=”text/javascript”></script>
</head>
<body>
NetInput 3 <span id=”text7″></span><br />
<canvas width=”1240″ height=”140″></canvas><br />
NetOut 3 <span id=”text8″></span><br />
<canvas width=”1240″ height=”140″></canvas><br />
memPercent <span id=”text1″></span><br />
<canvas width=”1240″ height=”140″></canvas><br />
memRealPercent <span id=”text2″></span><br />
<canvas width=”1240″ height=”140″></canvas><br />
memCachedPercent <span id=”text3″></span><br />
<canvas width=”1240″ height=”140″></canvas><br />
swapPercent <span id=”text4″></span><br />
<canvas width=”1240″ height=”140″></canvas><br />
NetInput 2 <span id=”text5″></span><br />
<canvas width=”1240″ height=”140″></canvas><br />
NetOut 2 <span id=”text6″></span><br />
<canvas width=”1240″ height=”140″></canvas><br />
<script type=”text/javascript”>
var memPercentCanvas = document.getElementById(“Canvas1″);
var memRealPercentCanvas = document.getElementById(“Canvas2″);
var memCachedPercentCanvas = document.getElementById(“Canvas3″);
var swapPercentCanvas = document.getElementById(“Canvas4″);
var NetInput2Canvas = document.getElementById(“Canvas5″);
var NetOut2Canvas = document.getElementById(“Canvas6″);
var NetInput3Canvas = document.getElementById(“Canvas7″);
var NetOut3Canvas = document.getElementById(“Canvas8″);
var c1 = memPercentCanvas.getContext(“2d”);
var c2 = memRealPercentCanvas.getContext(“2d”);
var c3 = memCachedPercentCanvas.getContext(“2d”);
var c4 = swapPercentCanvas.getContext(“2d”);
var c5 = NetInput2Canvas.getContext(“2d”);
var c6 = NetOut2Canvas.getContext(“2d”);
var c7 = NetInput3Canvas.getContext(“2d”);
var c8 = NetOut3Canvas.getContext(“2d”);
var t1 = $(“#text1″);
var t2 = $(“#text2″);
var t3 = $(“#text3″);
var t4 = $(“#text4″);
var t5 = $(“#text5″);
var t6 = $(“#text6″);
var t7 = $(“#text7″);
var t8 = $(“#text8″);
c1.fillStyle=”#000000″;
c1.strokeStyle=”#00FF00″;
c1.fillRect(0,0,1240,140);
c2.strokeStyle=”#00FF00″;
c2.fillStyle=”#000000″;
c2.fillRect(0,0,1240,140);
c3.strokeStyle=”#00FF00″;
c3.fillStyle=”#000000″;
c3.fillRect(0,0,1240,140);
c4.strokeStyle=”#00FF00″;
c4.fillStyle=”#000000″;
c4.fillRect(0,0,1240,140);
c5.strokeStyle=”#00FF00″;
c5.fillStyle=”#000000″;
c5.fillRect(0,0,1240,140);
c6.strokeStyle=”#00FF00″;
c6.fillStyle=”#000000″;
c6.fillRect(0,0,1240,140);
c7.strokeStyle=”#00FF00″;
c7.fillStyle=”#000000″;
c7.fillRect(0,0,1240,140);
c8.strokeStyle=”#00FF00″;
c8.fillStyle=”#000000″;
c8.fillRect(0,0,1240,140);
var n2i=0;
var n3i=0;
var n2o=0;
var n3o=0;
refresh();
var tt = 0;
function refresh(){
$.getJSON(“statusjson.php”,function(data){
var n2is=parseFloat(data.NetInput[2])-n2i;
n2i=parseFloat(data.NetInput[2]);
var n2os=parseFloat(data.NetOut[2])-n2o;
n2o=parseFloat(data.NetOut[2]);
var n3is=parseFloat(data.NetInput[3])-n3i;
n3i=parseFloat(data.NetInput[3]);
var n3os=parseFloat(data.NetOut[3])-n3o;
n3o=parseFloat(data.NetOut[3]);
if (tt==0) { n2is=0; n2os=0; n3is=0; n3os=0;}
var t = tt%1200;
t7.html(Math.round(n3is*1024*1024)+’kb’);
t8.html(Math.round(n3os*1024*1024)+’kb’);
//console.log((data));
c1.moveTo(20+t, 120);
c1.lineTo(20+t, 120-parseFloat(data.memPercent));
c1.stroke();
c2.moveTo(20+t, 120);
c2.lineTo(20+t, 120-parseFloat(data.memRealPercent));
c2.stroke();
c3.moveTo(20+t, 120);
c3.lineTo(20+t, 120-parseFloat(data.memCachedPercent));
c3.stroke();
c4.moveTo(20+t, 120);
c4.lineTo(20+t, 120-parseFloat(data.swapPercent));
c4.stroke();
c5.moveTo(20+t, 120);
c5.lineTo(20+t, 120-2000000*n2is);
c5.stroke();
c6.moveTo(20+t, 120);
c6.lineTo(20+t, 120-2000000*n2os);
c6.stroke();
c7.moveTo(20+t, 120);
c7.lineTo(20+t, 120-200000*n3is);
c7.stroke();
c8.moveTo(20+t, 120);
c8.lineTo(20+t, 120-100000*n3os);
c8.stroke();
});
tt += 1;
setTimeout(‘refresh();’,1000);
}
</script>
</body>
</html>

# cat statusjson.php

<?php
// MEMORY
if (false === ($str = @file(“/proc/meminfo”))) return false;
$str = implode(“”, $str);
preg_match_all(“/MemTotal\s{0,}\:+\s{0,}([\d\.]+).+?MemFree\s{0,}\:+\s{0,}([\d\.]+).+?Cached\s{0,}\:+\s{0,}([\d\.]+).+?SwapTotal\s{0,}\:+\s{0,}([\d\.]+).+?SwapFree\s{0,}\:+\s{0,}([\d\.]+)/s”, $str, $buf);
preg_match_all(“/Buffers\s{0,}\:+\s{0,}([\d\.]+)/s”, $str, $buffers);
$res['memTotal'] = round($buf[1][0]/1024, 2);
$res['memFree'] = round($buf[2][0]/1024, 2);
$res['memBuffers'] = round($buffers[1][0]/1024, 2);
$res['memCached'] = round($buf[3][0]/1024, 2);
$res['memUsed'] = $res['memTotal']-$res['memFree'];
$res['memPercent'] = (floatval($res['memTotal'])!=0)?round($res['memUsed']/$res['memTotal']*100,2):0;
$res['memRealUsed'] = $res['memTotal'] – $res['memFree'] – $res['memCached'] – $res['memBuffers']; //ʹ
$res['memRealFree'] = $res['memTotal'] – $res['memRealUsed']; //
$res['memRealPercent'] = (floatval($res['memTotal'])!=0)?round($res['memRealUsed']/$res['memTotal']*100,2):0; //ʹ
$res['memCachedPercent'] = (floatval($res['memCached'])!=0)?round($res['memCached']/$res['memTotal']*100,2):0; //Cachedʹ
$res['swapTotal'] = round($buf[4][0]/1024, 2);
$res['swapFree'] = round($buf[5][0]/1024, 2);
$res['swapUsed'] = round($res['swapTotal']-$res['swapFree'], 2);
$res['swapPercent'] = (floatval($res['swapTotal'])!=0)?round($res['swapUsed']/$res['swapTotal']*100,2):0;
// LOAD AVG
if (false === ($str = @file(“/proc/loadavg”))) return false;
$str = explode(” “, implode(“”, $str));
$str = array_chunk($str, 4);
$res['loadAvg'] = implode(” “, $str[0]);
//NETWORK
$strs = @file(“/proc/net/dev”);
for ($i = 1; $i < count($strs); $i++ )
{
preg_match_all( “/([^\s]+):[\s]{0,}(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)/”, $strs[$i], $info );
/*      $NetInput[$i] = formatsize($info[2][0]);
$NetOut[$i]  = formatsize($info[10][0]);
*/
$tmo = round($info[2][0]/1024/1024, 5);
$tmo2 = round($tmo / 1024, 5);
$res['NetInput'][$i] = $tmo2;
$tmp = round($info[10][0]/1024/1024, 5);
$tmp2 = round($tmp / 1024, 5);
$res['NetOut'][$i] = $tmp2;
}
echo json_encode($res);

效果图:

今天是周一,即将面临新一轮挑战。

上午看一会书,过会听说今天的502已经9%了,我就调了若干参数,把nginx 的worker prosess 调成8 了,php-fpm 调到250,接着502飙到了20%,资源监视窗更是变成了条形码。

据一个大牛说,要开启连接池,就是mysql的优化。
一个叫sqlrelay的东西,百度了一下。

参看了http://hi.baidu.com/mrvsumbeujeinxe/item/8ba0c60888cf47c490571896

wget在sourseforge下载了rudiments和sqlrelay。
解压了,./configure –prefix=XXX,按照帖子上面说的做了,结果运行
sqlr-start -id mysqltest
被提示Unable to load dynamic library ‘/usr/local/php/lib/php/extensions/no-debug-non-zts-20060613/sql_relay.so’
仔细检查,发现拼错了–with-php-prefix=/usq/local/php,囧
重新make make install,结果这个错误解决了。

再次运行sqlr-start -id mysqltest被提示
sqlr-listener error:Unable to create a shared memory segment.
搜索找不到
重启php-fpm,报错shmget() failed:  Invalid argument
觉得应该是shm共享内存的错误。
这下可以搜索到,http://blog.sina.com.cn/s/blog_9a4d43d801014avs.html
sysctl -a| grep shmm 居然发现 shmmax是0,什么情况!!
vi /etc/sysctl.conf 了,发现kernel.shmmax=4294967296,觉得是有些大了,就为0 了,
尝试设置为32M,重启reboot,经过漫长等待…………………………

擦,还得不行,只不过报的错不同了:shmget() failed:  No space left on device
搜索之,发现还有一个shmall的东西,应该和shmmax设置的一样。
再次重启,ok。。。

这是原来的配置文件
# Controls the maximum shared segment size, in bytes
kernel.shmmax = 4294967295
# Controls the maximum number of shared memory segments, in pages
kernel.shmall = 268435456

kernel.shmmax 数值说明:单位:字节。一般建议使用物理内存的一半
kernel.shmall 数值说明:单位:页。1页=4k,设置数值则为物理内存大小
以4G内存为例:4096*1024*1024/4000=1073742
注:以上两项数值如果填写大于本身物理内存则会不生效

看了这个文章http://www.xmydlinux.org/?p=366
觉得我们的kernel.shmmax=1073741824;kernel.shmall=262144

大功告成,502很少了!!共享内存也解决了。

主要是kernel.shmmax=1073741824;kernel.shmall=262144 这两个参数的设置问题。

ecoder是个很好的在线编辑器,不过有几个地方值得去搞一下,没有完善的登录功能,任何人不经授权可以读写代码,还有google的广告。

首先,上传到服务器上面要配置code.php文件,
两处 $code['root'] = ‘/wwwroot/’
还有secure的安全问题
$code['secure'] = 1;
$code['secure_variable'] = ‘login_security’;
$code['secure_url'] = ‘login.php’;
$code['secure_logouturl']=’login.php?action=logout’;

需要自己写一个login.php的登录入口。
<?php
session_start();

if ($_GET['action'] == ‘logout’){
unset ($_SESSION['login_security']);
echo “<strong>Logout!</strong><br />”;
}
if ($_POST['username'] == “root” && $_POST['password']==”YOURPASSWORD”){
$_SESSION['login_security'] = $_POST['username'];
header(“Location:index.php”);
}
elseif (isset($_POST['username']))
echo “<strong>Wrong password!</strong><br />”;
?>
<form action=”login.php” method=”POST”>
Username:<input name=”username” /><br />
Password:<input name=”password” type=”password”/><br />
<input name=”login” type=”submit” value=”Login” />
<a href=”login.php?action=logout”>Logout</a>
</form>

消除广告比较简单,只要在index.php的16行注释掉就可以
// test if javascript enabled ##
//include “code/base/loader.php”;

项目需要,需要将自己开发的应用和discuz共享用户表并且同步登陆。
首先下载discuz7.2和ucenter1.6,安装完毕,discuz直接和ucenter绑定到一起了。
接下来是将自己的程序和ucenter进行整合了。
在ucenter中新建一个应用,得到一个key,写到config.inc.php里,除此之外还要api、uc_client目录等。
———————–login.php———————-

<?php
require_once(“config.inc.php”);
require_once(“uc_client/client.php”);
list($uid,$username) = explode(“\t”, uc_authcode($_COOKIE['xuanjianghui_login'], ‘DECODE’));
$avatar = UC_API.’avatar.php?uid=’.$uid.’&size=small’;
if ($uid >0 ) {
echo $uid.” | “.$username;
echo “<a href=’logout.php’>logout</a>”;
}
else{
?>
<form method=”post” action=”dologin.php”>
账号<input name=”username” id=”username”><br/>
密码<input name=”password” id=”password” type=”password”><br/>
<input name=”login” id=”login” type=”submit” value=”登陆”>
</form>
<?php }

——————————–dologin.php——————————

<?php  error_reporting(E_ALL);
require_once(“config.inc.php”);
require_once(“uc_client/client.php”);
list($uid, $username, $password, $email) = uc_user_login($_POST['username'], $_POST['password']);
$avatar = UC_API.’avatar.php?uid=’.$uid.’&size=small’;
$p = array(‘uid’=>$uid,’username’=>$username,’email’=>$email,’avatar’=>$avatar);
setcookie(‘xuanjianghui_login’, ”, -86400);
if($uid > 0) { echo “!”;
//用户登陆成功,设置 Cookie,加密直接用 uc_authcode 函数,用户使用自己的函数
setcookie(‘xuanjianghui_login’, uc_authcode($uid.”\t”.$username, ‘ENCODE’));
//生成同步登录的代码
$ucsynlogin = uc_user_synlogin($uid);
echo ‘登录成功’.$ucsynlogin.’<br><a href=”‘.$_SERVER['PHP_SELF'].’”>继续</a>’;
echo $ucsynlogin;
}

echo json_encode($p);
同步登陆需要执行一段JS,即ucsynlogin返回的东西。
之前一直得不到ucsynlogin返回的代码,就深入往下找,直到找到一段代码,是访问缓存,如果同步的站点大于一才同步,不知为何我的缓存从来没变过,我就把那个验证缓存内容的if语句注释掉了,结果就返回了同步登陆代码,果然bbs也随之登陆了,注销也是如此。

接下来是通信失败的问题了,经过分析代码,发现检查通信是一个向、api/uc.php发送ping的一个过程。
返回1表示成功,其他是失败,我的程序什么都没返回。检查发现禁止报错了,error_reporting(E_ALL)一下,发现include就出问题了,
原来是配置文件的一个路径出问题了,修改一下路径,就通信成功了。

因为项目整合需要,需要机器人代发帖,于是乎开发一个接口。
有发布帖子和发布留言的两个接口。
有两种方法可以实现这个功能,一个是模拟用户提交表单,第二个是直接写数据库。
第一种的优点是高层接口,不用考虑底层的数据库操作,可以防止注入,灌水等,缺点是表单验证太复杂,而且有防灌水设置。
第二种的优点是随心所欲,不用考虑账户权限、防灌水等问题,缺点是数据库操作过于复杂。
采用第二种方法,这就需要知道发布一篇帖子时,数据库进行了哪些操作。
利用phpmyadmin导出整个数据库操作前和操作后的sql,利用Notepad++进行Compare操作,得到一些diff,这样可以找到发帖时的数据库改动。
主要有
1.向thread里添加一条记录,记录了帖子的标题、作者、上次回复时间等内容。
2.向posts里添加一条记录,记录了帖子的内容等信息。
3.向favoritethreads添加一条记录。
4.更新forum的最新帖子。
5.更新member的最后发布时间。

回复的一些改动
1.向posts里添加一条记录,记录了回复的内容等信息。
2.更新thread的最后回复时间。
3.更新forum的最新帖子。
4.更新member的最后发布时间。

找到了这些就可以开工了。最后测试成功。

function insert_thread($uid, $author, $fid, $title, $content)
{
global $tablepre,$dbname;
database_connect($dbname);
$time = time();
$sql1 = “INSERT INTO `{$tablepre}threads` (`fid`, `iconid`, `typeid`, `sortid`, `readperm`, `price`, `author`, `authorid`, `subject`, `dateline`, `lastpost`, `lastposter`, `views`, `replies`, `displayorder`, `highlight`, `digest`, `rate`, `special`, `attachment`, `moderated`, `closed`, `itemid`, `supe_pushstatus`, `recommends`, `recommend_add`, `recommend_sub`, `heats`, `status`) VALUES ($fid, 0, 0, 0, 0, 0, ‘$author’, $uid, ‘$title’, $time, $time, ‘$author’, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);”;
database_query($sql1);
$newid = mysql_insert_id();

$sql2 = “INSERT INTO `{$tablepre}posts` (`fid`, `tid`, `first`, `author`, `authorid`, `subject`, `dateline`, `message`, `useip`, `invisible`, `anonymous`, `usesig`, `htmlon`, `bbcodeoff`, `smileyoff`, `parseurloff`, `attachment`, `rate`, `ratetimes`, `status`) VALUES ($fid, $newid, 1, ‘$author’, $uid, ‘$title’, $time, ‘$content’, ’127.0.0.1′, 0, 0, 0, 0, -1, -1, 0, 0, 0, 0, 0);”;
database_query($sql2);

$sql3 = “INSERT INTO `{$tablepre}favoritethreads` (`tid`, `uid`, `dateline`, `newreplies`) VALUES ($newid, $uid, $time, 0);”;
database_query($sql3);

$sql4 = “UPDATE `{$tablepre}forums` SET `posts` = `posts`+1 , `threads` = `threads`+1 , `todayposts` = `todayposts`+1 , `lastpost` = ‘$newid\t$title\t$time\t$author’ WHERE `fid` = $fid ;”;
database_query($sql4);

$sql5 = “UPDATE `{$tablepre}members` SET `lastpost` = $time , `posts` = `posts`+1 , `threads` = `threads`+1 , `lastpost` = $time WHERE `uid` = $uid ;”;
database_query($sql5);

return $newid;
}

function insert_post($uid, $author, $fid, $tid, $content, $ip)
{
global $tablepre,$dbname;
database_connect($dbname);
$time = time();
$sql1 = “INSERT INTO `{$tablepre}posts` (`fid`, `tid`, `first`, `author`, `authorid`, `subject`, `dateline`, `message`, `useip`, `invisible`, `anonymous`, `usesig`, `htmlon`, `bbcodeoff`, `smileyoff`, `parseurloff`, `attachment`, `rate`, `ratetimes`, `status`) VALUES( $fid, $tid, 0, ‘$author’, $uid, ”, $time, ‘$content’, $ip, 0, 0, 0, 0, -1, -1, 0, 0, 0, 0, 0);”;
database_query($sql1);
$newid = mysql_insert_id();

$sql2 = “UPDATE `{$tablepre}threads` SET `views` = `views`+1 , `replies` = `replies`+1 , `lastpost` = $time, `lastposter` = ‘$author’ WHERE `tid` = $tid ;”;
database_query($sql2);

$sql3 = “UPDATE `{$tablepre}forums` SET `posts` = `posts`+1 , `todayposts` = `todayposts`+1 , `lastpost` = ‘$tid $title $time $author’ WHERE `fid` = $fid ;”;
database_query($sql3);

$sql4 = “UPDATE `{$tablepre}members` SET `lastpost` = $time , `posts` = `posts`+1 , `lastpost` = $time WHERE `uid` = $uid ;”;
database_query($sql4);

return $newid;
}