Yii2使用駝峯命名的形式訪問控制器

yii2在使用的時候,訪問控制器的時候,若是控制器的名稱是駝峯命名法,那訪問的url中要改爲橫線的形式。例如:php

public function actionRoomUpdate()
{
//
}
//訪問的時候就要www.test.com/room-update這樣訪問

最近在作某渠道的直連的時候,他們提供的文檔上明確指出接口的形式:web

剛開始覺得YII2中確定有這樣的設置,而後就去google了下,發現都說不行,本身去看了下,果真,框架裏面直接是寫死的:(源碼)\vendor\yiisoft\yii2\base\Controller.phpyii2

/**
     * Creates an action based on the given action ID.
     * The method first checks if the action ID has been declared in [[actions()]]. If so,
     * it will use the configuration declared there to create the action object.
     * If not, it will look for a controller method whose name is in the format of `actionXyz`
     * where `Xyz` stands for the action ID. If found, an [[InlineAction]] representing that
     * method will be created and returned.
     * @param string $id the action ID.
     * @return Action the newly created action instance. Null if the ID doesn't resolve into any action.
     */
    public function createAction($id)
    {
        if ($id === '') {
            $id = $this->defaultAction;
        }

        $actionMap = $this->actions();
        if (isset($actionMap[$id])) {
            return Yii::createObject($actionMap[$id], [$id, $this]);
        } elseif (preg_match('/^[a-z0-9\\-_]+$/', $id) && strpos($id, '--') === false && trim($id, '-') === $id) {
            $methodName = 'action' . str_replace(' ', '', ucwords(implode(' ', explode('-', $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;
    }

這點有點low,不過問題倒不大,這個代碼很容易理解,咱們發現,其實若是在這個源碼的基礎上再加上一個else就能夠搞定,可是仍是不建議直接改源碼。app

因爲咱們的項目用的事yii2的advanced版本,而且裏面有多個項目,還要保證其餘項目使用正常(也就是個別的控制器才須要使用駝峯命名的方式訪問),這也容易:cors

咱們能夠寫個components處理:\common\components\zController.php框架

<?php
/**
 * Created by PhpStorm.
 * User: Steven
 * Date: 2017/10/26
 * Time: 16:50
 */
namespace common\components;
use \yii\base\Controller;
use yii\base\InlineAction;

class zController extends Controller   //這裏須要繼承自\yii\base\Controller
{
    /**
     * Author:Steven
     * Desc:重寫路由,處理訪問控制器支持駝峯命名法
     * @param string $id
     * @return null|object|InlineAction
     */
    public function createAction($id)
    {
        if ($id === '') {
            $id = $this->defaultAction;
        }

        $actionMap = $this->actions();
        if (isset($actionMap[$id])) {
            return \Yii::createObject($actionMap[$id], [$id, $this]);
        } elseif (preg_match('/^[a-z0-9\\-_]+$/', $id) && strpos($id, '--') === false && trim($id, '-') === $id) {
            $methodName = 'action' . str_replace(' ', '', ucwords(implode(' ', explode('-', $id))));
            if (method_exists($this, $methodName)) {
                $method = new \ReflectionMethod($this, $methodName);
                if ($method->isPublic() && $method->getName() === $methodName) {
                    return new InlineAction($id, $this, $methodName);
                }
            }
        } else { $methodName = 'action' . $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;
    }
}

ok ,這就能夠支持使用駝峯形式訪問了,固然這個的形式不少,也能夠寫成一個控制器,而後其它控制器繼承這個控制器就好了,可是原理是同樣的yii

如何使用?  是須要用駝峯命名形式訪問的控制器中,繼承下這個zController就能夠了,this

<?php
/**
 * Created by PhpStorm.
 * User: Steven
 * Date: 2017/10/18
 * Time: 15:57
 */
namespace backend\modules\hotel\controllers;
use yii\filters\AccessControl;
use yii\filters\ContentNegotiator; use yii\web\Response;
use common\components\zController; class QunarController extends zController
{
    public $enableCsrfValidation = false;


    public function behaviors()
    {
        $behaviors = parent::behaviors();
        unset($behaviors['authenticator']);
        $behaviors['corsFilter'] = [
            'class' => \yii\filters\Cors::className(),
            'cors' => [ // restrict access to
                'Access-Control-Request-Method' => ['*'], // Allow only POST and PUT methods
                'Access-Control-Request-Headers' => ['*'], // Allow only headers 'X-Wsse'
                'Access-Control-Allow-Credentials' => true, // Allow OPTIONS caching
                'Access-Control-Max-Age' => 3600, // Allow the X-Pagination-Current-Page header to be exposed to the browser.
                'Access-Control-Expose-Headers' => ['X-Pagination-Current-Page'],
            ],
        ];
        //配置ContentNegotiator支持JSON和XML響應格式
        /*$behaviors['contentNegotiator'] = [
            'class' => ContentNegotiator::className(), 'formats' => [
                'application/xml' => Response::FORMAT_XML
            ]
        ];*/
        $behaviors['access'] = [
            'class' => AccessControl::className(),
            'rules' => [
                [
                    'ips' => ['119.254.26.*', //去哪兒IP訪問白名單
                        '127.0.0.1','106.14.56.77','180.168.4.58'  //蜘蛛及本地IP訪問白名單
                    ], 'allow' => true,
                ],
            ],
        ];
        return $behaviors;
    }

}

?>

示例:google

/**
     * Author:Steven
     * Desc:酒店靜態數據接口
     */
    public function actiongetFullHotelInfo()
    {

    }
 
訪問的時候url爲www.test.com/getFullHotelInfo

以上.

 Q:2384834530url

相關文章
相關標籤/搜索