Cet article présente principalement le format de plug-in de Symfony2, et analyse en détail le principe du plug-in de Symfony2 et les techniques associées pour créer et utiliser des plug-ins. Les amis dans le besoin peuvent s'y référer. J'espère que cela sera utile à tout le monde.
Un bundle est similaire aux plugins d'autres frameworks, mais fonctionne mieux que les plugins. La principale différence par rapport aux autres frameworks est que tout dans Symfony2 est un bundle, y compris les fonctions principales du framework et tout le code d'application que vous écrivez. Dans Symfony2, les bundles sont des citoyens de première classe. Cela vous donne plus de flexibilité pour utiliser des packages de contenu développés par d'autres tiers ou distribuer vos propres packages. Vous pouvez facilement choisir ce qu’il faut appliquer à votre programme et ce qu’il ne faut pas optimiser en fonction de vos idées.
Un bundle est un répertoire qui a une très bonne structure et peut stocker n'importe quoi, des classes aux contrôleurs et ressources Web.
Un bundle est simplement une collection structurée de répertoires de fichiers qui implémente un seul contenu.
Vous pouvez créer un BlogBundle, un ForumBundle ou un bundle qui implémente la gestion des utilisateurs (il semble qu'il existe déjà de nombreux bundles open source de ce type). Chaque répertoire de bundle contient tout ce qui concerne le contenu de l'implémentation, y compris les fichiers PHP, les modèles, les feuilles de style, les fichiers javascript, le contenu des tests et tout ce qui s'y rapporte. Tous les aspects du contenu à implémenter sont conservés dans un bundle.
Une application est composée de tous les bundles définis dans la méthode registerBundles() de la classe AppKernel.
// 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; }
Ici, vous pouvez utiliser cette méthode pour contrôler et gérer uniformément la composition de votre application.
Un bundle peut être stocké dans n'importe quel répertoire, et il suffit de le charger automatiquement en configurant l'autoloader dans le fichier app/autoload.php.
Créer un bundle
La version standard de Symfony2 a préparé pour vous un fichier d'outil de création de bundle complet. Vous pouvez l'exécuter pour créer tout le contenu du bundle, ou vous pouvez
choisir de le créer manuellement. Maintenant, nous créons un AcmeTestBundle et le faisons fonctionner dans notre application. Notez qu'Acme est ici un faux nom de fournisseur. Vous pouvez le remplacer complètement par le nom de votre propre organisation ou entreprise.
Tout d'abord, créez un répertoire src/Acme/TestBundle/ et ajoutez un nouveau fichier AcmeTestBundle.php
// src/Acme/TestBundle/AcmeTestBundle.php namespace Acme\TestBundle; use Symfony\Component\HttpKernel\Bundle\Bundle; class AcmeTestBundle extends Bundle { }
Ensuite, pour le rendre disponible dans votre application, vous devez l'ajouter dans la classe AppKernel Ajoutez-la dans la méthode registerBundles().
// app/AppKernel.php public function registerBundles() { $bundles = array( // ... // register your bundles new Acme\TestBundle\AcmeTestBundle(), ); // ... return $bundles; }
Bien qu'il ne puisse rien faire pour le moment, il fait désormais partie de votre candidature.
Nous pouvons également utiliser les outils de ligne de commande fournis par Symfony2 pour créer :
$ php app/console generate:bundle --namespace=Acme/TestBundle
Si vous utilisez les outils de ligne de commande ci-dessus, le bundle créé sera automatiquement enregistré au milieu de la classe appKernel .
Structure des répertoires du bundle
Regardez la structure des répertoires du bundle Demo fourni avec Symfony2 :
La structure des répertoires du bundle est simple et flexible, comme vous pouvez le voir sur la capture d'écran ci-dessus :
Controller/ contient tous les fichiers de contrôleurs du bundle, tels que HelloController.php.
DependencyInjection/ contient des classes d'extension d'injection de dépendances spécifiques qui peuvent importer des configurations de service, enregistrer des transports de compilateur, ou plus encore. Ce répertoire n'est pas obligatoire.
Resources/config/ stocke les fichiers de configuration, y compris la configuration du routage (par exemple : router.yml).
Ressources/vues/ Tous les modèles sont divisés en dossiers selon les noms des contrôleurs correspondants et enregistrés ici. Par exemple Bonjour/index.html.twig.
Resources/public/ Toutes les ressources Web accessibles (images, feuilles de style, etc.) et le contenu copié ou lié de manière asynchrone au répertoire web/ du projet via la commande de console assets:install.
Tests/enregistre tous les tests du bundle
Voici quelques règles standard pour les bundles recommandés par Symfony2 :
Nom du bundle :
un Bundle est également un espace de noms PHP. Les espaces de noms doivent être conformes aux normes techniques internes de PHP5.3 pour les espaces de noms et les noms de classe. Utilisez le nom du fournisseur au début, suivi du segment de classification (peut être omis) et enfin du nom abrégé de l'espace de noms, et le nom doit être suffixé par Bundle. Pour transformer un espace de noms en bundle, il vous suffit d'ajouter une classe bundle à l'espace de noms.
Nom des classes du bundle :
Uniquement des chiffres, des lettres et des traits de soulignement
Utilisez un nom en casse chameau
Utilisez un nom descriptif et concis (pas plus de deux caractères ) mots)
Utilisez le nom du fournisseur comme préfixe (espace de noms de classification facultatif)
Ajouter un bundle comme suffixe de nom
Par exemple :
Namespace => Nom de la classe Bundle
Acme\Bundle\BlogBundle => AcmeBlogBundle Acme\Bundle\Social\BlogBundle =>AcmeSocialBlogBundle Acme\BlogBundle => AcmeBlogBundle
La méthode getName() lors de la définition de la classe Bundle doit renvoyer le nom de la classe.
Chaque bundle a un alias, qui est la version abrégée du nom du bundle en caractères minuscules, séparés par des traits de soulignement. Par exemple, le nom d'origine du bundle acme_hello est AcmeHelloBundle et acme_social_blog est une instance de AcmeSocialBlogBundle.
L'alias doit être unique au sein d'un bundle.
Structure des répertoires du Bundle : structure des répertoires de base de 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('acme_hello.email.from', 'fabien@example.com');
INI格式:
[parameters] acme_hello.email.from = fabien@example.com
这样就可以在代码中从容器获取这些配置信息了:
$container->getParameter('acme_hello.email.from');
如果你定义服务,我们也推荐你使用bundle的别名作为前缀。
总结思考:
以上是关于Symfony2中最主要的插件格式bundle的大体情况,在整个Symfony2为基础开发的应用程序中,几乎全部都是有bundle组成。Symfony2本身的核心组件都是FrameworkBundle。在Symfony2交流社区中,已经有了大量的开发者贡献了他们的bundle,我们可以直接拿来集成到我们自己的应用程序中使用。上面所说的大部分规则,都是应用于你开发贡献bundle时应该遵循的统一规则,以方便其它用户使用。
带有第三方贡献的bundle的Symfony2开发包:
如果你不打算把你的bundle贡献出来,那么完全可以不用按照这里说的大部分规则进行开发。
相关推荐:
详解Symfony在模板和行为中取得request参数的方法
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!