Symfony - 快速指南


Symfony - 简介

PHP Web 框架是类的集合,有助于开发 Web 应用程序。Symfony 是一个开源 MVC 框架,用于快速开发现代 Web 应用程序。Symfony 是一个全栈 Web 框架。它包含一组可重用的 PHP 组件。您可以在应用程序中使用任何 Symfony 组件,独立于框架。

Symfony 拥有大量的功能和活跃的社区。它具有使用 YAML、XML 或注释的灵活配置。Symfony 集成了独立的库和 PHP 单元。Symfony 主要受到 Ruby on Rails、Django 和 Spring Web 应用程序框架的启发。Symfony 组件被许多开源项目使用,包括 Composer、Drupal 和 phpBB。

Symfony 框架由多个组件组成,例如 HttpFoundation 组件,它理解 HTTP 并提供其他组件使用的良好请求和响应对象。其他的只是辅助组件,例如帮助验证数据的验证器。内核组件是系统的核心。内核基本上是管理环境并负责处理 http 请求的“主类”。

Symfony 组织良好的结构、干净的代码和良好的编程实践使 Web 开发变得更加容易。Symfony 非常灵活,用于构建微型站点并处理具有数十亿连接的企业应用程序。

Symfony 框架 - 功能

Symfony 旨在优化 Web 应用程序的开发,并随着每个版本的发布而不断增加功能。

Symfony 框架的一些显着特征如下 -

  • 基于模型-视图-控制器的系统
  • 高性能PHP框架
  • 灵活的 URI 路由
  • 代码可重用且更易于维护
  • 会话管理
  • 错误记录
  • 支持多种平台的全功能数据库类
  • 支持庞大且活跃的社区
  • 一组解耦且可重用的组件
  • 应用程序的标准化和互操作性
  • 针对跨站点请求伪造和其他攻击的安全性
  • 树枝模板引擎

Symfony 为开发人员提供了很大的灵活性。它具有调试、代码可读性和开发可扩展程序的强大功能。

Symfony 是一个全栈 Web 框架;它是创建 Web 应用程序的非常有效的工具。许多公司为客户提供 Symfony 服务。

以下是使用 Symfony 框架可以获得的一些好处。

  • Microframework - Symfony 可用于开发特定功能。您不需要重新开发或安装整个框架。

  • 减少开发时间开销。

  • 极其成熟的模板引擎,快速将内容交付给用户。

  • 兼容且可扩展- 程序员可以轻松扩展所有框架类。

Symfony 框架 - 应用程序

Symfony 组件可以用作其他应用程序的一部分,例如 Drupal、Laravel、phpBB、Behat、Doctrine 和 Joomla。

  • Drupal 8 - Drupal 是一个开源内容管理 PHP 框架。Drupal 8 使用 Symfony 的核心层并对其进行扩展以提供对 Drupal 模块的支持。

  • Thelia - Thelia 是一个基于 Symfony 的电子商务解决方案。最初,Thelia 是用 PHP 代码和 MySQL 编写的,但是它在开发更快的应用程序方面落后了。为了克服这个缺点,Thelia 与 Symfony 集成,以可定制的方式开发应用程序。

  • Dailymotion - Dailymotion 是世界上最大的独立视频娱乐网站之一,总部位于法国。一旦他们决定迁移具有大型社区的开源框架,Dailymotion 开发人员就决定使用 Symfony 组件功能,因为它具有灵活性。

Symfony - 安装

本章介绍如何在您的计算机上安装 Symfony 框架。Symfony 框架的安装非常简单和容易。您有两种方法在 Symfony 框架中创建应用程序。第一种方法是使用 Symfony Installer,这是一个在 Symfony 框架中创建项目的应用程序。第二种方法是基于 Composer 的安装。让我们在以下部分中一一详细介绍每种方法。

系统要求

在进行安装之前,您需要满足以下系统要求。

  • Web 服务器(以下任何一项)
    • WAMP(Windows)
    • 灯(Linux)
    • XAMP(多平台)
    • MAMP(麦金塔)
    • Nginx(多平台)
    • 微软 IIS (Windows)
    • PHP内置开发Web服务器(多平台)
  • 操作系统:跨平台
  • 浏览器支持:IE (Internet Explorer 8+)、Firefox、Google Chrome、Safari、Opera
  • PHP 兼容性:PHP 5.4 或更高版本。为了获得最大的好处,请使用最新版本。

在本教程中,我们将使用 PHP 内置开发 Web 服务器。

Symfony 安装程序

Symfony Installer 用于在 Symfony 框架中创建 Web 应用程序。现在,让我们使用以下命令配置 Symfony 安装程序。

$ sudo mkdir -p /usr/local/bin 
$ sudo curl -LsS https://symfony.com/installer -o /usr/local/bin/symfony 
$ sudo chmod a+x /usr/local/bin/symfony

现在,您已经在计算机上安装了 Symfony 安装程序。

创建您的第一个 Symfony 应用程序

以下语法用于创建最新版本的 Symfony 应用程序。

句法

symfony new app_name

这里,app_name 是您的新应用程序名称。您可以指定任何您想要的名称。

例子

symfony new HelloWorld

执行上述命令后,您将看到以下响应。

Downloading Symfony...  

0 B/5.5 MiB ░░░░░░░░░░░  
……………………………………………………………  
……………………………………………………………   
Preparing project...  
✔  Symfony 3.2.7 was successfully installed. Now you can:  
   * Change your current directory to /Users/../workspace/firstapp  
   * Configure your application in app/config/parameters.yml file.  
   * Run your application: 
      1. Execute the php bin/console server:run command. 
      2. Browse to the http://localhost:8000 URL.  
   * Read the documentation at http://symfony.com/doc 

此命令创建一个名为“firstapp/”的新目录,其中包含 Symfony 框架最新版本的空项目。

安装特定版本

如果需要安装特定的 Symfony 版本,请使用以下命令。

symfony new app_name 2.8 
symfony new app_name 3.1

基于 Composer 的安装

您可以使用 Composer 创建 Symfony 应用程序。希望您已在计算机上安装了作曲家。如果尚未安装 Composer,请下载并安装它。

以下命令用于使用 Composer 创建项目。

$ composer create-project symfony/framework-standard-edition app_name

如果需要指定具体版本,可以在上面的命令中指定。

运行应用程序

移动到项目目录并使用以下命令运行应用程序。

cd HelloWorld 
php bin/console server:run 

执行上述命令后,打开浏览器并请求 url http://localhost:8000/。它产生以下结果。

结果

运行应用程序

Symfony - 架构

Symfony 基本上是高质量组件和捆绑包的集合。组件是提供单一核心功能的类的集合。例如,Cache组件提供缓存功能,可以将其添加到任何应用程序中。组件是 Symfony 应用程序的构建块。Symfony 拥有 30 多个高质量组件,这些组件被用于 Laravel、Silex 等许多 PHP 框架中。

捆绑包与插件类似,但易于创建且易于使用。实际上,Symfony 应用程序本身就是一个由其他包组成的包。单个包可以使用任意数量的 Symfony 组件以及第三方组件来提供 Webframework、数据库访问等功能。Symfony 核心 Web 框架是一个名为 FrameworkBundle 的包,还有一个名为 FrameworkExtraBundle 的包,它提供了更复杂的功能编写 Web 应用程序的选项。

下图指定了组件、捆绑包和 Symfony 应用程序之间的关系。

建筑学

网络框架

Symfony 主要设计用于相对轻松地编写高质量的 Web 应用程序。它提供了各种选项来编写不同类型的 Web 应用程序,从简单的网站到基于 REST 的高级 Web 服务。Symfony 以单独的捆绑包形式提供 Web 框架。Symfony Web 框架中使用的常见捆绑包如下 -

  • 框架包
  • 框架额外捆绑包
  • 教义束

Symfony Web 框架基于模型-视图-控制器 (MVC) 架构。模型代表了我们业务实体的结构。视图根据情况以最佳方式向用户显示模型。控制器处理来自用户的所有请求,通过与模型交互来完成实际工作,最后为视图提供必要的数据以将其显示给用户。

Symfony Web 框架提供了企业级应用程序所需的所有高级功能。以下是 Symfony Web 应用程序的简单工作流程。

Web应用程序

该工作流程由以下步骤组成。

步骤 1 - 用户通过浏览器向应用程序发送请求,例如 http://www.symfonyexample.com/index。

步骤 2 - 浏览器将向 Web 服务器(例如 Apache Web 服务器)发送请求。

步骤 3 - Web 服务器将请求转发到底层 PHP,PHP 又将其发送到 Symfony Web 框架。

步骤 4 - HttpKernel 是 Symfony Web 框架的核心组件。HttpKernel 使用路由组件解析给定请求的控制器,并将请求转发到目标控制器。

步骤 5 - 所有业务逻辑都发生在目标控制器中。

步骤 6 - 控制器将与模型交互,模型又通过 Doctrine ORM 与数据源交互。

步骤 7 - 一旦控制器完成该过程,它就会自行生成响应或通过 View Engine 生成响应,并将其发送回 Web 服务器。

步骤 8 - 最后,响应将由网络服务器发送到请求的浏览器。

Symfony - 组件

如前所述,Symfony 组件是提供特定功能的独立 PHP 库,可在任何 PHP 应用程序中使用。Symfony 的每个版本都引入了有用的新组件。目前,Symfony 框架中有 30 多个高质量组件。本章我们来学习一下Symfony组件的使用。

安装 Symfony 组件

使用composer命令可以轻松安装Symfony组件。以下通用命令可用于安装任何 Symfony 组件。

cd /path/to/project/dir 
composer require symfony/<component_name> 

让我们创建一个简单的 php 应用程序并尝试安装文件系统组件。

步骤 1 - 为应用程序创建一个文件夹,filesystem-example

cd /path/to/dev/folder 
mdkir filesystem-example 
cd filesystem-example 

步骤 2 - 使用以下命令安装文件系统组件。

composer require symfony/filesystem  

步骤 3 - 创建文件main.php并输入以下代码。

<?php 
   require_once __DIR__ . '/vendor/autoload.php'; 
   use Symfony\Component\Filesystem\Filesystem; 
   use Symfony\Component\Filesystem\Exception\IOExceptionInterface; 
   
   $fs = new Filesystem(); 
   try { 
      $fs->mkdir('./sample-dir'); 
      $fs->touch('./sample-dir/text.txt'); 
   } catch (IOExceptionInterface $e) { 
      echo $e; 
   } 
?>  

第一行非常重要,它从使用 Composer 命令安装的所有组件中加载所有必需的类。接下来的几行使用 Filesystem 类。

步骤 4 - 使用以下命令运行应用程序,它将创建一个新文件夹sample-dir并在其下创建一个文件test.txt 。

php main.php

Symfony 组件的详细信息

Symfony 提供的组件范围从简单的功能(例如文件系统)到高级功能(例如事件、容器技术和依赖项注入)。让我们在下面的部分中一一了解所有组件。

文件系统

文件系统组件提供了与文件和目录相关的基本系统命令,例如文件创建、文件夹创建、文件存在等。文件系统组件可以使用以下命令安装。

composer require symfony/filesystem

发现者

Finder 组件提供了流畅的类来查找指定路径中的文件和目录。它提供了一种迭代路径中文件的简单方法。可以使用以下命令安装 Finder 组件。

composer require symfony/finder

安慰

控制台组件提供了各种选项来轻松创建可以在终端中执行的命令。Symfony 广泛使用Command组件来提供各种功能,例如创建新应用程序、创建捆绑包等。甚至可以使用 Symfony 命令、php bin/console server:run调用 Web 服务器中的 PHP 构建,如安装部分所示。可以使用以下命令安装控制台组件。

composer require symfony/console

让我们创建一个简单的应用程序并使用控制台组件创建一个命令HelloCommand并调用它。

步骤 1 - 使用以下命令创建项目。

cd /path/to/project 
composer require symfony/console 

步骤 2 - 创建文件main.php并包含以下代码。

<?php 
   require __DIR__ . '/vendor/autoload.php'; 
   use Symfony\Component\Console\Application; 
   
   $app = new Application(); 
   $app->run(); 
?> 

应用程序类设置了一个简单的控制台应用程序的必要功能。

步骤 3 - 运行应用程序php main.php,这将产生以下结果。

Console Tool  
Usage: 
   command [options] [arguments]  
Options: 
   -h, --help            Display this help message 
   -q, --quiet           Do not output any message 
   -V, --version         Display this application version 
         --ansi            Force ANSI output 
         --no-ansi         Disable ANSI output 
   -n, --no-interaction  Do not ask any interactive question 
   -v|vv|vvv, --verbose  Increase the verbosity of messages: 1 for normal output, 
      2 for more verbose output and 3 for debug  
Available commands: 
   help  Displays help for a command 
   list  Lists commands

步骤 4 - 创建一个名为HelloCommand 的类,扩展main.php本身中的Command类。

use Symfony\Component\Console\Command\Command; 
use Symfony\Component\Console\Input\InputInterface; 
use Symfony\Component\Console\Output\OutputInterface; 
use Symfony\Component\Console\Input\InputArgument;

class HelloCommand extends Command { 
}

该应用程序使用命令组件中提供的以下四个类。

  • 命令- 用于创建新命令

  • InputInterface - 用于设置用户输入

  • InputArgument - 用于获取用户输入

  • OutputInterface - 用于将输出打印到控制台

步骤 5 - 创建一个函数configure()并设置名称、描述和帮助文本。

protected function configure() { 
   $this 
      ->setName('app:hello') 
      ->setDescription('Sample command, hello') 
      ->setHelp('This command is a sample command') 
} 

步骤 6 - 创建命令的输入参数、用户并将其设置为强制。

protected function configure() { 
   $this 
      ->setName('app:hello') 
      ->setDescription('Sample command, hello') 
      ->setHelp('This command is a sample command') 
      ->addArgument('name', InputArgument::REQUIRED, 'name of the user'); 
}

步骤 7 - 创建一个带有两个参数的函数execute() InputArgumentOutputArgument

protected function execute(InputInterface $input, OutputInterface $output) { 
}

步骤 8 - 使用InputArgument获取用户输入的用户详细信息,并使用OutputArgument将其打印到控制台。

protected function execute(InputInterface $input, OutputInterface $output) { 
   $name = $input->getArgument('name'); 
   $output->writeln('Hello, ' . $name); 
}

步骤 9 -使用Application类的add方法将HelloCommand注册到应用程序中。

$app->add(new HelloCommand()); 

完整的应用程序如下。

<?php 
   require __DIR__ . '/vendor/autoload.php'; 
   use Symfony\Component\Console\Application; 
   use Symfony\Component\Console\Command\Command; 
   use Symfony\Component\Console\Input\InputInterface; 
   use Symfony\Component\Console\Output\OutputInterface; 
   use Symfony\Component\Console\Input\InputArgument;  
   
   class HelloCommand extends Command { 
      protected function configure() { 
         $this 
            ->setName('app:hello') 
            ->setDescription('Sample command, hello') 
            ->setHelp('This command is a sample command') 
            ->addArgument('name', InputArgument::REQUIRED, 'name of the user'); 
      }  
      protected function execute(InputInterface $input, OutputInterface $output) { 
         $name = $input->getArgument('name'); 
         $output->writeln('Hello, ' . $name);
      }  
      $app = new Application(); 
      $app->add(new HelloCommand()); 
      $app->run(); 
   }         
?>      

步骤 10 - 现在,使用以下命令执行应用程序,结果将如预期所示为 Hello, Jon。

php main.php app:hello Jon

Symfony 在任何 Symfony Web 应用程序的 bin 目录中附带了一个名为console的预构建二进制文件,可用于调用应用程序中的命令。

过程

进程组件提供了在子进程中以安全高效的方式运行任何系统命令的选项。可以使用以下命令安装进程组件。

composer require symfony/process

类加载器

ClassLoader 组件提供PSR-0PSR-4类加载器标准的实现。它可用于自动加载类。近期会贬值。基于 Composer 的类加载器优于此组件。可以使用以下命令安装 ClassLoader 组件。

composer require symfony/class-loader

财产访问

PropertyAccess 组件提供了各种选项来使用字符串表示法读取和写入对象和数组详细信息。例如,可以使用[price]字符串动态访问具有关键价格的数组Product

$product = array( 
   'name' => 'Cake' 
   'price' => 10 
);  
var priceObj = $propertyAccesserObj->getValue($product, '[price]');

可以使用以下命令安装 PropertyAccess 组件。

composer require symfony/property-access 

房产信息

PropertyInfo 组件与 PropertyAccess 组件类似,但它仅适用于 PHP 对象并提供更多功能。

class Product { 
   private $name = 'Cake'; 
   private $price = 10;  
   
   public function getName() { 
      return $this->name; 
   }  
   public function getPrice() { 
      return $this->price; 
   } 
}  
$class = Product::class; 
$properties = $propertyInfoObj->getProperties($class);  
/* 
   Example Result 
   -------------- 
   array(2) { 
      [0] => string(4) "name" 
      [1] => string(5) "price" 
   } 
*/

可以使用以下命令安装 PropertyInfo 组件。

composer require symfony/property-info

事件调度器

EventDispatcher 组件提供了 PHP 中基于事件的编程。它使对象能够通过分派事件并侦听事件来相互通信。我们将在事件和事件监听器章节中学习如何创建事件并监听它们。

可以使用以下命令安装 EventDispatcher 组件。

composer require symfony/event-dispatcher

依赖注入

DependencyInjection 组件提供了一种简单有效的机制来创建具有依赖项的对象。当项目增长时,它会出现许多具有深度依赖关系的类,需要正确处理。否则,项目就会失败。DependencyInjection 提供了一个简单而强大的容器来处理依赖关系。我们将在服务容器章节中了解容器和依赖注入概念。

可以使用以下命令安装 DependencyInjection 组件。

composer require symfony/dependency-injection

串行器

Serializer 组件提供了一个选项,可以将 PHP 对象转换为特定格式(例如 XML、JSON、Binary 等),然后允许将其转换回原始对象,而不会丢失任何数据。

可以使用以下命令安装序列化器组件。

composer require symfony/serializer

配置

配置组件提供加载、解析、读取和验证 XML、YAML、PHP 和 ini 类型配置的选项。它还提供了各种选项来从数据库加载配置详细信息。这是以清晰简洁的方式配置 Web 应用程序的重要组件之一。可以使用以下命令安装配置组件。

composer require symfony/config

表达语言

ExpessionLanguage 组件提供了成熟的表达式引擎。表达式是单行的,旨在返回一个值。表达式引擎可以轻松地编译、解析表达式并获取表达式的值。它允许非 PHP 程序员(例如系统管理员)在配置环境(文件)中使用一个或多个表达式。可以使用以下命令安装 ExpressionLanguage 组件。

