php框架比较多,想实现restfulapi用哪个比较流行
我目前在用SlimFramework
做微信的开发及编写一些RestfulAPI.感觉还不错。你可以了解一下.
官方地址:
http://www.slimframework.com
中文文档:http://tutorial.jingwentian.com/slim/注:版本:2.x
我是来说反例的,但凡用以下风格实现controller的,实现RESTFul都很不方便
classController{publicfunctionactionFoo(){}publicfunctionactionBar(){}}
因为RESTFul是对HTTP动作(GET/POST/PUT/DELETE/...)敏感的,用这种风格的Controller的框架来实现就不可避免的会出现以下这种代码
classController{publicfunctionactionFoo(){if(is_get){/*一坨代码*/}elseif(is_post){/*一坨代码*/}elseif(is_put){/*一坨代码*/}elseif(is_delete){/*一坨代码*/}}}
很恶心吧,可惜的是,大部分的框架都是这种风格的Controller实现,差不多都成为标准了
当然了,Laravel也无法免俗。不过Laravel稍微把这个代码优化了一下,大概的逻辑差不多是这样
classController{publicfunctionactionFoo(){if(is_get){return$this->getAction();}elseif(is_post){return$this->postAction();}elseif(is_put){return$this->putAction();}elseif(is_delete){return$this->deleteAction();}}privatefunctiongetAction(){}privatefunctionpostAction(){}privatefunctionputAction(){}privatefunctiondeleteAction(){}}
Laravel里面真正的代码当然不可能是上面这样了,但是逻辑就是这么回事,框架帮你把不同的HTTPverb调用了不同的action,把这个路子套到了classiccontroller里面去
//就是这样,这是从Laravel手册里面copy的classUserControllerextendsBaseController{publicfunctiongetIndex(){//}publicfunctionpostProfile(){//}}
的确能用,但是不足够好。因为本质上都是从classiccontroller的角度出发,然后对RESTFul进行迁就的设计
比如一个需求,根据http协议,对一个不支持post的url发起post,应该响应http405(methodnotallowed),这些框架应该怎么做才方便呢?
必须提
一提到rest,就非得支持啥put、delete这些请求,感觉很无聊,我认为post和get就能应付的了我们所有的请求了。
因为框架使用的不是很多,所以不太好推荐哪个框架使用起来比较方便,目前自己使用的YII
实现起来就很方便,但是无论题主最后使用哪个框架,API
都是要根据需求自己来设计实现的,建议题主读下这篇文章:
《BestPracticesforDesigningaPragmaticRESTfulAPI》
另外,@lenbo_ma的博文也很值得一读:
楼上吐槽php写API必要有一堆条件判断的朋友,restful这个难道不判断get/post/put/delete条件语句,还有更好的办法吗?
若是说真的好,golang最好
SlimFramework,挺有趣的!赞
推荐一款非常适合RESTful和微服务接口的框架
让你在这些场景下彻底摆脱MVC。
看个例子,这是一个可能的订单管理接口实现,只需要编写下面代码,无效额外的继承和配置:
/***@path("/orders/")*/classOrders{/***获取所有订单*@route({"GET","/"})*@return({"body"})此注释表示将函数返回值作为body输出*/publicfunctiongetAllOrders(){returnSql::select('*')->from('orders')->get($this->db);//数组默认将被转换成json输出}/***获取指定的订单信息*@route({"GET","/*"})*是通配符,匹配任意/orders/的子目录*@param({"id","$.path[1]"})提取路径中的第二节作为参数$id,如/orders/123中的123*@return({"body"})*/publicfunctiongetOrderById($id){returnSql::select('*')->from('orders')->where('id=?',$id)->get($this->db);}/***创建订单*@route({"POST","/"})*@param({"goods_info","$._POST.goods"})*@return({"body"})*/publicfunctioncreateOrder($goods_info){$order_id=Sql::insertInto('orders')->values($goods_info)->exec($this->db)->lastInsertId();return['order_id'=>$order_id];}/***@property依赖注入点,可通过配置指定$db的示例*/public$db;}
框架通过@注释
定义路由和绑定参数,另外还有一些有用的高级特性:依赖注入、自动化接口文档、接口缓存等。
PhalconC扩展简单的路由,超高的效率
居然没看到symfony2的symfony2
基于symfony2的一些webservice的bundle
还有
推荐一个
楼主的话有定的道理,laravel号称巨匠级,那是自称。用了symfony再看lavravel,其实很糙……包括orm,实在是很弱啊……内部写法太不OO了。
个人认为,laravel就是个阉割了的速成版symfony2。不知大家怎么看?
YII
orYII2
其实Laravel做RESTful是很适合的。Laravel4中可以用Route::resource直接设置RESTful路由,而Laravel5中引入了路由注释的功能,只需要在Controller指定@Resource("...")即可,而且每一个Action通过注释都可以反向生成路由。Laravel生成Controller只需要一条命令就可以搞定:
phpartisanmake:controllerUserController
在github上发现一个
直接../api.php/[table_name]就行
laravel+1
Laravel是有ResourceController的
相关文档
这是通过generator自动创建的controller的代码
请参考一下注释中HTTPverb和url的匹配
classCommentsControllerextends\BaseController{
/***Displayalistingofcomments**getcomments**@returnResponse*/publicfunctionindex(){}/***Showtheformforcreatinganewcomment**getcomments/create**@returnResponse*/publicfunctioncreate(){}/***Storeanewlycreatedcommentinstorage.**postcomments**@returnResponse*/publicfunctionstore(){}/***Displaythespecifiedcomment.**getcomments/(:id)**@paramint$id*@returnResponse*/publicfunctionshow($id){}/***Showtheformforeditingthespecifiedcomment.**getcomments/(:id)/edit**@paramint$id*@returnResponse*/publicfunctionedit($id){}/***Updatethespecifiedresourceinstorage.**putcomments/(:id)**@paramint$id*@returnResponse*/publicfunctionupdate($id){}/***Removethespecifiedresourcefromstorage.**deletecomments/(:id);**@paramint$id*@returnResponse*/publicfunctiondestroy($id){}
}
ZendFrameWork
laravel++++++++1
YII
或者YII2
.除了这两个,没有之一。为什么?因为我看见laravel
还是什么的竟然用if-else
来做Restfull
。
关于实现RestFullAPI
。看这里:
这个是全部RESTFULL的,完全满足楼主的要求。看看它的这个扩展关于Howitworks
说明:
Howitworks
RestfullYiiaddsanewsetofRESTFulroutestoyourstandardroutes,butprepends'/api'.
SoifyouapplyRestfullYiitothe'WorkController'youwillgetthefollowingnewroutesbydefault.
[GET]
[GET]
[POST]
[PUT]
[DELETE]
为什么我会推荐YII。先看看这位的回答:
这位兄台肯定没有见过纯面向对象的形式,以为所有的人都像他一样动不动就if-else。还有看到laravel这样竟然用if-else
的实现我就笑了。
YII实现Restfull没有用到所谓的if-else,所有的实现都是纯面向对象,读完他的代码,你就知道这设计的简直太他妈精妙了,然后你读别的框架的代码,你就会很高兴,因为他写的你完全看得懂,比如if-else。
看了各个框架对RestfullAPI
的实现,我才知道了哪些框架是真的牛逼,哪些框架是在装牛逼。
不多说,看一看YII如何实现Restfull,我只贴上将一个PUT动作封装成一个类的代码代码,楼主再去看看所谓的laravel的代码,高下立见:
<?phpYii::import('RestfullYii.actions.ERestBaseAction');/***ActionForRestPuts**Providestheactionforrestputbehavior**@categoryPHP*@packageStarship*@subpackageRestfullyii/actions*@copyrightCopyright(c)2013EvanFrohlich(https://github.com/evan108108)*@licensehttps://github.com/evan108108OSS*@versionRelease:1.2.0*/classEActionRestPUTextendsERestBaseAction{/***run**CalledbyYiiforPUTverb**@param(Mixed/Int)(id)uniqueidentifieroftheresource*@param(Mixed)(param1)firstparamsentintherequest;Oftensubresourcename*@param(Mixed)(param2)Secondparamsentintherequest:OftensubresourceID*/publicfunctionrun($id=null,$param1=null,$param2=null){$this->finalRender(function($visibleProperties,$hiddenProperties)use($id,$param1,$param2){switch($this->getRequestActionType($id,$param1,$param2,'put')){case'RESOURCES':thrownewCHttpException('405','MethodNotAllowed');break;case'CUSTOM':return$this->controller->emitRest("req.put.$id.render",[$this->controller->emitRest(ERestEvent::REQ_DATA_READ),$param1,$param2]);break;case'SUBRESOURCES':thrownewCHttpException('405','MethodNotAllowed');break;case'SUBRESOURCE':return$this->controller->emitRest(ERestEvent::REQ_PUT_SUBRESOURCE_RENDER,[$this->handlePutSubresource($id,$param1,$param2),$param1,$param2,$visibleProperties,$hiddenProperties,]);break;case'RESOURCE':return$this->controller->emitRest(ERestEvent::REQ_PUT_RESOURCE_RENDER,[$this->handlePut($id),$this->getRelations(),$visibleProperties,$hiddenProperties]);break;default:thrownewCHttpException(404,"ResourceNotFound");}});}/***handlePut**HelpermethodforPUTactions**@param(Mixed/Int)(id)uniqueidentifieroftheresourcetoput**@return(Object)Returnsthemodeloftheupdatedresource*/publicfunctionhandlePut($id){$model=$this->controller->emitRest(ERestEvent::MODEL_ATTACH_BEHAVIORS,$this->getModel($id));$data=$this->controller->emitRest(ERestEvent::REQ_DATA_READ);$restricted_properties=$this->controller->emitRest(ERestEvent::MODEL_RESTRICTED_PROPERTIES);$model=$this->controller->emitRest(ERestEvent::MODEL_APPLY_PUT_DATA,[$model,$data,$restricted_properties]);return$this->controller->emitRest(ERestEvent::MODEL_SAVE,[$model]);}/***handlePutSubresource**HelpermethodforPUTsubresourceactions**@param(Mixed/Int)(id)uniqueidentifieroftheresource*@param(String)(subresource_name)nameofthesubresource*@param(Mixed/Int)(subresource_id)uniqueidentifierofthesubresourcetoput**@return(Object)Returnsthemodelcontainingtheupdatedsubresource*/publicfunctionhandlePutSubresource($id,$subresource_name,$subresource_id){$model=$this->controller->emitRest(ERestEvent::MODEL_ATTACH_BEHAVIORS,$this->getModel($id));$this->controller->emitRest(ERestEvent::MODEL_SUBRESOURCE_SAVE,[$model,$subresource_name,$subresource_id]);return$model;}}
如果Laravel有这么优雅的代码,我立马把电脑吃了。来看看Laravel所谓的优雅代码:
<?phpclassBlog_ControllerextendsBase_Controller{publicfunctionaction_index(){//letsgetourpostsandeagerloadthe//author$blogs=Blog::with('author')->order_by('created_at','desc')->paginate(20);//showthehomeview,andincludeour//poststoo//$posts->appends(array('a'=>'app'));//print_r($blogs);exit;returnView::make('blog.index')->with('blogs',$blogs);}publicfunctionaction_add(){$method=Request::method();if($method=='POST'){//let'ssetupsomerulesforournewdata//I'msureyoucancomeupwithbetterones$rules=array('title'=>'required|min:3|max:128','content'=>'required','file'=>'mimes:jpg,gif,png');////Input::upload('picture','path/to/pictures','filename.ext');//File::cpdir($directory,$destination);//File::rmdir($directory);//echoFile::mime('gif');//outputs'image/gif'//if(File::is('jpg','path/to/file.jpg'))//{//File::extension('picture.png');File::delete('path/to/file');//File::append('path/to/file','appendedfilecontent');//}File::put('path/to/file','filecontents');$contents=File::get('path/to/file');//makethevalidator//let'sgetthenewpostfromthePOSTdata//thisismuchsaferthanusingmassassignment$image=Input::file();$pictrue='';$title=Input::get('title');$content=Input::get('content');$description=Input::get('title');if(empty($description))$description=substr($content,0,120);$author_id=Input::get('author_id');$tags=Input::get('tags');if(!empty($image['file']['name'])){$ext=File::extension($image['file']['name']);//$image['file']['tmp_name']Input::upload('file',path('public').'data',md5(date('YmdHis').$image['file']['name']).'.'.$ext);$pictrue=md5(date('YmdHis').$image['file']['name']).'.'.$ext;}$new_blog=array('title'=>$title,'description'=>$description,'content'=>$content,'author_id'=>$author_id,'views'=>0,'pictrue'=>$pictrue,'tags'=>$tags);$v=Validator::make($new_blog,$rules);if($v->fails()){//redirectbacktotheformwith//errors,inputandourcurrently//loggedinuserreturnRedirect::to('blog/add')->with('user',Auth::user())->with_errors($v)->with_input();}//createthenewpost$blog=newBlog($new_blog);$blog->save();//redirecttoviewingournewpostreturnRedirect::to('blog/view/'.$blog->id);}else{//getthecurrentuser$user=Auth::user();//showthecreatepostform,andsend//thecurrentusertoidentifythepostauthorreturnView::make('blog.add')->with('user',$user);}}publicfunctionaction_edit($id){$method=Request::method();$user=Auth::user();$blog=Blog::find($id);if($user->id!=$blog->author->id){returnView::make('blog.view')->with('blog',$blog);}if($method=='POST'){//let'ssetupsomerulesforournewdata//I'msureyoucancomeupwithbetterones$rules=array('title'=>'required|min:3|max:128','content'=>'required','file'=>'mimes:jpg,gif,png');////Input::upload('picture','path/to/pictures','filename.ext');//File::cpdir($directory,$destination);//File::rmdir($directory);//echoFile::mime('gif');//outputs'image/gif'//if(File::is('jpg','path/to/file.jpg'))//{//File::extension('picture.png');File::delete('path/to/file');//File::append('path/to/file','appendedfilecontent');//}File::put('path/to/file','filecontents');$contents=File::get('path/to/file');//makethevalidator//let'sgetthenewpostfromthePOSTdata//thisismuchsaferthanusingmassassignment$image=Input::file();$pictrue='';$title=Input::get('title');$content=Input::get('content');$description=Input::get('title');if(empty($description))$description=substr($content,0,120);$author_id=Input::get('author_id');$tags=Input::get('tags');if(!empty($image['file']['name'])){$ext=File::extension($image['file']['name']);//$image['file']['tmp_name']Input::upload('file',path('public').'data',md5(date('YmdHis').$image['file']['name']).'.'.$ext);$pictrue=md5(date('YmdHis').$image['file']['name']).'.'.$ext;}$new_blog=array('title'=>$title,'description'=>$description,'content'=>$content,'author_id'=>$author_id,'views'=>0,'pictrue'=>$pictrue,'tags'=>$tags);$v=Validator::make($new_blog,$rules);if($v->fails()){//redirectbacktotheformwith//errors,inputandourcurrently//loggedinuserreturnRedirect::to('blog/add')->with('user',Auth::user())->with_errors($v)->with_input();}$blog->title=$title;$blog->description=$description;$blog->content=$content;$blog->author_id=$author_id;$blog->tags=$tags;if(!empty($pictrue))$blog->pictrue=$pictrue;$blog->save();//redirecttoviewingournewpostreturnRedirect::to('blog/view/'.$blog->id);}else{//showthefullview,andpassthepost//wejustaquiredreturnView::make('blog.edit')->with('blog',$blog);}}publicfunctionaction_view($id){//getourpost,identifiedbytheroute//parameter$blog=Blog::find($id);$blog->views+=1;$blog->save();//showthefullview,andpassthepost//wejustaquiredreturnView::make('blog.view')->with('blog',$blog);}publicfunctionaction_delete($id){}publicfunctionaction_search(){returnView::make('blog.search');}}
屎一样的代码我不忍心看了。这他妈的就是面向过程的开发好么,话说这么多静态方法是啥意思?
laravel之所以这么火,靠的是营销和吹牛逼。看看laravel的首页就知道,花花绿绿的。
金玉其外,败絮其中。symfony不知道比laravel高了多少个等级,去看看symfony首页。
laravel在github上面的提交更新好高啊!当然了,是个程序员都能提,当然高了。laravel里面的代码比起YII里面的代码。真的渣的跟屎一样。
laravel用的人好多啊!因为laravel不需要费脑子,源代码一看就懂,自信心爆棚,觉得老子好聪明啊,全球最多人使用的框架,数百位工程师的结晶的源代码一看就懂(同时用几款框架的不在此列)
再来看看laravel首页说的那些傻叉言论。什么Restfull,什么企业级,什么稳定,什么开源的。他妈的要是一个PHP框架连这些最基本的要求都达不到,还用PHP框架干什么?laravel把这些拿出来,就是骗一些脑残的程序员,殊不知这些要求都是好的PHP框架最基本的。
Laravel更优雅,第一次看见laravel的时候惊呼:这不就是php版的rails吗?
看到这句话我笑了。
Laravel搞不好面向对象,就把操作弄成rails的形式,美其名曰,简洁。当然,我不得不承认Laravel还真他妈简洁。说实话有时候简洁快速真的很重要。就说ORM来说,YII生成一个model比起Laravel要复杂太多。
YII是纯面向对象的,不会这些奇淫技巧。
laravel的精髓在于ioc和facade理解了思想就能更上一步。这他妈不是废话么?你把YII的Behavior理解了,你也能更上一步。而且IOC和facade这种东西就是奇淫技巧,没有一点用,耍花枪的真正上战场干不过耍大刀的。
而且百度和傻叉腾讯内部PHP项目基本上都是YII(腾讯也大量用thinkphp,比如腾讯家居)。
还有一点让某些程序员欲罢不能。laravel基本工作就是让你按照面向过程写代码,你需要的代码直接调用静态方法就行了。这就是为什么laravel会让程序员写代码感觉那么happy。面想过程起来真的很爽。
YII一开始就让程序员面向对象,面向对象写起来当然一点也没有面向过程写起来那么happy。
YII被广泛用于金融领域,试问哪个PHP框架可以做到?laravel的安全机制就是渣。经常被黑客们cookie伪造,解密。YII你来试试。
最近有人说YII会被Symfony取代,我只能说他们想多了。
YII被广泛用于那些对安全特性要求较高和稳定性要求较高的领域,比如OA系统(百度内部),百度商业基础平台,金融领域
补充一下,小米的php部分也是YII开发的。
多玩游戏也是YII开发的
其实我不想说奇虎360也是YII
腾讯大多数都是(与PHP相关的)
兄台去智联招聘搜搜吧!
搜YII几十页
搜所谓的laravel好像只有一页
去内推搜YII会发现多如狗
去内推搜laravel会发现好像一页都没有占满
拉勾网laravel一个都搜不到
所以说
laravel玩玩可以,用来做企业级,我只能呵呵
刺痛某些程序员的G点的来了!一般用laravel的,基本上都是外包公司,没有自己的核心产品。因为laravel开发快,做起来像那么回事
<?phpecho"hello,world";?>