PHP做一个登录jsp页面查询数据库,from已经完成了,要做一个PHP页,来验证登录信息是否和数据库中表的数据一致

一、匹配数据库登录
1.做一个普通的登录界面,注意提交方式为post。
&!--登录界面--&
&form action="chuli.php" method="post"&&!--表单提交action到chuli界面,提交方式设置为post。--&
&div&用户名:&input type="text"
name="uid"/&&/div& &!--用户名输入框--&
&div&密码:&input type="password" name="pwd" /&&/div& &!--密码输入框--&
&div&&input type="submit" value="登录" /&&/div&
2.用php匹配用户输入的用户名和密码
(1)**下面方法存在可以被SQL注入攻击的危险,安全性太低,要记住这种攻击的原理,在以后的工作中切记不能这样匹配登录信息。
&!--把html代码全部删除,做一个纯php处理界面--&
$uid = $_POST["uid"];//预定义数组_POST取跳转页面传递过来的数据,也就是取text界面中用户名和密码输入的值。把取到的值交给变量$uid
$pwd = $_POST["pwd"];//取到的密码交给变量$pwd
//取到这两个值之后,就要去判断用户名和密码是否匹配成功。
//造连接对象
$db = new MySQLi("localhost","root","666","text1");
//判断是否连接成功
mysqli_connect_error()?die("连接失败"):"";
//使用数据库中的login表验证
//写SQL语句
//SQL注入攻击
$sql = "select count(*) from login where username='{$uid}' and password='{$pwd}'";//查询有几条数据可以匹配成功,等于0则没有,大于0则匹配成功。'{$pwd}'中''是说明这是一个字符串,外面有"",这里就要用'',{}是为了特殊说明这里是一个变量。
//执行sql语句
$result = $db-&query($sql);//返回结果集对象
$n = $result-&fetch_row();//这里的$result是一个对,存到变量$n里面。
if($n[0]&0)//n&0代表能够匹配到,就能够登陆成功。然后跳转到主页面。在外部再建一个主页面main.php.$n是一个数组,要取里面的元素来判断。
header("location:main.php");//header方法表示跳转页面,()里面写location,冒号,跳转页面的名称。
else//如果匹配不成功
echo "用户名或密码错误";//输出 用户名或密码错误
//上面的方法能够实现匹配数据库的功能,但是做登录$sql语句一般不能这么写,需要别的方法写$sql语句,因为这种$sql语句做登录不安全。比如说在登录名和密码栏里都输入a' or '1'='1也能跳转到主页面,可以破解这种登录方法,称为SQL注入攻击,其原理是通过输入特定的字符串来修改sql语句,原来sql语句的意思完全变了。
(2).用php匹配用户输入的用户名和密码
  防止SQL注入攻击的方法:针对php来说的话,要么优化自己写的语句,要么把用户输入的内容处理一下,永远不要相信用户的任何输入数据,这是做程序的常识。
  处理用户输入内容是先自己写一个函数去判断用户输入的内容里面有没有特殊符号,像or、and、‘’等。如果有的话就去掉。
  后面还会学另一种方法pdo提供的一种方式,是最好的解决方案,其方法是先把这条sql语句分两次发动给服务器,第一次发送写好的sql语句框架,变量先不发送,mysql数据库接收到以后先等待执行,然后再把用户输入的内容提交过去,这样就把字符串拆开了,后来给的内容就是要查的内容,数据库就会原样的去匹配。
  我们下面采用优化sql语句的方法来防止注入攻击。sql语句换一种写法。