composer require symfony/expression-language

选项解析器

OptionsResolver 组件提供了一种验证我们系统中使用的选项系统的方法。例如,数据库设置放在一个数组中,dboption以主机、用户名、密码等作为键。在使用它连接到数据库之前,您需要验证条目。OptionsResolver 通过提供一个简单的类 OptionsResolver 和一个方法解析器来简化此任务,该方法解析器解析数据库设置,如果存在任何验证问题,它将报告它。

$options = array( 
   'host'     => '<db_host>', 
   'username' => '<db_user>', 
   'password' => '<db_password>', 
);  
$resolver = new OptionsResolver(); 
$resolver->setDefaults(array( 
   'host'     => '<default_db_host>', 
   'username' => '<default_db_user>', 
   'password' => '<default_db_password>', 
)); 
$resolved_options = $resolver->resolve($options);

可以使用以下命令安装OptionsResolver组件。

composer require symfony/options-resolver 

多滕夫

Dotenv 组件提供了各种选项来解析 .env 文件以及其中定义的变量,以便可以通过getenv()、 $_ENV$_SERVER访问。可以使用以下命令安装 Dotenv 组件。

composer require symfony/dotenv

缓存

缓存组件提供了扩展的PSR-6实现。它可用于向我们的 Web 应用程序添加缓存功能。由于它遵循PSR-6,因此很容易上手,并且可以轻松地用来代替另一个基于 PSR-6 的缓存组件。可以使用以下命令安装缓存组件。

composer require symfony/cache 

国际

Intl 组件是 C Intl 扩展的替代库。可以使用以下命令安装 Intl 组件。

composer require symfony/intl

翻译

翻译组件提供了各种选项来国际化我们的应用程序。通常,不同语言的翻译详细信息将存储在一个文件中,每种语言一个文件,并将在应用程序运行时动态加载。编写翻译文件有不同的格式。翻译组件提供了各种选项来加载任何类型的格式,例如纯 PHP 文件、CSV、ini、Json、Yaml、ICU 资源文件等。可以使用以下命令安装翻译组件。

composer require symfony/translation

工作流程

工作流组件提供了处理有限状态机的高级工具。通过以简单且面向对象的方式提供此功能,工作流组件可以相对轻松地使用 PHP 进行高级编程。我们将在“高级概念”章节中详细了解它。

可以使用以下命令安装工作流组件。

composer require symfony/workflow 

亚米尔

Yaml 组件提供了一个选项,可以解析 YAML 文件格式并将其转换为 PHP 数组。它还能够从纯 php 数组编写 YAML 文件。可以使用以下命令安装 Yaml 组件。

composer require symfony/yaml

LDAP

Ldap 组件提供 PHP 类来连接到 LDAP 或 Active Directory 服务器并对用户进行身份验证。它提供了连接到 Windows 域控制器的选项。可以使用以下命令安装 LDAP 组件。

composer require symfony/ldap

调试

调试组件提供了各种选项来在 PHP 环境中启用调试。通常,调试 PHP 代码很困难,但调试组件提供了简单的类来简化调试过程并使其干净且结构化。可以使用以下命令安装调试组件。

composer require symfony/debug

跑表

Stopwatch 组件提供了 Stopwatch 类来分析我们的 PHP 代码。一个简单的用法如下。

use Symfony\Component\Stopwatch\Stopwatch; 
$stopwatch = new Stopwatch(); 
$stopwatch->start('somename');  

// our code to profile 
$profiled_data = $stopwatch->stop('somename');  
echo $profiled_data->getPeriods()

可以使用以下命令安装秒表组件。

composer require symfony/stopwatch

变量转储器

VarDumper组件提供了更好的dump()函数。只需包含 VarDumper 组件并使用转储功能即可获得改进的功能。可以使用以下命令安装 VarDumper 组件。

composer require symfony/var-dumper

浏览器工具包

BrowserKit组件提供了一个抽象的浏览器客户端接口。它可用于以编程方式测试 Web 应用程序。例如,它可以请求表单、输入示例数据并提交,以通过编程方式查找表单中的任何问题。可以使用以下命令安装 BrowserKit 组件。

composer require symfony/browser-kit

PHPUnit桥

PHPUnit Bridge 组件提供了许多选项来改进 PHPUnit 测试环境。可以使用以下命令安装 PHPUnit Bridge 组件。

composer require symfony/phpunit-bridge

资产

资产组件在 Web 应用程序中提供通用资产处理。它为 CSS、HTML、JavaScript 等资产生成 URL,并执行版本维护。我们将在 View Engine 章节中详细检查 asset 组件。可以使用以下命令安装资产组件。

composer require symfony/asset

CSS选择器

CssSelector 组件提供了将基于 CSS 的选择器转换为 XPath 表达式的选项。Web 开发人员比 XPath 表达式更了解基于 CSS 的选择器表达式,但在 HTML 和 XML 文档中查找元素的最有效的表达式是XPath 表达式

CssSelector 使开发人员能够在CSS 选择器中编写表达式,但是该组件在执行之前将其转换为 XPath 表达式。因此,开发人员具有 CSS 选择器的简单性和 XPath 表达的高效性的优势。

可以使用以下命令安装 CssSelector 组件。

composer require symfony/css-selector

多姆·克劳勒

DomCrawler 组件提供了各种选项来使用 DOM 概念在 HTML 和 XML 文档中查找元素。它还提供使用 XPath 表达式查找元素的选项。DomCrawler 组件可以与 CssSelector 组件一起使用,以使用 CSS 选择器而不是 XPath 表达式。可以使用以下命令安装 DomCrawler 组件。

composer require symfony/dom-crawler

形式

表单组件可以在 Web 应用程序中轻松创建表单。我们将在“表单”章节中详细学习表单编程。可以使用以下命令安装表单组件。

composer require symfony/form

Http基金会

HttpFoundation 组件为 HTTP 规范提供了一个面向对象的层。默认情况下,PHP 以基于数组的对象形式提供 HTTP 请求和响应详细信息,例如$_GET、$_POST、$_FILES、$_SESSION等。基于 HTTP 的功能(例如设置 cookie)可以使用简单、普通的旧函数setCookie( )。HttpFoundation 在一小组类中提供了所有与 HTTP 相关的功能,例如 Request、Response、RedirectResponse 等,我们将在后面的章节中了解这些类。

可以使用以下命令安装 HttpFoundation 组件。

composer require symfony/http-foundation

Http内核

HttpKernel 组件是 Symfony Web 设置中的核心组件。它提供了 Web 应用程序所需的所有功能 - 从接收请求对象到发回响应对象。Symfony Web 应用程序的完整架构由 HttpKernel 提供,如 Symfony Web 框架架构中所述。

可以使用以下命令安装 HttpKernel 组件。

composer require symfony/http-kernel

路由

路由组件将 HTTP 请求映射到一组预定义的配置变量。路由决定应用程序的哪一部分应该处理请求。我们将在路由章节中了解有关路由的更多信息。

可以使用以下命令安装路由组件。

composer require symfony/filesystem

模板化

模板组件提供了构建高效模板系统所需的基础设施。Symfony 使用模板组件来实现其视图引擎。我们将在视图引擎章节中了解有关模板组件的更多信息。

可以使用以下命令安装模板组件。

composer require symfony/templating

验证器

验证器组件提供了JSR-303 Bean 验证规范的实现。它可用于在 Web 环境中验证表单。我们将在验证章节中了解有关验证器的更多信息。

可以使用以下命令安装验证器组件。

composer require symfony/validator

安全

安全组件为我们的Web应用程序提供了完整的安全系统,无论是HTTP基本身份验证、HTTP摘要身份验证、基于交互式表单的身份验证、X.509认证登录等。它还通过内置的ACL系统提供基于用户角色的授权机制。我们将在“高级概念”章节中了解更多详细信息。

可以使用以下命令安装安全组件。

composer require symfony/security

Symfony - 服务容器

在任何应用程序中,对象往往会随着应用程序的增长而增加。随着对象的增加,对象之间的依赖关系也会增加。为了成功的应用程序,需要正确处理对象依赖性。

正如组件一章中所讨论的,Symfony 提供了一个简单高效的组件DependencyInjection来处理对象依赖关系。服务容器是对象之间具有正确解析的依赖关系的容器。本章让我们学习如何使用 DependencyInjection 组件。

让我们创建一个Greeter类。Greeter 类的用途是向用户打招呼,如以下示例所示。

$greeter = new Greeter('Hi'); 
$greeter->greet('Jon'); // print "Hi, Jon" 

Greeter类的完整代码如下。

class Greeter { 
   private $greetingText; 
   
   public function __construct($greetingText) { 
      $this->greetingText = $greetingText; 
   }  
   public function greet($name) { 
      echo $this->greetingText . ", " . $name . "\r\n"; 
   } 
}

现在,让我们将 Greeter 类添加到服务容器中。Symfony 提供了ContainerBuilder来创建新容器。创建容器后,可以使用容器的 register 方法将 Greeter 类注册到其中。

use Symfony\Component\DependencyInjection\ContainerBuilder; 
$container = new ContainerBuilder(); 
$container 
   ->register('greeter', 'Greeter') 
   ->addArgument('Hi');

在这里,我们使用静态参数来指定问候语文本 Hi。Symfony 还提供参数的动态设置。要使用动态参数,我们需要选择一个名称并将其指定在 % 之间,并且可以使用容器的setParameter方法来设置该参数。

$container = new ContainerBuilder(); 
$container 
   ->register('greeter', 'Greeter') 
   ->addArgument('%greeter.text%');  
$container->setParameter('greeter.text', 'Hi');

我们已经注册了一个具有适当设置的 Greeter 类。现在,我们可以使用容器get方法要求容器提供正确配置的 Greeter 对象。

$greeter = $container->get('greeter'); 
$greeter->greet('Jon'); // prints "Hi, Jon" 

我们已经成功地将一个类 Greeter 注册到容器中,从容器中获取并使用它。现在,让我们创建另一个类User,它使用 Greeter 类并看看如何注册它。

class User { 
   private $greeter;  
   public $name; 
   public $age;  
   
   public function setGreeter(\Greeter $greeter) { 
      $this->greeter = $greeter; 
   }  
   public function greet() { 
      $this->greeter->greet($this->name); 
   } 
}

User 类使用其 setter 方法之一setGreeter获取Greeter类。对于这种情况,Symfony 提供了一个方法addMethodCall和一个类Reference来引用另一个类,如以下代码所示。

use Symfony\Component\DependencyInjection\Reference;  
$container 
   ->register('user', 'User') 
   ->addMethodCall('setGreeter', array(new Reference('greeter'))); 

最后,我们注册了两个类,GreeterUser,它们之间有很强的关系。现在,我们可以安全地从容器中获取具有正确配置的 Greeter 类的 User 对象,如以下代码所示。

$container->setParameter('greeter.text', 'Hi'); 
$user = $container->get('user'); 
$user->name = "Jon"; 
$user->age = 20; 
$user->greet(); // Prints "Hi, Jon"

我们已经了解了如何使用 PHP 本身在容器中配置对象。Symfony 还提供其他机制。它们是 XML 和 YAML 配置文件。让我们看看如何使用 YAML 配置容器。为此,请安装symfony/configsymfony/yaml组件以及symfony/dependency-injection组件。

cd /path/to/dir 
mkdir dependency-injection-example 
cd dependency-injection-example 
composer require symfony/dependency-injection 
composer require symfony/config 
composer require symfony/yaml

YAML 配置将写入单独的文件services.yml中。YAML 配置由两部分组成:参数服务。参数部分定义了所有必需的参数。服务部分定义了所有对象。服务部分进一步分为多个部分,即类、参数调用。类指定实际的类。参数指定构造函数的参数。最后,调用指定 setter 方法。另一个类可以使用@符号@greeter来引用。

parameters: 
   greeter.text: 'Hello' 
services: 
   greeter: 
      class: Greeter
      arguments: ['%greeter.text%'] 
   user: 
      class: User 
      calls: 
         - [setGreeter, ['@greeter']] 

现在,可以使用FileLoaderYamlFileLoader加载和配置services.yml,如以下代码所示。

use Symfony\Component\Config\FileLocator; 
use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;  

$yamlContainer = new ContainerBuilder(); 
$loader = new YamlFileLoader($yamlContainer, new FileLocator(__DIR__)); 
$loader->load('services.yml');  

$yamlUser = $yamlContainer->get('user'); 
$yamlUser->name = "Jon"; 
$yamlUser->age = 25; 
$yamlUser->greet(); 

完整的代码清单如下。

main.php

<?php  
   require __DIR__ . '/vendor/autoload.php';  
   use Symfony\Component\DependencyInjection\ContainerBuilder; 
   use Symfony\Component\Config\FileLocator; 
   use Symfony\Component\DependencyInjection\Loader\YamlFileLoader; 
   use Symfony\Component\DependencyInjection\Reference;  
   
   class Greeter { 
      private $greetingText; 
      
      public function __construct($greetingText) {
         $this->greetingText = $greetingText; 
      }  
      public function greet($name) { 
         echo $this->greetingText . ", " . $name . "\r\n"; 
      } 
   }  
   class User { 
      private $greeter;  
      public $name; 
      public $age;  
      
      public function setGreeter(\Greeter $greeter) { 
         $this->greeter = $greeter; 
      }  
      public function greet() { 
         $this->greeter->greet($this->name); 
      } 
   }  
   $container = new ContainerBuilder(); 
   $container 
      ->register('greeter', 'Greeter') 
      ->addArgument('%greeter.text%');  
   $container 
      ->register('user', 'User') 
      ->addMethodCall('setGreeter', array(new Reference('greeter')));
   
   $container->setParameter('greeter.text', 'Hi'); 
   $greeter = $container->get('greeter'); 
   $greeter->greet('Jon'); 
   
   $user = $container->get('user'); 
   $user->name = "Jon"; 
   $user->age = 20; 
   $user->greet();  
   
   $yamlContainer = new ContainerBuilder(); 
   $loader = new YamlFileLoader($yamlContainer, new FileLocator(__DIR__)); 
   $loader->load('services.yml');  

   $yamlHello = $yamlContainer->get('greeter'); 
   $yamlHello->greet('Jon'); 
   
   $yamlUser = $yamlContainer->get('user'); 
   $yamlUser->name = "Jon"; 
   $yamlUser->age = 25; 
   $yamlUser->greet();  
?>

服务.yml

parameters: 
   greeter.text: 'Hello' 
services: 
   greeter: 
      class: Greeter 
      arguments: ['%greeter.text%'] 
   user: 
      class: User 
      calls: 
         - [setGreeter, ['@greeter']] 

Symfony Web 框架广泛使用依赖注入组件。所有组件都受集中式服务容器的约束。Symfony Web框架通过container属性公开其所有Controller中的容器。我们可以通过它获取在其中注册的所有对象,例如记录器、邮件程序等。

$logger = $this->container->get('logger'); 
$logger->info('Hi'); 

要查找容器中注册的对象,请使用以下命令。

cd /path/to/app 
php bin/console debug:container

在安装章节中创建的hello Web 应用程序中有大约 200 多个对象。

Symfony - 事件和事件监听器

Symfony 通过其EventDispatcher组件提供基于事件的编程。任何企业应用程序都需要基于事件的编程来创建高度可定制的应用程序。事件是对象之间交互的主要工具之一。如果没有事件,对象就无法有效地交互。

基于事件的编程过程可以概括为 - 一个称为事件源的对象要求中央调度程序对象注册一个事件,例如 user.registered。一个或多个对象(称为侦听器)向中央调度程序对象询问它想要侦听特定事件(例如 user.registered)。在某个时间点,事件源对象要求中央调度程序对象调度事件,例如 user.registered 以及带有必要信息的事件对象。中央调度程序通知所有侦听器对象有关该事件的信息,例如 user.registered 及其 Event* 对象。

在基于事件的编程中,我们有四种类型的对象:事件源、事件侦听器、事件调度程序和事件本身。

让我们编写一个简单的应用程序来理解这个概念。

步骤 1 - 创建一个项目event-dispatcher-example

cd /path/to/dir 
mkdir event-dispatcher-example 
cd event-dispatcher-example 
composer require symfony/event-dispatcher 

步骤 2 - 创建一个类.User

class User { 
   public $name; 
   public $age; 
}  

$user = new User(); 
$user->name = "Jon"; 
$user->age = 25

步骤 3 - 创建一个事件UserRegisteredEvent

use Symfony\Component\EventDispatcher\Event;  
class UserRegisteredEvent extends Event {
   const NAME = 'user.registered';  
   protected $user;  
   
   public function __construct(User $user) { 
      $this-<user = $user; 
   }  
   public function getUser() { 
      return $this-<user; 
   } 
}  
$event = new UserRegisteredEvent($user);

在这里,UserRegisteredEvent可以访问User对象。事件的名称是user.registered

步骤 4 - 创建一个侦听器UserListener

class UserListener { 
   public function onUserRegistrationAction(Event $event) { 
      $user = $event->getUser(); 
         echo $user->name . "\r\n"; 
         echo $user->age . "\r\n"; 
   } 
}  
$listener = new UserListener(); 

步骤 5 - 创建一个事件调度程序对象。

use Symfony\Component\EventDispatcher\EventDispatcher;  
$dispatcher = new EventDispatcher(); 

步骤 6 - 使用调度程序对象及其方法addListener连接侦听器和事件。

$dispatcher 
   ->addListener( 
      UserRegisteredEvent::NAME,  
      array($listener, 'onUserRegistrationAction'));  

我们还可以添加一个匿名函数作为事件监听器,如以下代码所示。

$dispatcher 
   ->addListener( 
      UserRegisteredEvent::NAME,  
      
      function(Event $event) { 
         $user = $event->getUser(); 
         echo $user->name . "\r\n"; 
      }); 

步骤7 - 最后,使用事件调度程序的方法dispatch触发/调度事件。

 $dispatcher->dispatch(UserRegisteredEvent::NAME, $event);

完整的代码清单如下。

main.php

<?php  
   require __DIR__ . '/vendor/autoload.php';  
   use Symfony\Component\EventDispatcher\EventDispatcher; 
   use Symfony\Component\EventDispatcher\Event;  

   class User { 
      public $name; 
      public $age; 
   }  
   class UserRegisteredEvent extends Event { 
      const NAME = 'user.registered';  
      protected $user;  
      
      public function __construct(User $user) { 
         $this->user = $user; 
      }  
      public function getUser() { 
         return $this->user; 
      } 
   }  
   class UserListener { 
      public function onUserRegistrationAction(Event $event) { 
         $user = $event->getUser(); 
         echo $user->name . "\r\n"; 
         echo $user->age . "\r\n"; 
      } 
   } 
   $user = new User(); 
   $user->name = "Jon"; 
   $user->age = 25;  

   $event = new UserRegisteredEvent($user); 
   $listener = new UserListener();  

   $dispatcher = new EventDispatcher();  
   $dispatcher 
      ->addListener( 
         UserRegisteredEvent::NAME, 
         
         function(Event $event) { 
            $user = $event->getUser(); 
            echo $user->name . "\r\n"; 
         });  
   $dispatcher 
      ->addListener( 
         UserRegisteredEvent::NAME, array($listener, 'onUserRegistrationAction'));

   $dispatcher->dispatch(UserRegisteredEvent::NAME, $event); 
?>

结果

Jon 
Jon 
25

Symfony Web 框架有很多事件,可以为这些事件注册监听器并对其进行相应的编程。示例事件之一是 kernel.exception ,对应的事件是GetResponseForExceptionEvent,它保存响应对象(Web 请求的输出)。这用于捕获异常并使用通用错误信息修改响应,而不是向用户显示运行时错误。

Symfony - 表达

正如我们之前讨论的,表达式语言是 Symfony 应用程序的显着特征之一。Symfony 表达式主要是为了在配置环境中使用而创建的。它使非程序员能够轻松配置 Web 应用程序。让我们创建一个简单的应用程序来测试表达式。

步骤 1 - 创建一个项目,表达式语言示例

cd /path/to/dir 
mkdir expression-language-example 
cd expression-language-example 
composer require symfony/expression-language 

步骤 2 - 创建一个表达式对象。

use Symfony\Component\ExpressionLanguage\ExpressionLanguage; 
$language = new ExpressionLanguage();

步骤 3 - 测试一个简单的表达式。

echo "Evaluated Value: " . $language->evaluate('10 + 12') . "\r\n" ; 
echo "Compiled Code: " . $language->compile('130 % 34') . "\r\n" ;

步骤 4 - Symfony 表达式非常强大,它可以在表达式语言中拦截 PHP 对象及其属性。

class Product { 
   public $name; 
   public $price; 
} 
$product = new Product(); 
$product->name = 'Cake'; 
$product->price = 10;  

echo "Product price is " . $language 
   ->evaluate('product.price', array('product' => $product,)) . "\r\n";  
echo "Is Product price higher than 5: " . $language 
   ->evaluate('product.price > 5', array('product' => $product,)) . "\r\n"; 

这里,表达式product.priceproduct.price > 5截取$product对象的属性price并评估结果。

完整的编码如下。

main.php

<?php 
   require __DIR__ . '/vendor/autoload.php'; 
   use Symfony\Component\ExpressionLanguage\ExpressionLanguage; 
   $language = new ExpressionLanguage();  

   echo "Evaluated Value: " . $language->evaluate('10 + 12') . "\r\n" ; 
   echo "Compiled Code: " . $language->compile('130 % 34') . "\r\n" ;  
   
   class Product { 
      public $name; 
      public $price; 
   }  
   $product = new Product(); 
   $product->name = 'Cake'; 
   $product->price = 10;  

   echo "Product price is " . $language 
      ->evaluate('product.price', array('product' => $product,)) . "\r\n"; 
   echo "Is Product price higher than 5: " . $language 
      ->evaluate('product.price > 5', array('product' => $product,)) . "\r\n"; 
?> 

结果

Evaluated Value: 22 
Compiled Code: (130 % 34) 
Product price is 10 
Is Product price higher than 5: 1

Symfony - 捆绑包

Symfony 包是按特定结构组织的文件和文件夹的集合。捆绑包的建模方式使其可以在多个应用程序中重用。主应用程序本身被打包为一个包,通常称为AppBundle

捆绑包可以特定于应用程序打包,例如 AdminBundle(管理部分)、BlogBu​​ndle(站点的博客)等。此类捆绑包不能在应用程序之间共享。相反,我们可以将应用程序的某一部分(例如博客)建模为通用捆绑包,以便我们可以简单地将捆绑包从一个应用程序复制到另一个应用程序以重用博客功能。

捆绑包的结构

捆绑包的基本结构如下。

  • 控制器- 所有控制器都需要放置在这里。

  • DependencyInjection - 所有依赖注入相关的代码和配置都需要放置在这里。

  • Resources/config - 与捆绑包相关的配置放置在此处。

  • 资源/视图- 与捆绑包相关的视图模板放置在此处。

  • Resources/public - 捆绑相关的样式表、JavaScript、图像等放置在这里。

  • 测试- 捆绑相关的单元测试文件放置在此处。

创建捆绑包

让我们在HelloWorld应用程序中创建一个简单的包,TutorialspointDemoBundle

步骤 1 - 选择一个命名空间。捆绑包的命名空间应包括供应商名称和捆绑包名称。在我们的例子中,它是Tutorialspoint\DemoBundle

步骤2 -通过扩展Bundle类创建一个空类TutorialspointDemoBundle并将其放置在src/Tutorialspoint/DemoBundle下。

namespace Tutorialspoint\DemoBundle; 
use Symfony\Component\HttpKernel\Bundle\Bundle;  

class TutorialspointDemoBundle extends Bundle { 
}

步骤 3 - 在AppKernel类中应用程序支持的包列表中注册该类。

public function registerBundles() { 
   $bundles = array( 
      // ... 
      // register your bundle 
      new Tutorialspoint\DemoBundle\TutorialspointDemoBundle(), 
   ); 
   return $bundles; 
}

这是创建空包所需的全部内容,所有其他概念与应用程序的概念相同。Symfony还提供了一个控制台命令generate:bundle来简化创建新bundle的过程,如下所示。

php bin/console generate:bundle --namespace = Tutorialspoint/DemoBundle

结果

Welcome to the Symfony bundle generator!

Are you planning on sharing this bundle across multiple applications? [no]: no  

Your application code must be written in bundles. This command helps 
you generate them easily.  

Give your bundle a descriptive name, like BlogBundle. 
Bundle name [Tutorialspoint/DemoBundle]:   

In your code, a bundle is often referenced by its name. It can be the 
concatenation of all namespace parts but it's really up to you to come 
up with a unique name (a good practice is to start with the vendor name). 
Based on the namespace, we suggest TutorialspointDemoBundle.  

