Webman 1.5 能在中间件中能修改 Request 吗?

sfsfr

问题描述

Webman 1.5 能在中间件中能修改 Request 吗?

在文档中介绍了修改 Response 的例子,如果我想修改请求过来的 post 的数据,该怎么操作?

<?php
namespace app\middleware;

use Webman\MiddlewareInterface;
use Webman\Http\Response;
use Webman\Http\Request;

class AccessControlTest implements MiddlewareInterface
{
    public function process(Request $request, callable $handler) : Response
    {
        // 如果是options请求则返回一个空响应,否则继续向洋葱芯穿越,并得到一个响应
        $response = $request->method() == 'OPTIONS' ? response('') : $handler($request);

        // 给响应添加跨域相关的http头
        $response->withHeaders([
            'Access-Control-Allow-Credentials' => 'true',
            'Access-Control-Allow-Origin' => $request->header('origin', '*'),
            'Access-Control-Allow-Methods' => $request->header('access-control-request-method', '*'),
            'Access-Control-Allow-Headers' => $request->header('access-control-request-headers', '*'),
        ]);

        return $response;
    }
}
260 6 0
6个回答

efnic

任何PHP框架都遵循的基本规则,比如继承、对象的引用传递。
您可以 在自定义请求类里面实现你的功能 support/Request.php

  • 暂无评论
kof21411

直接在控制器的初始化函数里改更不是更简单吗

  • 暂无评论
ersic
  • fklee 6天前

    这是1.6新增的吧,他问1.5

  • sfsfr 6天前

    是的,1.5 没有 setPost

JustForFun

反射,大概就这样,可能有 bug,但原理就是这个原理。

    public function process(Request $request, callable $next): Response
    {
        $refObj = new \ReflectionClass(Request::class);
        $buffer = $refObj->getProperty('buffer');
        $buffer->setAccessible(true);
        $wholeRequest = $buffer->getValue($request);
        [$headers, $body] = explode("\r\n\r\n", $wholeRequest);
        $body = 'hello=world';
        $buffer->setValue($request, implode("\r\n\r\n", [
            $headers,
            $body,
        ]));

        $data = $refObj->getProperty('data');
        $data->setAccessible(true);
        $wholeData = $data->getValue($request);
        $wholeData['query_string'] = 'name=yyy';
        $wholeData['get'] = ['name' => 'yyy'];
        $wholeData['path'] = '/x/y/z';
        $data->setValue($request, $wholeData);

        $response = $next($request);

        return $response;
    }

效果如下:

截图

  • JustForFun 5天前

    或者像楼上说的直接改support/Request,简单得多,如下,不过不确定改support目录是不是一件好事,起码某些属性是不能修改的,要注意点。

    namespace support;
    
    /**
     * Class Request
     * @package support
     */
    class Request extends \Webman\Http\Request
    {
        public function __construct(string $buffer)
        {
            parent::__construct($buffer);
            $this->data['query_string'] = 'hello=world';
            $this->data['get'] = ['hello' => 'world'];
            $this->data['post'] = 'foo=bar';
        }
    }
  • sfsfr 5天前

    谢谢回复

阿沁

截图```php
/**

  • 设置$request数据,自动覆盖更新
  • @param string $method
  • @param array $data
  • */
    function setParams(string $method, array $data)
    {
    $method = strtolower($method);
    if (!isset($this->data[$method])) {
    if ($method == 'post'){
    $this->parsePost();
    }
    if ($method == 'get'){
    $this->parseGet();
    }
    }
    $rawData = $this->data ?: [];// 获取原数据
    $newData = $rawData; // 复制原始数据
    $newData[$method] = array_merge($newData[$method] ?? [], $data); // 合并特定方法的数据
    $this->data = $newData; // 更新对象数据
    }

中间件就是用来读写Resquest对象的, 把你需要存储的变量使用 setAttribute方法写入就行

  • 暂无评论
🔝