[英]yii2 “Unable to resolve the request” with ActiveController
我有一個簡單的 Yii2 REST 應用程序。 看:
如您所見,只有一個 model Category
,並且只有一個 controller CategoryController
Category
:
<?php
namespace api\models;
/**
* This is the model class for table "{{%category}}".
*
* @property int $id
* @property string $slug
* @property string $title
* @property int $enabled
*
*/
class Category extends \yii\db\ActiveRecord
{
/**
* {@inheritdoc}
*/
public static function tableName()
{
return '{{%category}}';
}
/**
* {@inheritdoc}
*/
public function rules()
{
return [
['enabled', 'default', 'value' => 0],
[['title'], 'required'],
[['enabled'], 'integer'],
[['slug', 'title'], 'string', 'max' => 255],
[['slug'], 'unique'],
];
}
}
CategoryController
:
<?php
namespace api\controllers;
use yii\rest\ActiveController;
/**
* Class CategoryController
*
* @package api\controllers
*/
class CategoryController extends ActiveController
{
public $modelClass = 'api\models\Category';
}
然后我將在此處固定我的應用程序配置:
config/main.php
<?php
$params = array_merge(
require __DIR__ . '/../../common/config/params.php',
require __DIR__ . '/../../common/config/params-local.php',
require __DIR__ . '/params.php',
require __DIR__ . '/params-local.php'
);
return [
'id' => 'app-api',
'basePath' => dirname(__DIR__),
'language' => 'ru-RU',
'bootstrap' => ['log'],
'controllerNamespace' => 'api\controllers',
'components' => [
'request' => [
'parsers' => [
'application/json' => 'yii\web\JsonParser',
]
],
'response' => [
'class' => 'yii\web\Response',
'format' => 'json'
],
'user' => [
'identityClass' => 'common\models\User',
'enableAutoLogin' => true,
'identityCookie' => ['name' => '_identity-frontend', 'httpOnly' => true],
],
'log' => [
'traceLevel' => YII_DEBUG ? 3 : 0,
'targets' => [
[
'class' => 'yii\log\FileTarget',
'levels' => ['error', 'warning'],
],
],
],
'urlManager' => [
'enablePrettyUrl' => true,
'enableStrictParsing' => true,
'showScriptName' => false,
'rules' => [
[
'class' => 'yii\rest\UrlRule',
'controller' => 'category',
],
],
],
],
'params' => $params,
];
我如何運行它? 簡單的。 只需在web
目錄中的$ php -S localhost:8900
的幫助下。
但是當我訪問 URL: localhost:8900/categories
時,我看到以下內容:
{"name":"Not Found","message":"找不到頁面。","code":0,"status":404,"type":"yii\web\NotFoundHttpException","previous":{ "name":"Invalid Route","message":"無法解析請求\"category/index\"。","code":0,"type":"yii\base\InvalidRouteException"}}
這是什么意思? 我想 Yii 做了以下事情。
/categories
請求(但 Yii 由於我的一些未知原因無法做到這一點)"name":"Not Found","message":"Page not found.","code":0,"status":404,"type":"yii\\web\\NotFoundHttpException",
但原因{"name":"Invalid Route","message":"Unable to resolve the request \"category/index\".","code":0,"type":"yii\\base\\InvalidRouteException"}
對我來說是未知的。
所有這些都是奇怪的行為。 我只是想遵循這個官方 指南我的配置有什么問題?
我已經深入研究(直接在框架的內部)。
我發現,崩潰發生在這里:
/**
* Creates a controller based on the given controller ID.
*
* The controller ID is relative to this module. The controller class
* should be namespaced under [[controllerNamespace]].
*
* Note that this method does not check [[modules]] or [[controllerMap]].
*
* @param string $id the controller ID.
* @return Controller|null the newly created controller instance, or `null` if the controller ID is invalid.
* @throws InvalidConfigException if the controller class and its file name do not match.
* This exception is only thrown when in debug mode.
*/
public function createControllerByID($id)
{
$pos = strrpos($id, '/');
if ($pos === false) {
$prefix = '';
$className = $id;
} else {
$prefix = substr($id, 0, $pos + 1);
$className = substr($id, $pos + 1);
}
if ($this->isIncorrectClassNameOrPrefix($className, $prefix)) {
return null;
}
$className = preg_replace_callback('%-([a-z0-9_])%i', function ($matches) {
return ucfirst($matches[1]);
}, ucfirst($className)) . 'Controller';
$className = ltrim($this->controllerNamespace . '\\' . str_replace('/', '\\', $prefix) . $className, '\\');
// THE PROBLEM IS HERE !!! WITH THE !class_exists($className)
if (strpos($className, '-') !== false || !class_exists($className)) {
return null;
}
if (is_subclass_of($className, 'yii\base\Controller')) {
$controller = Yii::createObject($className, [$id, $this]);
return get_class($controller) === $className ? $controller : null;
} elseif (YII_DEBUG) {
throw new InvalidConfigException('Controller class must extend from \\yii\\base\\Controller.');
}
return null;
}
!class_exists($className)
將此字符串作為參數"api\controllers\CategoryController"
並返回true
。 條件有效,結果是null
。
那會發生什么? 以下:
/**
* Runs a controller action specified by a route.
* This method parses the specified route and creates the corresponding child module(s), controller and action
* instances. It then calls [[Controller::runAction()]] to run the action with the given parameters.
* If the route is empty, the method will use [[defaultRoute]].
* @param string $route the route that specifies the action.
* @param array $params the parameters to be passed to the action
* @return mixed the result of the action.
* @throws InvalidRouteException if the requested route cannot be resolved into an action successfully.
*/
public function runAction($route, $params = [])
{
$parts = $this->createController($route);
// $parts IS NULL !!!!!!!!!!
if (is_array($parts)) {
/* @var $controller Controller */
list($controller, $actionID) = $parts;
$oldController = Yii::$app->controller;
Yii::$app->controller = $controller;
$result = $controller->runAction($actionID, $params);
if ($oldController !== null) {
Yii::$app->controller = $oldController;
}
return $result;
}
$id = $this->getUniqueId();
throw new InvalidRouteException('Unable to resolve the request "' . ($id === '' ? $route : $id . '/' . $route) . '".');
}
我看到了熟悉的異常InvalidRouteException
。 有任何想法嗎?
好的。 答案很簡單。 如果您正在借助從另一個應用程序(如我)復制和粘貼來開發新的應用程序,請不要忘記更新common/config/bootstrap.php
並添加新的別名。 我的新應用程序的名稱是api
。 這意味着我的bootstrap.php
是:
<?php
Yii::setAlias('@common', dirname(__DIR__));
Yii::setAlias('@frontend', dirname(dirname(__DIR__)) . '/frontend');
Yii::setAlias('@backend', dirname(dirname(__DIR__)) . '/backend');
Yii::setAlias('@console', dirname(dirname(__DIR__)) . '/console');
Yii::setAlias('@api', dirname(dirname(__DIR__)) . '/api'); // <- new application!!!
PS我使用高級模板。 感謝閱讀)
您需要在CategoryController
上指定索引方法。
IE:
public function actionIndex()
{
return $this->render('index');
}
當然,您需要為此方法添加模板或
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.