webman 中如何实现自定义 Response 类?

kenneth

目标:

实现自定义 Response 类。以修改响应头 Server 字段默认为 nginx 来举例。

我的尝试改法:

想设置 http 响应头 Server 字段默认值为 nginx,故我作了以下修改:

support/Response.php
<?php

//省略版权信息,见谅。
namespace support;

/**
 * Class Response
 * @package support
 */
class Response extends \Webman\Http\Response
{
    public function __construct(
        $status = 200,
        $headers = array(),
        $body = ''
    ) {
        $this->_status = $status;
        $this->_header = $headers;
        $this->_body = $body;
        //伪装 nginx 服务器
        if(!isset($this->_header['Server'])){
            $this->_header['Server'] = 'nginx';
        }
    }

}
vendor/workerman/webman-framework/src/Exception/ExceptionHandlerInterface.php
<?php

//省略版权信息,见谅
namespace Webman\Exception;

use Throwable;
use Webman\Http\Request;
// use Webman\Http\Response;
use support\Response;

interface ExceptionHandlerInterface
{
    //省略代码...
}
vendor/workerman/webman-framework/src/Exception/ExceptionHandler.php
<?php

//省略版权信息,见谅
namespace Webman\Exception;

use Throwable;
use Psr\Log\LoggerInterface;
use Webman\Http\Request;
// use Webman\Http\Response;
use support\Response;

/**
 * Class Handler
 * @package support\exception
 */
class ExceptionHandler implements ExceptionHandlerInterface
{
    //省略代码...
}
vendor/workerman/webman-framework/src/MiddlewareInterface.php
<?php

//省略版权信息,见谅
namespace Webman;

use Webman\Http\Request;
// use Webman\Http\Response;
use support\Response;

interface MiddlewareInterface
{
    //省略代码...
}
vendor/workerman/webman-framework/src/App.php
<?php

//省略版权信息,见谅
namespace Webman;

use Workerman\Worker;
use Workerman\Timer;
use Workerman\Connection\TcpConnection;
use Webman\Http\Request;
// use Webman\Http\Response;
use support\Response;
use Webman\Route\Route as RouteObject;
use Webman\Exception\ExceptionHandlerInterface;
use Webman\Exception\ExceptionHandler;
use Webman\Config;
use FastRoute\Dispatcher;
use Psr\Container\ContainerInterface;
use Monolog\Logger;

/**
 * Class App
 * @package Webman
 */
class App
{
    //省略代码...
}

以上改法测试可用,但显然不是“正常”做法

问题

虽然以上能达到效果,但是不可能期望每次 composer install 之后都要改 vendor 内的源码。

我该如何正常实现自定义 Response 类?

3203 3 0
3个回答

walkor

直接改support/Response.php就行了

  • kenneth 2021-03-02

    只修改 support/Response.php 能够覆盖绝大多数的情况。
    但存在以下情况,返回的是 Webman\Http\Response 类:

    1. 访问的文件是 public/ 下静态文件。如 http://demo.test/test.html
    2. 访问的路由不存在;
    3. 内部错误返回500,如php语法错误;
      这几种情况,support/Response.php 内的修改是不生效的。
  • 小阳光 2021-03-12

    1,修改start.php use support\App;

    2, class App extends \Webman\App

    然后

    protected static function send(TcpConnection $connection, $response, Request $request)
    {
    if ($response instanceof \Workerman\Protocols\Http\Response) {
    $response->header('Server', 'Tomcat');
    }
    parent::send($connection, $response, $request);
    }

  • kenneth 2021-03-16

    谢谢!

小阳光

截图

继承出来,覆盖。

  • 暂无评论
qnnp

可以这样实现

#File: support/middleware/StaticFile.php

//添加
$response->withHeader('Server', 'nginx');
#File: support/Response.php

//添加

public function __construct(
    $status = 200,
    $headers = array(),
    $body = ''
) {
    $this->_status = $status;
    $this->_header = $headers;
    $this->_body   = $body;
    if (!isset($this->_header['Server'])) {
        $this->_header['Server'] = 'nginx';
    }
}
#File: config/route.php
//添加
Route::any(
    '/{notfound:.*}',
    function ($request) {
        //自己实现404响应
        //URL根路径适当自己处理一下
        return json(['status' => 404])->withStatus(404);
    }
);
年代过于久远,无法发表回答
🔝