如何使用Symfony2在VPS上执行CRUD操作(第1部分)
关于 Symfony
Symfony 是一个开源的 PHP Web 开发框架 - 一组工具和方法来帮助您构建出色的应用程序。 这个框架的一些特点是它的速度、灵活性、可扩展性和稳定性。 您可以将它用于完整的 Web 应用程序,也可以用于项目所需的较小功能。
在 上一篇教程 中,我们已经看到了如何安装 Symfony2 Standard Distribution 并将其配置为在您的 VPS 上工作。 在本教程和下一教程中,我们将创建一个小型 Symfony 应用程序,它对我们的数据模型执行一些基本的 CRUD(创建、读取、更新、删除)操作。 本教程假设您已按照上一篇文章中的步骤进行操作,并且可以从中断处继续。
我们将使用的数据是 新闻页面 。 我们将创建一个实体(作为新闻页面的数据模型)并学习如何阅读和显示它。 在下一篇中,我们将学习如何执行其他操作,即添加、更新和删除新闻页面。 但首先,我们需要创建一个捆绑包。
捆绑
Symfony 中的包是一个目录,您可以在其中保存应用程序中特定功能所需的所有文件。 这包括 PHP 文件、样式表、javascript 文件等。 在我们的应用程序中,我们将只创建一个包来负责与新闻页面有关的所有事情。 如果我们还想拥有一个博客,我们可以创建一个特定的包来负责。
bundle 最酷的地方在于它们也像插件一样工作(甚至 Symfony 的核心功能也被安排在 bundle 中)。 这意味着您可以自己创建新的包来保存特定功能的所有代码,或者您可以注册由其他人创建的外部包。 因此,在开始使用我们的数据之前,让我们在命令行中生成一个空包,因为 Symfony 标准发行版提供了这种简洁的工具。 这意味着您不需要创建所有文件夹并手动向 Symfony 注册捆绑包——所有这些都将自动完成。
所以要自动生成一个包,导航到你的应用程序的主文件夹,在我们的例子中,Symfony:
cd /var/www/Symfony
运行以下命令以生成一个名为 NewsBundle 的新包:
php app/console generate:bundle --namespace=Foo/NewsBundle --format=yml
按照屏幕上的说明并接受默认选项。 此命令将生成一个名称为 NewsBundle 的包,该包属于供应商 Foo。 您可以选择您想要的任何供应商名称(这基本上代表您),但您需要确保捆绑名称以单词 Bundle 结尾。 此外,该命令指定捆绑包的配置格式为 YAML 文件。
在后台,您的包的文件夹结构被创建(在 src/Foo/NewsBundle)并且包被注册到应用程序的其余部分。
实体
如果您按照上一教程中的所有步骤进行操作,那么您的数据库连接应该已经配置好了。 如果没有,您可以编辑 parameters.yml 文件:
nano /var/www/Symfony/app/config/parameters.yml
在那里,您可以指定您的数据库信息。 如果您已经创建了数据库,则可以跳过下一步。 但是,您可以使用以下命令让 Symfony 自动创建与此文件中的信息匹配的数据库:
php app/console doctrine:database:create
现在,为了使用我们的数据模型(新闻页面),我们需要创建一个叫做实体的东西。 这基本上是一个 PHP 类,它定义了有关我们新闻页面的所有信息。 Symfony 有一个漂亮的命令行工具,我们将使用它和另一个很好的工具来创建与这个数据模型匹配的实际数据库表。
因此,从命令行运行以下命令以生成名为 News 的实体:
php app/console doctrine:generate:entity
按照屏幕上的说明操作。 您需要指定的第一件事是名称,尽管是快捷方式名称。 对我们来说,它将是 FooNewsBundle:News (实体名称是冒号后面的名称,但您还需要指定它所属的包)。 接下来,继续进行配置管理并选择 yml。
接下来,您将为我们的数据模型添加类属性(将匹配表列)。 让我们添加一个标题(字符串,255)、正文(文本)和 created_date(日期时间)。 接下来,不需要存储库,因此选择否,然后确认生成。 实体现已创建。
如果你很好奇它的外观,可以探索新创建的实体类文件:
nano /var/www/Symfony/src/Foo/NewsBundle/Entity/News.php
接下来,让 Symfony 生成数据库表,该表将基于这个新创建的实体存储我们的新闻页面。 运行以下命令:
php app/console doctrine:schema:update --force
该命令将从实体中获取信息并基于此生成表。 你应该得到一个简单的确认:“ 数据库架构更新成功! 执行了“1”个查询。 " 现在,如果您查看数据库,您应该会看到一个名为消息有 4 列(id、title、body 和 created_date),它们都与消息实体类。
读取数据
由于我们的数据库是空的,让我们使用 phpmyadmin 或命令行插入 2 个测试行,我们可以使用新的 Symfony 应用程序读取它们。 稍后,我们将看到如何使用应用程序添加新内容,但现在,您可以在 mysql 终端中运行以下命令来添加 2 行:
use symfony; INSERT INTO News (title,body,created_date) VALUES ('News title 1', 'Some body text', NOW()); INSERT INTO News (title,body,created_date) VALUES ('News title 2', 'Another body text', NOW());
现在我们有了一些虚拟内容,让我们创建一个路由来将用户对特定新闻页面的请求映射到 Symfony 控制器。
您的应用程序中的主路由文件位于 app/config 文件夹中,但您也可以在位于 bundle 文件夹结构中的 routing.yml 文件中为您的 bundle 定义特定的路由规则:
nano /var/www/Symfony/src/Foo/NewsBundle/Resources/config/routing.yml
让我们删除已经存在的规则并添加另一个规则:
foo_news_show: pattern: /news/{id} defaults: { _controller: FooNewsBundle:Default:show }
这条规则的名字是foo_news_show,当浏览器请求www.example.com/Symfony/web/app_dev.php/news/{id},时触发]{id} 是所请求新闻页面的动态传递 ID 的通配符。 在 defaults 下,我们指定要调用的控制器和方法。 在这种情况下,它将是 DefaultController.php 文件中的 DefaultController 和其中的 showAction 方法(我们现在必须创建)。
我们在这里指定了 DefaultController 因为它的文件已经存在,由 Symfony 在我们创建包时自动生成。 所以我们不妨使用它。 我们现在要做的是创建一个方法,该方法将使用 News 实体类和 Doctrine 数据库库来请求新闻页面,然后将其以变量的形式传递给 Twig 模板文件。 所以让'编辑DefaultController.php文件:
nano /var/www/Symfony/src/Foo/NewsBundle/Controller/DefaultController.php
在此文件中,您将看到已定义的 indexAction() 方法。 在它下面,让我们声明 showAction() 方法:
public function showAction($id) { $news = $this->getDoctrine() ->getRepository('FooNewsBundle:News') ->find($id); if (!$news) { throw $this->createNotFoundException('No news found by id ' . $id); } $build['news_item'] = $news; return $this->render('FooNewsBundle:Default:news_show.html.twig', $build); }
此函数使用 Doctrine 检索带有传递 ID 的新闻实体(如果未找到新闻则抛出异常)并将新闻对象传递给我们接下来必须创建的 news_show.html.twig 模板文件. 代码非常简单。 所以让我们这样做。
视图位于 Resources/views 文件夹下的包中,该文件夹位于另一个以使用它们的控制器命名的文件夹中 - 在我们的示例中为 Default。 所以在那里创建一个名为 news_show.html.twig 的新文件:
nano /var/www/Symfony/src/Foo/NewsBundle/Resources/views/Default/news_show.html.twig
并粘贴以下模板代码:
{{ news_item.Title }} {{ news_item.Body }} <h1>{{ news_item.Title }}</h1> {{ news_item.Body }}
这是一个带有 Twig 模板语言的 html 文件。 我们不会在这里详细介绍 Symfony 中的 Twig,因此请随时在 此处 阅读有关它的更多信息。 现在,如果您将浏览器指向 www.example.com/Symfony/web/app_dev.php/news/1,您应该会看到 ID 为 1 的新闻。
现在让我们通过创建另一个路由规则和控制器方法来创建所有新闻页面的列表。 打开之前编辑过的 routing.yml 文件:
nano /var/www/Symfony/src/Foo/NewsBundle/Resources/config/routing.yml
并添加以下内容:
foo_news_home: pattern: /news/ defaults: { _controller: FooNewsBundle:Default:index }
这条路由会触发 DefaultController 的 indexAction() 方法,所以让我们去编辑它(如果你记得它已经在 Controller 文件中,我们只需要修改它):
nano /var/www/Symfony/src/Foo/NewsBundle/Controller/DefaultController.php
删除默认情况下在此处指定的参数 ($name) 和方法本身内的代码。 相反,粘贴以下内容:
$news = $this->getDoctrine() ->getRepository('FooNewsBundle:News') ->findAll(); if (!$news) { throw $this->createNotFoundException('No news found'); } $build['news'] = $news; return $this->render('FooNewsBundle:Default:news_show_all.html.twig', $build);
与我们之前创建的方法类似,这个方法会在表格中找到所有新闻,并将它们传递给 news_show_all.html.twig 模板文件。 因此,让我们在与之前创建的文件夹相同的文件夹中创建此文件:
nano /var/www/Symfony/src/Foo/NewsBundle/Resources/views/Default/news_show_all.html.twig
并遍历 $news 对象数组以显示所有新闻标题:
{% for new in news %} <h3>{{ new.Title }}</h3> {% endfor %}
现在,如果您访问 www.example.com/Symfony/web/app_dev.php/news/,您应该会看到我们手动添加到表格中的 2 个新闻标题。 让我们也使用 Symfony 路由系统在这些标题周围添加链接,这些链接将指向我们之前创建的相应页面。 所以替换以下内容:
<h3>{{ new.Title }}</h3>
有了这个:
<h3><a href="{{ path('foo_news_show', {'id': new.Id }) }}">{{ new.Title }}</a></h3>
这是在 Twig 模板中生成链接的便捷方式。 您基本上指定要使用的路由以及路由所期望的通配符的值 - 在本例中是在新闻对象中找到的 ID。 现在,如果您刷新页面,标题会变成指向各自页面的链接。
结论
在本教程中,我们了解了 Symfony 包是什么以及如何创建它们。 我们还开始了需要与数据库中的新闻页面交互的小型应用程序。 为此,我们定义了一个与表结构匹配的 Entity 类,并使用 Doctrine 来访问信息并填充实体对象。 此外,我们还使用 Symfony 路由系统将浏览器请求与 PHP 控制器方法连接起来,然后请求数据并在 Twig 模板中将其呈现给浏览器。
在下一个也是最后一个教程中,我们将着眼于创建、更新和删除新闻页面。