关于Luthier CI 路由介绍

505 阅读6分钟

路由 ( Routes )

内容 ( Contents )

  1. 介绍 Introduction
  2. 路由类型 Route types
  3. 句法 Syntax
    1. 命名空间 Namespaces
    2. 前缀 Prefixes
    3. 命名路线 Named routes
    4. 回调为路线 Callbacks as routes
    5. Groups
    6. 资源路线 Resource routes
    7. 默认控制器 Default controller
  4. 参数 Parameters
    1. 可选参数 Optional parameters
    2. 参数正则表达式 Parameter regex
    3. “粘性”参数 "Sticky" parameters

介绍 ( Introduction )

Luthier CI更改CodeIgniter路由的行为:

  • 在CodeIgniter中,默认情况下,可以在任何HTTP谓词下访问路由。使用Luthier CI时,必须为每个路由定义接受的HTTP谓词,并且任何与这些参数不匹配的请求都将生成404错误。
  • 在CodeIgniter中,可以直接从URL访问控制器,而无需定义路由。另一方面,使用Luthier CI,尝试访问未定义的路径(即使URL与控制器的名称和方法匹配)也会生成404错误。
  • 在CodeIgniter中,路由参数是指向控制器的简单正则表达式,在Luthier CI中,路由是一个独立且唯一的实体,它包含定义明确的参数以及从中构建URL的能力。
  • 在CodeIgniter中,您只能创建指向控制器的路由。使用Luthier CI,可以使用匿名函数作为控制器,甚至可以在不使用单个控制器的情况下构建完整的Web应用程序。

路由类型 ( Route types )

您可以使用三种类型的路由:

  • HTTP routes: 它们在HTTP请求下访问,并在application/routes/web.php文件中定义
  • AJAX routes: 它们仅在AJAX请求下访问,并在application/routes/api.php文件中定义
  • CLI routes: 它们仅在CLI(命令行界面)环境下访问,并在application/routes/cli.php文件中定义
AJAX路由进入api.php
虽然你可以在 web.php 文件中定义AJAX路由,但最好这样做 api.php

如果您使用相同的URL和相同的HTTP动词定义两条或更多路线,则第一条路线将被返回ALWAYS Luthier CI允许您使用动词GET,POST,PUT,PATCH,DELETE,HEAD,OPTIONS和TRACE定义HTTP路由:

句法 ( Syntax )

如果您使用过Laravel,那么您将知道如何使用Luthier CI,因为它的语法是相同的。这是路线最简单的例子:

Route::get('foo', 'bar@baz');
第一条路由是获胜的路由
其中foo是路径的URL,bar @ baz是它所指向的控制器和方法(由@分隔)的名称。通过使用get()您告诉Luthier CI 的方法,该路由将在GET请求下可用。

Luthier CI允许您使用动词GET,POST,PUT,PATCH,DELETE,HEAD,OPTIONS和TRACE定义HTTP路由:

Route::post('foo', 'bar@baz');
Route::put('foo', 'bar@baz');
Route::patch('foo', 'bar@baz');
Route::delete('foo', 'bar@baz');
Route::head('foo', 'bar@baz');
Route::options('foo', 'bar@baz');
Route::trace('foo', 'bar@baz');

此外,您可以将具有路径属性的数组作为第三个参数传递(稍后解释)。

Route::get('test', 'controller@method', ['prefix' => '...', 'namespace' => '...', (...)] );

要在路由中接受多个HTTP谓词,请使用以下match()方法:

Route::match(['GET', 'POST'], 'path', 'controller@method', [ (...) ]);

命名空间 ( Namespaces )

namespace属性告诉CodeIgniter控制器所在的子目录。(注意,这不是PHP名称空间,它是目录名称)

// The controller is located in application/controllers/admin/Testcontroller.php
Route::get('hello/world', 'testcontroller@index', ['namespace' => 'admin']);

前缀 ( Prefixes )

使用该prefix属性为路由添加前缀:

// The URL will be 'admin/hello/world' instead of 'hello/world'
Route::get('hello/world', 'testcontroller@index', ['prefix' => 'admin']);

命名路由 ( Named routes )

您可以(事实上,这是可取的)为您的路线指定一个名称。这将允许您从其他地方调用它们:

Route::get('company/about_us', 'testcontroller@index')->name('about_us');

要通过它的名称获取路由,请使用该route()函数,其第一个参数是路由的名称,第二个可选参数是具有该路由的参数值的数组。例如,要获取上一个路由,只需写route('about_us'):

// http://example.com/company/about_us
<a href="<?= route('about_us');?>">My link!</a>
重复的名称 ( Duplicated names )
您不能使用相同的名称调用两个或多个路由

组 ( Groups )

您可以使用该group()方法创建路由组,其中第一个参数是它们共有的前缀,第二个参数是具有子路由的匿名函数:

Route::group('prefix', function(){
    Route::get('bar','test@bar');
    Route::get('baz','test@baz');
});

此外,可以为路由组分配共同的属性。这是扩展语法的示例:

Route::group('prefix', ['namespace' => 'foo', 'middleware' => ['Admin','IPFilter']], function(){
    Route::get('bar','test@bar');
    Route::get('baz','test@baz');
});

资源路由 ( Resource routes )

资源路由允许您在单行上为控制器定义CRUD操作(Create, Read, Update, Delete) 例:

