簡體   English   中英

yii2 使用 ActiveController “無法解析請求”

[英]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 由於我的一些未知原因無法做到這一點)
  • 然后框架將我重定向到 404 功能。 這就是為什么我們可以在這里看到"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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM