Phalcon搭建多模块框架十四:封装转发到其他控制器/动作(forward)

这里为了方便在应用内部转发,所以对forward进行了封装。
这里写图片描述
1、打开common下的BaseController.php文件
添加:

final protected function forward($url, $vars = null, $namespace = null) {
        if (is_array($url)) {
            $forward = $url;
        } else if (is_string($url)) {
            $forward = [ ];
            $lastbBackslash = strrpos($url, '\\');
            if ($lastbBackslash) {
                $namespace = substr($url, 0, $lastbBackslash);
            }
            if (!empty($namespace)) {
                $forward['namespace'] = $namespace;
            }
            $start = $lastbBackslash === false ? 0 : $lastbBackslash + 1;
            $rest = substr($url, $start);
            $restStrposRes = strpos($rest, '?');
            if($rest == '' || $restStrposRes === 0){
                throw new Exception('方法不能为空');
            }
            if($restStrposRes === false){
                $capname = $rest;
                $paramsString = null;
            }else {
                list ($capname, $paramsString) = explode('?', $rest, 2);
                $capname = trim($capname, '/');
                if (empty($capname)) {
                    throw new Exception('控制器或方法不能为空');
                }
            }
            $capnameArr = explode('/', $capname);
            $capnameArrCount = count($capnameArr);
            if ($capnameArrCount == 1) {
                $forward['action'] = $capnameArr[0];
            } else {
                $forward['controller'] = $capnameArr[0];
                $forward['action'] = $capnameArr[1];
                for ($i = 2; $i < $capnameArrCount; $i += 2) {
                    $forward['params'][$capnameArr[$i]] = $capnameArr[$i + 1] ?? null;
                }
            }
            if ($paramsString !== null) {
                parse_str($paramsString, $paramsArr);
                $forward['params'] = array_merge($forward['params'] ?? [ ], $paramsArr);
            }
        } else {
            throw new Exception('url只能为字符串或者数组');
        }
        if (is_string($vars)) {
            $vars = trim($vars, '?');
            parse_str($vars, $vars);
        }
        if (is_array($vars)) {
            $forward['params'] = array_merge($forward['params'] ?? [ ], $vars);
        }
        $this->dispatcher->forward($forward);
    }

完整的BaseController.php

<?php
/** 
 * @desc 控制器基类
 * @author zhaoyang 
 * @date 2018年5月8日 下午10:37:37 
 */
namespace Common;

use Phalcon\Mvc\Controller;
use Phalcon\Exception;

class BaseController extends Controller {

    /** 
     * @desc 获取get参数
     * @param string $name 参数名
     * @param string|array $filter 过滤类型,支持string、trim、absint、int、email、float、int!、float!、alphanum、striptags、lower、upper、url、special_chars
     * 当为false时,不使用默认过滤,当为字符串例如'string,trim'时采用参数过滤 ,当为数组例如['string','trim']时采用参数+默认过滤,当为null等其他值时时采用默认过滤
     * @param mixed $defaultValue 默认值
     * @param bool $noRecursive 不递归过滤
     * @return mixed
     * @author zhaoyang 
     * @date 2018年5月8日 下午10:38:50 
     */
    final protected function get(string $name = null, $filter = null, $defaultValue = null, bool $noRecursive = false) {
        $data = array_merge($this->request->getQuery(), $this->dispatcher->getParams());
        unset($data['_url']);
        return $this->sanitize($data, $name, $filter, $defaultValue, $noRecursive);
    }

    /** 
     * @desc 获取post参数
     * @param string $name 参数名
     * @param string|array $filter 过滤类型,支持string、trim、absint、int、email、float、int!、float!、alphanum、striptags、lower、upper、url、special_chars
     * 当为false时,不使用默认过滤,当为字符串'string,trim'时采用参数过滤 ,当为数组['string','trim']时采用参数+默认过滤,当为null等其他值时时采用默认过滤
     * @param mixed $defaultValue 默认值
     * @param bool $noRecursive 不递归过滤
     * @param bool $notAllowEmpty 不允许为空
     * @return mixed
     * @author zhaoyang 
     * @date 2018年5月9日 下午8:40:27 
     */
    final protected function post(string $name = null, $filter = null, $defaultValue = null, bool $noRecursive = false, bool $notAllowEmpty = false) {
        $data = $this->request->getPost();
        return $this->sanitize($data, $name, $filter, $defaultValue, $noRecursive);
    }

    /** 
     * @desc 获取post或者get参数
     * @param string $name 参数名
     * @param string|array $filter 过滤类型,支持string、trim、absint、int、email、float、int!、float!、alphanum、striptags、lower、upper、url、special_chars
     * 当为false时,不使用默认过滤,当为字符串例如'string,trim'时采用参数过滤 ,当为数组例如['string','trim']时采用参数+默认过滤,当为null等其他值时时采用默认过滤
     * @param mixed $defaultValue 默认值
     * @param bool $noRecursive 不递归过滤
     * @return mixed
     * @author zhaoyang 
     * @date 2018年5月9日 下午9:41:49 
     */
    final protected function request(string $name = null, $filter = null, $defaultValue = null, bool $noRecursive = false){
        if (isset($name) && $name !== '') {
            return $this->post($name, $filter, $defaultValue, $noRecursive) ?? $this->get($name, $filter, $defaultValue, $noRecursive);
        }
        return array_merge($this->post(null, $filter, $defaultValue, $noRecursive), $this->get(null, $filter, $defaultValue, $noRecursive));
    }

    /** 
     * @param string $name 参数名
     * @param string|array $filter 过滤类型,支持string、trim、absint、int、email、float、int!、float!、alphanum、striptags、lower、upper、url、special_chars
     * 当为false时,不使用默认过滤,当为字符串例如'string,trim'时采用参数过滤 ,当为数组例如['string','trim']时采用参数+默认过滤,当为null等其他值时时采用默认过滤
     * @param mixed $defaultValue 默认值
     * @param bool $noRecursive 不递归过滤
     * @return mixed
     * @author zhaoyang 
     * @date 2018年5月9日 下午10:43:11 
     */
    final protected function json(string $name = null, $filter = null, $defaultValue = null, bool $noRecursive = false){
        $data = $this->request->getJsonRawBody(true);
        if ($data === false) {
            return [ ];
        }
        return $this->sanitize($data, $name, $filter, $defaultValue, $noRecursive);
    }

    /**
     * @param array $data 数据源
     * @param string $name 参数名
     * @param string|array $filter 过滤类型,支持string、trim、absint、int、email、float、int!、float!、alphanum、striptags、lower、upper、url、special_chars
     * 当为false时,不使用默认过滤,当为字符串例如'string,trim'时采用参数过滤 ,当为数组例如['string','trim']时采用参数+默认过滤,当为null等其他值时时采用默认过滤
     * @param mixed $defaultValue 默认值
     * @param bool $noRecursive 不递归过滤
     * @return mixed
     * @author zhaoyang
     * @date 2018年5月9日 下午8:20:15
     */
    final protected function sanitize(array $data, string $name = null, $filter = null, $defaultValue = null, bool $noRecursive = false){
        $nowFilter = null;
        if (is_string($filter) && !empty($filter)) {
            $nowFilter = explode(',', $filter);
        } else if ($filter !== false) {
            $defaultFilter = $this->config->services->filter->default_filter;
            $defaultFilter = isset($defaultFilter) ? explode(',', $defaultFilter) : [ ];
            if (is_array($filter)) {
                $defaultFilter = array_unique(array_merge($filter, $defaultFilter));
            }
            if (!empty($defaultFilter)) {
                $nowFilter = $defaultFilter;
            }
        }
        if (isset($name) && $name !== '') {
            if (isset($data[$name]) && $data[$name] !== '') {
                $data = $data[$name];
            } else {
                $data = $defaultValue;
            }
        }
        if (isset($nowFilter)) {
            $data = $this->filter->sanitize($data, $nowFilter, $noRecursive);
        }
        return $data;
    }