Route::resource('photos','PhotosController');

生产:

[Name]                 [Path]               [Verb]          [Controller action]
photos.index           photos               GET             PhotosController@index
photos.create          photos/create        GET             PhotosController@create
photos.store           photos               POST            PhotosController@store
photos.show            photos/{id}          GET             PhotosController@show
photos.edit            photos/{id}/edit     GET             PhotosController@edit
photos.update          photos/{id}          PUT, PATCH      PhotosController@update
photos.destroy         photos/{id}          DELETE          PhotosController@destroy

此外,可以创建部分资源路由,传递第三个参数,其中包含要过滤的操作数组:

Route::resource('photos','PhotosController', ['index','edit','update']);

生产:

[Name]                 [Path]               [Verb]          [Controller action]
photos.index           photos               GET             PhotosController@index
photos.edit            photos/{id}/edit     GET             PhotosController@edit
photos.update          photos/{id}          PUT, PATCH      PhotosController@update

默认控制器 ( Default controller )

Luthier CI自动设置使用URL / 和HTTP谓词 GET 定义的任何路由作为默认控制器,但是您可以使用 set() 方法和这种特殊语法显式设置它:

// Note that the value is binded to the special 'default_controller' route of CodeIgniter and you must
// use the native syntax:
Route::set('default_controller', 'welcome/index');

回调为路线 ( Callbacks as routes )

您可以使用匿名函数(也称为闭包或lambda函数)而不是指向控制器,例如:

Route::get('foo', function(){
    ci()->load->view('some_view');
});

要访问匿名函数中的框架实例,请使用该ci()函数。

参数 ( Parameters )

可以在路线中定义参数,以便它们可以是动态的。要将参数添加到路径的某个段,请将其括起来{curly brackets}

Route::post('blog/{slug}', 'blog@post');
重复参数 ( Duplicated parameters )
您不能使用相同名称调用两个或多个参数

可选参数 ( Optional parameters )

要创建可选参数,请?在关闭大括号之前添加一个:

Route::put('categories/{primary?}/{secondary?}/{filter?}', 'clients@list');

请注意,在定义第一个可选参数后,以下所有参数必须是可选的。

Routes generated automatically
生成的路由Luthier CI将为您生成所有可选参数的完整路径树,因此您不必担心编写除主要路径之外的更多路径。

参数正则表达式 ( Parameter regex )

您可以将参数限制为正则表达式:

// These are the equivalents of (:num) and (:any), respectively:
Route::get('cars/{num:id}/{any:registration}', 'CarCatalog@index');

此外,您可以使用具有以下{([expr]):[name]}语法的自定义正则表达式:

// This is equivalent to /^(es|en)$/
Route::get('main/{((es|en)):_locale}/about', 'about@index');

“粘性”参数 ( "Sticky" parameters )

您可能需要在一组路由中定义一个参数,然后在所有子路由中都可以使用该参数,而不必在所有控制器中的所有方法的参数中定义它,这很繁琐。考虑到这一点,Luthier CI提供了所谓的Sticky参数。粘性参数以下划线(_) 开头并具有一些奇点:

  • 它不会传递给路径指向的控制器方法的参数。
  • 在共享粘合剂参数的所有子路径中,将从URL中获取值,并将在route()函数中自动提供,因此您可以省略它,或覆盖任何其他值。

考虑这个例子:

Route::group('shop/{_locale}', function()
{
    Route::get('category/{id}', 'ShopCategory@categoryList')->name('shop.category');
    Route::get('product/{id}/details', 'ShopProduct@details')->name('shop.product.details');
});

路由shop.category并shop.product.details共享_locale粘性参数。虽然该参数必须位于URL中,但route()在此上下文中使用该函数时,并不强制它出现在参数值数组中。当您需要链接到当前路径的其他变体时,这尤其有用:

// If the URL is 'shop/en/category/1', {_locale} will be 'en' here:
echo route('shop.category', ['id' => 1]); # shop/en/category/1
echo route('shop.category', ['id' => 2]); # shop/en/category/2
echo route('shop.category', ['id' => 3]); # shop/en/category/3

// You can overwrite that value for any other:
echo route('shop.category', ['_locale' => 'es', 'id' => 1]); # shop/es/category/1

粘性参数的一个优点是您不必将它们定义为指向控制器的所有方法的参数。在前面的示例中,在ShopCategory和ShopProduct控制器中,它们的方法将只有一个参数:$id,因为它是路由器提供的唯一参数:

<?php
# application/controllers/ShopCategory.php

defined('BASEPATH') OR exit('No direct script access allowed');

class ShopCategory extends CI_Controller
{

    // Define the method as categoryList($_locale, $id) will not work: it is
	// waiting for exactly 1 argument:
    public function categoryList($id)
    {

    }
}
<?php
# application/controllers/ShopProduct.php

defined('BASEPATH') OR exit('No direct script access allowed');

class ShopProduct extends CI_Controller
{
    // Same here:
    public function details($id)
    {

    }
}

要获取sticky参数的值,请使用控制器中属性的param()方法route:

<?php
# application/controllers/ShopCategory.php

defined('BASEPATH') OR exit('No direct script access allowed');

class ShopCategory extends CI_Controller
{
    public function categoryList($id)
    {
        $locale = $this->route->param('_locale');
    }
}