首頁  >  文章  >  後端開發  >  詳解Symfony2的插件格式

詳解Symfony2的插件格式

*文
*文原創
2018-01-05 17:47:391556瀏覽

本文主要介紹了Symfony2的插件格式,詳細分析了Symfony2的插件原理及創建與使用插件的相關技巧。需要的朋友可以參考下,希望對大家有幫助。

一個bundle類似於其它框架中的插件,但是比插件表現更好。它跟其它框架最主要的不同是在Symfony2中所有東西都是bundle,包括核心框架功能和你寫的所有應用程式程式碼。 Symfony2中,bundle可是一等公民。這給了你使用其它第三方開發的內容包或分發你自己的bundle更多靈活性。你可以方便的選擇哪些內容可以應用到你的程式中那些不用,來根據你的想法優化它們。

一個bundle就是一個目錄,它具有很好的結構性,它能存放從類別到controller和web資源等任何東西。

一個bundle只是一個結構化的檔案目錄集合,它實作一個單一的內容。

你可以建立一個BlogBu​​ndle,一個ForumBundle或一個實作使用者管理的bundle(好像已經有很多這類開源的bundle了)。每個bundle目錄包含與實現內容有關的所有東西,包括PHP文件,模板,樣式表,javascript文件,測試內容以及其它任何相關的東西。要實現的內容的各方面都保存在一個bundle中。

一個應用程式是由在AppKernel類別中registerBundles()方法裡定義的所有bundle所組成。

// app/AppKernel.php
public function registerBundles()
{
  $bundles = array(
    new Symfony\Bundle\FrameworkBundle\FrameworkBundle(),
    new Symfony\Bundle\SecurityBundle\SecurityBundle(),
    new Symfony\Bundle\TwigBundle\TwigBundle(),
    new Symfony\Bundle\MonologBundle\MonologBundle(),
    new Symfony\Bundle\SwiftmailerBundle\SwiftmailerBundle(),
    new Symfony\Bundle\DoctrineBundle\DoctrineBundle(),
    new Symfony\Bundle\AsseticBundle\AsseticBundle(),
    new Sensio\Bundle\FrameworkExtraBundle\SensioFrameworkExtraBundle(),
    new JMS\SecurityExtraBundle\JMSSecurityExtraBundle(),
  );
  if (in_array($this->getEnvironment(), array('dev', 'test'))) {
    $bundles[] = new Acme\DemoBundle\AcmeDemoBundle();
    $bundles[] = new Symfony\Bundle\WebProfilerBundle\WebProfilerBundle();
    $bundles[] = new Sensio\Bundle\DistributionBundle\SensioDistributionBundle();
    $bundles[] = new Sensio\Bundle\GeneratorBundle\SensioGeneratorBundle();
  }
  return $bundles;
}

在這裡你可以透過這個方法來統一控制和管理你的應用程式組成。

一個bundle可以存放在任何目錄下,只需要能夠透過設定app/autoload.php檔案中的自動載入器即可被自動載入。

建立一個bundle

Symfony2標準版中已經為你準備好了一全功能的建立bundle的工具檔。你可以運行它來創建bundle的所有內容,當然你也可以

選擇自己手工創建。現在我們創建一個AcmeTestBundle並讓它能夠在我們的應用程式中工作。注意,這裡的Acme是一個虛假的提供者名字,你完全可以替換它為你自己組織或公司的名字。

首先,建立一個src/Acme/TestBundle/ 目錄並新增檔案AcmeTestBundle.php

// src/Acme/TestBundle/AcmeTestBundle.php
namespace Acme\TestBundle;
use Symfony\Component\HttpKernel\Bundle\Bundle;
class AcmeTestBundle extends Bundle
{
}

接下來,讓它在你的應用程式可用,則需要在AppKernel類別中的registerBundles()方法中加入它。