    /** 
     * @desc 转发到其他动作 
     * @param array|string $url  'App\Home\Controllers\forward/index/a/aaa?b=bbb' or 'forward/index/a/aaa?b=bbb' or 'index?b=bbb'
     * @param array|string $vars 参数 ['a'=>'aaa','b'=>'bbb'] or 'a=aaa&b=bbb'
     * @param sring $namespace 命名空间
     * @return void 
     * @author zhaoyang 
     * @date 2018年5月24日 下午5:11:26 
     */
    final protected function forward($url, $vars = null, $namespace = null) {
        if (is_array($url)) {
            $forward = $url;
        } else if (is_string($url)) {
            $forward = [ ];
            $lastbBackslash = strrpos($url, '\\');
            if ($lastbBackslash) {
                $namespace = substr($url, 0, $lastbBackslash);
            }
            if (!empty($namespace)) {
                $forward['namespace'] = $namespace;
            }
            $start = $lastbBackslash === false ? 0 : $lastbBackslash + 1;
            $rest = substr($url, $start);
            $restStrposRes = strpos($rest, '?');
            if($rest == '' || $restStrposRes === 0){
                throw new Exception('方法不能为空');
            }
            if($restStrposRes === false){
                $capname = $rest;
                $paramsString = null;
            }else {
                list ($capname, $paramsString) = explode('?', $rest, 2);
                $capname = trim($capname, '/');
                if (empty($capname)) {
                    throw new Exception('控制器或方法不能为空');
                }
            }
            $capnameArr = explode('/', $capname);
            $capnameArrCount = count($capnameArr);
            if ($capnameArrCount == 1) {
                $forward['action'] = $capnameArr[0];
            } else {
                $forward['controller'] = $capnameArr[0];
                $forward['action'] = $capnameArr[1];
                for ($i = 2; $i < $capnameArrCount; $i += 2) {
                    $forward['params'][$capnameArr[$i]] = $capnameArr[$i + 1] ?? null;
                }
            }
            if ($paramsString !== null) {
                parse_str($paramsString, $paramsArr);
                $forward['params'] = array_merge($forward['params'] ?? [ ], $paramsArr);
            }
        } else {
            throw new Exception('url只能为字符串或者数组');
        }
        if (is_string($vars)) {
            $vars = trim($vars, '?');
            parse_str($vars, $vars);
        }
        if (is_array($vars)) {
            $forward['params'] = array_merge($forward['params'] ?? [ ], $vars);
        }
        $this->dispatcher->forward($forward);
    }
}

2、在app/home/controllers下创建ForwardController.php控制器

<?php
namespace App\Home\Controllers;

use Common\BaseController;

class ForwardController extends BaseController {

    public function indexAction() {
        return $this->forward('test');
    }

    public function testAction() {
        echo __METHOD__,'<br>';
        return $this->forward('test2?a=aaa&b=bbb', 'c=ccc');
    }

    public function test2Action (){
        echo __METHOD__,'<br>';
        var_dump($this->get());
        return $this->forward('index/index/f?e=ee', ['d'=>'ddd']);
    }
}

3、在IndexController.php控制器中写入

<?php
/**
 * @desc 主页
 * @author zhaoyang
 * @date 2018年3月23日 上午10:11:38
 */
namespace App\Home\Controllers;

use Common\BaseController;

class IndexController extends BaseController {

    public function indexAction() {
        echo __METHOD__,'<br>';
        var_dump($this->get());
        exit;
    }
}

4、访问/forward/index,可以看到如下,因为forward不走http请求,直接调用控制器操作,所以可以节约资源,内部跳转优先使用froward
这里写图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值