ajax+php做的search,显示和关闭的问题?

 更新时间:2016年11月25日 17:35  点击:1256


我用ajax+php作了个简易的类似于google search的搜索,当我没输入字母的时候,显示是这样的,1.jpg:

当我输入字母时显示是,2.jpg的效果。

请问大家,当我鼠标点击别处时,使弹出的search的那个框自动关闭,应如何修改,代码如下
 

<html>
<body>
<style type="text/css">
#livesearch
  {
  margin:0px;
  width:140px;
  }
#txt1
  {
  margin:0px;
  }
</style>
<script type="text/javascript">
var xmlHttp
function showResult(str)
{
if (str.length==0)
 {
 document.getElementById("livesearch").
 innerHTML="";
 document.getElementById("livesearch").
 style.border="0px";
 return
 }
xmlHttp=GetXmlHttpObject()
if (xmlHttp==null)
 {
 alert ("Browser does not support HTTP Request")
 return
 }
var url="suggest_list.php"
url=url+"?q="+str
url=url+"&sid="+Math.random()
xmlHttp.onreadystatechange=stateChanged
xmlHttp.open("GET",url,true)
xmlHttp.send(null)
}
function stateChanged()
{
if (xmlHttp.readyState==4 || xmlHttp.readyState=="complete")
 {
 document.getElementById("livesearch").
 innerHTML=xmlHttp.responseText;
 document.getElementById("livesearch").
 style.border="1px solid #999999";
 }
}
function GetXmlHttpObject()
{
var xmlHttp=null;
try
 {
 // Firefox, Opera 8.0+, Safari
 xmlHttp=new XMLHttpRequest();
 }
catch (e)
 {
 // Internet Explorer
 try
  {
  xmlHttp=new ActiveXObject("Msxml2.XMLHTTP");
  }
 catch (e)
  {
  xmlHttp=new ActiveXObject("Microsoft.XMLHTTP");
  }
 }
return xmlHttp;
}
</script>
<form>
        <TABLE align="center" style="margin-top:140px" >
                <TR>
                        <TD>           
                                <input type="text" id="txt1" size="26"  name="username">
                                <div id="livesearch"></div>
                                wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww
                        </TD>
                </tr>
        </TABLE>
</form>
</body>
</html>
 

在这一章里你将了解到迷人而又让人容易糊涂的套接字(Sockets)。Sockets在PHP中是没有充分利用的功能。今天你将看到产生一个能使用客户端连接的服务器,并在客户端使用socket进行连接,服务器端将详细的处理信息发送给客户端。
当你看到完整的socket过程,那么你将会在以后的程序开发中使用它。这个服务器是一个能让你连接的HTTP服务器,客户端是一个Web浏览器,这是一个单一的 客户端/服务器 的关系。

◆ Socket 基础


PHP使用Berkley的socket库来创建它的连接。你可以知道socket只不过是一个数据结构。你使用这个socket数据结构去开始一个客户端和服务器之间的会话。这个服务器是一直在监听准备产生一个新的会话。当一个客户端连接服务器,它就打开服务器正在进行监听的一个端口进行会话。这时,服务器端接受客户端的连接请求,那么就进行一次循环。现在这个客户端就能够发送信息到服务器,服务器也能发送信息给客户端。
产生一个Socket,你需要三个变量:一个协议、一个socket类型和一个公共协议类型。产生一个socket有三种协议供选择,继续看下面的内容来获取详细的协议内容。
定义一个公共的协议类型是进行连接一个必不可少的元素。下面的表我们看看有那些公共的协议类型。

表一:协议
名字/常量     描述
AF_INET  这是大多数用来产生socket的协议,使用TCP或UDP来传输,用在IPv4的地址
AF_INET6     与上面类似,不过是来用在IPv6的地址
AF_UNIX  本地协议,使用在Unix和Linux系统上,它很少使用,一般都是当客户端和服务器在同一台及其上的时候使用
表二:Socket类型
名字/常量     描述
SOCK_STREAM  这个协议是按照顺序的、可靠的、数据完整的基于字节流的连接。这是一个使用最多的socket类型,这个socket是使用TCP来进行传输。
SOCK_DGRAM  这个协议是无连接的、固定长度的传输调用。该协议是不可靠的,使用UDP来进行它的连接。
SOCK_SEQPACKET  这个协议是双线路的、可靠的连接,发送固定长度的数据包进行传输。必须把这个包完整的接受才能进行读取。
SOCK_RAW  这个socket类型提供单一的网络访问,这个socket类型使用ICMP公共协议。(ping、traceroute使用该协议)
SOCK_RDM  这个类型是很少使用的,在大部分的操作系统上没有实现,它是提供给数据链路层使用,不保证数据包的顺序

表三:公共协议
名字/常量     描述
ICMP  互联网控制消息协议,主要使用在网关和主机上,用来检查网络状况和报告错误信息
UDP      用户数据报文协议,它是一个无连接,不可靠的传输协议
TCP 传输控制协议,这是一个使用最多的可靠的公共协议,它能保证数据包能够到达接受者那儿,如果在传输过程中发生错误,那么它将重新发送出错数据包。

现在你知道了产生一个socket的三个元素,那么我们就在php中使用socket_create()函数来产生一个socket。这个socket_create()函数需要三个参数:一个协议、一个socket类型、一个公共协议。socket_create()函数运行成功返回一个包含socket的资源类型,如果没有成功则返回false。
Resourece socket_create(int protocol, int socketType, int commonProtocol);

现在你产生一个socket,然后呢?php提供了几个操纵socket的函数。你能够绑定socket到一个IP,监听一个socket的通信,接受一个socket;现在我们来看一个例子,了解函数是如何产生、接受和监听一个socket。

<?php
$commonProtocol = getprotobyname(“tcp”);
$socket = socket_create(AF_INET, SOCK_STREAM, $commonProtocol);
socket_bind($socket, ‘localhost’, 1337);
socket_listen($socket);
// More socket functionality to come
?>

 

上面这个例子产生一个你自己的服务器端。例子第一行,
$commonProtocol = getprotobyname(“tcp”);
使用公共协议名字来获取一个协议类型。在这里使用的是TCP公共协议,如果你想使用UDP或者ICMP协议,那么你应该把getprotobyname()函数的参数改为“udp”或“icmp”。还有一个可选的办法是不使用getprotobyname()函数而是指定SOL_TCP或SOL_UDP在socket_create()函数中。
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
例子的第二行是产生一个socket并且返回一个socket资源的实例。在你有了一个socket资源的实例以后,你就必须把socket绑定到一个IP地址和某一个端口上。
socket_bind($socket, ‘localhost’, 1337);
在这里你绑定socket到本地计算机(127.0.0.1)和绑定socket到你的1337端口。然后你就需要监听所有进来的socket连接。
socket_listen($socket);
在第四行以后,你就需要了解所有的socket函数和他们的使用。

表四:Socket函数
函数名      描述
socket_accept()    接受一个Socket连接
socket_bind()     把socket绑定在一个IP地址和端口上
socket_clear_error()   清除socket的错误或者最后的错误代码
socket_close()     关闭一个socket资源
socket_connect()    开始一个socket连接
socket_create_listen()   在指定端口打开一个socket监听
socket_create_pair()   产生一对没有区别的socket到一个数组里
socket_create()    产生一个socket,相当于产生一个socket的数据结构
socket_get_option()    获取socket选项
socket_getpeername()   获取远程类似主机的ip地址
socket_getsockname()   获取本地socket的ip地址
socket_iovec_add()    添加一个新的向量到一个分散/聚合的数组
socket_iovec_alloc()   这个函数创建一个能够发送接收读写的iovec数据结构
socket_iovec_delete()   删除一个已经分配的iovec
socket_iovec_fetch()   返回指定的iovec资源的数据
socket_iovec_free()    释放一个iovec资源
socket_iovec_set()    设置iovec的数据新值
socket_last_error()    获取当前socket的最后错误代码
socket_listen()     监听由指定socket的所有连接
socket_read()     读取指定长度的数据
socket_readv()     读取从分散/聚合数组过来的数据
socket_recv()     从socket里结束数据到缓存
socket_recvfrom()    接受数据从指定的socket,如果没有指定则默认当前socket
socket_recvmsg()    从iovec里接受消息
socket_select()     多路选择
socket_send()     这个函数发送数据到已连接的socket
socket_sendmsg()    发送消息到socket
socket_sendto()    发送消息到指定地址的socket
socket_set_block()    在socket里设置为块模式
socket_set_nonblock()   socket里设置为非块模式
socket_set_option()    设置socket选项
socket_shutdown()    这个函数允许你关闭读、写、或者指定的socket
socket_strerror()    返回指定错误号的详细错误
socket_write()     写数据到socket缓存
socket_writev()    写数据到分散/聚合数组

(注: 函数介绍删减了部分原文内容,函数详细使用建议参考英文原文,或者参考PHP手册)
 

以上所有的函数都是PHP中关于socket的,使用这些函数,你必须把你的socket打开,如果你没有打开,请编辑你的php.ini文件,去掉下面这行前面的注释:
extension=php_sockets.dll
如果你无法去掉注释,那么请使用下面的代码来加载扩展库:
<?php
if(!extension_loaded(‘sockets’))
{
if(strtoupper(substr(PHP_OS, 3)) == “WIN”)
{
dl(‘php_sockets.dll’);
}
else
{
dl(‘sockets.so’);
}
}
?>

 

如果你不知道你的socket是否打开,那么你可以使用phpinfo()函数来确定socket是否打开。你通过查看phpinfo信息了解socket是否打开。如下图:
 
查看phpinfo()关于socket的信息


◆ 产生一个服务器


现在我们把第一个例子进行完善。你需要监听一个指定的socket并且处理用户的连接。

<?php
$commonProtocol = getprotobyname("tcp");
$socket = socket_create(AF_INET, SOCK_STREAM, $commonProtocol);
socket_bind($socket, 'localhost', 1337);
socket_listen($socket);
// Accept any incoming connections to the server
$connection = socket_accept($socket);
if($connection)
{
 socket_write($connection, "You have connected to the socket...\n\r");
}
?>

你应该使用你的命令提示符来运行这个例子。理由是因为这里将产生一个服务器,而不是一个Web页面。如果你尝试使用Web浏览器来运行这个脚本,那么很有可能它会超过30秒的限时。你可以使用下面的代码来设置一个无限的运行时间,但是还是建议使用命令提示符来运行。
set_time_limit(0);
在你的命令提示符中对这个脚本进行简单测试:
Php.exe example01_server.php
如果你没有在系统的环境变量中设置php解释器的路径,那么你将需要给php.exe指定详细的路径。当你运行这个服务器端的时候,你能够通过远程登陆(telnet)的方式连接到端口1337来测试这个服务器。如下图:

 

上面的服务器端有三个问题:1. 它不能接受多个连接。2. 它只完成唯一的一个命令。3. 你不能通过Web浏览器连接这个服务器。
这个第一个问题比较容易解决,你可以使用一个应用程序去每次都连接到服务器。但是后面的问题是你需要使用一个Web页面去连接这个服务器,这个比较困难。你可以让你的服务器接受连接,然后些数据到客户端(如果它一定要写的话),关闭连接并且等待下一个连接。
在上一个代码的基础上再改进,产生下面的代码来做你的新服务器端:

<?php
// Set up our socket
$commonProtocol = getprotobyname("tcp");
$socket = socket_create(AF_INET, SOCK_STREAM, $commonProtocol);
socket_bind($socket, 'localhost', 1337);
socket_listen($socket);
// Initialize the buffer
$buffer = "NO DATA";
while(true)
{
 // Accept any connections coming in on this socket

 $connection = socket_accept($socket);
 printf("Socket connected\r\n");
 // Check to see if there is anything in the buffer
 if($buffer != "")
 {
  printf("Something is in the buffer...sending data...\r\n");
  socket_write($connection, $buffer . "\r\n");
  printf("Wrote to socket\r\n");
 }
 else
 {
  printf("No Data in the buffer\r\n");
 }
 // Get the input
 while($data = socket_read($connection, 1024, PHP_NORMAL_READ))
 {
  $buffer = $data;
  socket_write($connection, "Information Received\r\n");
  printf("Buffer: " . $buffer . "\r\n");
 }
 socket_close($connection);
 printf("Closed the socket\r\n\r\n");
}
?>

这个服务器端要做什么呢?它初始化一个socket并且打开一个缓存收发数据。它等待连接,一旦产生一个连接,它将打印“Socket connected”在服务器端的屏幕上。这个服务器检查缓冲区,如果缓冲区里有数据,它将把数据发送到连接过来的计算机。然后它发送这个数据的接受信息,一旦它接受了信息,就把信息保存到数据里,并且让连接的计算机知道这些信息,最后关闭连接。当连接关闭后,服务器又开始处理下一次连接。(翻译的烂,附上原文)
This is what the server does. It initializes the socket and the buffer that you use to receive
and send data. Then it waits for a connection. Once a connection is created it prints “Socket connected” to the screen the server is running on. The server then checks to see if
there is anything in the buffer; if there is, it sends the data to the connected computer.
After it sends the data it waits to receive information. Once it receives information it stores
it in the data, lets the connected computer know that it has received the information, and
then closes the connection. After the connection is closed, the server starts the whole
process again.

 


◆ 产生一个客户端

处理第二个问题是很容易的。你需要产生一个php页连接一个socket,发送一些数据进它的缓存并处理它。然后你又个处理后的数据在还顿,你能够发送你的数据到服务器。在另外一台客户端连接,它将处理那些数据。
To solve the second problem is very easy. You need to create a PHP page that connects to
a socket, receive any data that is in the buffer, and process it. After you have processed the
data in the buffer you can send your data to the server. When another client connects, it
will process the data you sent and the client will send more data back to the server.


下面的例子示范了使用socket:

<?php
// Create the socket and connect
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
$connection = socket_connect($socket,’localhost’, 1337);
while($buffer = socket_read($socket, 1024, PHP_NORMAL_READ))
{
 if($buffer == “NO DATA”)
 {
 echo(“<p>NO DATA</p>”);
 break;
 }
 else
 {
  // Do something with the data in the buffer
  echo(“<p>Buffer Data: “ . $buffer . “</p>”);
 }
}
echo(“<p>Writing to Socket</p>”);
// Write some test data to our socket
if(!socket_write($socket, “SOME DATA\r\n”))
{
 echo(“<p>Write failed</p>”);
}
// Read any response from the socket
while($buffer = socket_read($socket, 1024, PHP_NORMAL_READ))
{
 echo(“<p>Data sent was: SOME DATA<br> Response was:” . $buffer . “</p>”);
}
echo(“<p>Done Reading from Socket</p>”);
?>

这个例子的代码演示了客户端连接到服务器。客户端读取数据。如果这是第一时间到达这个循环的首次连接,这个服务器将发送“NO DATA”返回给客户端。如果情况发生了,这个客户端在连接之上。客户端发送它的数据到服务器,数据发送给服务器,客户端等待响应。一旦接受到响应,那么它将把响应写到屏幕上。


结合Socket的坦克大战

(因为是描述游戏和socket结合,跟本文联系不大,所以不翻译,建议参考英文原文)

 

[ 题外话 ]

翻译文章的初衷是因为我个人对socket非常感兴趣,而且目前国内见php的文章比较少,除了php手册里面的部分内容,所以在我看了《PHP Game Programming》这本书里有关于socket的内容后毅然决定要翻译,我知道翻译出来的质量不行,还请见谅。

另外,我在《Core PHP Programming》Third Edition中也发现里面的Socket内容讲的不错,如果有空,我想也许我会把它也给翻译一下。这是我第一次翻译文章,花了我近五个小时,文章可以说是错误百出,如果翻译的不合理请见谅,如果有兴趣提高这个内容可以给我发邮件。这个凌晨时分,竟然无法入眠,不知道是不是在其他角落,也有人同我一样。

希望本文能够给向学习PHP Socket编程的朋友一点帮助,感谢你阅读这个错误百出的文章


在看本文之前,请确保你已掌握了PHP的一些知识以及MYSQL的查询操作基础哦。
作为一个Web程序,经常要和不计其数的数据打交道,比如会员的数据,文章数据,假如只有几十个会员那很好办,在一页显示就可以了,可是假如你的网站是几千甚至几十万会员的话,如果都在一页打开的话无论对浏览器还是观看者都是一种折磨。
相信每个学习PHP的新手都会对分页这个东西感觉很头疼,不过有了默默的这一水帖,你肯定会拍拍脑袋说,嘿,原来分页竟然如此简单?的确,现在请深呼吸一口新鲜的空气,仔细的听默默给你一点一点的分解。
假设我们要处理1000条数据,要在每页中显示10条,这样的话就会分100页来显示,咱们先看一看在mysql里提取10条信息是如何操作的。
Select * from table limit 0,10
上面是一句很简单的mysql查询语句,它的作用是从一个名叫table的表里提取10条数据,并且把所有字段的值都获得。
关键的地方就在这段“limit 0,10”,它其中的0是以0为起始点,后面的10则是显示10条数据,那么我们要以10为起始点,显示到第20条数据该怎么写呢?
可能很多大大会心直口快的说“limit 10,20”嘛!啊哦,这样可就错误了哦,正确的写法是“limit 10,10”它后面的参数并非是结束点而是要提取的数目,记住哦。
懂得了如何提取10条数据,那么提取1000条也就是做100次这种查询呀,就是说要做如下的查询:
Limit 0,10                 //第一页
Limit 10,10                //第二页
Limit 20,10                //第三页
Limit 30,10                //第四页
……
看出有什么规律了吗?没错,第一个参数每翻一页就增加10,可是第二个参数是不变的。
也就是说咱们设法根据页数来改变第一个参数的值,就可以进行分页显示数据了,怎么样,原理是不是很简单?
可是要怎么设法根据页数来改变第一个参数的值呢?首先,咱们要有一个页数的值,用url的GET方式获取。
比如index.php?page=18
相信大部分的大大对这个东西不陌生吧,这种url地址可是随处可见,其中的page参数的作用就是传入要显示的页数。
咱们通过一段代码来看一看究竟是如何实现的吧:
复制PHP内容到剪贴板PHP代码:
<?php
/*
Author:默默
Date  :2006-12-03
*/
$page=isset($_GET['page'])?intval($_GET['page']):1;        //这句就是获取page=18中的page的值,假如不存在page,那么页数就是1。
$num=10;                                      //每页显示10条数据
$db=mysql_connect("host","name","pass");           //创建数据库连接
$select=mysql_select_db("db",$db);                 //选择要操作的数据库
/*
首先咱们要获取数据库中到底有多少数据,才能判断具体要分多少页,具体的公式就是
总数据数除以每页显示的条数,有余进一。
也就是说10/3=3.3333=4 有余数就要进一。
*/
$total=mysql_num_rows(mysql_query("select id from table")); //查询数据的总数,id是数据库中的一个自动赋值的字段
$pagenum=ceil($total/$num);                                    //获得总页数
//假如传入的页数参数大于总页数,则显示错误信息
$totalrecord=mysql_num_rows($result);
    $pagesize=10;
    $page=isset($_GET['page'])?$_GET['page']:1;  
    $pagecount=($totalrecord % $pagesize==0)?$totalrecord / $pagesize:(int) ($totalrecord / $pagesize)+1;
    $page=($page>$pagecount || $page<1 )?1:$page;
    $start=$pagesize*($page-1);
    $res=mysql_query("select * from tablename  order by id desc limit $start,$pagesize")
//获取相应页数所需要显示的数据,name是数据里的一个字段
While($rsmysql_fetch_array($res)){
       Echo $rs['name']."<br />";
}                                                              //显示数据
  
下面就用for了,就不说了哒.还其它很多办法.万变不离其中.
/*显示分页信息,假如是当页则显示粗体的数字,其余的页数则为超连接,假如当前为第三页则显示如下
1 2 3 4 5 6
*/
?>
假如你仔细的读过上面的代码,把数据库连接和查询的表替换成你的,那么就能看见它的执行效果哦。
 
//无限分类,主要思想是这样的,用fid 来记录该类的上一级ID,通过fid和id建立起上下级的关系。
<?php
$conn = mysql_connect("localhost","root","root")  or die("数据库连接失入");
  mysql_select_db("new",$conn);
?>
分类:<select name="fid">
<?php
function mainfl()
{
    global $conn;
  $result=mysql_query("select id,fid,name from a where fid=0 order by id ",$conn);//这里默认的fid=0,表示这是第一级。通过这个可以查出所有fid=0的项,即所有的第一级主类
  if ($myrow=mysql_fetch_array($result))
  {
   do {
?>
    <option value=<?php echo $myrow["id"];?>><?php echo $myrow["name"];?></option>//$myrow["id"]输出主类的ID为查询子类做准备,$myrwo["name"]主类名字
<?php echo subfl($myrow["id"],"--");?>//调用子类函数subfl,使用--
/*
应一网友的要求,将其发的一段购物车类代码进行简单的分析,希望对需要的新手们有所帮助~
本人也是新手,分析讲解的同时也相当于学习了,不对的地方大虾们赶紧指正哈,呵呵^^
代码讲解分析: Linvo. 2008-2-15
*/
//购物车session的产生代码
if(!$session && !$scid) {
/*
session用来区别每一个购物车,相当于每个车的身份证号;
scid只用来标识一个购物车id号,可以看做是每个车的名字;
当该购物车的id和session值两者都不存在时,就产生一个新购物车
*/
    $session = md5(uniqid(rand()));
    /*
    产生一个唯一的购物车session号
    rand()先产生个随机数,uniqid()再在该随机数的基础上产生一个独一无二的字符串,最后对该字符串进行md5
    */
    SetCookie(scid, $session, time() + 14400);
    /*
    设置该购物车cookie
    变量名:scid(不知到这里是不是少了一个$号呢?)
    变量值:$session
    有效时间:当前时间+14400秒(4小时内)
    关于setcookie函数的详细用法,大家还是参看php手册吧~
    */
}

class Cart { //开始购物车类
    function check_item($table, $session, $product) {
    /*
    查验物品(表名,session,物品)
    */
        $query = SELECT * FROM $table WHERE session='$session' AND product='$product' ;
        /*
        看一看'表'里该'购物车'中有没有该'产品'
        即,该产品有没有已经放入购物车
        */
        $result = mysql_query($query);
        if(!$result) {
            return 0;
        }
        /*
        查询失败
        */
        $numRows = mysql_num_rows($result);
        if($numRows == 0) {
            return 0;
        /*
        若没有找到,则返回0
        */
        } else {
            $row = mysql_fetch_object($result);
            return $row->quantity;
            /*
            若找到,则返回该物品数量
            这里有必要解释一下mysql_fetch_object函数(下面还会用到):
            【mysql_fetch_object() 和 mysql_fetch_array() 类似,只有一点区别 - 返回一个对象而不是数组。】
            上面这句话摘自php手册,说得应该很明白了吧~
            简单的说就是,取一条记录中的某个字段,应该用“->”而不是像数组一样用下标
            */
        }
    }
    function add_item($table, $session, $product, $quantity) {
    /*
    添加新物品(表名,session,物品,数量)
    */
        $qty = $this->check_item($table, $session, $product);
        /*
        调用上面那个函数,先检查该类物品有没有已经放入车中
        */
        if($qty == 0) {
            $query = INSERT INTO $table (session, product, quantity) VALUES ;
            $query .= ('$session', '$product', '$quantity') ;
            mysql_query($query);
            /*若车中没有,则像车中添加该物品*/
        } else {
            $quantity += $qty; //若有,则在原有基础上增加数量
            $query = UPDATE $table SET quantity='$quantity' WHERE session='$session' AND ;
            $query .= product='$product' ;
            mysql_query($query);
            /*
            并修改数据库
            */
        }
    }
    function delete_item($table, $session, $product) {
    /*
    删除物品(表名,session,物品)
    */
        $query = DELETE FROM $table WHERE session='$session' AND product='$product' ;
        mysql_query($query);
        /*
        删除该购物车中该类物品
        */
    }
    function modify_quantity($table, $session, $product, $quantity) {
    /*
    修改物品数量(表名,session,物品,数量)
    */
        $query = UPDATE $table SET quantity='$quantity' WHERE session='$session' ;
        $query .= AND product='$product' ;
        mysql_query($query);
        /*
        将该物品数量修改为参数中的值
        */
    }
    function clear_cart($table, $session) {
    /*
    清空购物车(没什么好说)
    */
        $query = DELETE FROM $table WHERE session='$session' ;
        mysql_query($query);
    }
    function cart_total($table, $session) {
    /*
    车中物品总价
    */
        $query = SELECT * FROM $table WHERE session='$session' ;
        $result = mysql_query($query);
        /*
        先把车中所有物品取出
        */
        if(mysql_num_rows($result) > 0) {
            while($row = mysql_fetch_object($result)) {
            /*
            如果物品数量>0个,则逐个判断价格并计算
            */
           
                $query = SELECT price FROM inventory WHERE product='$row->product' ;
                $invResult = mysql_query($query);
                /*
                从inventory(库存)表中查找该物品的价格
                */
                $row_price = mysql_fetch_object($invResult);
                $total += ($row_price->price * $row->quantity);
                /*
                总价 += 该物品价格 * 该物品数量
                ( 大家应该能看明白吧:) )
                */
            }
        }
        return $total; //返回总价钱
    }

    function display_contents($table, $session) {
    /*
    获取关于车中所有物品的详细信息
    */
        $count = 0;
        /*
        物品数量计数
        注意,该变量不仅仅为了对物品数量进行统计,更重要的是,它将作为返回值数组中的下标,用来区别每一个物品!
        */
        $query = SELECT * FROM $table WHERE session='$session' ORDER BY id ;
        $result = mysql_query($query);
        /*
        先取出车中所有物品
        */
        while($row = mysql_fetch_object($result)) {
        /*
        分别对每一个物品进行取详细信息
        */
            $query = SELECT * FROM inventory WHERE product='$row->product' ;
            $result_inv = mysql_query($query);
            /*
            从inventory(库存)表中查找该物品的相关信息
            */
            $row_inventory = mysql_fetch_object($result_inv);
            $contents[product][$count] = $row_inventory->product;
            $contents[price][$count] = $row_inventory->price;
            $contents[quantity][$count] = $row->quantity;
            $contents[total][$count] = ($row_inventory->price * $row->quantity);
            $contents[description][$count] = $row_inventory->description;
            /*
            把所有关于该物品的详细信息放入$contents数组
            $contents是一个二维数组
            第一组下标是区别每个物品各个不同的信息(如物品名,价钱,数量等等)
            第二组下标是区别不同的物品(这就是前面定义的$count变量的作用)
            */
            $count++; //物品数量加一(即下一个物品)
        }
        $total = $this->cart_total($table, $session);
        $contents[final] = $total;
        /*
        同时调用上面那个cart_total函数,计算下总价钱
        并放入$contents数组中
        */
        return $contents;
        /*
        将该数组返回
        */
    }

    function num_items($table, $session) {
    /*
    返回物品种类总数(也就是说,两个相同的东西算一种    好像是废话- -!)
    */
        $query = SELECT * FROM $table WHERE session='$session' ;
        $result = mysql_query($query);
        $num_rows = mysql_num_rows($result);
        return $num_rows;
        /*
        取出车中所有物品,获取该操作影响的数据库行数,即物品总数(没什么好说的)
        */
    }
    function quant_items($table, $session) {
    /*
    返回所有物品总数(也就是说,两个相同的东西也算两个物品   - -#)
    */
        $quant = 0;// 物品总量
        $query = SELECT * FROM $table WHERE session='$session' ;
        $result = mysql_query($query);
        while($row = mysql_fetch_object($result)) {
        /*
        把每种物品逐个取出
        */
            $quant += $row->quantity; //该物品数量加到总量里去
        }
        return $quant; //返回总量
    }
}
 
[!--infotagslink--]

相关文章

  • Postgresql 如何选择正确的关闭模式

    这篇文章主要介绍了Postgresl 如何选择正确的关闭模式,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-01-18
  • PHP传值到不同页面的三种常见方式及php和html之间传值问题

    在项目开发中经常见到不同页面之间传值在web工作中,本篇文章给大家列出了三种常见的方式。接触PHP也有几个月了,本文总结一下这段日子中,在编程过程里常用的3种不同页面传值方法,希望可以给大家参考。有什么意见也希望大...2015-11-24
  • js修改input的type属性问题探讨

    js修改input的type属性有些限制。当input元素还未插入文档流之前,是可以修改它的值的,在ie和ff下都没问题。但如果input已经存在于页面,其type属性在ie下就成了只读属性了,不可以修改。...2013-10-19
  • Mysql常见问题集锦

    1,utf8_bin跟utf8_general_ci的区别 ci是 case insensitive, 即 "大小写不敏感", a 和 A 会在字符判断中会被当做一样的; bin 是二进制, a 和 A 会别区别对待. 例如你运行: SELECT * FROM table WHERE txt = 'a'...2013-10-04
  • Elasticsearch工具cerebro的安装与使用教程

    这篇文章主要介绍了Elasticsearch工具cerebro的安装与使用教程,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2021-03-08
  • Mysql大小写敏感的问题

    一、1 CREATE TABLE NAME(name VARCHAR(10)); 对这个表,缺省情况下,下面两个查询的结果是一样的:复制代码 代码如下: SELECT * FROM TABLE NAME WHERE name='clip'; SELECT * FROM TABLE NAME WH...2015-03-15
  • 深入理解C#窗体关闭事件

    很多初学者都想把默认的C#关闭按钮事件弄明白,本文就介绍一下C#窗体关闭事件,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2021-10-31
  • linux mint 下mysql中文支持问题

    一.mysql默认不支持中文,它的server和db默认是latin1编码.所以我们要将其改变为utf-8编码,因为utf-8包含了地球上大部分语言的二进制编码 1.关闭mysql服务 sudo /etc/init.d/mysql stop 2.修改mysql配置文件 mysql配...2015-10-21
  • docker 启动elasticsearch镜像,挂载目录后报错的解决

    这篇文章主要介绍了docker 启动 elasticsearch镜像,挂载目录后报错的解决,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-11-20
  • C#实现延时并自动关闭MessageBox的方法

    这篇文章主要介绍了C#实现延时并自动关闭MessageBox的方法,非常实用的功能,需要的朋友可以参考下...2020-06-25
  • C#窗体编程不显示最小化、最大化、关闭按钮的方法

    这篇文章主要介绍了C#窗体编程不显示最小化、最大化、关闭按钮的方法,即windows forms编程中取消最小化、最大化、关闭按钮,需要的朋友可以参考下...2020-06-25
  • C#使用队列(Queue)解决简单的并发问题

    这篇文章主要介绍了使用队列(Queue)解决简单的并发问题,讲解的很细致,喜欢的朋友们可以了解一下...2020-06-25
  • Python爬虫之Selenium实现关闭浏览器

    这篇文章主要介绍了Python爬虫之Selenium实现关闭浏览器,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-12-04
  • windows 10 安装和使用中5个常见问题

    2015年7月29日0点起,Windows 10推送全面开启,Windows7、Windows8.1用户可以免费升级到Windows 10,用户也可以通过系统升级到Windows10,在这过程中,用户会遇到这样那样的问题,下面小编总结了windows 10 安装和使用中5个常见问题,需要的朋友可以参考下...2016-01-27
  • 一文搞定Docker安装ElasticSearch的过程

    通过本文可以帮助大家快速学习Docker安装ElasticSearch的过程,本文通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧...2021-08-31
  • php中session常见问题分析

    PHP的session功能,一直为许多的初学者为难。就连有些老手,有时都被搞得莫名其妙。本文,将这些问题,做一个简单的汇总,以便大家查阅。 1. 错误提示 引用 代...2016-11-25
  • javascript学习指南之回调问题

    回调函数被认为是一种高级函数,一种被作为参数传递给另一个函数(在这称作"otherFunction")的高级函数,回调函数会在otherFunction内被调用(或执行)。回调函数的本质是一种模式(一种解决常见问题的模式),因此回调函数也被称为回调模式。...2016-04-25
  • vivo手机怎么关闭充电提示音 vivo手机充电提示音关闭方法

    vivo手机充电提示音在哪里设置?如何快速关闭充电提示音?很多人喜欢充电提示音的同时,也有很多人不喜欢,觉得这个充电提示音有点烦,那么我们就来学习一下充电提示音的设置方法...2020-12-08
  • c# 实现子窗口关闭父窗口也关闭的简单实例

    下面小编就为大家带来一篇c# 实现子窗口关闭父窗口也关闭的简单实例。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧...2020-06-25
  • json error: Use of overloaded operator [] is ambiguous错误的解决方法

    今天小编就为大家分享一篇关于json error: Use of overloaded operator [] is ambiguous错误的解决方法,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧...2020-04-25