听 Fabien Potencier 谈Symfony2 之 《What is Symfony2 ?》
Symfoy2 是什么?
PHP世界里又一广受关注的web MVC框架? Fabien Potencier 却不这么说!
Fabien Potencier这样定义Symfoy2 是个什么东西:
首先,Symfony2 是一个独立,松散的,有组织严密的PHP组件集合,它可以为你解决一些web开发中遇到的一般性问题。
其次,基于这些组件,Symfoy2 也可以作为一个独立的web框架使用。
那么Symfony2 是一个MVC框架吗?
Fabien Potencier 说Symfony2从来没有把自己定义为一个MVC框架!
那它是什么? Fabien Potencier 我们从来不关心MVC模式,关心的只有各个关注点的分离(separation of concerns)。
但是Symfony2 还是提供了部分的MVC模式的实现:比如Controller部分,View部分却没有Mode部分不过你可以通过和它紧密继承的ORM(Doctrine2和Propel)实现。
从这个角度看Symfony的确也没有逃出web MVC框架的圈子啊!!!
Fabien Potencier 又说Symfony2从来就没有想靠这些ORM来使自己成为另一个MVC的追随者,我们的目标更远大!
告诉你吧, Symfony2 是一个HTTP框架或者说是一个Request/Response 框架。我们紧盯的目标不是MVC模式,而是HTTP协议,我们是更低级的更基础的框架。
我们为什么要这么说呢? 有根据的!
近几年随着web的发展,有时候你只需要创建一组REST API,所有的逻辑都放到浏览器端,服务器端只提供数据就是一种web了。不信你看 backbone.js !
再说了,MVC模式只不过是Web 应用程序的其中一种实现方式罢了。
剥去所有框架模式的皮,你看看那个web程序不是处理一个接收到的Request然后返回一个Response啊?
我们Symfony2 抓住的就是web程序的根本! 再说我们众多的HTTP流媒体有哪个会选择使用MVC呢?
总之,我们Symfony2比MVC更靠近根本,我们更底层,更通用!!!
说起Symfony2,Fabien Potencier说我们有着更加远大的目标,怎么解释呢?
Symfony2 将继续专注于Pack技术的研究和创新!我们相信她会继续推动web的向前发展。
先看看Symfony2 中我们已经包含的创新吧!
从Bundles,HTTP 缓存,分布式,依赖注入,模板引擎,声明式配置,资产管理,稳定的API到web分析器等等一系列技术都对web的发展起到了巨大的推动作用。
“ 要知道一个独立的框架永远不可能成为PHP世界里的一个标准,所以Symfony2 在探寻另外一条路!”
“ 共享无处不在。”
“ 我们不能重复制造轮子。”
因此,我们紧密的集成了Monolog,Composer,Doctrine,Propel,Assetic,Twig,Swiftmailer等伟大产品。
更重要的是我们想跟大家分享我们的工作!
所以,我们最终选择了走组件(components)化这条路!
我们将为一切web项目提供建筑模块,无论是个人项目还是商业项目,更或者是开源项目!
据说在Symfony2 的代码中可能会有标志为@api的类或者方法,它意味着一个方法从名字到参数以及返回值都不会因为Symfony2发展版本而变化,所以,如果
你的项目只使用了这些,那么你就不用担心Symfony2的版本升级问题。
看看Symfony2 现在拥有的组件吧:
DependencyInjection
EventDispatcher
HttpFoundation
DomCrawler
ClassLoader
CssSelector
HttpKernel
BrowserKit
Templating
Translation
Serializer
Validator
Security
Routing
Console
Process
Config
Finder
Locale
Yaml
Form
Fabien 简单介绍了几个bundle:
1. ClassLoader:
实现了PSR-o 标准(自动加载具有命名空间的类,适用于PHP5.3以上)的自动加载器,同时它也能按照PEAR命名规则加载类。它非常灵活可以基于子命名空间在不同的目录中查询要加载的类。你甚至可以为一个命名空间指定多个目录。
require_once __DIR__.'/src/Symfony/Component/ClassLoader/UniversalClassLoader.php'; use Symfony\Component\ClassLoader\UniversalClassLoader; $loader = new UniversalClassLoader();
$loader->registerNamespaces(array(
'Symfony' => array(__DIR__.'/src', __DIR__.'/symfony/src'),
'Doctrine\\Common' => __DIR__.'/vendor/doctrine-common/lib',
'Doctrine\\DBAL' => __DIR__.'/vendor/doctrine-dbal/lib',
'Doctrine' => __DIR__.'/vendor/doctrine/lib',
'Monolog' => __DIR__.'/vendor/monolog/src',
));
$loader->registerPrefixes(array(
'Twig_' => __DIR__.'/vendor/twig/lib',
));
$loader->register();
如果你想获取更加高的执行效率,可以选择使用APC缓存版Universal类加载器。
2.Console 命令行工具
在创建web应用程序时使用命令行工具很方便,你可以想如下代码一样创建自己的命令行工具:
use Symfony\Component\Console\Application;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface; $console = new Application();
$console
->register('ls')
->setDefinition(array(
new InputArgument('dir', InputArgument::REQUIRED, 'Directory name'),
))
->setDescription('Displays the files in the given directory')
->setCode(function (InputInterface $input, OutputInterface $output) {
$dir = $input->getArgument('dir'); $output->writeln(sprintf('Dir listing for <info>%s</info>', $dir));
})
;
$console->run();
3.YAML 一种现在很流行的配置格式。
use Symfony\Component\Yaml\Yaml; $array = Yaml::parse($file); print Yaml::dump($array);
4. Finder 优秀文件资源的操作接口。
use Symfony\Component\Finder\Finder; $finder = new Finder(); $iterator = $finder
->files()
->name('*.php')
->depth(0)
->size('>= 1K')
->in(__DIR__); foreach ($iterator as $file) {
print $file->getRealpath()."\n";
}
你甚至可以用它获取远程服务器文件系统中的资源,比如获取Amazon S3上的文件:
$s3 = new \Zend_Service_Amazon_S3($key, $secret);
$s3->registerStreamWrapper("s3"); $finder = new Finder();
$finder->name('photos*')->size('< 100K')->date('since 1 hour ago');
foreach ($finder->in('s3://bucket-name') as $file) {
print $file->getFilename()."\n";
}
5.Process 进程组件,你可以用来在一个外部进程中执行命令!下面例子是执行一个简单的目录列表命令并返回结果:
use Symfony\Component\Process\Process; $process = new Process('ls -lsa');
$process->setTimeout(3600);
$process->run();
if (!$process->isSuccessful()) {
throw new RuntimeException($process->getErrorOutput());
} print $process->getOutput();
如果你想监控执行过程,你可以给run方法传入一个匿名方法:
use Symfony\Component\Process\Process; $process = new Process('ls -lsa');
$process->run(function ($type, $buffer) {
if ('err' === $type) {
echo 'ERR > '.$buffer;
} else {
echo 'OUT > '.$buffer;
}
});
6.DomCrawler jQuery的php版本!你可以用它导航定位HTML的DOM结构或者XML文档。
use Symfony\Component\DomCrawler\Crawler; $crawler = new Crawler();
$crawler->addContent('<html><body><p>Hello World!</p></body></html>'); print $crawler->filterXPath('descendant-or-self::body/p')->text();
7.CssSelector 我们经常用XPath来访问Dom结构,其实用Css 选择器更加容易,这个组件就是把Css选择器转为XPath等效的东西。
use Symfony\Component\CssSelector\CssSelector; print CssSelector::toXPath('div.item > h4 > a');
所以你可以使用CssSelector 和DomCrawler来替代XPath:
use Symfony\Component\DomCrawler\Crawler; $crawler = new Crawler();
$crawler->addContent('<html><body><p>Hello World!</p></body></html>'); print $crawler->filter('body > p')->text();
8.HttpFoundation
该组件只是在PHP的相关web内容上面增加了一个面向对象层,包括Request,Response,Uploaded files,Cookies,Sessions...
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response; $request = Request::createFromGlobals();
echo $request->getPathInfo();
你用它可以很容易的创建自己的Request 和 Response:
$request = Request::create('/?foo=bar', 'GET');
echo $request->getPathInfo(); $response = new Response('Not Found', 404, array('Content-Type' => 'text/plain'));
$response->send();
9.Routing
路由组件和Request对象是相互配合着把Request转换为Response。
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Matcher\UrlMatcher;
use Symfony\Component\Routing\RequestContext;
use Symfony\Component\Routing\RouteCollection;
use Symfony\Component\Routing\Route; $routes = new RouteCollection();
$routes->add('hello', new Route('/hello', array('controller' => 'foo'))); $context = new RequestContext(); // this is optional and can be done without a Request instance
$context->fromRequest(Request::createFromGlobals()); $matcher = new UrlMatcher($routes, $context); $parameters = $matcher->match('/hello');
10.EventDispatcher
use Symfony\Component\EventDispatcher\EventDispatcher;
use Symfony\Component\EventDispatcher\Event; $dispatcher = new EventDispatcher(); $dispatcher->addListener('event_name', function (Event $event) {
// ...
}); $dispatcher->dispatch('event_name');
11.DependencyInjection
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference; $sc = new ContainerBuilder();
$sc
->register('foo', '%foo.class%')
->addArgument(new Reference('bar'))
;
$sc->setParameter('foo.class', 'Foo'); $sc->get('foo');
12.HttpKernel
Http 内核组件提供了HTTP协议中最有活力的部分,以下面接口的形式定义展示,它也是Symfony2框架的核心。
interface HttpKernelInterface
{
/**
* Handles a Request to convert it to a Response.
*
* @param Request $request A Request instance
*
* @return Response A Response instance
*/
function handle(Request $request, $type = self::MASTER_REQUEST, $catch = true);
}
它接受一个Request输入并返回一个Response输出。 只要遵循这个接口规定,你就能使用Symfony2中所有的精彩内容。
下面使用Symfony2 组件来创建一个简单的框架:
$routes = new RouteCollection();
$routes->add('hello', new Route('/hello', array('_controller' =>
function (Request $request) {
return new Response(sprintf("Hello %s", $request->get('name')));
}
))); $request = Request::createFromGlobals(); $context = new RequestContext();
$context->fromRequest($request); $matcher = new UrlMatcher($routes, $context); $dispatcher = new EventDispatcher();
$dispatcher->addSubscriber(new RouterListener($matcher)); $resolver = new ControllerResolver(); $kernel = new HttpKernel($dispatcher, $resolver); $kernel->handle($request)->send();
ok, 这就是框架了!
如果想添加一个HTTP反向代理以获取HTTP caching和ESI(Edge Side Includes)带来的好处,那么这样做!
$kernel = new HttpKernel($dispatcher, $resolver); $kernel = new HttpCache($kernel, new Store(__DIR__.'/cache'));
想对它做一下功能测试:
$client = new Client($kernel);
$crawler = $client->request('GET', '/hello/Fabien'); $this->assertEquals('Fabien', $crawler->filter('p > span')->text());
想要一个好看的错误展示页面?
$dispatcher->addSubscriber(new ExceptionListener(function (Request $request) {
$msg = 'Something went wrong! ('.$request->get('exception')->getMessage().')'; return new Response($msg, 500);
}));
你可以继续发挥你的想象...
看看HttpKernelInterface 有多么强大!
总结一下,Symfony2 好像很牛啊,继续研究研究!!!
关注URL: http://fabien.potencier.org/article/49/what-is-symfony2
听 Fabien Potencier 谈Symfony2 之 《What is Symfony2 ?》的更多相关文章
- 听 Fabien Potencier 谈Symfony2 之 《What is Dependency Injection ?》
听 Fabien Potencier 谈Symfony2 之 <What is Dependency Injection ?> 什么是依赖注入?从PHP实现角度来分析依赖注入,因为PH ...
- 有容云:上车 | 听老司机谈Docker安全合规建设
编者注: 本文根据7月19日DockOne社群分享内容整理而成,分享嘉宾蒋运龙,有容云高级咨询顾问,一个IT的老兵,十年来混迹于存储.三网融合.多屏互动.智能穿戴.第三方支付.Docker等行业:经历 ...
- 依赖注入(DI)与服务容器(IoC)
参考文章:http://www.yuansir-web.com/2014/03/20/%E7%90%86%E8%A7%A3php-%E4%BE%9D%E8%B5%96%E6%B3%A8%E5%85%A ...
- Symfony2 是什么(转)
本文转自:http://www.cnblogs.com/Seekr/archive/2012/06/15/2550894.html Symfoy2 是什么? PHP世界里又一广受关注的web MVC框 ...
- 深入浅出Symfony2 - 如何提高网站响应速度 [转]
简介 Symfony2是一个基于PHP语言的Web开发框架,有着开发速度快.性能高等特点.但Symfony2的学习曲线也比较陡峭,没有经验的初学者往往需要一些练习才能掌握其特性.相对其他框架,Symf ...
- Symfony2 学习笔记之内部构件
Symfony2内部是怎样工作的以及我们如何来扩展它呢?从外部整体上看,symfony2代码是由许多独立的层构成,每一层都是建立在前一层基础之上.其中,自动加载时不受框架直接管理的,它完全是在Univ ...
- 浅谈C#依赖注入
什么是依赖注入?不管是js中的一些前端框架还是,java,C#,php等中的一些后端开发框架中,都会涉及这个看着逼格略高的词语:依赖注入,越是看着好像很厉害的东西越是会让许多人学习产生恐惧,好像很厉害 ...
- Swift语言精要 - 浅谈代理模式(Delegate)
在iOS编程中,我们经常谈到代理代理,也就是delegate,那么什么是代理呢? 我们来看一下cocoa对它的描述: Delegation is Cocoa’s term for passing of ...
- 【转】.NET(C#):浅谈程序集清单资源和RESX资源 关于单元测试的思考--Asp.Net Core单元测试最佳实践 封装自己的dapper lambda扩展-设计篇 编写自己的dapper lambda扩展-使用篇 正确理解CAP定理 Quartz.NET的使用(附源码) 整理自己的.net工具库 GC的前世与今生 Visual Studio Package 插件开发之自动生
[转].NET(C#):浅谈程序集清单资源和RESX资源 目录 程序集清单资源 RESX资源文件 使用ResourceReader和ResourceSet解析二进制资源文件 使用ResourceM ...
随机推荐
- ERROR 1153 (08S01): Got a packet bigger than 'max_allowed_packet' bytes怎么处理
今天ytkah进行了应急数据库恢复,用Navicat for Mysql导入sql文件出现ERROR 1153 (08S01): Got a packet bigger than 'max_allow ...
- 003-RFC关于媒体类型说明
一.概述 RFC-822 Standard for ARPA Internet text messages [ARPA互连网文本信息标准]RFC-2045 MIME Part 1: Format ...
- mongodb studio 3t 破解无限使用脚本
@echo off ECHO 重置Studio 3T的使用日期...... FOR /f "tokens=1,2,* " %%i IN ('reg query "HKEY ...
- 发现Boost官方文档的一处错误(numpy的ndarray)
文档位置:https://www.boost.org/doc/libs/1_65_1/libs/python/doc/html/numpy/tutorial/ndarray.html shape在这里 ...
- Mac提醒事项如何设置为24小时制
- 数据分析与挖掘 - R语言:贝叶斯分类算法(案例三)
案例三比较简单,不需要自己写公式算法,使用了R自带的naiveBayes函数. 代码如下: > library(e1071)> classifier<-naiveBayes(iris ...
- vue打包后404,webpack配置问题
首先声明这是基于vue2.x的 1. 将其中build的配置项assetsPublicPath进行修改,改为上图-->目的是将资源文件的引入路径,改为相对地址(相对index.html) 2.h ...
- cocos2d JS-(JavaScript) JavaScript 中的简单继承关系
JavaScript 语言本身没有提供类,没有其他语言的类继承机制,它的继承时通过对象的原型实现的,但这不能满足我们对 Cocos2d-JS 引擎的要求,所有类都直接或间接继承实现的. var Per ...
- asp.net拦截器
一 拦截器又称过滤器. asp.net mvc本身是自带3种拦截器:Action拦截器.Result拦截器.Exception拦截器. 应用中常见的拦截器有日志拦截器(Action拦截器)和异常处理拦 ...
- MySQL.Linux.安装
Linux 7.x.安装 MySQL 环境: linux是安装在虚拟机中的,宿主机是:win10系统.安装MySQL的时候,首先需要网络是通的(宿主机和虚拟机之间通信).相关配置,参见:虚拟机和宿主机 ...