路由 (Routes)
内容 (Contents)
- 介绍 Introduction
- 路由类型 Route types
-
句法 Syntax
- 命名空间 Namespaces
- 前缀 Prefixes
- 命名路线 Named routes
- 回调为路线 Callbacks as routes
- 组 Groups
- 资源路线 Resource routes
- 默认控制器 Default controller
-
参数 Parameters
- 可选参数 Optional parameters
- 参数正则表达式 Parameter regex
- “粘性”参数 “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');
}
}