如何使用CakePHP创建小型Web应用程序(第二部分)

来自菜鸟教程
跳转至:导航、​搜索


状态: 已弃用

本文介绍了不再受支持的 Ubuntu 版本。 如果您当前正在运行运行 Ubuntu 12.04 的服务器,我们强烈建议您升级或迁移到受支持的 Ubuntu 版本:

原因: Ubuntu 12.04 已于 2017 年 4 月 28 日终止生命周期 (EOL) and no longer receives security patches or updates. This guide is no longer maintained.

请参阅:
本指南可能仍可用作参考,但可能不适用于其他 Ubuntu 版本。 如果可用,我们强烈建议使用为您正在使用的 Ubuntu 版本编写的指南。 您可以使用页面顶部的搜索功能来查找更新的版本。


关于 CakePHP

CakePHP 是一个强大且健壮的 PHP 框架,围绕模型-视图-控制器 (MVC) 编程范式构建。 除了可以使用它来构建应用程序的灵活方式之外,它还提供了用于组织文件和数据库表名的基本结构 - 保持一切一致和合乎逻辑。

在上一个教程中,我们开始创建一个小型应用程序,它将在我们的数据库上执行一些基本的 CRUD(创建、读取、更新、删除)操作。 到目前为止,我们设法使用模型(Post)读取数据(帖子),使用控制器(PostsController)请求它,并创建了几个视图来显示信息。 在本教程中,我们将通过实现其他 CRUD 操作(即创建、更新和删除)来完成应用程序。 为此,我们将主要在现有的控制器中工作,并使用我们创建的模型来访问我们的数据。

如果您还没有完成之前的两个教程,请先阅读前两个教程,然后再继续学习:

添加数据

在看到我们如何阅读表格中的帖子之后,让我们看看如何添加新帖子。 在创建我们的 Controller 方法之前,让我们首先确保 Controller 具有我们需要的所有组件。 在上一个教程中,我们只包含了 Form 帮助器:

public $helpers = array('Form');

现在让我们通过添加到数组中来添加 HTML 和 Session 助手:

public $helpers = array('Form', 'Html', 'Session');

此外,让我们包含 Session 组件。 在我们刚刚编辑的行下方,添加以下内容:

public $components = array('Session');

现在让我们继续创建一个 View 来容纳我们的表单以添加新帖子。 这将使用我们刚刚包含的表单助手来使事情变得更容易。 因此,在 app/View/Posts/ 文件夹中创建一个名为 add.ctp 的文件。 在里面,粘贴以下代码:

<h1>Add Post</h1>
<?php
echo $this->Form->create('Post');
echo $this->Form->input('title');
echo $this->Form->input('body', array('rows' => '3'));
echo $this->Form->end('Save');
?>

如您所见,我们可以直接从视图中访问表单助手,它允许我们快速绘制表单。 这里有一件重要的事情是,如果 create() 方法没有传递任何参数,它将假定表单提交给它自己(加载此视图的控制器方法 - 我们将在一秒钟内创建)。 如您所见,input() 方法非常不言自明,但一件很酷的事情是它会生成与表格中的数据相匹配的表单元素。 所以让我们保存文件并在 PostsController 中创建我们的方法来处理这个问题。

在我们之前在 PostsController 中创建的 view() 方法正下方添加以下代码:

public function add() {
        if ($this->request->is('post')) {
            $this->Post->create();
            $post_data = $this->request->data;
            if ($this->Post->save($post_data)) {
                $this->Session->setFlash(__('New post saved successfully to the database'));
                return $this->redirect(array('action' => 'index'));
            }
            $this->Session->setFlash(__('Unable to save the post to the database.'));
        }
}

