Custom Yii Module Routing

Installing the Project⌗
I’ve chosen the Yii advanced version here. If you don’t have a running environment, you can refer to the official documentation to install the running environment using Vagrant.
Since I already have a PHP runtime environment locally, I’ll use Composer to create the project directly:
composer create-project --prefer-dist yiisoft/yii2-app-advanced service
Enter the project directory and initialize the project:
$ cd service
$ php init
Yii Application Initialization Tool v1.0
Which environment do you want the application to be initialized in?
[0] Development
[1] Production
Your choice [0-1, or "q" to quit] 0
Initialize the application under 'Development' environment? [yes|no] yes
Start initialization ...
generate frontend/config/test-local.php
generate frontend/config/params-local.php
generate frontend/config/main-local.php
generate frontend/config/codeception-local.php
generate frontend/web/index.php
generate frontend/web/robots.txt
generate frontend/web/index-test.php
generate yii
generate backend/config/test-local.php
generate backend/config/params-local.php
generate backend/config/main-local.php
generate backend/config/codeception-local.php
generate backend/web/index.php
generate backend/web/robots.txt
generate backend/web/index-test.php
generate common/config/test-local.php
generate common/config/params-local.php
generate common/config/main-local.php
generate common/config/codeception-local.php
generate yii_test.bat
generate yii_test
generate console/config/test-local.php
generate console/config/params-local.php
generate console/config/main-local.php
generate cookie validation key in backend/config/main-local.php
generate cookie validation key in common/config/codeception-local.php
generate cookie validation key in frontend/config/main-local.php
chmod 0777 backend/runtime
chmod 0777 backend/web/assets
chmod 0777 console/runtime
chmod 0777 frontend/runtime
chmod 0777 frontend/web/assets
chmod 0755 yii
chmod 0755 yii_test
... initialization completed.
After installation, the directory structure is as follows:
$ tree -L 1
.
├── LICENSE.md
├── README.md
├── Vagrantfile
├── backend
├── codeception.yml
├── common
├── composer.json
├── composer.lock
├── console
├── docker-compose.yml
├── environments
├── frontend
├── init
├── init.bat
├── requirements.php
├── vagrant
├── vendor
├── yii
├── yii.bat
├── yii_test
└── yii_test.bat
7 directories, 14 files
Next, we will modify the routing functionality in the backend app.
Module⌗
Generation⌗
Use gii to generate a Module for the project. As you can see below, I generated an auth Module:
$ php yii gii/module --moduleClass='backend\modules\auth\Module' --moduleID=auth
Running 'Module Generator'...
The following files will be generated:
[new] /Users/George/Develop/PHP/service/backend/modules/auth/Module.php
[new] /Users/George/Develop/PHP/service/backend/modules/auth/controllers/DefaultController.php
[new] /Users/George/Develop/PHP/service/backend/modules/auth/views/default/index.php
Ready to generate the selected files? (yes|no) [yes]:yes
Files were generated successfully!
Generating code using template "/Users/George/Develop/PHP/service/vendor/yiisoft/yii2-gii/src/generators/module/default"...
generated /Users/George/Develop/PHP/service/backend/modules/auth/Module.php
generated /Users/George/Develop/PHP/service/backend/modules/auth/controllers/DefaultController.php
generated /Users/George/Develop/PHP/service/backend/modules/auth/views/default/index.php
done!
Registration⌗
Edit the backend\config\main.php
file and add the auth
Module to modules
:
'modules' => [
'auth' => ['class' => 'backend\modules\auth\Module'],
],
And modify the urlManager
property as follows:
'urlManager' => [
'enablePrettyUrl' => true,
'showScriptName' => false,
'enableStrictParsing' => false,
'rules' => [
'<modules>/<controller>' => '<modules>/<controller>/enter'
],
],
The main part is the rules
section, which routes all requests to the enter method of the corresponding Controller in the corresponding Module. The purpose of doing this is to be able to handle all requests uniformly.
Controller for Handling Unified Logic⌗
Create Controller⌗
Create the common\controllers\RestController.php
controller with the following content:
<?php
namespace common\controllers;
use Yii;
use yii\base\Action;
use ReflectionException;
use yii\rest\Controller;
use yii\base\InlineAction;
use yii\base\InvalidRouteException;
use yii\base\InvalidConfigException;
/**
* Date: 2019/1/1
* @author George <[email protected]>
* @package common\controllers
*/
class BaseController extends Controller
{
/**
* Unified request handling
*
* Date: 2019/1/1
* @return mixed
* @throws InvalidRouteException
* @author George
*/
public function main()
{
$request = Yii::$app->request;
$method = strtolower($request->getMethod());
$params = array_merge($request->get(), $request->post());
// Your unified business logic to handle
$result = $this->runAction($method, ['params' => $params]);
return $result;
}
/**
* Date: 2019/1/1
* @param array $params
* @return array
* @author George <[email protected]>
*/
public function post(array $params = []): array
{
return [];
}
/**
* Date: 2019/1/1
* @param array $params
* @return array
* @author George <[email protected]>
*/
public function put(array $params = []): array
{
return [];
}
/**
* Date: 2019/1/1
* @param array $params
* @return array
* @author George <[email protected]>
*/
public function get(array $params = []): array
{
return [];
}
/**
* Using method name index instead of actionIndex
*
* Date: 2019/1/1
* @param string $id
* @return object|Action|InlineAction|null
* @throws ReflectionException
* @throws InvalidConfigException
* @author George <[email protected]>
*/
public function createAction($id)
{
if ($id === '') {
$id = $this->defaultAction;
}
$actionMap = $this->actions();
if (isset($actionMap[$id])) {
return Yii::createObject($actionMap[$id], [$id, $this]);
}
if (preg_match('/^(?:[a-z0-9_]+-)*[a-z0-9_]+$/', $id)) {
$methodName = $id;
if (method_exists($this, $methodName)) {
$method = new \ReflectionMethod($this, $methodName);
if ($method->isPublic() && $method->getName() === $methodName) {
return new InlineAction($id, $this, $methodName);
}
}
}
return null;
}
}
Inherit Controller⌗
Have all Module Controllers in the project inherit from the common\controllers\RestController
created above.
<?php
namespace backend\modules\auth\controllers;
use common\controllers\RestController;
/**
* User SingIn Controller logic
*
* Date: 2019/1/1
* @author George <[email protected]>
* @package backend\modules\auth\controllers
*/
class SigninController extends RestController
{
public function post(array $params = []): array
{
return $params;
}
}
At this point, it’s basically complete. Now when you request POST /auth/signin
, it will automatically route to the post
method of the SigninController
.
I hope this is helpful, Happy hacking…