php实现restful api有什么框架使用方便?

发布于 2022-09-04 15:09:31 字数 39 浏览 27 评论 0

php框架比较多,想实现restful api用哪个比较流行

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(24

红ご颜醉 2022-09-11 15:09:32

我目前在用 SlimFramework 做微信的开发及编写一些 Restful API .感觉还不错。你可以了解一下.

官方地址:http://www.slimframework.com
中文文档:http://tutorial.jingwentian.com/slim/ 注:版本:2.x

洛阳烟雨空心柳 2022-09-11 15:09:32

我是来说反例的,但凡用以下风格实现controller的,实现RESTFul都很不方便

class Controller {
    public function actionFoo() {}
    public function actionBar() {}
}

因为RESTFul是对HTTP动作(GET/POST/PUT/DELETE/...)敏感的,用这种风格的Controller的框架来实现就不可避免的会出现以下这种代码

class Controller {
    public function actionFoo() {
        if (is_get) {
            /* 一坨代码 */
        } else if (is_post) {
            /* 一坨代码 */
        } else if (is_put) {
            /* 一坨代码 */
        } else if (is_delete) {
            /* 一坨代码 */
        }
    }
}

很恶心吧,可惜的是,大部分的框架都是这种风格的Controller实现,差不多都成为标准了

当然了,Laravel也无法免俗。不过Laravel稍微把这个代码优化了一下,大概的逻辑差不多是这样

class Controller {
    public function actionFoo() {
        if (is_get) {
            return $this->getAction();
        } else if (is_post) {
            return $this->postAction();
        } else if (is_put) {
            return $this->putAction();
        } else if (is_delete) {
            return $this->deleteAction();
        }
    }

    private function getAction() {}
    private function postAction() {}
    private function putAction() {}
    private function deleteAction() {}
}

Laravel里面真正的代码当然不可能是上面这样了,但是逻辑就是这么回事,框架帮你把不同的HTTP verb调用了不同的action,把这个路子套到了classic controller里面去

// 就是这样,这是从Laravel手册里面copy的
class UserController extends BaseController {

    public function getIndex()
    {
        //
    }

    public function postProfile()
    {
        //
    }

}

的确能用,但是不足够好。因为本质上都是从classic controller的角度出发,然后对RESTFul进行迁就的设计

比如一个需求,根据http协议,对一个不支持post的url发起post,应该响应http 405 (method not allowed),这些框架应该怎么做才方便呢?

万劫不复 2022-09-11 15:09:32

必须提 Yii2

鹤仙姿 2022-09-11 15:09:32

因为框架使用的不是很多,所以不太好推荐哪个框架使用起来比较方便,目前自己使用的 YII 实现起来就很方便,但是无论题主最后使用哪个框架,API 都是要根据需求自己来设计实现的,建议题主读下这篇文章:

《Best Practices for Designing a Pragmatic RESTful API》

另外,@lenbo_ma 的博文也很值得一读:《HTTP API响应数据规范整理》

蓝天白云 2022-09-11 15:09:32

楼上吐槽php写API必要有一堆条件判断的朋友,restful这个难道不判断get/post/put/delete条件语句,还有更好的办法吗?

若是说真的好,golang最好

SlimFramework,挺有趣的!赞

如日中天 2022-09-11 15:09:32

一提到rest,就非得支持啥put、delete这些请求,感觉很无聊,我认为post和get就能应付的了我们所有的请求了。

风为裳 2022-09-11 15:09:32

推荐 PhpBoot, 为快速开发 RESTful API 设计的PHP框架。它可以帮助开发者更聚焦在业务本身, 而将原来开发中不得不做, 但又重复枯燥的事情丢给框架, 比如编写接口文档、参数校验和远程调用代码等。

特色

PhpBoot 框架提供许多主流的特性, 如ORM、依赖注入等。 这些特性都经过精心设计和选择(有些是第三方开源代码,如 PHP-DI),但和其他框架相比较, PhpBoot 最显著的特色是:

1. 以面向对象的方式编写接口

你肯定看到过这样的代码:

// **不用** PhpBoot 的代码
class BookController
{
    public function findBooks(Request $request)
    {
        $name = $request->get('name');
        $offset = $request->get('offset', 0);
        $limit = $request->get('limit', 10);
        ...
        return new Response(['total'=>$total, 'data'=>$books]);
    }
    
    public function createBook(Request $request)
    ...
}

很多主流框架都需要用类似代码编写接口。但这种代码的一个问题是, 方法的输入输出隐藏在实现里, 这不是通常我们提倡的编码方式。如果你对代码要求更高, 你可能还会实现一层 Service 接口, 而在 Controller 里只是简单的去调用 Service 接口。而使用 PhpBoot, 你可以用更自然的方式去定义和实现接口。上面的例子, 在 PhpBoot 框架中实现是这样的:

/**
 * @path /books/
 */
class Books
{
    /**
     * @route GET /
     * @return Book[]
     */
    public function findBooks($name, &$total=null, $offset=0, $limit=10)
    {
        $total = ...
        ...
        return $books;
    }
  
    /**
     * @route POST /
     * @param Book $book {@bind request.request} bind $book with http body
     * @return string id of created book
     */
    public function createBook(Book $book)
    {
        $id = ... 
        return $id;
    }
}

上面两份代码执行的效果是一样的。可以看到 PhpBoot 编写的代码更符合面向对象编程的原则, 以上代码完整版本请见phpboot-example

2. 轻松支持 Swagger

Swagger是目前最流行的接口文档框架。虽然很多框架都可以通过扩展支持Swagger, 但一般不是需要编写很多额外的注释, 就是只能导出基本的路由信息, 而不能导出详细的输入输出参数。而 PhpBoot 可以在不增加额外编码负担的情况下, 轻松去完成上述任务,下图为findBooks对应的文档。更多内容请见文档在线 Demo

3. 简单易用的分布式支持

使用 PhpBoot 可以很简单的构建分布式应用。通过如下代码, 即可轻松远程访问上面示例中的 Books 接口:

$books = $app->make(RpcProxy::class, [
        'interface'=>Books::class, 
        'prefix'=>'http://x.x.x.x/'
    ]);
    
$books->findBooks(...);

同时还可以方便的发起并发请求, 如:

$res = MultiRpc::run([
    function()use($service1){
        return $service1->doSomething();
    },
    function()use($service2){
        return $service2->doSomething();
    },
]);

更多内容请查看文档

4. IDE 友好

IDE 的代码提示功能可以让开发者轻松不少, 但很多框架在这方面做的并不好, 你必须看文档或者代码, 才能知道某个功能的用法。PhpBoot 在一开始就非常注重框架的 IDE 友好性, 尽可能让框架保持准确的代码提示。比如下图是 DB 库在 PhpStorm 下的使用:

可以看到, IDE 的提示是符合 SQL 语法规则的, 并不是简单罗列所有 SQL 指令。

主要特性

安装和配置

  1. 安装 composer (已安装可忽略)

    curl -s http://getcomposer.org/installer | php
  2. 安装 PhpBoot

    composer require "caoym/phpboot"
  3. index.php 加载 PhpBoot

    <?php
    require __DIR__.'/vendor/autoload.php';
          
    $app = \PhpBoot\Application::createByDefault(__DIR__.'/config/config.php');
    $app->loadRoutesFromPath(__DIR__.'/App/Controllers');
    $app->dispatch();

帮助和文档

暮倦 2022-09-11 15:09:32

自荐一下我写的 Blink Framework

Blink 重分借鉴了 Yii 和 Laravel 的优点,定位优雅简洁,专注于 API 的开发,高扩展性,默认提供了常见诸如路由、登陆认证、依赖注入、日志处理、插件机制等功能,更多组件也在不断扩充中。

同时,Blink 兼容 Swoole,FPM,CLI(php -S) 多种运行环境,对于性能要求高的场景,可以无缝接入 Swoole,获得可观的性能提升。

GitHub: https://github.com/bixuehujin...
文档:https://docs.rethinkphp.com/b...

誰認得朕 2022-09-11 15:09:32

Phalcon C扩展 简单的路由,超高的效率

套路撩心 2022-09-11 15:09:32

推荐一个 recess 应该会对你有所启发,restful 关键不在于框架的选择,而是你如何理解、实现restful。相比于其他框架,我更喜欢 recess 使用 Annotation 来实现的Router的方式,但显然性能差了点。当然它能在 Annotation 数据跟权限的 Validation 更好了。

瞄了个咪的 2022-09-11 15:09:32

ToroPHP 居然没人推荐这个 专门为restful api设计的啊。

怀中猫帐中妖 2022-09-11 15:09:32

楼主的话有定的道理,laravel号称巨匠级,那是自称。用了symfony再看lavravel,其实很糙……包括orm,实在是很弱啊……内部写法太不OO了。
个人认为,laravel就是个阉割了的速成版symfony2。不知大家怎么看?

悟红尘 2022-09-11 15:09:32

YIIorYII2

揽月 2022-09-11 15:09:32

其实 Laravel 做 RESTful 是很适合的。Laravel 4 中可以用 Route::resource 直接设置 RESTful 路由,而 Laravel 5 中引入了路由注释的功能,只需要在 Controller 指定@Resource("...")即可,而且每一个 Action 通过注释都可以反向生成路由。Laravel 生成 Controller 只需要一条命令就可以搞定:

php artisan make:controller UserController
郁金香雨 2022-09-11 15:09:32

http://book.cakephp.org/3.0/en/development/rest.html CakePHP 3.0 对REST 支持很强大的。

暮年 2022-09-11 15:09:32

在github上发现一个 https://github.com/mevdschee/...

直接../api.php/[table_name]就行

迷荒 2022-09-11 15:09:32

Laravel是有Resource Controller的

相关文档
http://www.golaravel.com/docs/4.1/controllers/#resource-controllers

这是通过generator自动创建的controller的代码
请参考一下注释中HTTP verb 和 url的匹配

class CommentsController extends \BaseController {

/**
 * Display a listing of comments
 *
 * get comments
 *
 * @return Response
 */
public function index() {}

/**
 * Show the form for creating a new comment
 *
 * get comments/create
 *
 * @return Response
 */
public function create(){}

/**
 * Store a newly created comment in storage.
 *
 * post comments
 *
 * @return Response
 */
public function store() {}

/**
 * Display the specified comment.
 *
 * get comments/(:id)
 *
 * @param  int  $id
 * @return Response
 */
public function show($id){}

/**
 * Show the form for editing the specified comment.
 *
 * get comments/(:id)/edit
 *
 * @param  int  $id
 * @return Response
 */
public function edit($id){}

/**
 * Update the specified resource in storage.
 *
 * put comments/(:id)
 *
 * @param  int  $id
 * @return Response
 */
public function update($id){}

/**
 * Remove the specified resource from storage.
 *
 * delete comments/(:id);
 *
 * @param  int  $id
 * @return Response
 */
public function destroy($id){}

}

我为君王 2022-09-11 15:09:32

ZendFrame Work

汹涌人海 2022-09-11 15:09:32

laravel +1

近箐 2022-09-11 15:09:32

laravel ++++++++1

春花秋月 2022-09-11 15:09:32

YII或者YII2.除了这两个,没有之一。为什么?因为我看见laravel还是什么的竟然用if-else来做Restfull
关于实现RestFullAPI。看这里:
https://github.com/evan108108/RESTFullYii
这个是全部RESTFULL的,完全满足楼主的要求。看看它的这个扩展关于How it works说明:
How it works
RestfullYii adds a new set of RESTFul routes to your standard routes, but prepends '/api' .
So if you apply RestfullYii to the 'WorkController' you will get the following new routes by default.
[GET] http://yoursite.com/api/work (returns all works)
[GET] http://yoursite.com/api/work/1 (returns work with PK=1)
[POST] http://yoursite.com/api/work (create new work)
[PUT] http://yoursite.com/api/work/1 (update work with PK=1)
[DELETE] http://yoursite.com/api/work/1 (delete work with PK=1)
为什么我会推荐YII。先看看这位的回答:
http://segmentfault.com/q/1010000000500665#a-1020000000503507
这位兄台肯定没有见过纯面向对象的形式,以为所有的人都像他一样动不动就if-else。还有看到laravel 这样竟然用if-else的实现我就笑了。
YII实现Restfull没有用到所谓的if-else,所有的实现都是纯面向对象,读完他的代码,你就知道这设计的简直太他妈精妙了,然后你读别的框架的代码,你就会很高兴,因为他写的你完全看得懂,比如if-else。

看了各个框架对RestfullAPI的实现,我才知道了哪些框架是真的牛逼,哪些框架是在装牛逼。
不多说,看一看YII如何实现Restfull,我只贴上将一个PUT动作封装成一个类的代码代码,楼主再去看看所谓的laravel 的代码,高下立见:

<?php
Yii::import('RestfullYii.actions.ERestBaseAction');

/**
 * Action For Rest Puts
 *
 * Provides the action for rest put behavior
 *
 * @category   PHP
 * @package    Starship
 * @subpackage Restfullyii/actions
 * @copyright  Copyright (c) 2013 Evan Frohlich (https://github.com/evan108108)
 * @license    https://github.com/evan108108   OSS
 * @version    Release: 1.2.0
 */
class EActionRestPUT extends ERestBaseAction
{
    /**
     * run
     *
     * Called by Yii for PUT verb
     * 
     * @param (Mixed/Int) (id) unique identifier of the resource
     * @param (Mixed) (param1) first param sent in the request; Often subresource name
     * @param (Mixed) (param2) Second param sent in the request: Often subresource ID
     */
    public function run($id=null, $param1=null, $param2=null) 
    {
        $this->finalRender(function($visibleProperties, $hiddenProperties) use($id, $param1, $param2) {
                switch ($this->getRequestActionType($id, $param1, $param2, 'put')) {
                    case 'RESOURCES':
                        throw new CHttpException('405', 'Method Not Allowed');
                        break;
                    case 'CUSTOM':
                        return $this->controller->emitRest("req.put.$id.render", [$this->controller->emitRest(ERestEvent::REQ_DATA_READ), $param1, $param2]);
                        break;
                    case 'SUBRESOURCES':
                        throw new CHttpException('405', 'Method Not Allowed');
                        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:
                        throw new CHttpException(404, "Resource Not Found");
                }
            }
        );
    }

    /**
     * handlePut
     *
     * Helper method for PUT actions
     *
     * @param (Mixed/Int) (id) unique identifier of the resource to put
     *
     * @return (Object) Returns the model of the updated resource
     */ 
    public function handlePut($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
     *
     * Helper method for PUT subresource actions
     *
     * @param (Mixed/Int) (id) unique identifier of the resource
     * @param (String) (subresource_name) name of the subresource
     * @param (Mixed/Int) (subresource_id) unique identifier of the subresource to put
     *
     * @return (Object) Returns the model containing the updated subresource
     */ 
    public function handlePutSubresource($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所谓的优雅代码:

<?php
class Blog_Controller extends Base_Controller
{
    public function action_index()
    {
            // lets get our posts and eager load the
        // author
        $blogs = Blog::with('author')->order_by('created_at', 'desc')->paginate(20);
        // show the home view, and include our
        // posts too
        //$posts->appends(array('a' => 'app'));
        //print_r($blogs);exit;
        return View::make('blog.index')->with('blogs', $blogs);
    }

    public function action_add()
    {
        $method = Request::method();
        if($method =='POST'){


            // let's setup some rules for our new data
            // I'm sure you can come up with better ones
       $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);
        //echo File::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', 'appended file content');
        //}File::put('path/to/file', 'file contents');$contents = File::get('path/to/file');
        // make the validator
            // let's get the new post from the POST data
            // this is much safer than using mass assignment
        $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() )
        {
            // redirect back to the form with
            // errors, input and our currently
            // logged in user
            return Redirect::to('blog/add')
            ->with('user', Auth::user())
            ->with_errors($v)
            ->with_input();
        }


        // create the new post
        $blog = new Blog($new_blog);
        $blog->save();

        // redirect to viewing our new post
        return Redirect::to('blog/view/'.$blog->id);
        }
        else{
            // get the current user
            $user = Auth::user();

            // show the create post form, and send
            // the current user to identify the post author
            return View::make('blog.add')->with('user', $user);
        }


    }

    public function action_edit($id)
    {
        $method = Request::method();
        $user = Auth::user();

        $blog = Blog::find($id);
        if($user->id != $blog->author->id)
        {
            return View::make('blog.view')
            ->with('blog', $blog);
        }
        if($method =='POST')
        {

            // let's setup some rules for our new data
            // I'm sure you can come up with better ones
       $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);
        //echo File::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', 'appended file content');
        //}File::put('path/to/file', 'file contents');$contents = File::get('path/to/file');
        // make the validator
            // let's get the new post from the POST data
            // this is much safer than using mass assignment
        $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() )
        {
            // redirect back to the form with
            // errors, input and our currently
            // logged in user
            return Redirect::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();

        // redirect to viewing our new post
        return Redirect::to('blog/view/'.$blog->id);
        }
        else
        {

            // show the full view, and pass the post
            // we just aquired
            return View::make('blog.edit')->with('blog', $blog);
        }
    }

    public function action_view($id)
    {
        // get our post, identified by the route
        // parameter
        $blog = Blog::find($id);
        $blog->views += 1;
        $blog->save();
        // show the full view, and pass the post
        // we just aquired
        return View::make('blog.view')
        ->with('blog', $blog);
    }

    public function action_delete($id)
    {
    }

    public function action_search()
    {
        return View::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开发快,做起来像那么回事

感受沵的脚步 2022-09-11 15:09:32
<?php
    echo "hello,world";
?>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文