继续后面的内容之前,需要对 MySQL 做一点准备工作。需要创建数据库、添加表和创建访问它的新用户。
在 MySQL 控制台中输入以下内容:
create database workflow;
use workflow;
create table users (id int auto_increment primary key, username
varchar(50), email varchar(255), password varchar(50));
show tables;
最后的结果看起来类似于:
+--------------------+
| Tables_in_workflow |
+--------------------+
| users |
+--------------------+
1 row in set (0.00 sec)
最后添加新用户 wfuser
,口令为 wfpass
:
GRANT ALL PRIVILEGES ON *.* TO 'wfuser'@'localhost'
IDENTIFIED BY 'wfpass' WITH GRANT OPTION;
然后我们来使用这个数据库。
连接 MySQL
如果不与某种形式的数据库交互,那么创建任何较大的 Web 应用程序基本上是不可能的。在这个示例应用程序中,我们将使用 MySQL 数据库保存用户名和口令信息。这一节将在注册页面中添加必要的功能,以检查提交的用户名是否惟一,如果是惟一的,则将其添加到表中。还可以查看已经显示在数据库中的信息。最终我们将创建应用程序登录页面。
首先要连接到数据库。PHP 有一些函数完全是用于处理 MySQL 数据库的,这一节中将用到它们。
第一步是创建一个函数,以连接到 设置 一节中创建的工作流数据库:
...
return $message;
}
function db_connect($user='wfuser',
$password='wfpass', $db='workflow'){
mysql_connect('localhost', $user, $password)
or die('I cannot connect to db: ' . mysql_error());
}
foreach ($_POST as $key=>$value) {
echo "<p>".$key." = " . $value . "</p>";
}
...
if (validate($_POST) == "OK") {
echo "<p>Thank you for registering!</p>";
db_connect();
} else {
echo "<p>There was a problem with your registration:</p>";
...
这里建立了一个函数 db_connect()
,该函数将尝试打开 PHP 和 MySQL 数据库之间的连接。要注意该函数的定义,其中包含了一些参数值。这些是默认值,也就是说,如果不提供用户名、口令和数据库名,那么 PHP 将使用这些值(实际上很快就要这样做。)
该函数尝试连接到本地机器 localhost
上的数据库。要注意的是,在这个例子中,“本地机器”指的是对 PHP 服务器而言的本地机器,因此,本地机器指的是 Web 服务器而不是客户机。
如果 PHP 打不开连接,那么处理将终止(或者死掉),PHP 只显示一条消息,说明遇到了什么情况。
假设一切正常,那么该连接将一直处于打开状态,直到您关闭它,或者完成该页面的处理。发出的其他所有数据库命令都被定向到该连接。
最后还需要调用该函数来执行这些操作。
选择数据库
一个 MySQL 数据库服务器可能有多个数据库,因此打开到服务器的连接之后,还需要指定连接的数据库:
...
function db_connect($user='wfuser',
$password='wfpass', $db='workflow'){
mysql_connect('localhost', $user, $password)
or die('I cannot connect to db: ' . mysql_error());
mysql_select_db($db);
}
...
现在,这个函数可以用于连接本地服务器上的任何 MySQL 数据库。实际上,该函数的一大优点就是这一点,从某种意义上说,这个优点是与数据库无关的。您不仅可以改变数据库的名称,还可以更改将要访问的数据库类型,而且所有修改都在这个函数中完成。
现在可以准备插入用户数据了。
插入记录
现在可以向前面创建的用户表中添加数据了。为此需要创建一个向该表插入数据的 SQL 语句,然后执行该语句。
该语句的形式如下:
insert into users (username, email, password) values
('roadnick', 'ibmquestions@nicholaschase.com', 'supersecretpassword')
如果在创建表时特别注意,您可能会奇怪 id
列是干什么的。可以指定第一列为 AUTO_INCREMENT
,因此如果不去考虑它(正像我们这里所做的那样),那么 MySQL 将自动向其中填入下一个可用的整数。因此,您在这里必须做的事情是,使用用户提交的数据替换占位符,并执行以下语句:
...
if (validate($_POST) == "OK") {
echo "<p>Thank you for registering!</p>";
db_connect();
$sql = "insert into users (username, email, password) values
('".$_POST["name"]."', '".$_POST["email"]."', '".$passwords[0]."')";
$result = mysql_query($sql);
if ($result){
echo "It's entered!";
} else {
echo "There's been a problem: ".mysql_error();
}
} else {
echo "<p>There was a problem with your registration:</p>";
...
注意,调用 mysql_query()
函数时返回的值保存在 $result
变量中。如果操作成功,则该值将是 true,如果出现问题,则为 false。然后可以使用该值作为 if-then 语句的表达式,根据结果执行不同的操作。
如果出现问题,MySQL 将为 mysql_error()
函数设置一个返回值,然后可以将这个值输出到页面。
现在已经在数据库中添加了信息,下一步则是查看存储的信息。
选择记录
现在可以向数据库中添加数据了,但是如何知道用户名是否惟一呢?目前还不知道,但是可以通过在执行插入之前检查用户表来加以补救:
...
if (validate($_POST) == "OK") {
echo "<p>Thank you for registering!</p>";
db_connect();
$sql = "select * from users where username='".$_POST["name"]."'";
$result = mysql_query($sql);
if (!$result) {
$sql = "insert into users (username, email, password) values
('".$_POST["name"]."', '".$_POST["email"]."', '".$passwords[0]."')";
$result = mysql_query($sql);
if ($result){
echo "It's entered!";
} else {
echo "There's been a problem: ".mysql_error();
}
} else {
echo "There is already a user with that name: <br />";
$sqlAll = "select * from users";
$resultsAll = mysql_query($sqlAll);
}
} else {
echo "<p>There was a problem with your registration:</p>";
...
首先创建一个 SQL 语句,该语句将选出拥有与打算插入的用户名匹配的用户名的所有记录。与插入语句一样,也可以对数据库执行该语句。如果该语句返回的结果不为空,则 mysql_query()
返回一个结果为 true 的值,否则返回 false。
现在我们不希望存在这样的用户名,因此希望 $result
的值为 false。但如果使用的是 if-then 语句的话,那么希望获得的将是 true 语句,而不是 false 语句。因此要使用取反运算符,即叹号,其含义为“如果该值的反是 true,则应该做什么”,在这里,所谓做什么是指将数据插入数据库。
但是,如果 $result
为 true,那么该怎么做呢?如果 $result
的反是 false,则执行 else 语句。最后我们将列出已有的用户名和邮件地址,因此,首先要创建并执行这样的 SQL 语句。
然后是检索结果。
检索结果
当然,在现实中,如果输入了已经存在的用户名,则绝对不需要显示已有的用户名,不过,在这里这样做是为了说明如何完成这类工作。
上一节中创建了一个 SQL 语句,以便从用户表中选择所有记录,并把结果存放在 $resultsAll
变量中。现在要从该变量中检索数据:
...
} else {
echo "There is already a user with that name: <br />";
$sqlAll = "select * from users";
$resultsAll = mysql_query($sqlAll);
$row = mysql_fetch_array($resultsAll);
echo $row["username"]." -- ".$row["email"]."<br />";
}
...
检索数据的第一步是从 $resultsAll
中取出一行,它实际上是表示整个数据集的资源。mysql_fetch_array()
函数正如其名称所指示的那样,返回包含某一行中数据的关联数组。键和列名相同,因此,通过从 $row
数组中请求适当的值,很容易输出这一行中的数据。
不过该例中只有一行,如何访问所有数据呢?
查看所有的结果:while
循环
如果在第一次检索中,至少有一行可供检索,那么在 if-then 语句(或者后面使用的 while 语句)中, $row
将显示为 true。当 PHP 遇到 while
($row
) 语句时,它会说,“哦,该表达式的值是 true,那么执行这一段代码吧。”于是输出这一行数据,然后再提取另一行,又回到循环的顶端。
...
} else {
echo "There is already a user with that name: <br />";
$sqlAll = "select * from users";
$resultsAll = mysql_query($sqlAll);
$row = mysql_fetch_array($resultsAll);
while ($row) {
echo $row["username"]." -- ".$row["email"]."<br />";
$row = mysql_fetch_array($result);
}
}
...
如果检索另一行成功,那么 $row
将再次为 true,循环再次执行。如此反复,直到没有剩余的行为止,mysql_fetch_array()
返回 false。现在,PHP 知道要跳出循环执行脚本中剩下的语句。
顺便说一下:如果忘掉最后一步,即检索另一行,那么 $row
将一直为 true,服务器不停地运行该循环,直到内存溢出或者超时为止。因此,创建这类循环时,首先应该添加的语句就是递增要遍历的对象。
关闭数据库连接
继续下一步之前,一定要关闭打开的数据库连接:
...
if (validate($_POST) == "OK") {
echo "<p>Thank you for registering!</p>";
db_connect();
$sql = "select * from users where username='".$_POST["name"]."'";
$result = mysql_query($sql);
if (!$result) {
...
}
mysql_close();
} else {
...
现在就等着整理了……