Chinaunix首页 | 论坛 | 博客
  • 博客访问: 19279426
  • 博文数量: 7460
  • 博客积分: 10434
  • 博客等级: 上将
  • 技术积分: 78178
  • 用 户 组: 普通用户
  • 注册时间: 2008-03-02 22:54
文章分类

全部博文(7460)

文章存档

2011年(1)

2009年(669)

2008年(6790)

分类:

2008-05-17 08:54:22

连接

前两章中集中介绍了PHP语言,现在停下来开始创建一个应用程序。在本章中将创建一个连接MySQL数据库的应用程序。
  
  
在过前面两章之后,你肯定已经学会了怎样处理PHP内部数据,以及怎样编写语句和函数。下一步从逻辑上讲,应该到了学习如何用SQL(结构化查询语句)处理PHP的外部数据的时候了。但是,在开始学习这部分内容前,让我们暂时中断基本原理的学习,放松一下。
  
让我带你一道探究PHP应用程序的开发历程。从字面意义上讲,每一个应用程序都应该是独特的,但是每一个应用程序也都能在此前的基础上,即一系列通用功能的基础上构建。我建议将这两项混合在一起。盲目地使用前人已编写好的功能,会剥夺在程序中加入新特色,还会阻止为提高函数的效率而去修改旧函数。从另一方面讲,使用已有函数意味着能更快的开发出应用程序。所以必须在这两个极端中把握好自己,才能成为一个优秀的程序设计员。
  
  
注意:如果现在还对HTML不熟悉,那么现在就是开始学习的时间了。本书中假定你已经熟悉HTML了。如果还不熟悉HTML表格和表单的话,很快就会被搞糊涂的。
  
  5.1
开端
  
每当开始一个新项目时,我喜欢从一个新的空目录开始。在这里,让我们把这个目录称为phpbook/ch05。当然,这个目录必须在Web服务器的根目录下。如果你是按照第一章的指令安装PHP的话,那么,Web服务器的根目录就应该为/usr/local/apache/htdocs。接着,我们将创建一个名为menu.php3的文件,其中包含有一个后台管理任务菜单,如清单5.1所示。
  
  
清单5.1 menu.php3
  php
require('common.inc'); ?>
  php affy_header('Administrative Menu') ?>
  

Administrative Menu


  <ol>
  <li>href="connect.php3">Creat Database
  Connection
li>
  ol>
  php affy_footer() ?>
  
  在文件common.inc中包含对函数affy_headeraffy_footer的定义。这些函数在本章中稍后还会出现。
  5.2
创建连接
  
当点击Create Database Connect(创建数据库连接)联接时,将会执行connect.php3文件,该文件将尝试连接在第二章学习中安装的MySQL数据库服务器。
  
清单5.2 显示了connect.php3文件使用用户名codebits和密码codebits尝试进行数据库连接,因为在安装MySQL时还没有创建该用户名,所以连接肯定失败。然而失败 -- 最起码在本例中 -- 却是一件好事,因为我们可以看看应该如何处理这个问题。图5.1给出了连接失败后将会显示的错误信息和表单。
  
  
清单5.2 connect.php3
  
  Page 107 -108
清单 5.2
  
  
  Page 108 Figure 5.1
  
  
5.1 连接失败时的错误信息显示
  
  
当数据库连接失败时,程序会给出一个错误信息提示和一个表单,用户可以在里面输入root用户的密码。就像在本章稍后讲的那样,有了root的密码,就可以创建名为codebits的用户。现在先跳过有关$arr_request数组的部分。
  
当函数mysql_connect被调用且连接失败时,该函数通常会显示如下信息:
  
  Warnint: MySQL connection Failed: Access denied
  for user: 'codebits@localhost' (Using password: YES)
  
  
绝大多数应用程序需要精确的控制显示的内容,尤其是高度图形化的应用程序。在函数mysql_connect前加上(@)符号将会抑制错误信息的显示。
  
注意表单语句的action属性指定点击submit按钮时,将会执行connect.php3文件。这是一个递归程序的例子,也就是说允许PHP文件调用它自己。
  
应用递归编程技术,可以将有关同一个主题的所有编制在同一个文件中。至于什么时候应该将函数组合成一个文件,或将程序分解成几个文件,这得凭经验。我的首要原则是:当实现一个特定功能所编的程序代码超过100行以上时,就要创建一个独立的文件。
  
  5.3
获取HTML表单信息
  
即使输入一个密码并点击连接数据库,连接仍然会失败,原因是connect.php3还没有使用表单中的输入值去建立数据库连接。
  PHP
引擎将每一个表单域放到一个叫做$HTTP_POST_VARS的数组中。在上述给出的例子中,数组有两个元素:usernamepassword。在此程序中可以通过$HTTP_POST_VARS['username']$HTTP_POST_VARS['password']访问表单信息。
  
使用$HTTP_POST_VARS['password']获得表单中的信息看起来比较简单。但是仍有一些隐藏的问题。首先,要检查表单域的名字(本例中的password)是大写、小写、还是大小写都有。
  
第二件问题包含的内容与本例关系不大。除了表单以外,还可以使用URL来运行PHP脚本,例如:
  
  root&password=password
  
  
可以看到,用户名和密码通过URL进行传递,问号标志着域信息的开始,“&”则是域的定界符。幸运的是,PHP引擎也自动分析URL行,并将结果存入$HTTP_GET_VARS数组中。
  
问题(如果你认为它是的话)在于,程序可以从不止一个地方获得信息 -- 数组$HTTP_GET_VARS和数组 $HTTP_POST_VARS
  
对待这些(或其它一些的)问题,我的解决办法是创建一个名为$arr_request的数组,它从两个$HTTP数组中获得初始化的信息。在common.inc中可以使用如下编码行对数组$arr_repuest进行数值初始化。
  
  // declare the request array which holds both
  // url-based (get) and form-based (post) parameters.
  $arr_request = array();
  
  // move the url and form parameters into the
  // request array. Form parameters supercede url
  // parameters. Additionally, all keys are vonverted
  // to lower-case.
  If (count($HTTP_GET-VARS)) {
  While (list($key, $value) = each ($HTTP_GET_VARS)) {
  $arr_request[strtolower($key)] = $value;
  }
  }
  if (count($HTTP_POST_VARS)) {
  while (list($key, $value) = each ($HTTP_POST_VARS)) {
  $arr_request[strtolower($key)] = $value;
  }
  }
  
  
如果在所有的PHP脚本中都包含有common.inc文件的话,那么不用担心脚本是怎么运行的。所有传过去的信息都以小写形式保存在数组$arr_request中,这就意味着,可以使用$arr_request['username']得到用户名信息。
  PHP
提供了数组$HTTP_GET_VARS和数组$HTTP_POST_VARS的替代方式,HTML表单和基于URL的信息都可以直接做为PHP变量进行访问。例如,在PHP 脚本中,一个定义为的域信息可以直接在PHP程序中用$last_name访问,同样的基于URL的信息,比方说,http://=join,能由$last_name获得。不过,我还是比较喜欢使用数组$arr_request,因为对于要循环使用传递给程序的所有信息来讲,这是非常有用的。如果该信息是一个标量,那么它就不适合被循环使用。例如:将所有参数名改为大写,以保证不致于因为使用换档键而破坏程序;或者在错误检测时,会需要显示所有的输入参数。
  
  
注意:本节只对CGI(通用网关接口)协议作很简单的介绍,更详细的内容请参阅本书附录A因特网资源中所列内容。
  
  5.4
使用HTML表单信息
  
既然可以很容易地从PHP脚本程序中存取表单信息,现在是利用这些信息连接数据库的时间了。第一步是检查连接数据库的代码:
  
  $id_link = @mysql_connect('localhost', 'affy', 'affy');
  
  
在这行代码中,用户名和密码都是字符串数值。为了能利用表单中的信息,这行代码需要加以变动,用变量代替数值:
  
  $id_link = @mysql_connect(
  'localhost',
  $username,
  $password);
  
  
既然用到了变量,那么必须对变量进行初始化。以下代码将执行这种初始化:
  
  if ( count($arr_request) ) {
  $username = $arr_request['username'];
  $password = $arr_request['password'];
  }
  else {
  $username = 'phpuser';
  $password = 'phpuser';
  }
  
  
当表单信息可用时,函数count的结果将大于1,使得if语句执行真条件的子句,此子句依次从$arr_request数组中取出用户名和密码信息。
  
当没有表单信息存在时,用户名和密码仍可以用字符串数值进行初始化。
  
第三种可能性是一个表单有这两个域但没有表单信息。如果调用connect.php3的表单没有usernamepassword域,会发生什么情况呢?如果这样,以上代码将失败。通过直接检查表单字段,而不是只依赖于$arr_request数组的元素数目可以让这段代码的更强壮(即,能处理这种环境下的失败)。例如:
  
  $username = $arr_request['username'];
  $password = $arr_request['password'];
  
  if (empty($username)) $username = 'phpuser';
  if (empty($password)) $password = 'phpuser';
  
  
因为PHP对没有初始化的数组元素将返回空字符串,以上代码的适应性将更强。使用标量比使用数组可以使代码更容易理解,并且在某些方面更有效率。如果这两个变量有一个为空时,这意味着表单没有提供任何值,将使用缺省值。
  
清单5.3显示了有以上更改的connect.php3文件,可以在上下文看到这两个变化的描述。
  
  
清单5.3 connect.php3修订版
  
  Page 112 - 113
清单 5.3
  
  
  
当正确的root密码如图5.2所示被输入到表单时,将会成功地建立数据库连接。
  
  
  Page 113, Figure 5.2
  
  
5.2 证实成功地建立了数据库连接
  
  5.5 common.inc
文件
  
清单5.4显示了本章需要的common.inc文件的版本。
  
  
清单5.4 common.inc--多个应用程序使用的一套例程。
  php

  function affy_footer() {
  echo ' ';
  }
  
  function affy_header($title) {
  echo ''; <BR>  echo "$title"; <BR>  echo '';
  }
  
  function affy_message($msg) {
  echo '';
  echo '<tr>tr>';
  echo '
';
  echo "$msg";
  echo '
';
  }
  ?>
  
  5.6

阅读(342) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~