如何在Ubuntu14.04上开始使用Silex
介绍
Silex 是一个基于 Symfony2 组件的 PHP 微框架。 它可用于构建小型网站和大型应用程序。 它简洁、可扩展且可测试。
在本教程中,我们将从下载和配置 Silex 开始。 然后您将学习如何制作一个基本的 Silex 应用程序。
我们将使用 Composer 安装 Silex,这是一个流行的 PHP 包管理器。 更多关于 Composer 的信息可以在 this tutorial 中找到。 在本教程结束时,您将拥有一个功能齐全的博客站点。
注意: 本教程在 Ubuntu 上进行了测试,但在其他 Linux 发行版上也同样适用。 这些链接参考了 Ubuntu 教程,但请随时找到设置服务器和安装 LAMP 堆栈和 Git 的适当指南。
先决条件
请完成这些先决条件。
第 1 步 — 安装 Silex
在本节中,我们将使用 Composer 安装 Silex。 首先,将您的工作目录更改为 Apache 文档根目录 /var/www/html
:
cd /var/www/html
接下来,删除此文件夹的默认内容:
sudo rm /var/www/html/index.html
然后,移动到 /var/www
目录,以免将所有文件暴露给公众:
cd /var/www
然后,下载 Composer:
sudo curl -sS https://getcomposer.org/installer | sudo php
接下来,我们将创建和编辑 Composer 文件 composer.json
:
sudo nano composer.json
在此文件中,添加以下内容:
{ "require": { "silex/silex": "~1.2" } }
我们现在告诉 Composer 下载 Silex 1.2 版作为依赖项。 要开始下载,请执行以下命令:
sudo php composer.phar update
现在,Composer 将下载 Silex 及其依赖项; 这可能需要几秒钟。
第 2 步 — 引导 Silex
在本节中,我们将通过包含所需文件和创建应用程序来引导 Silex。 首先,编辑文件 /var/www/html/index.php
:
sudo nano /var/www/html/index.php
在此文件中,添加以下基本内容:
<?php require_once __DIR__.'/../vendor/autoload.php'; // Add the autoloading mechanism of Composer $app = new Silex\Application(); // Create the Silex application, in which all configuration is going to go // Section A // We will later add the configuration, etc. here // This should be the last line $app->run(); // Start the application, i.e. handle the request ?>
在本教程中,我们将向该文件添加更多配置信息和其他数据。 我们添加的所有新行都将进入 Section A
,在 $app = new Silex\Application();
和 $app->run();
行之间。
在同一个文件中,/var/www/html/index.php
打开调试,这在开发应用程序时很有用。 在 部分 A 中添加这一行:
$app['debug'] = true;
第 3 步 - 创建博客应用程序
在本节中,我们将创建一个示例博客应用程序。 如果您想专注于自己的应用程序,请查看 Silex 文档。
我们将创建一个示例博客应用程序。 它不会使用数据库,但可以通过查看 DoctrineServiceProvider 文档 相对轻松地进行转换。
添加 Twig 模板引擎
首先,首先添加另一个依赖项:Twig。 Twig 是 Symfony 框架也使用的模板引擎。 它将提供我们应用程序的模板。 要添加它,请编辑 composer.json
:
sudo nano /var/www/composer.json
然后,为 twig
添加新的依赖行,如下图红色所示。 不要忘记上一行的逗号:
{ "require": { "silex/silex": "~1.2", "twig/twig": ">=1.8,<2.0-dev" } }
接下来,更新 Composer 依赖项:
sudo php composer.phar update
启用 mod_rewrite
现在,您需要配置 Web 服务器,在本例中为 Apache。
首先,确保您已启用 mod_rewrite
并且您已允许在 .htaccess
文件中进行更改。 该过程在本教程中有描述,但请记住Ubuntu 14.04的默认虚拟主机在/var/www/html
而不是/var/www
。
启用模块后(如链接教程中所述),将以下行添加到 /etc/apache2/sites-available/000-default.conf
文件中:
sudo vim /etc/apache2/sites-available/000-default.conf
<Directory /var/www/html/> Options Indexes FollowSymLinks MultiViews AllowOverride All Order allow,deny allow from all </Directory>
然后,创建并编辑 .htaccess
文件:
sudo nano /var/www/html/.htaccess
在此文件中,添加以下内容:
<IfModule mod_rewrite.c> Options -MultiViews RewriteEngine On RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^ index.php [QSA,L] </IfModule>
这将确保对不存在的文件的任何请求都指向我们的应用程序,从而允许应用程序进行路由。
创建博客内容
要添加一些文章,我们将创建一个包含标题、内容、作者和出版日期的数组。 我们可以通过它扩展的容器对象将它存储在我们的应用程序对象中。 一个容器对象能够容纳多个对象,这些对象可以被应用程序中的所有其他对象重用。 为此,请在 /var/www/html/index.php
中的 Section A
中添加以下内容
sudo nano /var/www/html/index.php
添加以下内容:
$app['articles'] = array( array( 'title' => 'Lorem ipsum dolor sit amet', 'contents' => 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean mollis vestibulum ultricies. Sed sit amet sagittis nisl. Nulla leo metus, efficitur non risus ut, tempus convallis sem. Mauris pharetra sagittis ligula pharetra accumsan. Cras auctor porta enim, a eleifend enim volutpat vel. Nam volutpat maximus luctus. Phasellus interdum elementum nulla, nec mollis justo imperdiet ac. Duis arcu dolor, ultrices eu libero a, luctus sollicitudin diam. Phasellus finibus dictum turpis, nec tincidunt lacus ullamcorper et. Praesent laoreet odio lacus, nec lobortis est ultrices in. Etiam facilisis elementum lorem ut blandit. Nunc faucibus rutrum nulla quis convallis. Fusce molestie odio eu mauris molestie, a tempus lorem volutpat. Sed eu lacus eu velit tincidunt sodales nec et felis. Nullam velit ex, pharetra non lorem in, fringilla tristique dolor. Mauris vel erat nibh.', 'author' => 'Sammy', 'date' => '2014-12-18', ), array( 'title' => 'Duis ornare', 'contents' => 'Duis ornare, odio sit amet euismod vulputate, purus dui fringilla neque, quis eleifend purus felis ut odio. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Pellentesque bibendum pretium ante, eu aliquet dolor feugiat et. Pellentesque laoreet est lectus, vitae vulputate libero sollicitudin consequat. Vivamus finibus interdum egestas. Nam sagittis vulputate lacus, non condimentum sapien lobortis a. Sed ligula ante, ultrices ut ullamcorper nec, facilisis ac mi. Nam in vehicula justo. In hac habitasse platea dictumst. Duis accumsan pellentesque turpis, nec eleifend ex suscipit commodo.', 'author' => 'Sammy', 'date' => '2014-11-08', ), );
这些文章现在可以在我们的应用程序中的任何地方重复使用,您甚至可以自己添加更多。 对于现实世界的网站,使用数据库可能是一个更好的主意。
路由
基本上,路由将 http://www.example.com/
之类的 URL 映射到 / 并执行与之关联的函数。 要添加基本路线,请在 /var/www/html/index.php
的 Section A
中添加以下内容:
sudo nano /var/www/html/index.php
内容:
$app->get('/', function (Silex\Application $app) { // Match the root route (/) and supply the application as argument $output = ''; foreach ($app['articles'] as $article) { // Create a basic list of article titles $output .= $article['title']; $output .= '<br />'; } return $output; // Return it to so it gets displayed by the browser });
现在,当您访问 http://your_server_ip
时,它应该显示文章标题列表:
模板
即使我们的网站现在显示正确的输出,它看起来也不是很好。 为了解决这个问题,我们将使用 Twig。
首先,Silex 要求我们将 Twig 注册为 服务提供者,这基本上是一种在另一个应用程序中重用应用程序的某些部分的方法。 要注册 Twig,请在 section A
中添加:
sudo nano /var/www/html/index.php
内容:
$app->register(new Silex\Provider\TwigServiceProvider(), array( 'twig.path' => __DIR__.'/../templates', // The path to the templates, which is in our case points to /var/www/templates ));
我们现在可以使用 Twig 模板引擎。 为此,请编辑定义 /
路线的 $app->get('/', function (Silex\Application $app) { });
块,以匹配此处显示的内容。 新行显示为 red:
$app->get('/', function (Silex\Application $app) { // Match the root route (/) and supply the application as argument return $app['twig']->render( // Render the page index.html.twig 'index.html.twig', array( 'articles' => $app['articles'], // Supply arguments to be used in the template ) ); });
保存更改并关闭文件。
现在让我们创建 index.html.twig
模板。 创建目录,然后创建并打开文件base.html.twig
:
sudo mkdir /var/www/templates sudo nano /var/www/templates/base.html.twig
这个文件将是我们的基本模板,这意味着所有其他模板都将从它继承,因此我们不必在每个模板中添加基础知识。 在此文件中,添加以下内容:
<!doctype html> <html> <head> <title>{% block title %}Blog{% endblock %}</title> </head> <body> {% block body %} {% endblock body %} </body> </html>
该文件包含两个 块 。 可以在子模板中覆盖块以提供内容。 名为 title
的块将用于为单个文章页面提供标题。 块 body
将用于显示所有内容。
保存您的更改。
现在我们将创建和编辑文件 /var/www/templates/index.html.twig
:
sudo nano /var/www/templates/index.html.twig
添加以下内容:
{% extends 'base.html.twig' %} {% block body %} <h1> Blog index </h1> {% for article in articles %} <article> <h1>{{ article.title }}</h1> <p>{{ article.contents }}</p> <p><small>On {{ article.date }} by {{ article.author }}</small></p> </article> {% endfor %} {% endblock %}
首先,我们指定要扩展模板 base.html.twig
。 之后,我们可以开始覆盖父模板中定义的块。 在这个模板中,我们只覆盖了块 body
,在这里我们创建了一个显示所有文章的循环。
现在访问http://your_server_ip
; 它应该显示您所有帖子的索引:
单个帖子的另一个控制器
接下来,我们将添加另一个显示单个帖子的控制器。 这些帖子将通过它们的数组索引匹配。 再次打开/var/www/html/index.php
:
sudo nano /var/www/html/index.php
将此添加到 Section A
,这将允许我们显示单个文章的页面:
$app->get('/{id}', function (Silex\Application $app, $id) { // Add a parameter for an ID in the route, and it will be supplied as argument in the function if (!array_key_exists($id, $app['articles'])) { $app->abort(404, 'The article could not be found'); } $article = $app['articles'][$id]; return $app['twig']->render( 'single.html.twig', array( 'article' => $article, ) ); }) ->assert('id', '\d+') // specify that the ID should be an integer ->bind('single'); // name the route so it can be referred to later in the section 'Generating routes'
保存您的更改。 然后,创建并编辑文件 /var/www/templates/single.html.twig
:
sudo nano /var/www/templates/single.html.twig
添加以下内容:
{% extends 'base.html.twig' %} {% block title %}{{ article.title }}{% endblock %} {% block body %} <h1> {{ article.title }} </h1> <p>{{ article.contents }}</p> <p><small>On {{ article.date }} by {{ article.author }}</small></p> {% endblock %}
在这个模板中,我们还利用 title
块来显示文章标题。 body
块看起来与之前的 body
块几乎相同,所以它应该是不言自明的。
如果您现在访问 http://your_server_ip/0
或 http://your_server_ip/1
,它应该显示一篇文章:
但是,如果您访问一个不存在的 ID,例如本例中的 http://your_server_ip/2
,它将显示一个错误页面:
生成路线
接下来,我们将添加从主页到单篇文章视图的链接,以及从文章返回到主页的链接。 Silex 能够使用 Symfony 组件生成路由。 它作为 服务提供者 提供,因此您应该首先将其添加到 Section A
。 打开/var/www/html/index.php
:
sudo nano /var/www/html/index.php
将以下内容添加到 Section A
:
$app->register(new Silex\Provider\UrlGeneratorServiceProvider());
这将允许我们使用 URL 生成器服务。 当我们创建单视图控制器时,我们已经添加了一个命名路由。 它是使用以下行完成的:
->bind('single'); // name the route so it can be referred to later in the section 'Generating routes'
现在,我们还需要将路由绑定到主页。 为此,请在此块的末尾添加 ->bind('index')
路由,就在最后一个分号之前。 更改标记为 红色 :
$app->get('/', function (Silex\Application $app) { // Match the root route (/) and supply the application as argument return $app['twig']->render( 'index.html.twig', array( 'articles' => $app['articles'], ) ); })->bind('index');
接下来,我们需要实际生成 URL。 打开/var/www/templates/index.html.twig
:
sudo nano /var/www/templates/index.html.twig
然后,更改下面的<h1>
行,如下图:
{% extends 'base.html.twig' %} {% block body %} <h1> Blog index </h1> {% for article in articles %} <article> <h1><a href="{{ app.url_generator.generate('single', { id: loop.index0 }) }}">{{ article.title }}</a></h1> <p>{{ article.contents }}</p> <p><small>On {{ article.date }} by {{ article.author }}</small></p> </article> {% endfor %} {% endblock %}
这将创建从文章标题到单个文章页面的链接。 app.url_generator
指的是我们已经注册的服务。 generate
函数有两个参数:路由名称,在本例中为 single
,以及路由的参数,在本例中为 ID。 loop.index0
指的是循环中的 0 索引索引。 因此,当第一项循环时,它是 0
; 当第二项循环时,它是1
等。
同样可以在单页模板中引用索引页:
sudo nano /var/www/templates/single.html.twig
添加以下 <p>
行以创建链接:
{% extends 'base.html.twig' %} {% block title %}{{ article.title }}{% endblock %} {% block body %} <h1> {{ article.title }} </h1> <p>{{ article.contents }}</p> <p><small>On {{ article.date }} by {{ article.author }}</small></p> <p><a href="{{ app.url_generator.generate('index') }}">Back to homepage</a></p> {% endblock %}
这应该是不言自明的。
就是这样! 请随时再次访问该网站 http://your_server_ip/
。 您应该可以单击文章标题访问该文章的页面,然后使用文章底部的链接返回主页。
完成 index.php 文件
供您参考,这是最终的 /var/www/html/index.php
文件的外观。
<?php require_once __DIR__.'/../vendor/autoload.php'; // Add the autoloading mechanism of Composer $app = new Silex\Application(); // Create the Silex application, in which all configuration is going to go // Section A // We will later add the configuration, etc. here $app['debug'] = true; $app['articles'] = array( array( 'title' => 'Lorem ipsum dolor sit amet', 'contents' => 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean mollis vestibulum ultricies. Sed sit amet sagittis nisl. Nulla leo metus, efficitur non risus ut, tempus convallis sem. Mauris pharetra sagittis ligula pharetra accumsan. Cras auctor porta enim, a eleifend enim volutpat vel. Nam volutpat maximus luctus. Phasellus interdum elementum nulla, nec mollis justo imperdiet ac. Duis arcu dolor, ultrices eu libero a, luctus sollicitudin diam. Phasellus finibus dictum turpis, nec tincidunt lacus ullamcorper et. Praesent laoreet odio lacus, nec lobortis est ultrices in. Etiam facilisis elementum lorem ut blandit. Nunc faucibus rutrum nulla quis convallis. Fusce molestie odio eu mauris molestie, a tempus lorem volutpat. Sed eu lacus eu velit tincidunt sodales nec et felis. Nullam velit ex, pharetra non lorem in, fringilla tristique dolor. Mauris vel erat nibh.', 'author' => 'Sammy', 'date' => '2014-12-18', ), array( 'title' => 'Duis ornare', 'contents' => 'Duis ornare, odio sit amet euismod vulputate, purus dui fringilla neque, quis eleifend purus felis ut odio. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Pellentesque bibendum pretium ante, eu aliquet dolor feugiat et. Pellentesque laoreet est lectus, vitae vulputate libero sollicitudin consequat. Vivamus finibus interdum egestas. Nam sagittis vulputate lacus, non condimentum sapien lobortis a. Sed ligula ante, ultrices ut ullamcorper nec, facilisis ac mi. Nam in vehicula justo. In hac habitasse platea dictumst. Duis accumsan pellentesque turpis, nec eleifend ex suscipit commodo.', 'author' => 'Sammy', 'date' => '2014-11-08', ), ); $app->get('/', function (Silex\Application $app) { // Match the root route (/) and supply the application as argument return $app['twig']->render( // Render the page index.html.twig 'index.html.twig', array( 'articles' => $app['articles'], // Supply arguments to be used in the template ) ); })->bind('index'); $app->register(new Silex\Provider\TwigServiceProvider(), array( 'twig.path' => __DIR__.'/../templates', // The path to the templates, which is in our case points to /var/www/templates )); $app->get('/{id}', function (Silex\Application $app, $id) { // Add a parameter for an ID in the route, and it will be supplied as argument in the function if (!array_key_exists($id, $app['articles'])) { $app->abort(404, 'The article could not be found'); } $article = $app['articles'][$id]; return $app['twig']->render( 'single.html.twig', array( 'article' => $article, ) ); }) ->assert('id', '\d+') // specify that the ID should be an integer ->bind('single'); // name the route so it can be referred to later in the section 'Generating routes' $app->register(new Silex\Provider\UrlGeneratorServiceProvider()); // This should be the last line $app->run(); // Start the application, i.e. handle the request ?>
结论
您已经使用 Silex 创建了一个简单的博客应用程序。 它可以进一步扩展,从与数据库耦合开始。 不过,这超出了本教程的范围。 官方文档很有帮助,如果你想继续使用Silex,绝对是必读的。
如果 Silex 对你来说太小了,你绝对应该考虑使用 Symfony 框架,可以在 here 找到教程。