php+ajax购物车的基本原理--移出购物车

陈勇文 发表于 PHP技术 分类,标签:
30

上一篇文章,我简单介绍了php+ajax购物车的基本原理--加入购物车。而有时客户可能会临时把一些加入购物车的东西去掉,所以我们不得不加入一个移出购物车的功能。如下图:
remove_to_cart

加入购物车就是为商品创建一个$_SESSION变量,那移出购物车就是销毁这个变量。
我们会新建一个文件remove_to_cart.php----ajax请求的页面,用来把商品移出购物车。
首先我们对check_out.php用来显示购物车商品信息的代码增加一个移除的按钮。另外给在显示总金额那里增加一个id="totalamount"的标记,因为移出购物车,总金额会发生变化。更改后的代码如下:(只在表格那里修改就行了。)

<table>
<tr><td>商品</td><td>大小</td><td>数量</td><td>价格</td><td>操作</td></tr>
<?php foreach($products as $product){ ?>
<tr>
<td><?php echo $product['name'];?></td>
<td><?php echo $product['size'];?></td>
<td><?php echo $product['num'];?></td>
<td><?php echo $product['num']*$product['price'];?></td>
<td><input type="button" value="移除" onclick="remove_to_cart(this,'<?php echo $product[$key];?>')"</td>
</tr>
<?php } ?>
<tr><td colspan="5">总金额为:<span id="totalamount"><?php echo $_SESSION['totalamount'];?></span></td></tr>
</table>
<!---上面的代码增加了一个移除的按钮,点击就会触发remove_to_cart()函数,有两个参数,第一个this表示是按钮本身,方便把商品信息去掉,见下面分析,第二个参数key,是商品的标识符,方便销毁$_SESSION[$key]这个变量。-->
 
<!--我们先分析一下js代码remove_to_car()函数应该怎么写。第一个肯定是把参数key传递给remove_to_cart.php页面。第二个就是把移出购物车的商品信息从页面中去掉。第三个就是更改页面的总金额。-->
<script type="text/javascript">
function remove_to_cart(myInput,key){
createXMLHttpRequest(); //创建一个XMLHttpReques对象。最终会把所有的js代码放在同一个文件,所以就不必重复写createXMLHttpRequest()这个函数了。
var postStr="key="+key;
xmlHttp.open("post", "remove_to_cart.php");  //设置请求的页面,这里为remove_to_cart.php;
xmlHttp.setRequestHeader("cache-control","no-cache"); 
xmlHttp.setRequestHeader("Content-Type","application/x-www-form-urlencoded"); 
xmlHttp.send(postStr);
xmlHttp.onreadystatechange=function(){
if(xmlHttp.readyState==4 & xmlHttp.status==200){
//myINput表示按钮本身,它的父元素是td,td的父元素是tr,我们把tr设为隐藏,也就删除了商品信息了。
myInput.parentNode.parentNode.style.display="none";
//下面这句更改移除后商品的总金额,xmlHttp.responseText为返回的总金额。
document.getElementById("totalamount").innerHTML=xmlHttp.responseText;
}else  alert("移除失败");
}
}
</script>
<!--上面的js代码把参数key作为参数以poss方式传递给remove_to_cart.php,请求成功后删除该商品信息并更改商品总金额。-->

下面我们看一下remove_to_cart.php代码是怎么写的。

<?php
session_start();
ob_start();
if($_POST['key']){
$key=$_POST['key'];
//第一步先更改商品总金额。
$num=$_SESSION[$key]['num'];
$price=$_SESSION[$key]['price'];
//之前我们已经把总金额保存在$_SESSION['totalamount']里了,所以这里只需减去移除商品的金额就可以了。
$_SESSION['totalamount']-=$num*$price;
//第二步销毁该商品的变量。
unset($_SESSION[$key]);
echo $_SESSION['totalamount']; //返回更改后的总金额。
}
?>

ok,搞定了,如有任何问题,欢迎留言指出。

php+ajax购物车的基本原理--加入购物车

陈勇文 发表于 PHP技术 分类,标签:
9

最近在帮一个同学做一个小型的网店系统,所以简单分享一下自己是如何运用这个php购物车的基本原理。

简单来说,php购物车的基本原理就是用$_SESSION来临时保存客户的订单信息。一个$_SESSION变量保存一件商品的信息,所以要求每件商品都有一个惟一的标识符。
首先我们假设有以下两件商品:
cvgirl
我们新建三个文件:productlist.php------商品展示
check_out.php------结账页面,并显示购物车的商品信息。
add_to_cart.php-----ajax请求的页面,用来把商品信息加入购物车。
编码统一为utf-8,如出现乱码,请看一下php乱码问题的解决方案
首先看一下productlist.php的页面代码:

<!-- 这里我为了简化,只把商品的基本信息列出来。-->
<form>
<table>
<!-- key字段为商品的惟一标识符,值必须确保是惟一的。
    把key、shoename、shoeprice字段设为隐藏,一个是为了方便获取信息,另一个是为了界面比较好看。 
 -->
<input type="hidden" name="key" value="shoe1">
<input type="hidden" name="shoename" value="经典红色低帮">
<input type="hidden" name="shoeprice" value="200">
<tr><td>经典红色低帮</td></tr>
<tr><td><select name="shoesize"><option value="35">35<option value="36">36</option></td></tr>
<tr><td><input type="text" name="shoenum" value="1"></td></tr>
<tr><td>200</td></tr>
<tr><td><input type="button" value="加入购物车" onclick="add_to_cart(this.form);">
</table>
</form>
<!-- ok,上面的代码列出了商品1的基本信息,点击加入购物车就会触发add_to_cart()函数,我们看一下js代码是怎么写的。-->
<script type="text/javascript">
//用过ajax的都知道下面这个函数是创建XMLHttpReques对象的通用函数,这里就不讲解了。
function createXMLHttpRequest(){
if(window.ActiveXObject)
xmlHttp=new ActiveXObject("Microsoft.XMLHttp");
else if(window.XMLHttpRequest)
xmlHttp=new XMLHttpRequest();
 }
//参数myform,每一件商品给它分配一个form表单,这样就很容易获取每件商品的信息了。
function add_to_cart(myform){
createXMLHttpRequest(); //创建一个XMLHttpReques对象。
var key=myform.key;
var shoename=myform.shoename;
var shoesize=myform.shoesize;
var shoenum=myform.shoenum;
var shoeprice=myform.price;
//用来传递的参数,我这里选择的是用post方式传送。
var postStr="key="+key+"&name="+shoename+"&size="+shoesize+"&num="+shoenum+"&price="+shoeprice;
xmlHttp.open("post", "add_to_cart.php");  //设置请求的页面,这里为add_to_cart.php;
xmlHttp.setRequestHeader("cache-control","no-cache"); 
xmlHttp.setRequestHeader("Content-Type","application/x-www-form-urlencoded"); 
xmlHttp.send(postStr);
xmlHttp.onreadystatechange=function(){
if(xmlHttp.readyState==4 & xmlHttp.status==200){
alert(xmlHttp.responseText);
}else  alert("添加失败");
}
}
</script>
<!--以上的js代码获取了商品的基本信息,并把它作为参数以post的方式传递给add_to_cart.php。-->

下面我们看一下add_to_cart.php页面的代码。

<?php
session_start();
ob_start();//是为了防止出现Cannot modify header information之类的问题,可看一下http://www.googlephp.cn/archives/21这篇文章。
if($_POST['key']){
$key=$_POST['key'];
$name=$_POST['name'];
$size=$_POST['size'];
$num=$_POST['num'];
$price=$_POST['price'];
//我们把每一件商品信息都保存在$_SESSION['key']数组里。
//下面是一个逻辑判断,如果该商品是第一次加入购物车,就新创建一个$_SESSION['key']数组,否则数量就累加。
if(!isset($_SESSION[$key])){    //不存在$_SESSION[$key]这个变量,表示是第一次加入购物车。
$_SESSION[$key]['name']=$name;
$_SESSION[$key]['size']=$size;
$_SESSION[$key]['num']=$num;
$_SESSION[$key]['price']=$price;
} else{
$_SESSION[$key]['num']+=$num;
} 
echo "加入购物车成功";  //作为返回信息。
}
//以上的php代码程序显示了如何保存每一件加入购物车的基本信息。
?>

最后我们看一下check_out.php页面的代码。

<?php
session_start();
ob_start();
$_SESSION['totalamount']=0; //用来保存商品的总金额。
/*如何循环输出购物车的商品信息,第一个我想到是循环输出$_SESSION数组,但是print_r($_SESSION);会发现一个问题:$_SESSION数组不仅保存着商品信息,还保存着其它乱七八糟的信息,那样的话我们就需要对这个数组进行过滤,把商品信息提取出来。于是我想到可不可以用商品的标识符key来作判断呢,如果还有某个字符串就是我们需要的商品信息,上面我们商品1的key为shoe1,于是我们可以帮其它商品的key取值为shoe2,shoe3,shoe4....,这样我们的key都包含了"shoe"这个字符串。看下面代码是怎么过滤$_SESSION的。
*/
$products=array(); // 用来保存$_SESSION过滤后的商品信息。
foreach($_SESSION as $key=>$value){
if(strstr($key,"shoe")){     //包含"shoe字符串的才是我们真正需要的商品信息。"
$products[$key]['name']=$value['name'];
$products[$key]['size']=$value['size'];
$products[$key]['num']=$value['num'];
$products[$key]['price']=$value['price'];
$_SESSION['totalamount']+=$value['num']*$value['price'];
}
}
//接下来我们就循环输出购物车每个商品的信息。
?>
<table>
<tr><td>商品</td><td>大小</td><td>数量</td><td>价格</td></tr>
<?php foreach($products as $product){ ?>
<tr>
<td><?php echo $product['name'];?></td>
<td><?php echo $product['size'];?></td>
<td><?php echo $product['num'];?></td>
<td><?php echo $product['num']*$product['price'];?></td>
</tr>
<?php } ?>
<tr><td colspan="4">总金额为:<?php echo $_SESSION['totalamount'];?></td></tr>
</table>

ok,php购物车的简单基本原理就是这样了,最后我没有加入付账的链接了,假如需要提交给支付宝接口,只需在支付宝接口代码那里循环输出$_SESSION(过滤后的商品信息)就可以了。以上代码纯手工输入,未经测试,如有问题,欢迎指出。

php安装程序的基本原理

陈勇文 发表于 PHP技术 分类,标签:
8

当我们写了一个网站程序想分享给别人一起使用时,通常我们都会把数据库表的结构、表的初始化数据导出来,以方便他人导入数据库。但为何我们不写个安装程序,只要填写了主机,连接数据库的用户名跟密码、要创建的数据库名,程序就会帮我们创建数据库、表、初始化表的数据。所以写安装程序主要出于两个目的:第一个是方便自己移植自己的网站,第二个就是方便别人使用你的程序。下面就简单介绍一下php安装程序的基本原理。

简单步骤如下:
1、写一个form表单供用户填写主机名$host,连接数据库的用户名$user跟密码$password,要创建的数据库名$dbname。
2、将获得表单的数据写入一个配置文件config.php,以方便其它文件来调用数据库的信息。
3、调用配置文件include_once("config.php"),写程序进行数据库的连接,创建数据库、创建表、初始化表的数据。

ok,首先开始第一步

<form action="install.php" method="post">
填写主机:<input type="text" name="host">本地主机为localhost<br />
连接数据库的用户名:<input type="text" name="user"><br />
连接数据库的密码:<input type="text" name="password"><br />
要创建的数据库名:<input type="text" name="dbname"><br />
<input type="submit" name="install" value="安装">
</form>

2、将获得表单的数据写入一个配置文件config.php,以方便其它文件来调用数据库的信息。

<?php
header("Content-type:text/html;charset=gb2312") //看你用的是什么编码,要保持一致。
$files="config.php"; //要写入的配置文件。
if(!is_writable($files)){    //判断是否有可写的权限,linux操作系统要注意这一点,windows不必注意。
    echo "<font color=red>文件不可写</font>";
      exit();
}
if($_POST['install']){  //获取用户提交的数据。
$host=$_POST['host'];
$user=$_POST['user'];
$password=$_POST['password'];
$dbname=$_POST['dbname'];
 
$config="<?php ";        //$config的内容就是要写入配置文件的内容。
$config.="\n";            //   \n是用来换行的。
$config.="\$host='".$host."';";
$config.="\n";  
$config.="\$user='".$user."';";
$config.="\n";  
$config.="\$password='".$password."';";
$config.="\n";  
$config.="\$dbname='".$dbname."';";
$config.="\n";  
$config.="?>";
 
$file = fopen($files, "w");   //以写入的方式打开config.php这个文件。
fwrite($file,$config);  //将配置信息写入config.php文件。
fclose($file);
}
?>

