Symfony Flex:为更快、更好的 Symfony 铺平道路
Symfony Flex 是 Symfony Installer 的现代替代品,而不是下一个 Symfony 版本的名称。 正如介绍文字所说:
在内部,Symfony Flex 是一个 Composer 插件,可以修改 require 和 update 命令的行为。 在启用 Flex 的应用程序中安装或更新依赖项时,Symfony 可以在执行 Composer 任务之前和之后执行任务。
新的 Symfony 将被称为 Symfony 4,虽然本教程将只涉及 Flex 工具,但它也会提到一些 Symfony 4 升级。
仍在开发中
Symfony Flex 可以被认为是 Composer 包装器,因为它在安装和配置期间为您的 Symfony 项目提供额外的选项。 它的开发考虑到了简单性,并且显然深受 Laravel 用户友好性的影响。 请记住,Laravel 由于其易用性和为新手提供的低入门门槛而达到了目前的流行水平,而 Symfony 想要效仿这一点。
需要注意的是,Flex 和 Symfony 4 仍在开发中,预计将于今年(2017 年)11 月底发布。 因此,这篇文章中提到的一些功能在您阅读时可能已经发生变化,但我们会尽最大努力使其保持最新。
最值得注意的是,如果 Symfony/Console 不可用,使用 makefile 和 make 工具来构建项目仍然悬而未决,因为它似乎无法在某些操作系统上正常工作。 Fabien 最近围绕这个进行了一项调查,征求社区对替代品的建议,并且压倒性地,社区投票赞成只需要 Symfony/Console。
有什么不同?
最值得注意的是,Flex 尊重即将到来的 Symfony 4 更新,这些更新归结为以下主要变化:
- PHP 7+ 是必需的,所有文件夹都是可选的。 如果您的项目没有使用它,则它不必存在。 这使得目录树更简单,更易读。 此外,通常无用的文件如
.htaccess
, LICENSE
, 和 README
也已被删除——需要这些的项目可以轻松添加它们。 没有了 web
文件夹。 相反,有 public
文件夹,就像在所有其他主要框架中一样。 这整合了跨生态系统的用户体验。 临时文件下 /var
在项目文件夹的根目录中,使用 /var/cache
为长期缓存保留的子文件夹,例如用于部署应用程序的合并类文件,因为只读工件源代码在下面 /src
. 不 /app
. 配置进入 /config
. 模板进入 /templates
. Flex 将拥有自己的 Symfony 验证的包列表,这些包仅由一个别名引用。 所以执行 composer require cli
实际上会触发 Flex,它会在它的包列表中查找,找到标记为 cli
(在本例中为 Symfony 控制台),然后安装它。 这些“官方”包被称为食谱,可以在这里找到。 要接受用户提交的配方,Flex 的配置中存在一个标志,需要将其设置为 true: composer config extra.symfony.allow-contrib true
. 这些食谱可以在这里找到。 通过正式认可一些包,Symfony 在很多方面变得和 Laravel 一样固执己见。 虽然这在某些方面很糟糕,但它在很多方面都非常好:一种统一的、自以为是的方式来构建大多数人使用的 Symfony 应用程序,以便每个人都在同一页面上。 捆绑包片段不再需要自定义激活并添加到大量文件中。 Flex 自动执行此操作以及删除它们。 Symfony 4 将使用 Laravel 之类的环境变量,而不是配置文件中的参数
自举
像往常一样,我们假设您已经在运行一个健康的 VM 环境,例如 Homestead Improved,这样您就可以跟进了。
好吧,让我们开始使用示例应用程序。 所有 Symfony 应用程序现在都可以从最简单的超小型 Symfony Skeleton 应用程序开始:
composer create-project symfony/skeleton flexy
注意创建的目录结构。
在 /public
,我们不再有 app.php
和 app_dev.php
, 只有 index.php
文件。 环境类型(test / dev / prod)现在由环境变量决定,并从 /config
文件夹。
注意安装过程的结尾是如何提到的 make cache-warmup
被调用,你可以运行 make serve
. 这就是新的 Symfony 使用上面提到的“有争议的”Makefile 方法的地方。 这可能会改变。
开箱即用,在浏览器中打开此骨架将抛出错误,因为尚未定义任何路由。 让我们解决这个问题。
index:
path: /
defaults: { _controller: 'AppControllerDefaultController::index' }
config/routes.yaml
我们需要创建这个控制器及其 index
行动:
<?php
namespace AppController;
use SymfonyComponentHttpFoundationResponse;
class DefaultController
{
public function index()
{
return new Response('Hello');
}
}
这将产生一个简单的 Hello 屏幕,如下所示:
执行权限
如果你尝试安装像 Symfony/Console 这样的二进制文件 composer req cli
,您可能会遇到以下问题:
~ bin/console
-bash: bin/console: Permission denied
这是使用虚拟机时已知的问题,可以通过以下任一方式轻松修复:
- 运行控制台
php bin/console
而不是直接运行它,或者通过执行以下命令将“执行”权限添加到主机上的文件(而不是从虚拟机中): chmod +x bin/console
. 这将允许直接执行 bin/console
然后从虚拟机内部。
添加捆绑包
我们构建的“Hello”视图有点赤裸裸。 让我们添加一些模板。
composer req template
我们可以用 template
, twig
, templates
, 或者 templating
此处,如 Twig 配方的别名中所定义。
Symfony 4 / Flex 方法会自动为我们激活这个包并设置一个文件夹(/templates
) 与 base
布局视图,以及一个配置文件(config/packages/twig.yaml
).
我们现在可以自由地为我们的 Hello 路由定义一个视图:
{% extends '../base.html.twig' %}
{% block body %}
{{ greeting }}
{% endblock %}
/templates/default/index.html.twig
现在我们可以修改控制器来返回这个而不是纯文本响应:
<?php
namespace AppController;
use SymfonyBundleFrameworkBundleControllerController;
class DefaultController extends Controller
{
public function index()
{
return $this->render('default/index.html.twig', ['greeting' => 'hello']);
}
}
注意我们如何扩展 FrameworkBundle
的控制器访问 render
方法,但这就是我们必须做的所有添加的配置。 我们的 hello 路线现在更酷了。
大捆
现在让我们尝试添加一个大包——一个包含多个其他包的包。 这 admin
用于创建后端的 bundle 是一个不错的选择。 此外,这是 Symfony 团队决定正式认可的一个,它引入了 orm
recipe,它指的是 Doctrine——另一个 Symfony 推荐(你能看到行动中的自以为是吗?)
composer req admin
在使用管理包之前,我们需要创建一个实体。 为此,我们需要一个数据库。 创建一个新的数据库和用户。 这个过程应该没问题:
mysql -u homestead -psecret
create database flexy character set utf8mb4 collate utf8mb4_unicode_ci;
如果您觉得有必要,也可以随意创建一个特定于数据库的用户。 然后,修改 .env
文件尊重这一点:
DATABASE_URL="mysql://homestead:[email protected]:3306/flexy?charset=utf8mb4&serverVersion=5.7"
最后,让我们创建一个实体。 假设我们正在制作一个网站,允许用户向该网站提交内容——例如 Reddit,提交链接。 我们将有一个名为“提交”的实体,如下所示:
<?php
namespace AppEntity;
use DoctrineORMMapping as ORM;
/**
* Class Submission
* @package AppEntity
*
* @ORMEntity
* @ORMTable(name="submission")
*/
class Submission
{
/**
* @ORMColumn(type="integer")
* @ORMId
* @ORMGeneratedValue(strategy="AUTO")
*/
public $id;
/**
* @ORMColumn(type="string", length=255)
*/
public $name;
/**
* @ORMColumn(type="string", length=255)
*/
public $url;
/**
* @ORMColumn(type="text")
*/
public $description;
}
该实体需要在 config/packages/easy_admin.yml
文件:
easy_admin:
entities:
- AppEntitySubmission
现在我们将让 Doctrine 为我们创建这张表。
bin/console doctrine:schema:update --force
请注意,如果数据库不存在,您也可以让 Doctrine 创建数据库。 调查 doctrine:database:create
对于该功能。
如果我们现在访问 /admin
我们应用程序的 URL,我们应该看到这样的东西:
添加提交现在应该像魅力一样工作:
非官方捆绑包
那些没有被 Symfony 官方支持的包呢?
为此,我们需要拨动 Composer 标志的开关。
composer config extra.symfony.allow-contrib true
这也将允许从该存储库中提取食谱。 假设我们想让我们的提交有 uuid
对于 ID 而不是简单的自动递增整数。 为此,我们可以使用 Ramsey 的 UUID-Doctrine 包。 请求 contrib 食谱时,它们通常没有别名,必须完整引用,就像常规包一样。
composer req ramsey/uuid-doctrine
由于这是一个社区贡献的包,Symfony 会在下载完成后向您发出警告。
注意:contrib repo 是死包和包的一个很好的过滤器——每个关心他们工作的包/包开发人员都会把它移到那里,所以你可以确定丢失的包的开发已经停滞了。
安装包后,我们可以在我们的项目中使用它。
首先,我们需要告诉 Doctrine 它现在可用(在我看来,配方应该自己做的事情——还不够自动化!):
doctrine:
dbal:
url: '%env(DATABASE_URL)%'
types:
uuid: RamseyUuidDoctrineUuidType
orm:
...
config/packages/doctrine.yaml
接下来,我们更改提交实体以在其上使用此类型 id
属性:
...
class Submission
{
/**
* @var RamseyUuidUuid
*
* @ORMId
* @ORMColumn(type="uuid", unique=true)
* @ORMGeneratedValue(strategy="CUSTOM")
* @ORMCustomIdGenerator(class="RamseyUuidDoctrineUuidGenerator")
*/
public $id;
...
现在让我们更新数据库并清除当前实体:
bin/console doctrine:schema:drop --force
bin/console doctrine:schema:update --force
最后,让我们尝试重新访问 /admin
并添加一个新实体。
果然,我们的新实体有一个 UUID 作为主键。
注意:在 InnoDB 类型数据库中使用 UUID 作为主键时,建议使用其他类型,但为了简洁起见,我们使用默认值。 完整说明在这里。
添加第三方工具
其他第三方工具可以像以前一样使用——只是它们不能由 Flex 自动配置。 您必须手动注册它们并以相同的方式删除它们。 因此,建议您将任何需要额外配置才能与 Symfony 顺利工作的包移动到 contrib
食谱回购,以便其他人可以从更流畅的 Flex 工作流程中受益。
结论
Symfony Flex 是安装和管理 Symfony 应用程序的现代方式,它是通往 Symfony 4 大门的红地毯。不用说,我们对 Symfony 最近涉足现代开发和高 DX 领域感到非常兴奋,我们会密切关注它。 我们希望您觉得这篇介绍很有用!
我们没有将这个最终结果与另一个框架进行基准测试,纯粹是因为当你考虑你可以做的可能的优化时它没有意义,而且因为我们有一个性能月(整个 11 月),在此期间我们将吞噬各种与性能相关的问题,并通过一整套技术,您将能够应用于您的项目——无论框架或应用程序类型如何。 敬请关注!