【发布时间】:2021-10-23 05:44:00
【问题描述】:
我的 PHP 脚本由 php-fpm docker 容器处理,我还运行 nginx docker 容器来接受请求。
我正在使用 Lumen 框架开发一个小型 JSON API 服务。我正在尝试处理我的Handler.php 中的异常。
case ($e instanceof Exception\NotFoundHttpException):
return ResponseProvider::render(
new ResponseMessagesDTO(
new Messages\ENTITY_NOT_FOUND_Message
),
exception: $e
);
代码可能看起来很吓人,但我只是在为客户制定一个响应。
代码应该返回 HTTP 状态 404,但它总是返回 200。
如果尝试给出类似(标准)的答案,那么一切正常。
case ($e instanceof Exception\NotFoundHttpException):
return response()->json(['data' => 'data'], 404);
然后它按预期返回404。问题是当我通过内置的 PHP 服务器运行这个项目时,一切正常,如果我运行:
$ php -S local: 8000 -t ./public
然后我提出一个请求:
case ($e instanceof Exception\NotFoundHttpException):
return ResponseProvider::render(
new ResponseMessagesDTO(
new messages\ENTITY_NOT_FOUND_Message
),
exception: $e
);
ResponseProvider.php
<?php
namespace App\Helpers;
use Exception;
use Symfony\Component\HttpFoundation\Cookie;
use phpcommon\http\ResponseMessagesDTO as DTO;
class ResponseProvider
{
public static function render(DTO $body = null, Cookie $cookie = null , Exception $exception = null, string $type = "json")
{
$data = $body->serialize();
if($cookie){
return response()->json($data,$body->getStatus())->cookie($cookie);
}
return response()->json($data,$body->getStatus());
}
}
?>
我的 Nginx 配置
worker_processes auto;
error_log /var/log/nginx/error.log notice;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
large_client_header_buffers 4 16k;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
error_log /var/log/nginx/gateway_error.log debug;
sendfile on;
keepalive_timeout 600;
server {
listen 80;
server_name project.loc;
root /var/www/app/public;
index index.php index.html index.htm;
charset utf-8;
server_tokens off;
add_header X-Frame-Options 'SAMEORIGIN';
add_header 'Access-Control-Allow-Origin' '*' always;
add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, PATCH, DELETE, OPTIONS' always;
add_header 'Access-Control-Allow-Headers' 'Authorization, DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,preview-file-uuid,access-level,access_level,user-uuid' always;
add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range' always;
error_page 405 =200 $uri;
location / {
try_files $uri $uri/ /index.php;
}
location ~ \.php$ {
fastcgi_pass fpm:9000;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
}
它按预期返回 HTTP 状态 404。
问题是为什么nginx / php-fpm方案总是返回200,但是如果你使用标准响应方法,那么404(如预期的那样)返回?
但如果您使用php -S,那么一切都会按预期进行。
也许我在php-fpm 的配置中遗漏了一些东西?
【问题讨论】:
-
超级个人推荐,坚持
PSR,做return ResponseProvider :: render等等,都是空格不标准,避免100%,也避免catch (...) :,应该是catch (...) { ... }。将您的 IDE 配置为遵循标准,因为代码不可读。另外,分享ResponseProvider的作用,因为我们不是猜测您代码的魔术师。我确定那里有问题或类似问题。 -
也许 nginx 触发了重定向并呈现异常响应?检查浏览器的网络选项卡以查看(确保选中“保留日志”或类似的内容以不丢弃重定向)
-
@matiaslauriti 感谢您的回答!我附上了代码,但如上所述,如果您像这样运行项目,代码可以正常工作:
php -S local: 8000 -t. / Public -
@Mila 分享您的
nginx配置。