3、调用配置文件include_once("config.php"),写程序进行数据库的连接,创建数据库、创建表、初始化表的数据。

<?php
include_once("config.php");   //导入配置信息.
if(!$conn=@mysql_connect($host,$user,$password)){
       echo "连接数据库失败!请返回上一页检查连接参数 <a href='javascript:history.go(-1)'><font color=#ff0000>返回修改</font></a>";
       exit();
}else{
  mysql_query("set names gb2312");  //设置数据库的编码,注意要与前面一致。
   if(!mysql_select_db($dbname,$conn)){   //如果数据库不存在,我们就进行创建。
         $dbsql="CREATE DATABASE `$dbname`";
         if(!mysql_query($dbsql)){
           echo "创建数据库失败,请确认是否有足够的权限!<a href='javascript:history.go(-1)'><font color=#ff0000>返回修改</font></a>";
           exit();
          }
   }
//下面根据你实际的表的结构跟初始化表的数据来写,这些sql语句,我们在导出时可以找到。
   //新建一个表test1
   $sql_query[] = "CREATE TABLE `test1` (   
                 `id` int(4) NOT NULL auto_increment,
                 `name` varchar(20) character set gb2312 NOT NULL,
                 `major` varchar(40) character set gb2312 NOT NULL,
                  PRIMARY KEY  (`id`)
                  ) ENGINE=InnoDB  DEFAULT CHARSET=gb2312 AUTO_INCREMENT=1;";
    //新建一个表test2
    $sql_query[] = "CREATE TABLE `test2` (   
                 `id` int(4) NOT NULL auto_increment,
                 `name` varchar(20) character set gb2312 NOT NULL,
                 `major` varchar(40) character set gb2312 NOT NULL,
                  PRIMARY KEY  (`id`)
                  ) ENGINE=InnoDB  DEFAULT CHARSET=gb2312 AUTO_INCREMENT=1;";
     //为test1表默认初始化一些数据。
     $sql_query[]="INSERT INTO `test1` (`name`, `major`) VALUES('张三','电子商务')";
     foreach($sql_query as $sql){
            if(!mysql_query($sql)){      //依次执行以上的sql语句,就是创建表和初始化数据。
            echo "创建表失败或者初始化数据失败";
                exit();
           }
     }
     mysql_close();
     echo "安装成功";//可以做一个跳转到首页。
     exit();
}
?>

有人或许为问,直接把表单提交的数据来进行安装不就可以了,为什么还要写入配置信息文件呢,这个是因为为了方便其它要使用到数据库的文件来连接数据库。嗯,到这里,这个安装程序的原理就差不多了,自己可以去完善一下,写一个更好的安装程序来,有什么问题欢迎留言指出。

完整的程序如下:写进同一个文件install.php。运行install.php就可以进行安装了。
install.php

php乱码问题的解决方案

陈勇文 发表于 PHP技术 分类,
10

php乱码问题一直是困扰初学者的一个很大问题。这里我分享一下我的解决方案,至少对我来说,用了这种方法之后就没出现过乱码问题了。

首先我们要搞清楚如下几个编码的概念:
①文件编码:每新建一个文件都会有对应的一个编码,把文件另存为就可以查看它的编码类型了。
wjbm

②页面编码,也就是浏览器以什么编码来显示你的网页,打开这个网页,鼠标右击就可以查看它的编码类型了。

③数据库编码。这里不是指建数据库时设置的编码,而是说指你的程序要连接数据库时,设置你读取数据的编码,通常这样设置mysql_query("set names GBK")或者mysql_query("set names gb2312")或者mysql_query("set names utf8")注意是utf8不是utf-8。

我们搞清了以上几个概念就好办了,使编码统一就可以解决乱码的问题了。
①在没有连接数据库的情况下,使页面编码跟文件编码统一就可以防止出现乱码了。上面说了,文件编码可以另存为查看,那页面编码怎么设置呢?如果用php语句就是在最前面加上header("Content-type=text/html;charset=文件编码");注意使用header()函数前不能有任何HTML输出。如果用HTML语法呢就是在<head></head>标记间加上<meta http-equiv="Content-Type" Content="text/html;charset=文件编码" />。
小提示:文件编码为GBK,ANSI,gb2312,页面编码都可以设置为gb2312即header("Content-type=text/html;charset=gb2312");
文件编码为utf-8时,页面编码就设置为utf-8,不过要注意utf-8的两种模式,这里有解决方案:http://www.googlephp.cn/archives/21

②在有连接数据库的情况下,使三者的编码统一就可以了。
文件编码跟页面编码是GBK,ANSI,gb2312情况下,在连接数据库后加上mysql_query("set names gb2312")或者mysql_query("set names GBK");
文件编码跟页面编码是utf-8时,在连接数据库后加上mysql_query("set names utf8"),注意后面那个utf8是没有“-”的。

有任何问题欢迎留言指出。

完美程序

陈勇文 发表于 PHP技术 分类,标签:
24

今天逛论坛看到一道非常有意思的题目“由杀人游戏写程序分析”

原题如下:
某地发生了一起谋杀案,警察通过排查确定杀人凶手必为4个嫌疑犯中的一个。以下为4个嫌疑犯的供词。
A说:不是我。
B说:是C。
C说:是D。
D说:C在胡说。 已知3个人说了真话,1个人说的是假话。请根据这些信息,写一个程序来确定到底谁是凶手 。

这是一道非常简单的逻辑思维题,正常人都可以推理出谁是凶手,但是如果叫你写一个程序来判断谁是凶手呢?你能写出来吗?或许你能写出来,但你写的程序一定是最好的吗?

事实上很多人都是写不出来的,因为不懂得把自己所想的用程序表示出来,而一些能够写出来的,却把程序写得过于复杂。昨天一个同学跟我说了这样一句话“程序是最公正的,能够运行出你想要结果的程序就是对的”。我想了一下,是对的。但不够完美,真正的程序员应该追求用最完美的程序来运行出想要的结果。

答案揭晓了,(*^__^*) ,你一定会惊叹作者的聪明才智。

<?php
$men = array ( 'A','B','C','D' ) ;   //四个嫌疑犯
foreach ( $men as $man )   //逐个判断。
{ 
if( ($man!='A')+($man=='C')+($man=='D')+($man!='D') == 3 ) //有三个人说的话是真的话条件成立
echo $man . ' is the killer.' ; 
}
?>

This is perfect program。

php简单实现将excel文件的数据批量导入到数据库

陈勇文 发表于 PHP技术 分类,标签:
12

借鉴了一个朋友的思路:http://mxp556.blog.hexun.com/23315689_d.html

简单思路如下:
1、将excel文件另存为txt文件。
2、用fopen()读取文件内容。
3、分析文件内容的结构,构成sql语句。
4、执行sql语句。

ok,下面开始举例。(最重要的是掌握思路!)
假设有一个test.xls的excel文件存储着我们要导入的内容。内容如下:
excel

首先将test.xls文件另存为test.txt文件(注意:要选择制表符分割的那个.txt)
txt
,中间可能会有什么提示,不管它,直接点“确定”或者“是”。然后打开test.txt文件,将它的编码另存为utf-8或者是gb2312,最主要是要跟下面的编码统一,以防出现乱码。

<?php 
header("Content-type:text/html;charset=utf-8"); //强制页面以utf-8编码显示,跟前面test.txt文件的编码要一致。
$conn=@mysql_connect("localhost","root","123456") or die("连接数据失败"); //连接数据库.
@mysql_select_db("test",$conn) or die("打开数据库失败"); //选择数据库,自己创建,还有表也是自己先建好来。
mysql_query("set names utf8");//跟上面的编码要统一,还有要注意的是utf8,不是utf-8。
$file=@fopen("test.txt",'r') or die("打开文件失败"); // 以只读方式打开test.txt文件。
//我们打开test.txt文件,可以看到test.txt文件内容的每一行与test.xls文件的每一行相对应。
//也就是说除了第一行外,每一行就相当于表的一条记录,我们只要循环插入每一行数据到表中就行了。
fgets($file);  //先读取文件的第一行,因为第一行不是我们要的内容。
//下面循环读取每一行,第一行已经读取了,所以从第二行开始读取。
while(!feof($file)){
       $val=fgets($file); 
       //下面一步很关键,用explode()将每一行转换为数组来存储每个字段的值。 
     //比如说第二行的内容是:1	陈勇文	男	电子商务;
       //转换为数组就变成array(1,"陈勇文","男","电子商务");这对于我们插入数据库就很有帮助了。
     $values=explode("\t",trim($val));  //注意用来分割的是制表符"\t",而不是空格" " ,自己也可以输出来测试一下。
     $sql="insert into `test`(`id`,`name`,`sex`,`major`) values('$values[0]','$values[1]','$values[2]','$values[3]')";
       if(!empty($values[0])) mysql_query($sql); //因为最后一行可能是空数据,所以做了个判断。   
}
fclose($file);
?>

搞定,收工。有问题欢迎提出。

//经一个朋友提醒,将excel文件转换为csv格式更好,然后用fetcsv()读取每一行,这样可以直接把每一行转换为数组,不用explode()分割了。

采集---强大的“小偷”

陈勇文 发表于 PHP技术 分类,标签: , ,
5

记得刚学php时,php100的张恩民老师就讲了一个“小偷程序”,那时我还不知道原来这就是采集啊,之后很长一段时间都没碰过“采集”,偶尔逛论坛的时候也会听到有人在讲采集,总感觉采集怎么那么像以前的那个“小偷程序”,后来才知道原来“小偷程序”就是采集。

最近在迷上一本仙侠“九阳绝脉”,觉得很好看,就问了作者可不可以在我的网站上连载,作者说可以,可麻烦的是他的小说有那么多章,如果我一章一章插入到数据库,这个工作量得多大,我突然想可不可以用采集来完成这个工作呢,马上测试了一下,果然行,不用几分钟就把它小说的内容采集到我的网站来了,下面我会讲一下我是怎么使用采集来完成这个工作的。(对于采集,我也还只是新手,有什么错误之处欢迎提出)

看了上面那么多,大家都应该大致对采集有一个了解了吧,简单来说,采集就是从别人的网站上获取我们要想要的内容,这感觉有点像“偷取”,所以也俗称“小偷程序”。采集大概一个工作流程如下:
1、寻找目标网站sUrl。(用file_get_contents(sUrl)获得目标网站的全部内容)
2、获得自己想要的内容(查看源文件,分析我们想要内容在什么标记之间,然后用正则表达式来匹配得到我们想要的内容)
3、将所得到的内容插入到我们的数据库(当然这里还要先对获得的内容进行过滤)

先举一个最简单的例子,采集百度的标题

<?php
//目标网站sUrl="http://www.baidu.com";
sUrl="http://www.baidu.com";
$con=file_get_contents(sUrl);用file_get_contents()来获取网站的全部内容;
//我们要采集的是百度的标题,先查看源文件,百度的标题在<title></title>标记之间,然后用正则表达式来匹配<title></title>标记之间的内容。
eregi("<title>(.*)</title>",$con,$title_arr);  //这里不对函数作解释了,这句的意思就是把<title></title>标记之间的内容匹配出来,然后保存到$title_arr数组上。
print_r($title_arr);//输出数组信息,我们会看到array(0=>"<title>百度一下,你就知道</title>",1=>"百度一下,你就知道");
//从上面的输出我可以看到,$title_arr[1]才是我们真正要匹配的内容。
?>

下面我讲一下怎么批量采集,不过这个批量采集有一定的条件,1、目标网址成一定规律递增,比如说网址1:http://googlephp.cn/1.html;网址2:http://googlephp.cn/2.html,依次类推。。。 2、批量采集的内容都在相同的标记之间。
我也就是通过批量采集来获得小说的内容,然后插入到我的数据库,下面实例看一下怎么完成这个工作的。

<?php
//我要采集的是小说阅读网---九阳绝脉1-163章的内容,而这1-163章的网址都是依次递增的。
//目标网址从http://www.readnovel.com/novel/69764/1.html到http://www.readnovel.com/novel/69764/163.html
//所以我这里可以用一个循环,依次读取每一章的内容;
for($i=1;$i<=163;$i++){
$sUrl="http://www.readnovel.com/novel/69764/".$i.".html";
$con=file_get_contents($sUrl);//读取网站的全部内容;
//查看源文件,分析我们想得到的内容在什么标记之间。我这里要得到是每一章的标题跟内容,它们在<div id="article"></div>标记之间。
//但是却不能直接匹配<div id="article"></div>之间的内容,因为后面还有</div>这个标记,它会把后面的内容也匹配进来,所以采集的时候要注意我们
//要匹配的内容是不是在惟一的标记之间。所以我又在<div id="article"></div>标记下找了一个<p class="shop">标记。
eregi("<div id=\"article\">(.*)<p class=\"shop\">",$con,$con_arr)//把<div id="article"><p class="shop">标记之间的内容匹配出来。
//我们已经获得了我们想要的内容,接下来还要把文章的标题跟文章的内容分离出来
eregi("<h2>(.*)</h2>",$con_arr[1],$title_arr)  //从我们获得的内容再把<h2></h2>标记之间的内容匹配出来,也就是文章的标题。
$title=addslashes($title_arr[1]);  //前面已经说了$title_arr[1]才是我们真正要的内容,另外还要进行转义,因为还要插入到数据库。 
eregi("</h2>(.*)</div>",$con_arr[1],$content_arr);//把</h2></div>标记之间的内容匹配出来,也就是文章的内容。
$content=addslashes($content_arr[1]);
$sql="insert into novel(id,title,content) values('','$title','$content');
mysql_query($sql);//插入到数据库,前面还要对数据库连接,这里没写了。
}
//搞定,收工。
?>

第一次使用采集,可能理解还不是很深,欢迎一起讨论。另喜欢武侠仙侠的朋友可以看一下我采集的小说“九阳绝脉”。
PS:对于采集别人网站的内容可能会涉及到版权问题,所以最好跟原作者联系好。

学生选课系统的一个简单构思

陈勇文 发表于 PHP技术 分类,标签: ,
1

要做一个课程设计,想做学生选课系统,所以就简单构思了一下。欢迎朋友们提出更多宝贵的意见,比如功能操作,数据库的设计等。

xk2

PHP中完美解决fckeditor上传中文文件与新建中文目录出现乱码的问题

陈勇文 发表于 PHP技术 分类,标签: ,
5

转载于:http://hi.baidu.com/houwenbin1986/blog/item/583acec52ea3dac139db49bd.html

1、修正上传中文文件时文件名乱码问题
在文件fckeditor/editor/filemanager/connectors/php/commands.php中查找:
$sFileName = $oFile['name'] ;
在后面添加一行:
$sFileName = iconv("utf-8","gbk",$sFileName);

2、修正文件列表时中文文件名显示乱码问题
在文件fckeditor/editor/filemanager/connectors/php/util.php中查找:
return ( utf8_encode( htmlspecialchars( $value ) ) ) ;
修改为:
return iconv('','utf-8',htmlspecialchars( $value ));

3、修正新建中文文件夹时的文件夹名乱码问题
在文件fckeditor/editor/filemanager/connectors/php/commands.php中查找:
$sNewFolderName = $_GET['NewFolderName'] ;
在后面添加一行:
$sNewFolderName = iconv("utf-8","gbk",$sNewFolderName);

1、2步解决上传中文文件出现乱码的问题,2、3步解决新建中文目录出现乱码的问题,第2步很关键额,因为它关系到显示文件列表跟目录列表。
tp

哈哈,终于找到了解决这个中文乱码的问题,另外网上也有另外一种解决上传中文文件出现乱码问题的方法,就是通过把上传的文件名改成不是中文来保存,这种方法也不错,具体怎么操作大家可以去网上搜一下,不过我还是比较喜欢上面的这种方法,这样文件看上去比较直观点,方便以后查找。

PHP无限分类的原理

陈勇文 发表于 PHP技术 分类,标签: ,
0

什么是无限分类呢?就像windows下新建一个文件夹,在新建的文件夹下又可以新建一个文件夹,这样无限循环下去,无限分类也是这样,父类可以分出它子类,子类又可以分出它的子类,这样一直无限循环下去。

那PHP又是如何实现它的无限分类的呢?如何把它的各个分类一一列出来呢?
首先我们假设有这样的一个三级分类,新闻→PHP新闻→PHP6.0出来了。
如果我们要查找“PHP6.0出来了”这条新闻,我们先点击新闻,然后再点击PHP新闻就可以查出来了,也就是说我们可以通过祖父类一级一级地往下找,反过来我们只要知道一个子类的父类,就可以把它查找出来了。这样我们在设计数据库时就可以多设计一个父类id的字段就可以实现无限分类的功能了。

