Как реализовать массив шаблонов в urlManager web.php?

У меня есть приложение Yii2. И я пытаюсь добавить массив шаблонов в urlManager web.php. И я много искал и нашел много ссылок с правильным решением. Например:

https://stackoverflow.com/questions/41873686/yii2-apply-custom-url-rule-class
https://www.yiiframework.com/doc/guide/2.0/en/runtime-routing

Но это не решило проблему.

Итак, если я сделаю это так:

'urlManager' => [
            'enablePrettyUrl' => true,
            'showScriptName' => false,
            
            'rules' =>  [
                'class' => 'yii\rest\UrlRule', 
                'controller' => 'v1/user', 
                'POST' => 'v1/user/signup',
                'POST' => 'v1/user/login',
                
                
            ],                          
            
        ],

А в почтальоне я публикую сообщение по этому URL: http://localhost:8080/v1/user/login

все работает нормально. Но если я сделаю это:

        'urlManager' => [
            'enablePrettyUrl' => true,
            'showScriptName' => false,
            
            'rules' =>  [
                'class' => 'yii\rest\UrlRule', 
                'controller' => 'v1/user', 
                'patterns' => [
                    'POST' => 'signup',
                    'POST login' => 'login',
                    'OPTIONS login' => 'options',                    
                ],
                
                
            ],                         
            
        ],

весь файл web.php выглядит:

<?php
// phpcs:ignoreFile

$params = require __DIR__ . '/params.php';
$db = require __DIR__ . '/db.php';

$config = [
    'id' => 'basic',
    'name' => 'internetsuite 2.0',
    'basePath' => dirname(__DIR__),
    'bootstrap' => ['log'],
    'aliases' => [
        '@bower' => '@vendor/bower-asset',
        '@npm'   => '@vendor/npm-asset',
    ],
    'modules' => [
        'v1' => [
            'class' => 'app\modules\v1\Module',
        ],
    ],
    'components' => [
        'request' => [

            'parsers' => [
                'application/json' => 'yii\web\JsonParser',
            ],
            // !!! insert a secret key in the following (if it is empty) - this is required by cookie validation
            'cookieValidationKey' => 'OEtCunrAfQNETtmUSDnZw1JPHTB44i3A',
        ],
        

        'cache' => [
            'class' => 'yii\caching\FileCache',
        ],
        'user' => [
            'identityClass' => 'app\models\User',
            'enableAutoLogin' => true,
        ],
        'errorHandler' => [
            'errorAction' => 'site/error',
        ],
        'mailer' => [
            'class' => \yii\symfonymailer\Mailer::class,
            'viewPath' => '@app/mail',
            // send all mails to a file by default.
            'useFileTransport' => true,
        ],
        'log' => [
            'traceLevel' => YII_DEBUG ? 3 : 0,
            'targets' => [
                [
                    'class' => 'yii\log\FileTarget',
                    'levels' => ['error', 'warning'],
                ],
            ],
        ],
        'db' => $db,
        'urlManager' => [
            'enablePrettyUrl' => true,
            'showScriptName' => false,
            'enableStrictParsing' => true,
            
            'rules' =>  [[
                'class' => 'yii\rest\UrlRule', 
                'controller' => 'v1/user', 
                'pluralize' => false,
                ],
                'extraPatterns' => [
                    'OPTIONS {login}' => 'options',                    
                    'POST signup' => 'signup',
                    'POST login' => 'login',
                ],
                
                
            ],                         
            
        ],

    ],
    'params' => $params,
];

if (YII_ENV_DEV) {
    // configuration adjustments for 'dev' environment
    $config['bootstrap'][] = 'debug';
    $config['modules']['debug'] = [
        'class' => 'yii\debug\Module',
        // uncomment the following to add your IP if you are not connecting from localhost.
        //'allowedIPs' => ['127.0.0.1', '::1'],
    ];

    $config['bootstrap'][] = 'gii';
    $config['modules']['gii'] = [
        'class' => 'yii\gii\Module',
        // uncomment the following to add your IP if you are not connecting from localhost.
        //'allowedIPs' => ['127.0.0.1', '::1'],
    ];
}

return $config;

Я получаю эту ошибку:

Unknown Property – yii\base\UnknownPropertyException
Setting unknown property: yii\web\UrlRule::POST

И мне нужен параметр OPTIONS, потому что я вызываю вызов API из приложения реагирования.

Вопрос: как правильно реализовать паттерн в urlManager?

🤔 А знаете ли вы, что...
Синтаксис PHP схож с синтаксисом C, C++, Java и Perl.


52
2

Ответы:

Эти правила кажутся немного бессмысленными по сравнению с документацией.
Вероятно, это больше похоже на это (<controller> — это просто подстановочный знак, используемый для стандартного CRUD):

[
    'class' => 'yii\rest\UrlRule',
    'controller' => ['user'], 
    'pluralize' => false,
    'patterns' => [
        'POST user/login' => 'user/login',
        'POST user'       => 'user/signup'               
    ]    
]

К глаголу OPTIONS следует обращаться с .htaccess. Установка точек останова внутри UrlManager.php может способствовать пониманию этих наборов правил. В каждом случае документация кажется неверной относительно отсутствия поддержки глагола OPTIONS, потому что строка 236 гласит:

$verbs = 'GET|HEAD|POST|PUT|PATCH|DELETE|OPTIONS';

Также смотрите Полное руководство по Yii 2.0 — Маршрутизация.


Решено

Я нашел проблему во всем коде конфигурации web.php. Вы помещаете 'extraPatterns' вне конфигурации правила отдыха, чтобы оно рассматривалось как еще одно правило, а не как часть правила отдыха.

'urlManager' => [
            'enablePrettyUrl' => true,
            'showScriptName' => false,
            'enableStrictParsing' => true,
            
            'rules' =>  [[
                'class' => 'yii\rest\UrlRule', 
                'controller' => 'v1/user', 
                'pluralize' => false,
                ], // <-- THIS SHOULDN'T BE HERE
                'extraPatterns' => [
                    'OPTIONS {login}' => 'options',                    
                    'POST signup' => 'signup',
                    'POST login' => 'login',
                ],
                // Here should end the yii\rest\UrlRule configuration
                
            ],                         
            
        ],

Итак, правильная конфигурация должна выглядеть так:

'urlManager' => [
    'enablePrettyUrl' => true,
    'showScriptName' => false,
    'enableStrictParsing' => true,
    'rules' => [
        [
            'class' => 'yii\rest\UrlRule', 
            'controller' => 'v1/user', 
            'pluralize' => false,
            'extraPatterns' => [
                'OPTIONS {login}' => 'options',                    
                'POST signup' => 'signup',
                'POST login' => 'login',
            ],
        ],    
    ],
],

Примечание: я не знаю, почему вы вот так ставите login внутри брекетов {login}, но это кажется неправильным. OPTIONS login будет соответствовать запросу OPTIONS, отправленному на такой маршрут v1/user/login. Когда вы помещаете его в фигурные скобки, вы говорите UrlRule заменить его токеном, определенным в массиве $tokens.