发新话题
打印

Zend 框架学习之模型-视图-控制器及添加数据库篇

推而广之:创建一行

因为要直接执行一个 SQL 语句,所以如果您选择使用不同类型的数据库就会遇到一些问题。Zend_DB 类的一个要点是代码应该一次性编写完成,并用 Zend 框架支持的任何数据库运行之。这需要使用一些 Zend_Db 函数。例如,我们可以从提交的表单中提取数据并将其转入一个行对象,如清单 14 所示。


清单 14. 创建一行
复制内容到剪贴板
代码:
...
    function createAction()
    {
        $params = array(
            'host' => 'localhost',
            'username' => 'chompuser',
            'password' => 'chomppassword',
            'dbname' => 'chomp'
        );

        $DB = Zend_Db::factory('pdoMysql', $params);

        $row = array(
            'firstname' => $_POST['fName'],
            'LastName' => $_POST['lName'],
            'EmailAddress' => $_POST['email'],
            'Username' => $_POST['user'],
            'Password' => $_POST['pass']
        );

    }
...
如您所知,行只是一个联合数组。现在将其插入数据库中。

TOP

将数据插入数据库

这实际上非常简单。


清单 15. 插入数据
复制内容到剪贴板
代码:
...
    function createAction()
    {
        $params = array(
            'host' => 'localhost',
            'username' => 'chompuser',
            'password' => 'chomppassword',
            'dbname' => 'chomp'
        );

        $DB = Zend_Db::factory('pdoMysql', $params);

        $row = array(
            'FirstName' => $_POST['fName'],
            'LastName' => $_POST['lName'],
            'EmailAddress' => $_POST['email'],
            'Username' => $_POST['user'],
            'Password' => $_POST['pass']
        );

        $table = 'users';
        $rowsAffected = $DB->insert($table, $row);        

    }
...
我们仅为表格指定了名称,并将此名称和行传给 insert() 函数。

TOP

查看结果

您可以打开新的命令窗口,键入 mysql -u root -h localhost(当然要使用您自己的值)来查看此操作的运行结果。您会看到如下所示的结果。


清单 16. 数据
                    
+-----------+----------+----------------------+----------+----------+
| firstName | lastName | emailAddress         | username | password |
+-----------+----------+----------------------+----------+----------+
| Nick      | Chase    | nchase@earthlink.net | roadnick | mypasswd |
+-----------+----------+----------------------+----------+----------+
1 row in set (0.00 sec)



我们了解了如何向数据库中输入数据,那么现在来看一下如何从中获取数据。

[ 本帖最后由 TigerChou 于 2007-9-10 15:54 编辑 ]

TOP

重新获取并更新数据

将数据输入数据库是很有用的,但前提是要能够再次从中获取数据。在这一部分中,我们来了解登录及更新注册信息的函数。

登录行为

登录行为仅仅显示了一个像视图一样的表单,如下所示。


清单 17. 登录视图
复制内容到剪贴板
代码:
<html>
<body>
<p><strong>Chomp Login</strong></p>
<form name="login" method=\
"post" action="/user/authenticate">
  <p>Username
    <input name="username" type="text" id="username">
</p>
  <p>Password
    <input name="password" type="password" id="password">
</p>
  <p>
    <input type="submit" name="Submit" value="Submit">
  </p>
</form>

<p>If you don't have an account yet, please <a
href="/user/register">register here</a>. </p>

</body>
</html>
将这些数据放入一个文件,并以 login.php 作为文件名将其保存在 views 目录中。从登录行为中调用此视图即可显示这个文件。


清单 18. 显示登录表单
复制内容到剪贴板
代码:
<?php
require_once 'Zend/Db.php';

Zend::loadClass('Zend_Controller_Action');
Zend::loadClass('Zend_View');

class UserController extends Zend_Controller_Action
{
    function indexAction()
    {
        echo 'This is the loginAction.';
    }

    function loginAction()
    {
        $view = new Zend_View();
        $view->setScriptPath('views');
        echo $view->render('login.php');
    }
   
    function authenticateAction()
    {
        echo 'This is the authenticateAction.';
    }
...
现在将浏览器转到 http://localhost/user/login,就可以看到登录表单。

TOP

处理登录

处理登录涉及到从数据库中提取适当的信息并将这些信息与用户输入的信息进行比较。


清单 19. 处理登录
复制内容到剪贴板
代码:
...
    function loginAction()
    {
        $view = new Zend_View();
        $view->setScriptPath('views');
        echo $view->render('login.php');
    }
   
    function authenticateAction()
    {
        $params = array(
            'host' => 'localhost',
            'username' => 'chompuser',
            'password' => 'chomppassword',
            'dbname' => 'chomp'
        );

        $DB = Zend_Db::factory('pdoMysql', $params);

        $select = $DB->select();
        $select->from('users', '*');
        $select->where('Username = ?', $_POST['username']);
        $select->where('Password = ?', $_POST['password']);
        $sql = $select->__toString();

        echo $sql;

    }

    function logoutAction()
...
在本例中,我们像以往一样连接数据库,但不仅是执行一个简单的 select SQL 语句,而是创建一个检索一切数据的 select 对象,并过滤出适当的用户名及密码。为确保提取了适当的数据,我们可以通过调用 __toString() 方法来输出 SQL 语句。

一但确认了查询内容的正确性,就可以执行了。

TOP

执行查询

构建查询后,需要对数据库执行此查询,如下所示。


清单 20. 执行查询
复制内容到剪贴板
代码:
...
    function authenticateAction()
    {
        $params = array(
            'host' => 'localhost',
            'username' => 'chompuser',
            'password' => 'chomppassword',
            'dbname' => 'chomp'
        );

        $DB = Zend_Db::factory('pdoMysql', $params);

        $select = $DB->select();
        $select->from('users', '*');
        $select->where('Username = ?', $_POST['username']);
        $select->where('Password = ?', $_POST['password']);
        $sql = $select->__toString();

        $rowsFound = $DB->fetchAll($select);
        if (isset($rowsFound[0]["username"]))
        {
           $this->_redirect('/');
        }
        else
        {
           echo "Login information incorrect. Please <a
href='/user/login'>try again</a>.";
        }

    }
...
fetchAll() 函数检索所有满足 select 语句的记录并将其放入一个二维数组。其中第一维是行,第二维是列。因而表达式 $rowsFound[0]['username'] 引用了所找到的第一行的 username 列(参见图 19)。

当然,如果用户名和密码与数据库中的信息相匹配,系统只会找到一行。如果这样的话,我们将用户重定向到主页。(稍后,我们会进一步深入探讨。)

如果找不到记录,我们让用户再试一次。

TOP

设置会话信息

如果 select 语句真正地检索到了一条记录,表明用户名和密码至少有一条记录同用户在登录表单中键入的内容相匹配。现在需要让网站了解到用户已登录。为此,需要设置会话变量,如清单 21 所示。


清单 21. 设置会话信息
复制内容到剪贴板
代码:
...
    function authenticateAction()
    {
        $params = array(
            'host' => 'localhost',
            'username' => 'chompuser',
            'password' => 'chomppassword',
            'dbname' => 'chomp'
        );

        $DB = Zend_Db::factory('pdoMysql', $params);

        $select = $DB->select();
        $select->from('users', '*');
        $select->where('Username = ?', $_POST['username']);
        $select->where('Password = ?', $_POST['password']);
        $sql = $select->__toString();

        $rowsFound = $DB->fetchAll($select);
        if (isset($rowsFound[0]['username']))
        {
           session_start();
           $_SESSION['RSS_SESSION'] = session_id();
           $_SESSION['firstname'] = $rowsFound[0]['firstname'];
           $_SESSION['username'] = $rowsFound[0]['username'];

           echo "Login successful. Please <a
href='/'>continue</a>.";
        }
        else
        {
           echo "Login information incorrect. Please <a
href='/user/login'>try again</a>.";
        }

    }
...
在 authenticateAction() 函数中,我们先让 PHP 启动会话,如果可能的话使用现有会话也可。然后可以在 $_SESSION 变量中设置值。此变量数据自动地就成为全局变量,这意味着在应用程序中可以随处获取此变量。并一直持续到用户打开浏览器为止。

我们有了 3 个值。第一个是会话 ID,这是引用会话的惟一方式。第二个是用户的姓,这样我们就可以在主页上礼貌而友好地欢迎用户。第三个是用户的用户名,这样我们可以执行任何与用户相关的功能。

TOP

检索会话并显示在页面上

我们需要将新的用户数据添加到适当的视图对象中,以使其在主页上显示出来。将下列代码添加到 IndexController 中。


清单 22. 往主页中添加信息
复制内容到剪贴板
代码:
<?php
Zend::loadClass('Zend_Controller_Action');
Zend::loadClass('Zend_View');

class IndexController extends Zend_Controller_Action
{
    public function indexAction()
    {

        session_start();

        $view = new Zend_View();
        $view->setScriptPath('views');

        $view->title = 'Chomp! The online feedreader';
        $view->slogan = 'all the feeds you can eat';

        if (isset($_SESSION['username']))
        {
            $view->loginSection = 'Welcome back, ' .
$_SESSION['firstname'];
        } else {
            $view->loginSection = 'Login info here';
        }

        echo $view->render('indexIndexView.php');
    }