Bundle name [TutorialspointDemoBundle]:  
Bundles are usually generated into the src/ directory. Unless you're 
doing something custom, hit enter to keep this default!
Target Directory [src/]:   

What format do you want to use for your generated configuration?  

Configuration format (annotation, yml, xml, php) [annotation]:

Bundle generation

> Generating a sample bundle skeleton into app/../src/Tutorialspoint/DemoBundle 
   created ./app/../src/Tutorialspoint/DemoBundle/ 
   created ./app/../src/Tutorialspoint/DemoBundle/TutorialspointDemoBundle.php 
   created ./app/../src/Tutorialspoint/DemoBundle/Controller/ 
   created ./app/../src/Tutorialspoint/DemoBundle/Controller/DefaultController.php 
   created ./app/../tests/TutorialspointDemoBundle/Controller/   
   created ./app/../tests/TutorialspointDemoBundle/Controller/DefaultControllerTest.php 
   created ./app/../src/Tutorialspoint/DemoBundle/Resources/views/Default/   
   created ./app/../src/Tutorialspoint/DemoBundle/Resources/views/Default/index.html.twig 
   created ./app/../src/Tutorialspoint/DemoBundle/Resources/config/ 
   created ./app/../src/Tutorialspoint/DemoBundle/Resources/config/services.yml 
> Checking that the bundle is autoloaded 
> Enabling the bundle inside app/AppKernel.php 
   updated ./app/AppKernel.php 
> Importing the bundle's routes from the app/config/routing.yml file 
   updated ./app/config/routing.yml 
> Importing the bundle's services.yml from the app/config/config.yml file 
   updated ./app/config/config.yml 
Everything is OK! Now get to work :).  

创建一个简单的 Web 应用程序

本章介绍如何在 Symfony 框架中创建一个简单的应用程序。如前所述,您知道如何在 Symfony 中创建新项目。

我们可以举一个“学生”详细信息的例子。让我们首先使用以下命令创建一个名为“student”的项目。

symfony new student

执行命令后,会创建一个空项目。

控制器

Symfony 基于模型-视图-控制器 (MVC) 开发模式。MVC 是一种将应用程序逻辑与表示分离的软件方法。控制器在 Symfony 框架中扮演着重要的角色。应用程序中的所有网页都需要由控制器来处理。

DefaultController类位于“src/AppBundle/Controller”。您可以在那里创建自己的控制器类。

移动到位置“src/AppBundle/Controller”并创建一个新的StudentController类。

以下是StudentController类的基本语法。

学生控制器.php

namespace AppBundle\Controller; 
use Symfony\Component\HttpFoundation\Response;  
class StudentController { 
} 

现在,您已经创建了一个 StudentController。在下一章中,我们将详细讨论控制器。

创建路线

创建控制器后,我们需要路由特定页面。路由将请求 URI 映射到特定控制器的方法。

以下是路由的基本语法。

namespace AppBundle\Controller;  
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route; 
use Symfony\Component\HttpFoundation\Response; 
use Symfony\Bundle\FrameworkBundle\Controller\Controller;  

class StudentController { 
   /** 
      * @Route("/student/home") 
   */ 
   public function homeAction() { 
      return new Response('Student details application!'); 
   } 
}

在上面的语法中,@Route(“/student/home”)是路线。它定义页面的 URL 模式。

homeAction()是操作方法,您可以在其中构建页面并返回 Response 对象。

我们将在下一章详细介绍路由。现在,请求 url“http://localhost:8000/student/home”,它会产生以下结果。

结果

交响乐框架

Symfony - 控制器

控制器负责处理进入 Symfony 应用程序的每个请求。控制器从请求中读取信息。然后,创建响应对象并将其返回给客户端。

根据 Symfony 的说法,DefaultController类位于“src/AppBundle/Controller”。它的定义如下。

默认控制器.php

<?php 
namespace AppBundle\Controller; 
use Symfony\Bundle\FrameworkBundle\Controller\Controller; 
use Symfony\Component\HttpFoundation\Response;  

class DefaultController extends Controller {  
} 

这里,HttpFoundation组件为 HTTP 规范定义了一个面向对象的层,而 FrameworkBundle包含了大部分“基础”框架功能。

请求对象

Request 类是 HTTP 请求消息的面向对象表示。

创建请求对象

可以使用createFromGlobals()方法创建请求。

use Symfony\Component\HttpFoundation\Request; 
$request = Request::createFromGlobals();

您可以使用全局模拟请求。您还可以模拟请求,而不是基于 PHP 全局变量创建请求。

$request = Request::create( 
   '/student', 
   'GET', 
   array('name' => 'student1') 
);

这里,create()方法基于 URI、方法和一些参数创建请求。

重写请求对象

您可以使用overrideGlobals()方法覆盖 PHP 全局变量。它的定义如下。

$request->overrideGlobals();

访问请求对象

可以使用基本控制器的getRequest()方法在控制器(操作方法)中访问网页请求。

$request = $this->getRequest();

识别请求对象

如果你想标识你的应用程序中的一个请求,“PathInfo”方法将返回请求url的唯一标识。它的定义如下。

$request->getPathInfo();

响应对象

对控制器的唯一要求是返回一个 Response 对象。Response 对象保存来自给定请求的所有信息并将其发送回客户端。

下面是一个简单的例子。

例子

use Symfony\Component\HttpFoundation\Response; 
$response = new Response(‘Default'.$name, 10);

您可以按如下方式在 JSON 中定义 Response 对象。

$response = new Response(json_encode(array('name' => $name))); 
$response->headers->set('Content-Type', 'application/json');

响应构造函数

构造函数包含三个参数 -

  • 回复内容
  • 状态码
  • HTTP 标头数组

以下是基本语法。

use Symfony\Component\HttpFoundation\Response;  
$response = new Response( 
   'Content', 
   Response::HTTP_OK, 
   array('content-type' => 'text/html') 
); 

例如,您可以将内容参数传递为:

$response->setContent(’Student details’);

同样,您也可以传递其他参数。

发送响应

您可以使用send()方法向客户端发送响应。它的定义如下。

$response->send();

要将客户端重定向到另一个 URL,您可以使用RedirectResponse类。

它的定义如下。

use Symfony\Component\HttpFoundation\RedirectResp