$db = new MySQLi("localhost","root","666","text1");
mysqli_connect_error()?die("连接失败"):"";
$sql = "select password from login where username='{$uid}'";//先根据uid找到对应的密码,这样最多只能找到一条数据。这样fetch_row()最多能取到1列。
//执行sql语句
$result = $db-&query($sql);
$n = $result-&fetch_row();
if($uid !="" && $pwd !="")//防止出现代码下面所说的bug。
if($n[0]==$pwd)//判断从数据库中找到的密码和用户输入的密码是不是一样。
header("location:main.php");//如果相等局跳转
echo "用户名或密码错误";//如果不相等就出现提示
else//如果用户名或者密码不输入弹出的信息
echo "用户名或密码不能为空";
//这样写的优点就是不管用户名怎么写,密码就是固定的密码。验证两个密码是不是一样。
//这种方法还会有个bug就是用户名和密码都输入错误也能登陆,因为数据库中没有改用户名就会输出null,密码输错了也会返回null,正好会匹配上。这样就在外面再加上一个if判断输入的内容是不是空的,如果是空的就弹出提示信息。
二、将数据库中info表中的信息以表格的相识显示在页面中
(1)在网页上显示出数据
&table width="100%" border="1" cellpadding="0" cellspacing="0"&
&tr&&!--做表头--&
&td&代号&/td&
&td&姓名&/td&
&td&性别&/td&
&td&民族&/td&
&td&生日&/td&
&?php //做表的内容,嵌入php代码
//造连接对象
$db = new MySQLi("localhost","root","666","text1");
//写sql语句
$sql = "select *from info";
//执行sql语句
$result = $db-&query($sql);
//读数据,返回一个二维数组
$attr = $result-&fetch_all();
//将二维数组里面的数据显示出来
foreach($attr as $v)
echo"&tr&";
echo"&td&{$v[0]}&/td&&td&{$v[1]}&/td&&td&{$v[2]}&/td&&td&{$v[3]}&/td&&td&{$v[4]}&/td&";//当行数比较多时者采用下面的写法。
/*foreach($v as $v1)//$v1就是变量了,二不是数组了。
echo "&td&{$v1}&/td&";
echo"&/tr&";
&!--以上代码会显示出info表的信息,但是sex栏显示的是0或1,而不是男或女,nation栏显示的也是民族的代号--&
(2)网页表格中的性别显示为男、女和民族栏显示出民族的名称
  只更改php中的代码,其它地方的代码不变。
$db = new MySQLi("localhost","root","666","text1");
$sql = "select *from info";
$result = $db-&query($sql);
$attr = $result-&fetch_all();
foreach($attr as $v)
echo"&tr&";
$sex = $v[2]?"男":"女";//$v[2]里面显示的是sex,内容是0和1,现在要转化为男和女。最简单的是用三元运算符写。用变量$sex接收,然后把$sex放到表格中替换$v[2]。就会显示男女了。
//$v[3]是民族的那一列,nation有另外一张表,要根据民族代号查询民族名称。上面链接对象已经造好了,不需要再链接数据库了,用同一个连接就可以。直接写sql语句
$sname = "select name from nation where code='{$v[3]}'";//根据民资代号查询民族名称
$rname = $db-&query($sname);//返回结果集
$aname = $rname-&fetch_row();//返回一个数组,$aname[0]里面就是存的民族名称,直接代替$v[3].
echo"&td&{$v[0]}&/td&&td&{$v[1]}&/td&&td&{$sex}&/td&&td&{$aname[0]}&/td&&td&{$v[4]}&/td&";
/*foreach($v as $v1)//$v1就是变量了,二不是数组了。
echo "&td&{$v1}&/td&";
echo"&/tr&";
  如果觉得显示民族的代码写在foreach里面显得太乱,还可以封装一个函数,调用这个函数来显示民的名称,具体写法如下,也是只写php里面的代码。
$db = new MySQLi("localhost","root","666","text1");
$sql = "select *from info";
$result = $db-&query($sql);
$attr = $result-&fetch_all();
foreach($attr as $v)
echo"&tr&";
$sex = $v[2]?"男":"女";//$v[2]里面显示的是sex,内容是0和1,现在要转化为男和女。最简单的是用三元运算符写。用变量$sex接收,然后把$sex放到表格中替换$v[2]。就会娴熟男女了。
//根据民族代号查询民族名称
$name = NationName($v[3]);//调用封装的函数,根据民族代号显示出民族名称。
echo"&td&{$v[0]}&/td&&td&{$v[1]}&/td&&td&{$sex}&/td&&td&{$name}&/td&&td&{$v[4]}&/td&";
/*foreach($v as $v1)//$v1就是变量了,二不是数组了。
echo "&td&{$v1}&/td&";
echo"&/tr&";
//封装下面的函数,这个函数的作用是给一个民族代号,返回民族名称。
function NationName($code)
$db = new MySQLi("localhost","root","666","text1");
$sql = "select name from nation where code = '{$code}'";
$result = $db-&query($sql);
$attr = $result-&fetch_row();
return $attr[0];
(3)对表格增加删除的功能,每行后面都加一个删除按钮,点击后从数据库中删除该条数据。
  main.php页面中的代码如下:(后面带注释的就是需要修改的)
&table width="100%" border="1" cellpadding="0" cellspacing="0"&
&tr&&!--做表头--&
&td&代号&/td&
&td&姓名&/td&
&td&性别&/td&
&td&民族&/td&
&td&生日&/td&
&td&操作&/td&&!--添加一列,做删除列--&
$db = new MySQLi("localhost","root","666","text1");
$sql = "select *from info";
$result = $db-&query($sql);
$attr = $result-&fetch_all();
foreach($attr as $v)
echo"&tr&";
$sex = $v[2]?"男":"女";
$name = NationName($v[3]);
echo"&td&{$v[0]}&/td&&td&{$v[1]}&/td&&td&{$sex}&/td&&td&{$name}&/td&&td&{$v[4]}&/td&&td&&a href='shanchu.php?c={$v[0]}'&onclick=\"return confirm('确定删除吗?')\"&删除&/a&&/td";//这里也要加一列,里面加删除。在删除外层添加一个&a&标签,‘删除’变成了超链接。点击删除后页面跳转到另一个页面chuli.php处理 //&onclick=\"return confirm('确定删除吗?')代表的是删除之前会弹出提示信息,确认或者取消,留给用户后悔的余地。onclick事件先于跳转页面执行,confirm是弹出一个带有确认或者删除的和用户交互的对话框,点击确定就会返回true继续执行,点击取消就会返回flase停止执行。confirm()里面填写的信息就会出现在弹出的对话框里面,用于提醒用户。无论是使用的&a&标签或者是按钮,都可以使用这句话。
/*foreach($v as $v1)
echo "&td&{$v1}&/td&";
echo"&/tr&";
function NationName($code)
$db = new MySQLi("localhost","root","666","text1");
$sql = "select name from nation where code = '{$code}'";
$result = $db-&query($sql);
$attr = $result-&fetch_row();
return $attr[0];
shanchu.php页面中的代码:
&?php //做删除页面,这种页面是不让用户看到的页面,把html代码全部删掉。
$code = $_GET["c"];//取出来传过来的值,传的c,就取c的值。把c的值放在主键code里面。
//造连接对象
$db = new MySQLi("localhost","root","666","text1");
$sql = "delete from info where code='{$code}'";//根据传过来的值删除数据库对应的数据
$r = $db-&query($sql);
header("location:main.php");//如果执行成功,就跳转到主页面main.php
echo "删除失败";
(4)对表格增加添加功能
a.先在main.php页面里面添加一个添加数据的按钮,写在table后面就可以。点击添加数据按钮后跳转到页面add.php。
&a href="add.php"&&input type="button" value="添加数据" /&&/a&&!--做一个添加按钮,点击添加数据,跳转到add.php页面执行。--&
b.做一个add.php页面,该页面是让用户填写要添加的数据,下方有“添加”的提交按钮,点击“提交”按钮跳转到addchuli.php页面。但是在填写数据时,性别要填写0或者1,民族要填写民族代号,后面会有解决方法。
&!--做添加的界面--&
&form action="addchuli.php" method="post"&
&div&代号:&input type="text" name="code" /&&/div&
&div&姓名:&input type="text" name="name" /&&/div&
&div&性别:&input type="text" name="sex" /&&/div&
&div&民族:&input type="text" name="nation" /&&/div&
&div&生日:&input type="text" name="birthday" /&&/div&
&div&&input type="submit" value="添加" /&&/div&&!--做个添加按钮--&
addchuli.php页面代码,填写完数据以后点击“添加”,跳转到此页面处理,处理完以后再跳转回主页面。
&?php //处理界面,把html代码全部删除
$code = $_POST["code"];//取到传过来的所有的值
$name = $_POST["name"];
$sex = $_POST["sex"];
$nation = $_POST["nation"];
$birthday = $_POST["birthday"];
//造连接对象
$db = new MySQLi("localhost","root","666","text1");
$sql = "insert into info values('{$code}','{$name}',{$sex},'{$nation}','{$birthday}')";//波尔型数据往里添加时不能有‘’,添加字符串的话永远返回的是true。
$db-&query($sql);
header("location:main.php");//往数据库里添加完数据以后再返回主页面。
c.解决b中提到的缺陷。并且将性别选项做成单选按钮,将民族做成下拉菜单。
&!--做添加的界面--&
&form action="addchuli.php" method="post"&
&div&代号:&input type="text" name="code" /&&/div&
&div&姓名:&input type="text" name="name" /&&/div&
&div&性别:
&input type="radio" name="sex" value="1" checked="checked" /&男&!--将性别作成单选按钮--&
&&input type="radio" name="sex" value="0" /&女
&div&民族:
&select name="nation"&
//造连接对象
$db = new MySQLi("localhost","root","666","text1");
$sql = "select * from nation";
$result = $db-&query($sql);
$attr = $result-&fetch_all();
foreach($attr as $v)
echo "&option value='$v[0]'&{$v[1]}&/option&";//表单提交的时候是提交的value值,$v[1]仅仅是显示用的,value值$v[0]才是要提交的数据,下拉菜单选中哪一项就提交哪一项的value值。
&div&生日:&input type="text" name="birthday" /&&/div&
&div&&input type="submit" value="添加" /&&/div&&!--做个添加按钮--&
阅读(...) 评论()正文 php与mysql开发用户登录验证的实例代码
php与mysql开发用户登录验证的实例代码
发布时间: & 编辑:
本文介绍下,php与mysql数据库结合,实现的一个用户登录验证的代码,有需要的朋友,可以参考学习下。简单 PHP + MySQL 数据库动态网站制作 - Blog - Renfei Song在这篇文章中,我尽量用最浅显易懂的语言来说明使用 PHP, MySQL 制作一个动态网站的基本技术。阅读本文需要简单的 HTML 基础知识和(任一编程语言的)编程基础知识(例如变量、值、循环、语句块的概念等)。PHP 基础概述PHP 是一种解释性语言,可用于对网页进行预处理。PHP 脚本在服务器端运行,其运行结果是一个可用来显示的网页。尽管可以完成许多类似工作,但是 JavaScript 和 PHP 的一大区别就是,JavaScript 是在浏览器端运行的。事实上,浏览器会接收 JavaScript 代码并运行它,所以用户是可以查看 JavaScript 代码的。而 PHP 不会将原始代码交给浏览器, 只会将其运行的结果交给浏览器,所以用 PHP 处理用户登陆、用户权限等问题是安全可靠的。PHP 与 HTML实际编写的时候,通常采用的方式是建立扩展名为 php 的文件(网页文件本质上是文本文件)。编写 php 代码和编写 html 代码并没有多少区别,而最方便的地方在于,在一个 php 文件中,两种代码是可以混编的。规则:php 代码需要包含在 &?php ... ?& 标签中,就像这样:&?php
// code goes here
?&提示:这是一个 php 和 html 混编的较为生动的例子。&?php
if ($var == true):
&html id=&ie6&&
&html id=&ie8&&
?&这里的意思是,如果 php 中的变量 $var 的值为 true,则放置一个标签,否则放置另一个标签。PHP 的 if 语句可以像上面那样写,也可以写成C/C++风格的:&?php
if ($var == true) {
// do something
// do other things
?&关于 PHP 中的操作符PHP 采用的操作符和 C/C++ 是类似的,例如用 = 表示赋值,== 表示相等性比较,以及 & 和 & (小于、大于)比较符、! 取反、&&逻辑与、||逻辑或等。当然,也支持 +-*/ 等数学表达式的运算。关于 PHP 中的变量PHP 中变量的命名一律以符号 $ 开头,可以使用下划线,例如 $is_logged_in 就是一个表意清晰的变量名。和大多数编程语言不同,PHP 中变量没有类型的概念,而且不用声明就可以直接使用。虽然很爽,但是变量多了的时候也容易混乱,这一点需要特别注意。关于 PHP 中的语句这一点 PHP 和许多其他常见的编程语言很类似,也可以用 if...else 选择语句(之前已经见过了),PHP 还包括 while 循环、foreach 循环等,以后遇到了会详细介绍。MySQL 基础使用 MySQL 数据库是存储数据的一种方法,MySQL 需要和 PHP 配合来完成对数据库的查询(这里术语“查询”包括写入、更新、读取等)操作。利用 MySQL,你可以创建许多数据库(database),每个数据库可以包含多个表(table),而每个表包含若干字段。为了高效,一般会采取分类维护多个表的方式,而不是把所有数据都储存在同一个表中。MySQL 需要服务器支持。使用的第一步是建立一个数据库,可以用相应的图形化工具(例如 phpMyAdmin)来建立数据库,也可以在终端直接使用下列 SQL 语句来创建一个名为 database_name 的数据库:CREATE DATABASE database_name;创建好数据库之后,需要创建表。可以通过下列 SQL 语句来创建一个名为 table_name 的表:USE database_name;
CREATE TABLE table_name (
first_name varchar(30),
last_name varchar(30),
);第一句说明在哪个数据库中添加表,第二个说明添加的表的详情。这里我们在表中添加了两个字段,分别叫做 first_name 和 last_name,它们的类型是 varchar(30)。其中 varchar 是一种可变长字符类型,而 30 代表了最大长度。其他常见的数据类型如下:VARCHAR(100) --可变字符
CHARACTER(1) --定长
INTEGER --整数
DECIMAL(10, 2) --小数(小数点前后的位数)
TIMESTAMP --日期和时间
DATE --日期你可能已经看出来了,MySQL 的注释符为 --。你可能觉得没太大用,但是它却是一种稍后要提到的攻击的关键之处。此外,一般字符串都应该使用变长的VARCHAR类型,而非定长的CHARACTER类型,因为后者会占据更多的空间,而这是不必要的。使 PHP 和 MySQL 协作第一种方式现在你已经创建好了 SQL 数据表,并对 PHP 语言有了一个概览。下面我们直奔主题,学习如何对数据表进行查询。为了使 PHP 和 MySQL 进行交互,需要为 PHP 提供你的数据库用户名、密码、数据库名和数据表名。当然,最重要的,查询操作的 SQL 语句。我们一一来观察是如何实现的。&?php
define('DB_HOST', 'localhost');
define('DB_USER', 'renfei');
define('DB_PASS', 'root');
define('DB_NAME', 'database_name');
$dbc = mysqli_connect(DB_HOST, DB_USER, DB_PASS, DB_NAME);
$query = &INSERT INTO table_name (column1, column2) VALUES ('value1', 'value2')&;
mysqli_query($dbc, $query);
?&下面来解释一下这一坨代码的工作原理。首先 3~6 行为 PHP 中的 define 语句,作用很明显,把 DB_HOST 定义为 localhost,下面的代码中就可以使用 DB_HOST 来代替 localhost。这样做的好处在于,如果mysqli_connect函数在代码中出现多次,修改参数的时候则只需修改 define语句,非常方便。然后是一个叫做 mysqli_connect() 的函数,它需要四个变量,分别是主机名、用户名、密码、数据库名。这个函数执行后的返回值传递给变量 $dbc,$dbc 包含了一次数据库连接。注意,这个变量名是任意的,并不强制要求叫做$dbc。然后,我们把要对数据库执行的操作对应的 SQL 语句以字符串的形式赋给变量 $query。这个变量名也是任意的。应该注意到,这里的 SQL 语句是不以分号结尾的。最后,我们执行 mysqli_query(); 函数,该函数有两个参数,分别是一个数据库连接,和一个 SQL 查询操作。执行该函数后,相应的查询操作被执行。如果把这些代码保存成一个网页,当用户打开网页的时候,如果各项参数正确,它就会完整地运行下去。这里的 SQL 语句的含义是向叫做 table_name 的表中插入一行,其中把 colume# 字段的值相应地设置为 value#。这里只设定了两个字段的数值(表中还可以有其他字段;没有显式说明的字段则留空或者使用数据表指定的默认值)。该语句的通用形式为:INSERT INTO table_name (column1, column2, ...) VALUES ('value1', 'value2', ...)如果你要做的仅仅是执行一个 SQL 语句,那么使用这种模式就可以完成。提醒一下,$dbc 变量往往是重复使用的。另一个常用的 SQL 语句就是修改某一行。它的形式为:UPDATE table_name SET
column1 = 'preferred_value1',
column2 = 'preferred_value2',
WHERE id = '$id'当然,这个语句应该是写到一行的,不过为了清晰我分开来写。它的含义是,修改名为 table_name 的表中字段 id 的值是变量 $id 的值的所有行,把 column1 字段的值设为 preferred_value1,把 column2 字段的值设为 preferred_value2,依此类推。这里我们还看到,值既可以用常量表示,也可以用变量表示。注意:会修改所有符合 WHERE 子句限定的条件的行(如果省略 WHERE 子句,就会修改所有行)。WHERE 子句可以设定多个条件,也可以使用比较运算符。例如:WHERE age & 20 AND gender = 'male'
WHERE is_admin = 'true' OR id = '$id'(如果你想问 AND 和 OR 为什么不是符号 && 和 || 的话,我想提示你,不要把 PHP 语言和 SQL 语言搞混了。这是 SQL 语言,而我只说过 PHP 语言和 C/C++ 有些类似)。下面介绍其他 SQL 语句。-删除table_name表中的所有行
DELETE FROM table_name
--删除table_name表中email字段为david@example.com的所有行
DELETE FROM table_name WHERE email = ''
--删除table_name表
DROP TABLE table_name
--删除table_name表中的score字段
ALTER TABLE table_name DROP COLUMN score
--给table_name表添加一个叫age的字段,类型为 INTEGER
ALTER TABLE table_name ADD COLUMN age INTEGER可见,第一种方式的本质就是编写一条 SQL 语句,然后通过 PHP 来执行它。下面,我们来看第二种方式。第二种方式有时,我们不满足于让服务器去执行一条 SQL 语句。我们会需要从数据库中查询信息,然后把得到的信息储存起来(其实就是储存在变量中)。这样,我们需要一些额外的工作。先看一坨代码:&?php
$dbc = mysqli_connect(DB_HOST, DB_USER, DB_PASS, DB_NAME);
$query = &SELECT * FROM table_name WHERE problem_id='$id'&;
$result = mysqli_query($dbc, $query);
$row = mysqli_fetch_array($result);
$problem_title = $row['problem_title'];
?&这里我们省略了 define 语句。这一坨代码和上一坨的主要区别是,我们使用了 mysqli_query() 函数的返回值,把它保存到 $result 变量中。这个 $result 变量里边保存的即为执行 SELECT 语句的返回结果。解释一下 SELECT 语句,它的作用是选取 table_name 表中符合 WHERE 子句条件的所有行。上面的语句会选定每一行的所有字段(通配符说明了这一点),并且把这些信息全部储存到变量 $result中。然后,用变量 $row 储存 mysqli_fetch_array() 函数的返回值。$row 这个变量非常神奇,$row['column_name'] 这个事儿包含的内容正是刚才选定的行的 column_name 字段的值(事实上,$row 正是一个数组)。这里,我们把它赋给了 $problem_title 变量。到这里你应该问一个问题:如果满足 WHERE 子句条件的有不止一行的话怎么办?要解答这个问题,需要稍微细致的讲解一下 $row 这个事儿。如果满足条件的只有一行,那么使用 $row = mysqli_fetch_array($result) 自然会把这唯一的一行信息储存到 $row 中。如果有很多行,那么第一次使用 $row = mysqli_fetch_array($result) 会把第一行的信息储存到 $row 中,而第二次使用 $row = mysqli_fetch_array($result) 会把第二行的信息储存到 $row 中。如果这时没有下一行了,再次调用的话 $row 会储存逻辑假(false 或 0)。类似,如果符合 WHERE 子句条件的一行都没有,那么执行后 $row 直接存储逻辑假。最后补充一点刚才没有提到的。如果不需要所有字段的数据,可以只选择需要的字段。方法是把原来 SQL 语句中的通配符换成字段名称。例如:SELECT problem_name, problem_type FROM table_name WHERE problem_id='$id'while 循环在 PHP 中的应用举例如果我们要把一个数据库的许多行信息都展示在网页中,那么需要用到 while 循环和上面的第二种方式。代码如下:&?php
$dbc = mysqli_connect(DB_HOST, DB_USER, DB_PASS, DB_NAME);
$query = &SELECT user_id FROM database_name ORDER BY user_id ASC&;
$result = mysqli_query($dbc, $query);
while ($row = mysqli_fetch_array($result)) {
$user_id = $row['user_id'];
echo &&tr&&;
echo &&td&&.$user_id.&&/td&&;
echo &&/tr&&;
?&如果有一定编程基础的话上面的代码很容易看懂。上面新出现了三种用法,说明如下:SELECT 语句可以附加一个 ORDER BY 子句,用来控制顺序。例如这里是按照字段 user_id 升序排列。下面的例子会先按照 user_rank 降序排列,user_rank 相同时按照 user_id 升序排列:SELECT user_id, user_rank FROM table_name ORDER BY user_rank DESC, user_id ASC关于 PHP 中的 echo 语句,它可以用来生成文本,类似于 C 中的 printf() 函数。这里利用它直接生成 HTML 代码。它的用法参考例子就可以了。关于符号 . 的用法,它的作用是连接字符串(和变量),往往和 echo 配合使用,用法参考示例。从表单获取信息概述这一部分我们演示如何构建一个表单,使用户填写这个表单并把内容储存到数据库。这一技术是用户注册系统和用户互动的基础。要实现这个功能,需要 HTML 和 PHP 配合完成。HTML 负责表单,而 PHP 负责获取信息并使用 SQL 查询储存信息。首先来看 HTML 部分(就是普通的表单):&form method=&post& action=&&?php echo $_SERVER['PHP_SELF']; ?&&&
&label for=&username&&用户名:&/label&
&input type=&text& id=&username& name=&username& /&&br/&
&label for=&info&&信息:&/label&
&input type=&text& id=&info& name=&info& /&&br/&
&input type=&submit& value=&Submit& name=&submit&/&
&/form&属于 HTML 部分的不再解释了,说一说新鲜的。这里的 action 属性后面的 $_SERVER['PHP_SELF'](严格地说,$_SERVER),是 PHP 的一个超级全局变量,内容是当前页面的相对路径,例如 signup.php。这个 action 属性的含义是指定用户填写的信息在哪里被处理,这里是在当前页面处理。一般的做法都是将负责处理这部分信息的 PHP 代码和 HTML 代码放在同一页面内。下面来看一下相应的 PHP 处理部分的代码:&?php
$dbc = mysqli_connect(DB_HOST, DB_USER, DB_PASS, DB_NAME);
if (isset($_POST['submit'])) {
$user = $_POST['username'];
$info = $_POST['info'];
$query = &INSERT INTO table_name (tb_user, tb_info) VALUES ('$user', '$info')&;
mysqli_query($dbc, $query);
echo &&p&提交成功&/p&&;
mysqli_close($dbc);
?&首先仍然是建立数据库连接。当用户点击 sumbit 按钮后,表单的内容会被储存在 PHP 中 $_POST 超级全局变量内,这个超级全局变量仍然是一个数组。isset() 函数用来检查变量是否被设置,只有用户点击 submit 后 isset($_POST['submit']) 才返回真,所以不用担心,首次加载表单(那时用户还没有填写任何内容)是不会执行这部分 PHP 代码的,只有用户提交之后才会执行。用户填写的具体内容可以用 $_POST['name'] 来获取。这里的 name 对应的是 HTML 中 name 属性的内容。这一段程序把用户填写的内容赋给变量,然后执行插入到数据库的操作。这里新出现了一个内容,就是 mysqli_close() 函数,它的作用是关闭数据库连接。当我们不再需要这个连接的时候,及时关闭是一个好主意。需要注意的是,这仅仅是最简单的代码,而且实际上是不完善的。如果要真正投入使用,我们需要使它更健壮一些。下面逐一讨论这些内容。检查用户输入是否合法如果用户根本没有填写表单,就直接点击提交按钮,会发生什么?在上面的实例中,PHP 依然会乖乖地把空内容插入,而这显然是垃圾信息,不是我们需要的。所以,需要在插入前检查被插入的变量是否为空。例如:&?php
if (!empty($user) && !empty($info)) {
// 插入操作
?&这里出现了 empty() 函数,用于检查内容是否为空。注意这里使用 isset() 是无效的,因为 isset() 检查的是是否“被设置”,而被设置为空也属于被设置。错误提示用户输入有误时,上面的改进除了不执行SQL查询,并没有多少直观上的变化。用户不会收到任何信息表明他们的填写是不合适的。所以我们要在这时产生一些提示,引导用户正确填写表单。&?php
if (!empty($user) && !empty($info)) {
// 插入操作
echo &请填写全部内容后再提交&;
?&防范 SQL 注入攻击我们执行的 SQL语句中包含变量,执行的时候会直接把变量内容替换进去。而如果攻击者在输入框中输入一些危险的字符(通常包含 SQL 注释符 --,以及其他预先精心设置的内容),就可能导致该次 SQL 查询完全被改写成攻击者需要的意思。为了防范这种攻击,我们需要对可能存在的危险字符进行过滤和转义,较为便捷的方法是使用两个函数。改进后的部分如下:&?php
$user = mysqli_real_escape_string($dbc, trim($_POST['username']));
$info = mysqli_real_escape_string($dbc, trim($_POST['info']));
?&粘性表单如果用户第一次填写失败,他们希望能保留已经填写好的内容,只做些修改就好了。这需要使用粘性表单技术。要实现,只需要稍稍改动 HTML 表单部分的代码:&label for=&username&&用户名:&/label&
&input type=&text& id=&username& name=&user& value=&&?php if (!empty($user)) echo $ ?&& &显而易见,如果用户填写后因为某些原因没有提交而是回到了这个表单,并且之前填写了 user 字段的内容,那么此时 $user 变量已经被赋值了。那么就会在 HTML 表单显示这些内容,避免用户再次输入。构造一个注册页面虽然上面说了很多,但是仅仅满足了我们最基本的输入要求。许多时候我们需要更为复杂的功能。举例来说,要写一个注册页面,必须检查用户名是否重复,还要对密码采取某种技术加密以保证安全。检查用户是否重复基本原理就是,根据需要判重的字段(例如用户名)去数据库搜索。如果发现结果则用户名重复,如果没有找到则允许注册。需要一个新函数 mysqli_num_rows(),返回 SELECT 语句得到的行数,根据其是否等于 0 进行判断。&?php
$dbc = mysqli_connect(DB_HOST, DB_USER, DB_PASS, DB_NAME);
$query = &SELECT * FROM table_name WHERE user_name = '$user'&;
$data = mysqli_query($dbc, $query);
if (mysqli_num_rows($data) == 0) {
// 把内容插入数据库
echo &注册成功&;
mysqli_close($dbc);
echo &用户名已被占用,请重新选择用户名&;
$user = &&;
?&把 $user 清空是为了配合粘性表单。需要说明的是 exit(); 函数,它会立刻终止 PHP 的运行。因为用户已经注册成功,没有必要执行后面的任何代码,所以使用这个函数。写自己的程序的时候可以亲自试验是否需要这一行、PHP 和 HTML 在 php 中的顺序不同有何影响。我通常的做法是把 PHP 代码放在前面,HTML 代码放在后面。对密码进行加密存储明文存储密码是对用户很不负责的,不仅数据库管理员可以看到密码,一旦数据库泄漏,密码就会被公开。所以,我们应该加密存储用户密码。在 PHP 中,可以使用 sha1() 函数进行加密(sha 即 secure hash algorithm 的首字母缩写),它是一种不可逆的加密,加密后会生成定长的一段字符串,并且是无法由这段字符串还原原密码的。加密的原理是,用户输入密码后,利用 PHP 把 hash 过的密码储存在数据库中。用户登陆的时候,把用户输入的密码进行 hash 运算,之后和数据库中的进行比对。使用方法如下:sha1($password)识别用户登录:Cookie只注册没有用,必须添加登录功能。登录功能可以使用 Cookie 来实现。这里假定你已经了解 Cookie 的基础知识,只说如何实现。设置 Cookie&?php
setcookie('user_type', $user_type, time() + (60 * 60 * 24 * 30));
?&上面的代码用来设置 Cookie,其中函数的第一个参数为 Cookie 名称,第二个参数为数值(这里用一个变量传递),第三个参数为过期时间,单位秒。示例为一个月。可以用设置多个 Cookie 来存储许多内容,例如用户 ID、用户组(管理员还是普通用户)等。验证 Cookie用户登陆后,我们可以设置一个 Cookie 来存储登录信息(即哪个用户登陆的),然后通过检查这个 Cookie 来设定相应功能。&?php
if (isset($_COOKIE['user_type'])) {
$user_type = $_COOKIE['user_type'];
?&删除 Cookie要删除 Cookie,只需要把过期时间设定在过去。&?php
setcookie('user_type', '', time() - 3600);
?&不要问我为什么设定在过去一个小时,设定几个小时都没问题。Cookie 的安全性设置 Cookie 有其潜在的危险。由于 Cookie 是保存在用户本地的,所以用户完全可以通过篡改 Cookie 来达到他们的目的。所以,把 Cookie 的值设置得“通俗易懂”不是一个好主意。例如,我们要用 Cookie 来保存登陆的用户名,如果单纯把这个用户名存入 Cookie,那么攻击者会很容易通过修改成他人的用户名来伪造 Cookie 登陆。所以,我们需要其他的手段来防止这一点。我的做法是,用户注册的时候,把用户名按一定手段进行变换,然后使用 SHA() 函数加密生成一个用户密钥,然后把这个密钥储存进数据库。登陆时,再把这个密钥存储到 Cookie 中,通过检查 Cookie 中的密钥和数据库中用户密钥的匹配情况判定是哪位用户登录。这样,只要你的用户名变换方法不泄露,攻击者就很难按他们的想法伪造 Cookie。使用 GET 方法在网页间传递信息除了刚才介绍的 POST 方法外,还有 GET 方法。GET 方法是通过 URL 来完成信息传递的。例如,构造下列网址:http://www.renfei.org/index.php?id=2
网址最后有 ?id=2 标记。这个信息会储存在$_GET['id'] 这个超级全局变量中,并且可以在 PHP 中使用:&?php
if (isset($_GET['id'])) {
$id = $_GET['id'];
// code goes there
?&这个例子中我们把 2 赋给了变量 $id。当然,也可以构造这样的网址:http://www.renfei.org/index.php?id=2&message=10
除了多一个可以使用的 $_GET['message'] 以外没有任何不同。这个特性的用处之一就是可以根据网址的不同,配合数据库查询,返回不同的网页内容。例如我做的在线问答系统,就是根据 problem_id 来返回不同题目的。注意,由于 GET 方法的数值是不可靠的(用户可以手动构造 URL 来传递他们想要的参数),所以应该仅仅用它来做一些无关痛痒的事情(例如显示不同的页面内容)。这里我并没有强调 GET 方法的数值是“透明”的:虽然 POST 方法的数值不会显示在 URL 中,但是它还是会通过 HTTP Header 发送到服务器,用许多插件和小工具都可以查看 HTTP Header 信息。另外,如果你的表单是用来上传文件的,那么估计你会更喜欢 POST 方法:因为
GET 方法得到的 URL 可能会很长,甚至超过浏览器的限制!使用模板最后一部分,来讲一下使用模板构造一个网站。事实上,网站的每个页面中,有许多部分是完全相同的,例如数据库连接常量(就是那些define语句)以及每一页的 header 和 footer 部分等。这样,我们没必要在每一页内写相同的代码。除了麻烦和浪费空间以外,还有一点很重要的原因,就是修改的时候工作量很大。PHP 中 require_once 语句作用就是把其他文件的内容插入此处。例如,我们可以创建一个define.php,把define语句全部写到里面,并在每个页面顶部添加如下语句:&?php
require_once &define.php&;
?&这样一来,会把 define.php 中的内容插入当前位置。同理,我们可以建立一个 header.php 和 footer.php,写好页面的头部、底部之后在每个其他页面导入就可以了。PHP的错误处理分级的错误信息最后来讲一下 PHP 的错误处理机制。如果你写了有错误的 PHP 代码,那么运行的时候系统会自动生成一些错误提示信息并且打印到屏幕上,以提醒用户修复。通常,这些错误信息是分级的。首先,是 notice。如果屏幕出现了 notice: (...) 的提示说明你有需要修复的小问题(你没有完全按照规则进行),不过问题不大,代码还是会继续执行完毕。而 warning 则更严重一些,如果出现 warning,你可能需要思考一下你是否真的知道自己在做什么,并作出修改。但是,程序仍然会运行。如果出现了 error,那么 PHP 是在跟你说:你是个白痴;这种代码无法执行,程序的运行会中止。在写 PHP 程序的时候,我们需要这些错误提示来帮助我们改正错误,但是当产品发布的时候,开发人员往往倾向于隐藏错误提示:用户收到这些信息是很让人恼火的,而且,让他人知道你的代码有什么漏洞总归不是一个好主意,因为这可能被某些图谋不轨的攻击者加以利用。Suppression Operator有时,为了代码的简洁性考虑我们可能会故意犯一些无关痛痒的小错误。例如,如果 $_GET 中的某一个元素不一定总会被提交到 PHP,那么理论上应该使用 isset() 函数来进行检测。但是,如果你觉得到处使用这个函数太麻烦了,可以省略 isset() 函数而直接使用这个元素,只不过如果它没有被设置的话会返回一个 notice 错误信息(类似于 C/C++ 中的变量未声明)。这时,为了忽略这一条信息,可以使用错误抑制操作符 @。例如:&?php
if (@$_GET['opt']) {
// code goes here...
?&其他提示尽管没有特别强调,但是有几个函数是需要灵活掌握和使用的,例如 exit()。它可以立刻结束 PHP 程序的运行。例如,有的页面需要一定用户权限才能访问,则可以把验证权限的代码放在页面顶端,如果验证失败则显示错误信息并调用 exit() 函数。当一个 SQL 连接的使命完成后,不要忘了用 mysqli_close() 关闭它。设计 SQL 数据库的结构是一件非常重要的事情,设计的原则是高效且便于查询。一旦你的数据库充满各种信息,再想更改它的结构就会变得有些困难。SQL 的知识这里介绍得不多。它有许多特性,比如默认值、主键等。默认值的意思是如果不设定,那么该字段采用默认值;主键则规定该字段每行是不能重复的。默认值除了固定字符以外,还可以设定为时间,甚至自增。例如,要建立一个用户数据库,为每个用户分配一个唯一 ID,则可以把数据库中的 ID 字段设为 AUTO INCREMENT,这样每次不用手工维护这个字段,只要新增一行,这个字段的数值就增 1(默认从 1 开始),很方便。 一般会把这种 ID 字段设为主键。本来打算简要介绍一下 PHP 和 MySQL 的,但是一写就是 7000 字。即使如此,本文介绍的所有特性也仅仅是构建一个动态网站最基本的知识,而且许多非重要的知识并没有介绍。你应该通过书籍更深入地学习。额外推荐 PHP 的文档,对新手非常友好,值得一看:&来自话题&&/&相关文章讨论Please enable JavaScript to view the comments powered by Disqus.

我要回帖

更多关于 前端页面与数据库交互 的文章

 

随机推荐