//我们建一个表"class"
CREATE TABLE `class` (
  `id` int(11) NOT NULL auto_increment COMMENT '分类id',
  `f_id` int(11) NOT NULL COMMENT '父id',
  `name` varchar(25) collate gbk_bin NOT NULL COMMENT '分类名称',
  PRIMARY KEY  (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=gbk COLLATE=gbk_bin AUTO_INCREMENT=1 ;
 
//首先我们往数据库里插入‘新闻’这个大分类,因为‘新闻’是最大分类,上面没有父类了,所以我把它的f_id设置为0。
INSERT INTO `class` (`id`, `f_id`, `name`) VALUES(1, 0, '新闻');   //id这个字段是自动增长的,可以不写值。
 
//然后我们再往数据库里插入‘PHP新闻’这个分类,它的父类‘新闻’的id是1,所以它的f_id设置为1。
INSERT INTO `class` (`id`, `f_id`, `name`) VALUES(2, 1, 'PHP新闻');
 
//然后我们再往数据库里插入‘PHP6.0出来了’这个分类,它的父类‘PHP新闻’的id是2,所以它的f_id设置为2。
INSERT INTO `class` (`id`, `f_id`, `name`) VALUES(3, 2, 'PHP6.0出来了');
 
//同理,我们可以这样一直往下插入分类,也就达到了无限分类。
//我们可以发现插入一个分类的原则关键是找到这个分类的父类的id,然后作为这个分类的f_id字段的值。
//假设要插入跟‘新闻’同一个级别的分类‘技术’,也就是说它也是最大分类,上面没有父类了,那么它的f_id也设置为0;
INSERT INTO `class` (`id`, `f_id`, `name`) VALUES(4, 0, '技术'); 
 
//在‘技术’下面又有一个分类‘PHP技术’,那么我们怎么插入呢,首先找到‘PHP技术’的父类‘技术’的id,然后作为自己的f_id字段的值。
INSERT INTO `class` (`id`, `f_id`, `name`) VALUES(5, 4, 'PHP技术'); 
 
//看到这里,想必大家应该都明白怎么往数据库里插入各个分类了。就不再举例了。

我们已经知道如何往数据库里插入各个分类了,那又如何把各个分类罗列出来呢?

<?php
header("Content-type:text/html;charset=utf-8"); 
$db=new mysqli("localhost","root","","news_php100") ; //实例化一个数据库连接。使用这个前一定要确保已经加载了mysqli类库,或者用mysql_connect这个方式连接。 
if(mysqli_connect_errno()){
 	echo "链接失败:".mysqli_connect_error();
 	exit(); } 
$db->query("set names utf8");
$result=$db->query("select name from class where f_id=0"); //查找f_id=0的分类,也就是查找每一个大类。
while($row=$result->fetch_assoc()){
      echo $row['name']."<br>";        //这样就把每个大类循环出来了。
}
//同样我们可以把新闻的子类循环出来。
$result=$db->query("select * from class where f_id=1"); //查找f_id=1的分类,也就是查找‘新闻’的子类。
while($row=$result->fetch_assoc()){
      echo $row['name']."
";        //这样就把‘新闻’的子类循环出来了。注意:只是子类,不包括孙子类。
}
//写到这里,我们会发现一个问题,如果这个分类是10级分类,难道我们要写10个循环把它每个子类循环出来?如果是更多级分类呢,这样写显然是不现实的。
//那又有什么办法解决呢?我们可以写一个递归的函数,把f_id作为参数传入,不断循环每一个f_id的值,也就是说把每一个f_id值的子类循环出来。
//首先我们把各个分类的值保存在一个二维数组中,在下面的递归函数里有用。
$result=$db->query("select * from class");
while($row=$result->fetch_assoc()){
     $arr[]=array($row[id],$row[f_id],$row[name]);    //每一行保存一个分类的id,f_id,name的信息。
}
function fenlei($f_id=0){     //$f_id初始化为0,也就是从最大分类开始循环.
    global $arr;   //声明$arr为全局变量才可在函数里引用。
    for($i=0;$i<count($arr);$i++){       //对每个分类进行循环。
           if($arr[$i][1]==$f_id){         //$arr[$i][1]表示第$i+1个分类的f_id的值。开始$f_id=0,也就是把f_id=0的分类输出来。
                 echo $arr[$i][2]."<br>"; //$arr[$i][1]表示第$i+1个分类的name的值。
            fenlei($arr[$i][0]);   //$arr[$i][1]表示第$i+1个分类的id的值。进行递归,也就是把自己的id作为f_id参数把自己的子类再循环出来。
}
}
}
?>