PHP学习(四)---PHP与数据库MySql
主要有以下的内容:
1.怎么连接数据库
2.怎么操作数据库
(1)怎么执行sql语言
(2)怎么处理返回的结果集
方法一:面向过程(已经过时,只是了解)
假设:
1 $username=your_name; 2 $userpass=your_pass; 3 $dbhost=localhost; 4 $dbdatabase=your_database;
1 //生成一个连接 2 $db_connect=mysql_connect($dbhost,$username,$userpass) or die("Unable to connect to the MySQL!"); 3 4 //选择一个需要操作的数据库 5 mysql_select_db($dbdatabase,$db_connect); 6 7 //执行MySQL语句 8 $result=mysql_query("SELECT id,name FROM user"); 9 10 //提取数据 11 $row=mysql_fetch_row($result);
说明:
①在mysql_connect()、mysql_select_db()等函数之前使用@(错误控制运算符),可以忽略掉系统产生的错误信息,然后我们用die()来自定义错误信息;
②提取数据的时候,除了上面的mysql_fetch_row,常见的还有mysql_fetch_assoc和mysql_fetch_array,具体差别请查阅PHP Manual;
③对于mysql_query()函数的返回值,如果执行的语句有返回值(如SELECT、SHOW、DESCRIBE等),则返回相应数据(成功 时)或FALSE(失败时);如果执行的语句没有返回值(如DELETE、DROP、INSERT、UPDATE等),则返回TRUE(成功时)或 FALSE(失败时)。
方法二:面向对象(连接MySql数据库必选)
1 //创建数据库对象 2 $db=new MySQLi("localhost","root","123","exam"); 3 //判断是不是执行成功 4 !mysqli_connect_error() or die("连接失败!"); 5 //执行sql语句 6 $result=$db->query("SELECT * FROM student"); 7 //处理结果集 8 $arr=$result->fetch_row(); 9 //输出结果 10 var_dump($arr);
经典例题:
这是例子都是嵌在html中的,当然不嵌在也是可以的
1.数据库中的数据以表格的形式输出
1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 2 <html xmlns="http://www.w3.org/1999/xhtml"> 3 <head> 4 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 5 <title>以表格的形式显示数据库</title> 6 </head> 7 8 <body> 9 <?php 10 //连接数据库 11 $db=new MySQLi("localhost","root","123","testa"); 12 //判断是不是连接成功 13 ! mysqli_connect_error() or die("连接失败!"); 14 //执行sql语句 15 $result=$db->query("SELECT * FROM info;"); 16 //处理结果集 17 $arr=$result->fetch_all();//一个记录一个记录的取,以索引数组的形式显示 18 //$arr=$result->fetch_all();//取出全部的记录,并以二维数组的形式显示 19 //$arr=$result->fetch_assoc();//一个记录一个记录的取,以关联数组的形式显示 20 //可以在这里边用echo写,但是感觉代码多,而且还很乱 21 ?> 22 <!--创建表格--> 23 <table border="1" width="100%" cellpadding="0" cellspacing="0"> 24 <tr> 25 <td>代号</td> 26 <td>姓名</td> 27 <td>性别</td> 28 <td>民族</td> 29 <td>生日</td> 30 </tr> 31 <?php 32 for($i=0;$i<count($arr);$i++){ 33 echo "<tr>"; 34 for($j=0;$j<count($arr[$i]);$j++){ 35 echo "<td>{$arr[$i][$j]}</td>"; 36 }; 37 echo "</tr>"; 38 /*如果行数不多: 39 echo "<tr><td>{$arr[$i][0]}</td><td>{$arr[$i][1]}</td><td>{$arr[$i][2]}</td><td>{$arr[$i][3]}</td><td>{$arr[$i][4]}</td></tr>"; 40 */ 41 } 42 ?> 45 </table> 46 </body> 47 </html>
结果预览:
2.数据库的数据以下拉列表的形式呈现
1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 2 <html xmlns="http://www.w3.org/1999/xhtml"> 3 <head> 4 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 5 <title>以下拉列表的形式展现</title> 6 </head> 7 <body> 8 <!--连接数据库,以数组的形式显示数据--> 9 <?php 10 //连接数据库和处理结果集 11 $db=new MySQLi("localhost","root","123","testa"); 12 !mysqli_connect_error() or die("连接失败!"); 13 $result=$db->query("SELECT * FROM nation;"); 14 $arr=$result->fetch_all(); 15 ?> 16 <select> 17 <?php 18 //对于数据比较的多的情况可以这样写,要是比较少的话,直接写也是很快的 19 for($i=0;$i<count($arr);$i++){ 20 echo "<option value='{$arr[$i][0]}'>{$arr[$i][1]}</option>"; 21 } 22 /* 23 <option>$arr[0][1]</option>...... 24 表单元素中的value和name都是很重要的,一定要注意对其的使用 25 */ 26 ?> 27 </select> 28 </body> 29 </html>
结果:
这是页面效果
这是代码显示的形式
总结:
总结一下上边的这两个例子:
(1)首先这两个例子都是用PHP来控制输出的(仔细体会这句话),即把数据库中的内容呈现个用户,当然这里边是可以加一些样式的,给用户一个很好的用户体验.在设计的时候,要把数据和HTML分开来考虑,之后在找到他们之间的接口,将二者融合在一起. PHP从数据库中提取数据,借助HTML将数据更好的展现给用户.比如,提取出来的数据一般是数组,用户是看不懂数组的,要用HTML表格的形式展现给用户,这就是分开考虑和融合二者.
(2)注意细节,不管是用户体验的细节还是编程的细节.细节决定成败
3.利用php与数据库实现登录
实现登录就是多了一步填写的用户信息和数据库中的用户信息做比较.(这里边要是结合JS和CSS能实现很好的用户体验效果)
登录界面:
1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 2 <html xmlns="http://www.w3.org/1999/xhtml"> 3 <head> 4 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 5 <title>登录</title> 6 <style> 7 .login{ 8 width:50%; 9 margin:0px auto; 10 text-align:center; 11 } 12 table{ 13 text-align:center; 14 } 15 16 </style> 17 </head> 18 <body> 19 <div class="login"> 20 <!--设置好了,登录的界面--> 21 <form action="loginTest.php" method="post"> 22 <table width="50%" border="0" cellpadding="0" cellspacing="0" align="center"> 23 <tr> 24 <td width="10%">用户名:</td> 25 <td align="left"><input type="text" name="name" style="width:100%;" /><br/></td> 26 </tr> 27 <tr> 28 <td width="20%">密码:</td> 29 <td align="left"><input type="password" name="password" style="width:100%;"/><br/></td> 30 </tr> 31 <tr align="center"><td colspan=2><input type="submit" value="登录"/></td></tr> 32 </table> 33 </form> 34 35 </div> 36 </body> 37 </html>
结果:
登录处理页面:
1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 2 <html xmlns="http://www.w3.org/1999/xhtml"> 3 <head> 4 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 5 <title>登录验证</title> 6 </head> 7 <body> 8 9 <?php 10 //实现登录 11 $name=$_POST["name"]; 12 $password=$_POST["password"]; 13 //连接数据库 14 $db=new MySQLi("localhost","root","123","testa"); 15 !mysqli_connect_error() or die("连接失败!"); 16 $result=$db->query("SELECT count(*) FROM login WHERE username='{$name}' AND password='{$password}';"); 17 $arr=$result->fetch_all(); 18 //验证 19 if($arr[0][0]==1){ 20 echo "<h1>登录成功!</h1>"; 21 }else{ 22 echo "<h2>登录失败!</h2>"; 23 } 24 25 ?> 26 </body> 27 </html>
注意的地方:这个地方的验证是用匹配的数量来验证的,为1时唯一匹配,登录成功,当然这不是唯一的方法
4.在用户界面实现数据的增删改查(改和查难点)
总页面:
1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 2 <html xmlns="http://www.w3.org/1999/xhtml"> 3 <head> 4 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 5 <title>增加</title> 6 </head> 7 <?php 8 include("DBDA.php"); 9 $db=new DBDA(); 10 $sql="SELECT * FROM info"; 11 $arr=$db->Query($sql,1,"testa"); 12 ?> 13 <table width="100%" border="1" cellpadding="0" cellspacing="0"> 14 <tr><td>代号</td><td>姓名</td><td>性别</td><td>民族</td><td>生日</td><td>操作</td></tr> 15 <?php 16 for($i=0;$i<count($arr);$i++){ 17 echo "<tr><td>{$arr[$i][0]}</td><td>{$arr[$i][1]}</td><td>{$arr[$i][2]}</td><td>{$arr[$i][3]}</td><td>{$arr[$i][4]}</td><td><a href='delete.php?code={$arr[$i][0]}'>删除</a><a href='update.php'>修改</a></td></tr>"; 18 19 } 20 ?> 21 </table> 22 <a href="add.php"><input type="button" value="添加数据"/></a> 23 </body> 24 </html>
效果:
增加:
1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 2 <html xmlns="http://www.w3.org/1999/xhtml"> 3 <head> 4 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 5 <title>添加</title> 6 </head> 7 <body> 8 <form action="addTest.php" method="post"> 9 代号:<input type="text" name="code"/><br/> 10 姓名:<input type="text" name="name"/><br/> 11 <!--选择的男女--> 12 性别:<input type="radio" name="sex" value="1" checked="checked"/>男 13 <input type="radio" name="sex" value="0"/>女<br/> 14 <!--下拉列表的民族--> 15 民族: 16 <select name="nation"> 17 <?php 18 include("DBDA.php"); 19 $db=new DBDA(); 20 $sql="SELECT * FROM nation"; 21 $arr=$db->Query($sql,1,"testa"); 22 for($i=0;$i<count($arr);$i++){ 23 echo "<option value='{$arr[$i][0]}'>{$arr[$i][1]}</option>"; 24 } 25 ?> 26 27 </select><br/> 28 生日:<input type="text" name="birthday"/><br/> 29 <input type="submit" value="确认添加"/> 30 </form> 31 </body> 32 </html>
1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 2 <html xmlns="http://www.w3.org/1999/xhtml"> 3 <head> 4 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 5 <title>添加处理界面</title> 6 </head> 7 <body> 8 <?php 9 $code=$_POST["code"]; 10 $name=$_POST["name"]; 11 $sex=$_POST["sex"]; 12 $nation=$_POST["nation"]; 13 $birthday=$_POST["birthday"]; 14 include("DBDA.php"); 15 $db=new DBDA(); 16 $sql="INSERT INTO info VALUES ('{$code}','{$name}',{$sex},'{$nation}',{$birthday});"; 17 $result=$db->Query($sql,0); 18 if($result){ 19 header("location:table.php"); 20 }else{ 21 echo "<script>alert('添加失败!');</script>"; 22 } 23 ?> 24 </body> 25 </html>
删除:
1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 2 <html xmlns="http://www.w3.org/1999/xhtml"> 3 <head> 4 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 5 <title>删除</title> 6 </head> 7 <body> 8 <?php 9 $code=$_GET["code"]; 10 include("DBDA.php"); 11 $db=new DBDA(); 12 $sql="DELETE FROM info WHERE code='{$code}'"; 13 $result=$db->Query($sql,0); 14 if($result){ 15 header("location:table.php"); 16 } 17 ?> 18 </body> 19 </html>
修改:
5.封装数据库的连接(主要是连接函数)
封装的链接数据库的类:
1 <?php 2 3 class DBDA 4 { 5 public $host = "localhost"; //服务器地址 6 public $uid = "root"; //数据库的用户名 7 public $pwd = "123"; //数据库的密码 8 9 //执行SQL语句,返回相应结果的函数 10 //$sql是要执行的SQL语句 11 //$type是SQL语句的类型,0代表增删改,1代表查询 12 //$db代表要操作的数据库 13 public function Query($sql,$type=1,$db="testa") 14 { 15 //造连接对象 16 $conn = new MySQLi($this->host,$this->uid,$this->pwd,$db); 17 18 //判断连接是否成功 19 !mysqli_connect_error() or die("连接失败!"); 20 21 //执行SQL语句 22 $result = $conn->query($sql); 23 24 //判断SQL语句类型 25 if($type==1) 26 { 27 //如果是查询语句返回结果集的二维数组 28 return $result->fetch_all(); 29 } 30 else 31 { 32 //如果是其他语句,返回true或false 33 return $result; 34 } 35 } 36 37 }
分页类
1 <?php 2 /** 3 file: page.class.php 4 完美分页类 Page 5 */ 6 class Page { 7 private $total; //数据表中总记录数 8 private $listRows; //每页显示行数 9 private $limit; //SQL语句使用limit从句,限制获取记录个数 10 private $uri; //自动获取url的请求地址 11 private $pageNum; //总页数 12 private $page; //当前页 13 private $config = array( //弄成对象是很方便的,体会一下 14 'head' => "条记录", 15 'prev' => "上一页", 16 'next' => "下一页", 17 'first'=> "首页", 18 'last' => "末页" 19 ); 20 //在分页信息中显示内容,可以自己通过set()方法设置 21 private $listNum = 10; //默认分页列表显示的个数 22 23 /** 24 构造方法,可以设置分页类的属性 25 @param int $total 计算分页的总记录数 26 @param int $listRows 可选的,设置每页需要显示的记录数,默认为25条 27 @param mixed $query 可选的,为向目标页面传递参数,可以是数组,也可以是查询字符串格式 28 @param bool $ord 可选的,默认值为true, 页面从第一页开始显示,false则为最后一页 29 */ 30 public function __construct($total, $listRows=25, $query="", $ord=true){ 31 $this->total = $total; 32 $this->listRows = $listRows; 33 $this->uri = $this->getUri($query); 34 $this->pageNum = ceil($this->total / $this->listRows); 35 /*以下判断用来设置当前面*/ 36 if(!empty($_GET["page"])) { 37 $page = $_GET["page"]; 38 }else{ 39 if($ord) 40 $page = 1; 41 else 42 $page = $this->pageNum; 43 } 44 45 if($total > 0) { 46 if(preg_match('/\D/', $page) ){ 47 $this->page = 1; 48 }else{ 49 $this->page = $page; 50 } 51 }else{ 52 $this->page = 0; 53 } 54 55 $this->limit = "LIMIT ".$this->setLimit(); 56 } 57 58 /** 59 用于设置显示分页的信息,可以进行连贯操作 60 @param string $param 是成员属性数组config的下标 61 @param string $value 用于设置config下标对应的元素值 62 @return object 返回本对象自己$this, 用于连惯操作 63 */ 64 function set($param, $value){ 65 if(array_key_exists($param, $this->config)){ 66 $this->config[$param] = $value; 67 } 68 return $this; 69 } 70 71 /* 不是直接去调用,通过该方法,可以使用在对象外部直接获取私有成员属性limit和page的值 */ 72 function __get($args){ 73 if($args == "limit" || $args == "page") 74 return $this->$args; 75 else 76 return null; 77 } 78 79 /** 80 按指定的格式输出分页 81 @param int 0-7的数字分别作为参数,用于自定义输出分页结构和调整结构的顺序,默认输出全部结构 82 @return string 分页信息内容 83 */ 84 function fpage(){ 85 $arr = func_get_args(); 86 87 $html[0] = "<span class='p1'> 共<b> {$this->total} </b>{$this->config["head"]} </span>"; 88 $html[1] = " 本页 <b>".$this->disnum()."</b> 条 "; 89 $html[2] = " 本页从 <b>{$this->start()}-{$this->end()}</b> 条 "; 90 $html[3] = " <b>{$this->page}/{$this->pageNum}</b>页 "; 91 $html[4] = $this->firstprev(); 92 $html[5] = $this->pageList(); 93 $html[6] = $this->nextlast(); 94 $html[7] = $this->goPage(); 95 96 $fpage = '<div style="font:12px \'\5B8B\4F53\',san-serif;">'; 97 if(count($arr) < 1) 98 $arr = array(0,1,2,3,4,5,6,7); 99 100 for($i = 0; $i < count($arr); $i++) 101 $fpage .= $html[$arr[$i]]; 102 103 $fpage .= '</div>'; 104 return $fpage; 105 } 106 107 /* 在对象内部使用的私有方法,*/ 108 private function setLimit(){ 109 if($this->page > 0) 110 return ($this->page-1)*$this->listRows.", {$this->listRows}"; 111 else 112 return 0; 113 } 114 115 /* 在对象内部使用的私有方法,用于自动获取访问的当前URL */ 116 private function getUri($query){ 117 $request_uri = $_SERVER["REQUEST_URI"]; 118 $url = strstr($request_uri,'?') ? $request_uri : $request_uri.'?'; 119 120 if(is_array($query)) 121 $url .= http_build_query($query); 122 else if($query != "") 123 $url .= "&".trim($query, "?&"); 124 125 $arr = parse_url($url); 126 127 if(isset($arr["query"])){ 128 parse_str($arr["query"], $arrs); 129 unset($arrs["page"]); 130 $url = $arr["path"].'?'.http_build_query($arrs); 131 } 132 133 if(strstr($url, '?')) { 134 if(substr($url, -1)!='?') 135 $url = $url.'&'; 136 }else{ 137 $url = $url.'?'; 138 } 139 140 return $url; 141 } 142 143 /* 在对象内部使用的私有方法,用于获取当前页开始的记录数 */ 144 private function start(){ 145 if($this->total == 0) 146 return 0; 147 else 148 return ($this->page-1) * $this->listRows+1; 149 } 150 151 /* 在对象内部使用的私有方法,用于获取当前页结束的记录数 */ 152 private function end(){ 153 return min($this->page * $this->listRows, $this->total); 154 } 155 156 /* 在对象内部使用的私有方法,用于获取上一页和首页的操作信息 */ 157 private function firstprev(){ 158 if($this->page > 1) { 159 $str = " <a href='{$this->uri}page=1'>{$this->config["first"]}</a> "; 160 $str .= "<a href='{$this->uri}page=".($this->page-1)."'>{$this->config["prev"]}</a> "; 161 return $str; 162 } 163 164 } 165 166 /* 在对象内部使用的私有方法,用于获取页数列表信息 */ 167 private function pageList(){ 168 $linkPage = " <b>"; 169 170 $inum = floor($this->listNum/2); 171 /*当前页前面的列表 */ 172 for($i = $inum; $i >= 1; $i--){ 173 $page = $this->page-$i; 174 175 if($page >= 1) 176 $linkPage .= "<a href='{$this->uri}page={$page}'>{$page}</a> "; 177 } 178 /*当前页的信息 */ 179 if($this->pageNum > 1) 180 $linkPage .= "<span style='padding:1px 2px;background:#BBB;color:white'>{$this->page}</span> "; 181 182 /*当前页后面的列表 */ 183 for($i=1; $i <= $inum; $i++){ 184 $page = $this->page+$i; 185 if($page <= $this->pageNum) 186 $linkPage .= "<a href='{$this->uri}page={$page}'>{$page}</a> "; 187 else 188 break; 189 } 190 $linkPage .= '</b>'; 191 return $linkPage; 192 } 193 194 /* 在对象内部使用的私有方法,获取下一页和尾页的操作信息 */ 195 private function nextlast(){ 196 if($this->page != $this->pageNum) { 197 $str = " <a href='{$this->uri}page=".($this->page+1)."'>{$this->config["next"]}</a> "; 198 $str .= " <a href='{$this->uri}page=".($this->pageNum)."'>{$this->config["last"]}</a> "; 199 return $str; 200 } 201 } 202 203 /* 在对象内部使用的私有方法,用于显示和处理表单跳转页面 */ 204 private function goPage(){ 205 if($this->pageNum > 1) { 206 return ' <input 207 style="width:20px;height:17px !important;height:18px;border:1px solid #CCCCCC;" 208 type="text" 209 onkeydown="javascript: 210 if(event.keyCode==13){var page=(this.value>'.$this->pageNum.')?'.$this->pageNum.':this.value;location=\''.$this->uri.'page=\'+page+\'\'}" 211 value="'.$this->page.'"> 212 <input style="cursor:pointer;width:25px;height:18px;border:1px solid #CCCCCC;" type="button" value="GO" 213 onclick="javascript: 214 var page=(this.previousSibling.value>'.$this->pageNum.')?'.$this->pageNum.':this.previousSibling.value;location=\''.$this->uri.'page=\'+page+\'\'" 215 > '; 216 } 217 } 218 219 /* 在对象内部使用的私有方法,用于获取本页显示的记录条数 */ 220 private function disnum(){ 221 if($this->total > 0){ 222 return $this->end()-$this->start()+1; 223 }else{ 224 return 0; 225 } 226 } 227 } 228 229 230 231
主要是如何使用:
该类中有比较重要的函数,也是主要使用的函数
该类的构造函数和fpage()函数