// app/AppKernel.php
public function registerBundles()
{
  $bundles = array(
    // ...
    // register your bundles
    new Acme\TestBundle\AcmeTestBundle(),
  );
  // ...
  return $bundles;
}

雖然現在它不能做任何事情,但是它已經成為你應用程式的一部分了。

我們同樣可以使用Symfony2為我們提供給命令列工具來建立:

$ php app/console generate:bundle --namespace=Acme/TestBundle

如果你使用上面的命令列工具,則建立的bundle會自動的註冊到appKernel類別中。

Bundle的目錄結構

來看看我們Symfony2自帶的Demo bundle的目錄結構:

bundle的目錄機構簡單靈活,從上面的截圖中可以看到:

Controller/ 包含bundle的所有controllers文件,例如HelloController.php 。
DependencyInjection/ 保存了特定的依賴注入擴展類,該類可能會導入服務配置,註冊編譯器傳輸或更多其它。該目錄並不是必需的。
Resources/config/ 存放著設定文件,包括路由配置(例如:routing.yml)。
Resources/views/ 所有的模板都被按照對應controller的名字分成資料夾保存在這裡。例如Hello/index.html.twig 。
Resources/public/ 所有可存取的web資源(圖片,樣式表等)和透過assets:install控制台命令拷貝或非同步連結到項目 web/ 目錄的內容。
Tests/ 保存bundle所有的測試

下面是Symfony2 推薦的一些有關bundle的標準規則:

Bundle名稱:

一個bundle同時也是一個PHP的命名空間。命名空間必須遵守PHP5.3命名空間和類別名稱的內部技術標準。開頭使用提供者名,接著是分類段(可以省略),最後是命名空間的簡寫名字,而且該名字必須以Bundle作為後綴。一個命名空間變成一個bundle只需要你在該命名空間內加入一個bundle類別即可。

Bundle類別的命名:

只適用數字,字母和底線
使用駝峰式命名
使用描述性簡潔的名字(不超過兩單字)
使用供應商名稱做前綴(可選的分類命名空間)

加上Bundle作為名稱後綴

例如:

Namespace => Bundle 類別名稱

Acme\Bundle\BlogBundle => AcmeBlogBundle
Acme\Bundle\Social\BlogBundle =>AcmeSocialBlogBundle
Acme\BlogBundle => AcmeBlogBundle

定義bundle類別時的getName()方法應該回傳類別名稱。

每個bundle都有一個別名,它是小寫字元簡寫版的bundle名,使用底線分割。例如 acme_hello 的bundle原名是AcmeHelloBundle, acme_social_blog 則是Acme\Social\BlogBu​​ndle的實例。

別名在一個bundle中必須是唯一的。

Bundle的目錄架構:HelloBundle的基礎目錄架構

XXX/...
  HelloBundle/
    HelloBundle.php
    Controller/
    Resources/
      meta/
        LICENSE
      config/
      doc/
        index.rst
      translations/
      views/
      public/
    Tests/

上面的XXX/... 映射到该bundle的命名空间。其中下面的文件是必备的:

HelloBundle.php;

Resources/meta/LICENSE: 全文的许可代码;
Resources/doc/index.rst: bundle说明的根目录文件。

使用类的子文件夹的深度应该保持到最小(2级是极限)。如果更多级可以定义为非静态,不过很少使用。bundle的目录是只读的。如果你需要修改临时文件,把它们保存到主应用程序的cache/ 或者 log/ 目录下。

需要强调的类和文件

类型 VS 目录

Commands                            VS         Command/
Controllers                             VS        Controller/
Service Container Extensions   VS        /DependencyInjection/
Event Listeners                      VS         EventListener/
Configuration                         VS         Resources/config
Web Resources                      VS         Resources/public
Translation files                      VS         Resources/translations/
Templates                              VS         Resources/views
Unit and Functional Test          VS         Tests/

类:

bundle的目录结构是被用来当作命名空间层级的。比如HelloController类保存在 Bundle/HelloBundle/Controller/HelloController.php文件中。

所以类的完全限定名是 Bundle\HelloBundle\Controller\HelloController 。 一些类被看作是装饰,应该越短越好,比如Commands,Helpers, Listeners 和Controllers等,一般都会被当作后缀。

跟事件分发器有关的类应该用后缀Listener标识。

异常类应该保存到一个Exception子命名空间中。

关于提供商

一个bundle不应该被嵌入第三方的PHP类库,它应该依靠Symfony2标准来自动加载它们。

一个bundle不应该被嵌入第三方的javascript,CSS或者其它语言写的任何类库。

关于测试

一个bundle应该有一个使用PHPUnit的测试单元并把它存储在Tests/ 目录下。

测试应该遵循以下原则:

测试套件必须能够被一个简单的phpunit 命令从一个简单的应用程序中执行。

功能测试应该只备用来测试回复输出和一些监控信息。

测试代码覆盖应该至少在95%以上的基本代码。

一个测试套件可以不包含AllTests.php脚本,但必须依靠外部的phpunit.xml.dist文件。

文档说明

所有的类必须带有PHPDoc。

Controllers

最好的情况下,controller应该在一个可以部署到其它地方的bundle中,那么它不能继承Controller基类。而是通过实现ContainerAwareInterface接口或者继承ContainerAware来取代继承Controller。

Routing

如果bundle提供路由,他们必须使用bundle的别名为前缀,比如一个AcmeBlogBundle实例,所有的路由名必须是acme_blog_ 开头。

Templates

如果bundle提供模板,它必须使用Twig。 bundle不必低通一个主布局文件,如果你的bundle是一个完整的应用程序除外。

翻译文件

如果bundle提供信息翻译,它必须是被定义成XLIFF格式,区域名必须被命名在bundle名字之后,如bundle.hello

配置

为了提供更大的灵活性,一个bundle可以使用Symfony2的内建机制提供配置设置。对于简单的设置,依赖于默认的Symfony2的parameters配置入口。 Symfony2参数都是简单的 key/value 对。值可以是任意的合法的PHP值。 每个参数名应该以讹bundle的别名开始,这只是一个最佳的建议。参数名其余部分用点号(.)分割,比如 acme_hello.email.from

让最终用户可以在配置文件中直接提供值信息。

YAML格式:

# app/config/config.yml
parameters:
    acme_hello.email.from: fabien@example.com

XML格式:

<!-- app/config/config.xml -->
<parameters>
   <parameter key="acme_hello.email.from">fabien@example.com</parameter>
</parameters>

PHP代码格式:

// app/config/config.php
$container->setParameter(&#39;acme_hello.email.from&#39;, &#39;fabien@example.com&#39;);

INI格式:

[parameters]
acme_hello.email.from = fabien@example.com

这样就可以在代码中从容器获取这些配置信息了:

$container->getParameter(&#39;acme_hello.email.from&#39;);

如果你定义服务,我们也推荐你使用bundle的别名作为前缀。

总结思考:

以上是关于Symfony2中最主要的插件格式bundle的大体情况,在整个Symfony2为基础开发的应用程序中,几乎全部都是有bundle组成。Symfony2本身的核心组件都是FrameworkBundle。在Symfony2交流社区中,已经有了大量的开发者贡献了他们的bundle,我们可以直接拿来集成到我们自己的应用程序中使用。上面所说的大部分规则,都是应用于你开发贡献bundle时应该遵循的统一规则,以方便其它用户使用。

带有第三方贡献的bundle的Symfony2开发包:

如果你不打算把你的bundle贡献出来,那么完全可以不用按照这里说的大部分规则进行开发。

相关推荐:

详解Symfony模板快捷变量的用法

详解Symfony在模板和行为中取得request参数的方法

简述Symfony核心类

以上是詳解Symfony2的插件格式的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn