广告
返回顶部
首页 > 资讯 > 前端开发 > node.js >Laravel中Middleware如何使用
  • 954
分享到

Laravel中Middleware如何使用

2024-04-02 19:04:59 954人浏览 泡泡鱼
摘要

今天就跟大家聊聊有关Laravel中Middleware如何使用,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。PHP内置函数array_revers

今天就跟大家聊聊有关Laravel中Middleware如何使用,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。

PHP内置函数array_reverse、array_reduce、call_user_func和call_user_func_array

看Laravel源码之前,先看下这几个PHP内置函数的使用。首先array_reverse()函数比较简单,倒置数组,看测试代码:

$pipes = [     'Pipe1',     'Pipe2',     'Pipe3',     'Pipe4',     'Pipe5',     'Pipe6', ];  $pipes = array_reverse($pipes);  var_dump($pipes);  // output array(6) {   [0] =>   string(5) "Pipe6"   [1] =>   string(5) "Pipe5"   [2] =>   string(5) "Pipe4"   [3] =>   string(5) "Pipe3"   [4] =>   string(5) "Pipe2"   [5] =>   string(5) "Pipe1" }

array_reduce内置函数主要是用回调函数去迭代数组中每一个值,并且每一次回调得到的结果值作为下一次回调的初始值,***返回最终迭代的值:

 function rsum($v, $w) {     $v += $w;     return $v; }  $a = [1, 2, 3, 4, 5]; // 10为初始值 $b = array_reduce($a, "rsum", 10); // ***输出 (((((10 + 1) + 2) + 3) + 4) + 5) = 25 echo $b . php_EOL;

call_user_func()是执行回调函数,并可输入参数作为回调函数的参数,看测试代码:

class TestCallUserFunc {     public function index($request)     {         echo $request . PHP_EOL;     } }      function testCallUserFunc($test) {     echo $test . PHP_EOL; }  // [$class, $method] call_user_func(['TestCallUserFunc', 'index'], 'pipes'); // 输出'pipes'  // Closure call_user_func(function ($passable) {     echo $passable . PHP_EOL; }, 'pipes'); // 输出'pipes'  // function call_user_func('testCallUserFunc' , 'pipes'); // 输出'pipes'

call_user_func_array与call_user_func基本一样,只不过传入的参数是数组:

class TestCallUserFuncArray {     public function index($request)     {         echo $request . PHP_EOL;     } }   function testCallUserFuncArray($test) {     echo $test . PHP_EOL; }  // [$class, $method] call_user_func_array(['TestCallUserFuncArray', 'index'], ['pipes']); // 输出'pipes'  // Closure call_user_func_array(function ($passable) {     echo $passable . PHP_EOL; }, ['pipes']); // 输出'pipes'  // function call_user_func_array('testCallUserFuncArray' , ['pipes']); // 输出'pipes'

Middleware源码解析

了解了几个PHP内置函数后再去看下Middleware源码就比较简单了。Laravel学习笔记ioc  Container实例化源码解析已经聊过Application的实例化,得到index.php中的$app变量,即\Illuminate\Foundation\Application的实例化对象。然后继续看下index.php的源码:

 $kernel = $app->make(Illuminate\Contracts\Http\Kernel::class);  $response = $kernel->handle(     $request = Illuminate\Http\Request::capture() );  $response->send();  $kernel->terminate($request, $response);

首先从容器中解析出Kernel对象,对于\App\Http\Kernel对象的依赖:\Illuminate\Foundation\Application和\Illuminate\Routing\Router,容器会自动解析。看下Kernel的构造函数:

     public function __construct(Application $app, Router $router)     {         $this->app    = $app;         $this->router = $router;          foreach ($this->middlewareGroups as $key => $middleware) {             $router->middlewareGroup($key, $middleware);         }          foreach ($this->routeMiddleware as $key => $middleware) {             $router->middleware($key, $middleware);         }     }          // \Illuminate\Routing\Router内的方法     public function middlewareGroup($name, array $middleware)     {         $this->middlewareGroups[$name] = $middleware;          return $this;     }          public function middleware($name, $class)     {         $this->middleware[$name] = $class;          return $this;     }

构造函数初始化了几个中间件数组,$middleware[ ], $middlewareGroups[ ]和$routeMiddleware[  ],Laravel5.0的时候记得中间件数组还没有分的这么细。然后就是Request的实例化:

$request = Illuminate\Http\Request::capture()

这个过程以后再聊吧,不管咋样,得到了Illuminate\Http\Request对象,然后传入Kernel中:

    public function handle($request)    {        try {            $request->enableHttpMethodParameterOverride();             $response = $this->sendRequestThroughRouter($request);        } catch (Exception $e) {            $this->reportException($e);             $response = $this->renderException($request, $e);        } catch (Throwable $e) {            $this->reportException($e = new FatalThrowableError($e));             $response = $this->renderException($request, $e);        }         $this->app['events']->fire('kernel.handled', [$request, $response]);         return $response;    }

主要是sendRequestThroughRouter($request)函数执行了转换操作:把\Illuminate\Http\Request对象转换成了\Illuminate\Http\Response,然后通过Kernel的send()方法发送给客户端。同时,顺便触发了kernel.handled内核已处理请求事件。OK,重点关注下sendRequestThroughRouter($request)方法:

     protected function sendRequestThroughRouter($request)     {         $this->app->instance('request', $request);          Facade::clearResolvedInstance('request');                   $this->bootstrap();          return (new Pipeline($this->app))                     ->send($request)                     ->through($this->app->shouldSkipMiddleware() ? [] : $this->middleware)                     ->then($this->dispatchToRouter());     }

$this->bootstrap()主要是做了程序初始化工作,以后再聊具体细节。然后是Pipeline来传输Request,Laravel中把Pipeline管道单独拿出来作为一个service(可看Illuminate/Pipeline文件夹),说明Pipeline做的事情还是很重要的:主要就是作为Request的传输管道,依次通过$middlewares[  ], 或middlewareGroups[ ], 或$routeMiddleware[  ]这些中间件的前置操作,和控制器的某个action或者直接闭包处理得到Response,然后又带着Reponse依次通过$middlewares[ ],  或middlewareGroups[ ], 或$routeMiddleware[  ]这些中间件的后置操作得到准备就绪的Response,然后通过send()发送给客户端。

这个过程有点像汽车工厂的生产一样,Pipeline是传送带,起初Request可能就是个汽车空壳子,经过传送带旁边的一个个机械手middleware@before的过滤和操作(如检查零件刚度是不是合格,壳子尺寸是不是符合要求,给壳子喷个漆或抹个油啥的),然后进入中央控制区加个发动机(Controller@action,或Closure),然后又继续经过检查和附加操作middleware@after(如添加个挡风镜啥的),然后通过门外等着的火车直接运送到消费者手里send()。在每一步装配过程中,都需要Service来支持,Service是通过Container来解析{make()}提供的,并且Service是通过ServiceProvider注册绑定{bind(),singleton(),instance()}到Container中的。

看下Pipeline的send()和through()源码:

public function send($passable)    {        $this->passable = $passable;         return $this;    }        public function through($pipes)    {        $this->pipes = is_array($pipes) ? $pipes : func_get_args();         return $this;    }

send()传送的对象是Request,through()所要通过的对象是$middleware[  ],OK,再看下dispatchToRouter()的源码直接返回一个Closure:

protected function dispatchToRouter()     {         return function ($request) {             $this->app->instance('request', $request);              return $this->router->dispatch($request);         };     }

然后重点看下then()函数源码:

public function then(Closure $destination)     {         $firstSlice = $this->getInitialSlice($destination);          $pipes = array_reverse($this->pipes);          // $this->passable = Request对象         return call_user_func(             array_reduce($pipes, $this->getSlice(), $firstSlice), $this->passable         );     }          protected function getInitialSlice(Closure $destination)     {         return function ($passable) use ($destination) {             return call_user_func($destination, $passable);         };     }

这里假设$middlewares为(尽管源码中$middlewares只有一个CheckFORMaintenanceMode::class):

$middlewares = [     CheckForMaintenanceMode::class,     AddQueuedCookiesToResponse::class,     StartSession::class,     ShareErrorsFromSession::class,     VerifyCsrfToken::class, ];

先获得***个slice(这里作者是比作'洋葱',一层层的穿过,从一侧穿过到另一侧,比喻倒也形象)并作为array_reduce()的初始值,就像上文中array_reduce()测试例子中的10这个初始值,这个初始值现在是个闭包:

$destination = function ($request) {     $this->app->instance('request', $request);     return $this->router->dispatch($request); };  $firstSlice = function ($passable) use ($destination) {     return call_user_func($destination, $passable); };

OK,然后要对$middlewares[ ]进行翻转,为啥要翻转呢?

看过这篇Laravel学习笔记之Decorator Pattern文章就会发现,在Client类利用Decorator  Pattern进行依次装饰的时候,是按照$middlewares[ ]数组中值倒着new的:

public function wrapDecorator(IMiddleware $decorator)    {        $decorator = new VerifyCsrfToken($decorator);        $decorator = new ShareErrorsFromSession($decorator);        $decorator = new StartSession($decorator);        $decorator = new AddQueuedCookiesToResponse($decorator);        $response  = new CheckForMaintenanceMode($decorator);         return $response;    }

这样才能得到一个符合$middlewares[ ]顺序的$response对象:

$response = new CheckForMaintenanceMode(                 new AddQueuedCookiesToResponse(                     new StartSession(                         new ShareErrorsFromSession(                             new VerifyCsrfToken(                                 new Request()                         )                     )                 )             )         );

看下array_reduce()中的迭代回调函数getSlice(){这个迭代回调函数比作剥洋葱时获取每一层洋葱slice,初始值是$firstSlice}:

protected function getSlice()     {         return function ($stack, $pipe) {             return function ($passable) use ($stack, $pipe) {                 if ($pipe instanceof Closure) {                     return call_user_func($pipe, $passable, $stack);                 } elseif (! is_object($pipe)) {                     list($name, $parameters) = $this->parsePipeString($pipe);                     $pipe = $this->container->make($name);                     $parameters = array_merge([$passable, $stack], $parameters);                 } else{                     $parameters = [$passable, $stack];                 }                  return call_user_func_array([$pipe, $this->method], $parameters);             };         };     }

返回的是个闭包,仔细看下第二层闭包里的逻辑,这里$middlewares[ ]传入的是每一个中间件的名字,然后通过容器解析出每一个中间件对象:

$pipe = $this->container->make($name);

并***用call_user_func_array([$class, $method], array  $parameters)来调用这个$class里的$method方法,参数是$parameters。

Demo

接下来写个demo看下整个流程。先简化下getSlice()函数,这里就默认$pipe传入的是类名称(整个demo中所有class都在同一个文件内):

// PipelineTest.php  // Get the slice in every step. function getSlice() {     return function ($stack, $pipe) {         return function ($passable) use ($stack, $pipe) {                          return call_user_func_array([$pipe, 'handle'], [$passable, $stack]);         };     }; }

再把$middlewares[ ]中五个中间件类写上,对于前置操作和后置操作做个简化,直接echo字符串

     // PipelineTest.php <?php  interface Middleware {     public static function handle($request, Closure $closure); }  class CheckForMaintenanceMode implements Middleware {     public static function handle($request, Closure $next)     {         echo $request . ': Check if the application is in the maintenance status.' . PHP_EOL;         $next($request);     } }  class AddQueuedCookiesToResponse implements Middleware {     public static function handle($request, Closure $next)     {         $next($request);         echo $request . ': Add queued cookies to the response.' . PHP_EOL;     } }  class StartSession implements Middleware {     public static function handle($request, Closure $next)     {         echo $request . ': Start session of this request.' . PHP_EOL;         $next($request);         echo $request . ': Close session of this response.' . PHP_EOL;     } }  class ShareErrorsFromSession implements Middleware {     public static function handle($request, Closure $next)     {         $next($request);         echo $request . ': Share the errors variable from response to the views.' . PHP_EOL;     } }  class VerifyCsrfToken implements Middleware {     public static function handle($request, Closure $next)     {         echo $request . ': Verify csrf token when post request.' . PHP_EOL;         $next($request);     } }

给上完整的一个Pipeline类,这里的Pipeline对Laravel中的Pipeline做了稍微简化,只选了几个重要的函数:

// PipelineTest.php  class Pipeline  {          protected $middlewares = [];           protected $request;      // Get the initial slice     function getInitialSlice(Closure $destination)     {         return function ($passable) use ($destination) {             return call_user_func($destination, $passable);         };     }          // Get the slice in every step.     function getSlice()     {         return function ($stack, $pipe) {             return function ($passable) use ($stack, $pipe) {                                  return call_user_func_array([$pipe, 'handle'], [$passable, $stack]);             };         };     }          // When process the Closure, send it as parameters. Here, input an int number.     function send(int $request)     {         $this->request = $request;         return $this;     }      // Get the middlewares array.     function through(array $middlewares)     {         $this->middlewares = $middlewares;         return $this;     }          // Run the Filters.     function then(Closure $destination)     {         $firstSlice = $this->getInitialSlice($destination);              $pipes = array_reverse($this->middlewares);                  $run = array_reduce($pipes, $this->getSlice(), $firstSlice);              return call_user_func($run, $this->request);     } }

OK,现在开始传入Request,这里简化为一个整数而不是Request对象了:

// PipelineTest.php   function dispatchToRouter() {     return function ($request) {         echo $request . ': Send Request to the Kernel, and Return Response.' . PHP_EOL;     }; }  $request = 10;  $middlewares = [     CheckForMaintenanceMode::class,     AddQueuedCookiesToResponse::class,     StartSession::class,     ShareErrorsFromSession::class,     VerifyCsrfToken::class, ];  (new Pipeline())->send($request)->through($middlewares)->then(dispatchToRouter());

执行php PipelineTest.php得到Response:

10: Check if the application is in the maintenance status. 10: Start session of this request. 10: Verify csrf token when post request. 10: Send Request to the Kernel, and Return Response. 10: Share the errors variable from response to the views. 10: Close session of this response. 10: Add queued cookies to the response.

一步一步分析下执行过程:

1.首先获取$firstSlice

$destination = function ($request) {     echo $request . ': Send Request to the Kernel, and Return Response.' . PHP_EOL; }; $firstSlice = function ($passable) use ($destination) {     return call_user_func($destination, $passable); };

这时经过初始化后:

$this->request = 10; $pipes = [     VerifyCsrfToken::class,     ShareErrorsFromSession::class,     StartSession::class,     AddQueuedCookiesToResponse::class,     CheckForMaintenanceMode::class, ];

2.执行***次getSlice()后的结果作为新的$stack,其值为:

$stack   = $firstSlice; $pipe    = VerifyCsrfToken::class; $stack_1 = function ($passable) use ($stack, $pipe) {                          return call_user_func_array([$pipe, 'handle'], [$passable, $stack]); };

3.执行第二次getSlice()后的结果作为新的$stack,其值为:

$stack   = $stack_1; $pipe    = ShareErrorsFromSession::class; $stack_2 = function ($passable) use ($stack, $pipe) {                          return call_user_func_array([$pipe, 'handle'], [$passable, $stack]); };

4.执行第三次getSlice()后的结果作为新的$stack,其值为:

$stack   = $stack_2; $pipe    = StartSession::class; $stack_3 = function ($passable) use ($stack, $pipe) {                          return call_user_func_array([$pipe, 'handle'], [$passable, $stack]); };

5.执行第四次getSlice()后的结果作为新的$stack,其值为:

$stack   = $stack_3; $pipe    = AddQueuedCookiesToResponse::class; $stack_4 = function ($passable) use ($stack, $pipe) {                          return call_user_func_array([$pipe, 'handle'], [$passable, $stack]); };

6.执行第五次getSlice()后的结果作为新的$stack,其值为:

$stack   = $stack_4; $pipe    = CheckForMaintenanceMode::class; $stack_5 = function ($passable) use ($stack, $pipe) {                          return call_user_func_array([$pipe, 'handle'], [$passable, $stack]); };

这时,$stack_5也就是then()里的$run,然后执行call_user_func($run, 10),看执行过程:

1.$stack_5(10) = CheckForMaintenanceMode::handle(10, $stack_4)

echo '10: Check if the application is in the maintenance status.' . PHP_EOL; stack_4(10);

2.$stack_4(10) = AddQueuedCookiesToResponse::handle(10, $stack_3)

$stack_3(10);  echo '10: Add queued cookies to the response.' . PHP_EOL;

3.$stack_3(10) = StartSession::handle(10, $stack_2)

echo '10: Start session of this request.' . PHP_EOL;  $stack_2(10); echo '10: Close session of this response.' . PHP_EOL;

4.$stack_2(10) = ShareErrorsFromSession::handle(10, $stack_1)

$stack_1(10);  echo '10: Share the errors variable from response to the views.' . PHP_EOL;

5.$stack_1(10) = VerifyCsrfToken::handle(10, $firstSlice)

echo '10: Verify csrf token when post request.' . PHP_EOL;  $firstSlice(10);

6.$firstSlice(10) =

$firstSlice(10) = call_user_func($destination, 10) = echo '10: Send Request to the Kernel, and Return Response.' . PHP_EOL;

OK,再把上面执行顺序整理一下:

1. echo '10: Check if the application is in the maintenance status.' . PHP_EOL; // ***个step  3_1. echo '10: Start session of this request.' . PHP_EOL; // 第三个step  5. echo '10: Verify csrf token when post request.' . PHP_EOL; // 第五个step  6.echo '10: Send Request to the Kernel, and Return Response.' . PHP_EOL; //第六个step  4. echo '10: Share the errors variable from response to the views.' . PHP_EOL; // 第四个step  3_2. echo '10: Close session of this response.' . PHP_EOL; // 第三个step  2. echo '10: Add queued cookies to the response.' . PHP_EOL; // 第二个step

看完上述内容,你们对Laravel中Middleware如何使用有进一步的了解吗?如果还想了解更多知识或者相关内容,请关注编程网node.js频道,感谢大家的支持。

--结束END--

本文标题: Laravel中Middleware如何使用

本文链接: https://www.lsjlt.com/news/73696.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Laravel中Middleware如何使用
    今天就跟大家聊聊有关Laravel中Middleware如何使用,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。PHP内置函数array_revers...
    99+
    2022-10-19
  • laravel的中间件middleware怎么用
    这篇文章将为大家详细讲解有关laravel的中间件middleware怎么用,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。中间件可以对请求进行过滤,这里可以利用中间件来验证用户是否登录,如果用户登录则可以...
    99+
    2023-06-21
  • Node.js怎么使用Middleware中间件
    今天小编给大家分享一下Node.js怎么使用Middleware中间件的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。中间件中...
    99+
    2023-07-06
  • Laravel中如何使用Typescript
    本篇内容介绍了“Laravel中如何使用Typescript”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!为什么使用 TypeScriptT...
    99+
    2023-07-04
  • Laravel中Container如何使用
    Laravel中Container如何使用,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。PHPUnit测试下绑定在聊解析过程前...
    99+
    2022-10-19
  • Scrapy 之中间件(Middleware)的具体使用
    目录一、下载器中间件(Downloader Middleware)process_request(request, spider)process_response(request, ...
    99+
    2022-11-11
  • Node.js使用Middleware中间件教程详解
    目录中间件依赖注入应用中间件路由通配符中间件消费者路由排除函数式中间件多个中间件全局中间件中间件 中间件是一个在路由处理程序之前被调用的函数。中间件函数可以访问请求和响应对象,以及应...
    99+
    2023-05-15
    Node.js Middleware Node.js 中间件
  • 如何在 Laravel 中使用 Python?
    Laravel 是一个流行的 PHP 框架,它提供了一个简单而强大的平台,用于构建 Web 应用程序。Python 是一种高级编程语言,具有强大的数据处理和分析能力。在本文中,我们将介绍如何在 Laravel 中使用 Python,以及如何...
    99+
    2023-06-18
    面试 javascript laravel
  • laravel中has方法如何使用
    这篇文章主要介绍“laravel中has方法如何使用”,在日常操作中,相信很多人在laravel中has方法如何使用问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”laravel中has方法如何使用”的疑惑有所...
    99+
    2023-06-22
  • laravel中如何使用with方法
    这篇文章主要为大家展示了“laravel中如何使用with方法”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“laravel中如何使用with方法”这篇文章吧。在laravel中,with()方法...
    99+
    2023-06-26
  • 如何在Laravel中使用Tailwind CSS?
    Tailwind Tailwind是新的CSS实用程序框架,它很快成为我最喜欢的构建界面的方法。通常,尝试一个新的框架、包或语言的最困难的部分是建立起来。建造Tailwind的人做了一项令人难以置信的工作,记录了这个过程,而且非常容易做到。...
    99+
    2022-11-10
  • AWS S3在Laravel中如何使用
    今天小编给大家分享一下AWS S3在Laravel中如何使用的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。AWS S3 为我...
    99+
    2023-06-29
  • laravel如何使用RabbitMQ
    这篇文章主要介绍“laravel如何使用RabbitMQ”,在日常操作中,相信很多人在laravel如何使用RabbitMQ问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”laravel如何使用RabbitMQ...
    99+
    2023-06-22
  • Laravel Livewire如何使用
    这篇文章主要讲解了“Laravel Livewire如何使用”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Laravel Livewire如何使用”吧!Laravel Livewire是一个...
    99+
    2023-07-04
  • laravel如何使用websocket
    什么是WebSocket? WebSocket是一种在单个TCP连接上进行全双工通信的协议。它使得浏览器和服务器之间的实时通信变得更加容易。与HTTP请求不同,WebSocket连接是持久的,这意味着...
    99+
    2023-08-31
    php laravel websocket
  • 如何在Laravel中使用Python函数?
    Laravel是一个流行的PHP框架,它提供了许多功能和工具来帮助开发人员构建高质量的Web应用程序。Python是一种强大的编程语言,可以用于多种应用领域,包括数据分析、机器学习和自然语言处理等。在本文中,我们将探讨如何在Laravel中...
    99+
    2023-06-05
    git 函数 laravel
  • 如何在php中使用Laravel接口
    如何在php中使用Laravel接口?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。php是什么语言php,一个嵌套的缩写名称,是英文超级文本预处理语言(PHP:Hypert...
    99+
    2023-06-14
  • redux功能强大的Middleware中间件使用学习
    目录引言redux中的Middleware记录日志手动记录redux-sagaGenerator函数实际使用场景引言 上一节我们学习了redux在实际项目的应用细节,这一节我们来学习...
    99+
    2022-11-13
  • Laravel队列如何使用
    这篇文章主要讲解了“Laravel队列如何使用”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Laravel队列如何使用”吧!什么情况使用队列?耗时的,比如上传一个文件后进行一些格式的转化等。...
    99+
    2023-06-29
  • Laravel的Tinker如何使用
    这篇文章主要介绍“Laravel的Tinker如何使用”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Laravel的Tinker如何使用”文章能帮助大家解决问题。Laravel Tinker 的使用...
    99+
    2023-07-04
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作