    public function loginAction()
    {
        echo "This is the loginAction().";
    }

    public function registerAction()
    {
        echo "This is the registerAction().";
    }

}
?>
如果用户已登录,系统将设置 $_SESSION['username'] 变量,这样就可以在登录区域中显示用户的姓。如果未登录,将返回到原始登录信息。(请注意在本系列接下来的部分中您将看到,此处也可以调用其他的代码,包括来自其他控制器中的行为。)

TOP

更新视图

当然要真正看到其效果,还需要更新视图本身。打开 indexIndexView.php 文件并添加下列信息。


清单 23. 添加新信息
复制内容到剪贴板
代码:
<html>
<head>
   <title><?php echo $this->title ?></title>
</head>
<body>

<table>
<tr><td colspan="2">
   <h1>CHOMP!</h1>
   <h3><?php echo $this->slogan ?></h3>
</td></tr>
<tr>
<td style="width: 200px;"><?php echo $this->loginSection
?></td>


<td>Content here</td></tr>
</table>


</body>
</html>
我们也可以用这个视图提供一个链接,用于更新用户配置文件。

TOP

配置文件更新表单

使用视图的好处之一是,同样一个文件可以有多种用途。例如,注册表单可以一身二用,同时作为配置文件更新表单。为此,需要更改 register.php 文件,以使表单可以接受动态信息。


清单 24. 为注册表单添加动态信息
复制内容到剪贴板
代码:
<html>
<head>
</head>
<body>
<p><strong><?php echo $this->userFunction; ?> a User Account</strong></p>
<form name="form1" method="post" action="<?php echo $this->action; ?>">
  <p>First Name:
    <input name="fName" type="text" id=\
    "fName" value="<?php echo $this->firstname; ?>">
</p>
  <p>
    Last Name:
    <input name="lName" type="text" id="lName" value=\
    "<?php echo $this->lastname; ?>">
</p>
  <p>Email Address:
    <input name="email" type="text" id="email" value=\
    "<?php echo $this->email; ?>">
  </p>
  <p>Username:
    <input name="user" type="text" id="user" value=\
    "<?php echo $this->username; ?>">
</p>
  <p>Password:
    <input name="pass" type="password" id="pass" >
  </p>
  <p>Confirm Password:
    <input name="passConfirm" type="password" id="passConfirm">
  </p>
  <p>
    <input name="<?php echo $this->button; ?>" type="submit"
       id="<?php echo $this->button; ?>"
       value="<?php echo $this->button; ?>">
  </p>
</form>
</body>
</html>
有了以上更改,我们就可以将此此视图用作注册表单兼配置文件更新表单的视图了。

TOP

发新话题