这个函数(命名为它对应的 View)首先检查是否有一个 POST 类型的请求发送给它,如果有,则尝试使用 Post 模型将新数据插入到表中。 如果成功,它将为当前用户会话设置一个 flashdata 并重定向到 index() 方法(显示所有帖子的方法),然后该方法也会显示一个肯定的确认消息。 如果没有,它将设置一条错误消息。 您可以继续在 www.example.com/project/posts/add 上进行测试。 填写表格,它应该会保存新帖子,将您重定向到帖子索引页面并显示确认消息。

由于 PostsController 是通过扩展默认的 CakePHP 控制器创建的,我们可以访问很多好东西,例如请求对象。 使用它,我们可以检查正在发出什么样的 HTTP 请求并访问 POST 数据。 此外,我们可以访问 redirect() 方法,通过它我们可以快速将用户重定向到另一个方法或控制器。

验证数据

我确定您不希望在没有任何信息的情况下提交帖子,让我们在我们的 Post 模型中设置一个快速规则,以确保它强制用户在提交新帖子时设置标题。 在 Post 模型中,添加以下属性:

public $validate = array('title' => array('rule' => 'notEmpty'));

这将确保标题字段不能为空。 保存模型文件并尝试在不填写标题字段的情况下添加新帖子。 您会注意到现在您需要填写标题字段,但不一定要填写正文字段。

HTML 助手?

我们在 PostsController 中包含 HTML 帮助程序 的原因是为了向您展示如何以 CakePHP 的方式在页面上放置链接。 因此,让我们打开位于 app/View/Posts/ 文件夹中的 index.ctp 视图,并在 H1 标签后添加以下代码:

<?php echo $this->Html->link(
    'Add Post',
    array('controller' => 'posts', 'action' => 'add')
); ?>

这将输出一个带有锚点 Add Post 的链接,该链接将转到 PostsControlleradd() 方法。 如果您愿意,您还可以进一步编辑文件并使用相同的技术,将此页面上的帖子标题转换为各自页面的链接。 所以而不是:

<?php echo $post['Post']['title']; ?>

你可以放:

<?php echo $this->Html->link($post['Post']['title'], array('controller' => 'posts', 'action' => 'view', $post['Post']['id'])); ?>

有关 HTML 帮助程序的更多信息,您可以在 此处 找到。

编辑数据

现在我们了解了如何创建新帖子,让我们看看如何编辑现有帖子。 让我们在放置 add.ctp 视图的位置旁边再次创建视图,并将其命名为 edit.ctp。 在里面,粘贴以下内容:

<h1>Edit Post</h1>
<?php
    echo $this->Form->create('Post');
    echo $this->Form->input('title');
    echo $this->Form->input('body', array('rows' => '3'));
    echo $this->Form->input('id', array('type' => 'hidden'));
    echo $this->Form->end('Save');
?>

edit.ctpadd.ctp 视图之间的主要区别在于,在前者中,我们还将帖子的 ID 作为隐藏输入包括在内,以便 CakePHP 知道你想要编辑而不是添加新帖子。 保存文件并退出。 接下来,我们在 PostsController 中创建 edit() 方法:

public function edit($id = null) {
    if (!$id) {
        throw new NotFoundException(__('Post is not valid!'));
    }

    $post = $this->Post->findById($id);
    if (!$post) {
        throw new NotFoundException(__('Post is not valid!'));
    }

    if ($this->request->is('post') || $this->request->is('put')) {
        $this->Post->id = $id;
        $post_data = $this->request->data;
        if ($this->Post->save($post_data)) {
            $this->Session->setFlash(__('Your post has been updated.'));
            return $this->redirect(array('action' => 'index'));
        }
        $this->Session->setFlash(__('Unable to update your post.'));
    }

    if (!$this->request->data) {
        $this->request->data = $post;
    }
}

此操作首先通过检查 ID 的有效性以及它是否存在于数据库中来确保用户正在尝试访问有效的帖子。 与 add() 方法一样,它检查请求是否为 POST,如果是则尝试更新数据库中的帖子。 如果请求对象中不存在数据,它将使用数据库中存在的数据填充表单元素。 和 add() 动作一样,它会将用户重定向到 index() 方法并显示确认消息。 所以继续尝试吧。

您还可以修改 index.ctp 视图并添加链接以编辑单个帖子。 在 Created 字段之后添加以下代码:

<?php echo $this->Html->link('Edit', array('action' => 'edit', $post['Post']['id'])); ?>

删除数据

我们需要做的最后一件事是允许用户删除帖子。 因此,让我们将以下操作添加到 PostsController:

public function delete($id) {
   if ($this->request->is('post')) {
    if ($this->Post->delete($id)) {
      $this->Session->setFlash(__('The post number %s has been deleted.', h($id)));
      return $this->redirect(array('action' => 'index'));
    }
  }
}

如果请求是 GET 类型,则此方法首先抛出异常。 然后它像上面的操作一样使用 Post 模型,但这次删除了表中具有请求中提供的 ID 的行。 最后,它向用户设置一条消息并重定向到显示消息的 index() 方法。

要触发这个 delete() 方法,让我们编辑 index.ctp 视图并使用 postLink() 函数输出一个将发送 POST 的小表单请求删除表格行。 它将使用 javascript 添加一个确认警报框,然后将删除该帖子。 在编辑链接后的 index.ctp 文件中,您可以添加以下内容:

<?php echo $this->Form->postLink(
                'Delete',
                array('action' => 'delete', $post['Post']['id']),
                array('confirm' => 'Are you sure you want to delete this post?'));
?>

保存文件并尝试一下。 现在您应该也可以删除帖子了。

回顾一下,如果你跟着,你的类现在应该是这样的:

PostsController.php - 控制器

class PostsController extends AppController {
  public $helpers = array('Form', 'Html', 'Session');
  public $components = array('Session');
    
  public function index() {
      $this->set('posts', $this->Post->find('all'));
  }
  
  public function view($id = null) {
        $post = $this->Post->findById($id);
        $this->set('post', $post);
  }
  
  public function add() {
        if ($this->request->is('post')) {
            $this->Post->create();
            $post_data = $this->request->data;
            if ($this->Post->save($post_data)) {
                $this->Session->setFlash(__('New post saved successfully to the database'));
                return $this->redirect(array('action' => 'index'));
            }
            $this->Session->setFlash(__('Unable to save the post to the database.'));
        }
  }

  public function edit($id = null) {
    if (!$id) {
        throw new NotFoundException(__('Post is not valid!'));
    }

    $post = $this->Post->findById($id);
    if (!$post) {
        throw new NotFoundException(__('Post is not valid!'));
    }

    if ($this->request->is('post') || $this->request->is('put')) {
        $this->Post->id = $id;
        $post_data = $this->request->data;
        if ($this->Post->save($post_data)) {
            $this->Session->setFlash(__('Your post has been updated.'));
            return $this->redirect(array('action' => 'index'));
        }
        $this->Session->setFlash(__('Unable to update your post.'));
    }

    if (!$this->request->data) {
        $this->request->data = $post;
    }
  }

 public function delete($id) {
   if ($this->request->is('post')) {
    if ($this->Post->delete($id)) {
      $this->Session->setFlash(__('The post number %s has been deleted.', h($id)));
      return $this->redirect(array('action' => 'index'));
    }
   }
  }
}

Post.php - 模型

class Post extends AppModel {
  public $validate = array('title' => array('rule' => 'notEmpty'));
}

结论

在这个简短的教程系列中,我们已经看到使用 CakePHP 对您的数据执行 CRUD 操作是多么容易。 我们学习了如何阅读和显示信息,如何编辑和删除信息,以及如何添加新信息。 此外,要学习的重要一课是强烈建议遵循 CakePHP 设置的约定,因为它使您的生活更轻松。 我鼓励您使用您创建的这个小应用程序并使用它来构建更大的东西。 为此,您应该阅读 有关 CakePHP 组件和帮助程序的更多信息

文章提交者:Danny