Phalcon Micro API除根路径外返回404问题排查求助
Phalcon Micro API
/api/healthcheck 返回404问题排查 我使用Phalcon Micro搭建了两个简易API端点,调用根路径/可正常获取200响应,但调用/api/healthcheck时返回404未找到,请求指导排查此问题。
系统架构
- EC2服务器(部署在VPC公有子网)
- 系统环境:Ubuntu 22.04、PHP 5.6、Apache 2.4.52
- 请求流程:
domain.com→ Nginx(80端口)→ Apache虚拟主机(8081端口)→ 含.htaccess的项目目录
API端点测试结果
端点1:根路径
请求: domain.com/ 响应: 状态码200 { "id": "1", "version": "1" }
端点2:健康检查
请求: domain.com/api/healthcheck 响应: 状态码404 Not Found
相关配置文件
.htaccess 配置
<IfModule mod_rewrite.c> RewriteEngine On RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^((?s).*)$ index.php?_url=/$1 [QSA,L] </IfModule>
项目入口文件 /var/www/domain.com/index.php
<?php // Phalcon 依赖引入 use Phalcon\Loader; use Phalcon\Mvc\Micro; use Phalcon\Di\FactoryDefault; use Phalcon\Db\Adapter\Pdo\Mysql as PdoMysql; use Phalcon\Http\Response; use Phalcon\Http\Request; // 获取请求实例 $request = new Request(); // 初始化依赖注入容器 $di = new FactoryDefault(); // 注册数据库服务 $di->set('db', function () { return new PdoMysql( array( "host" => DB_SERVER, "username" => DB_USER, "password" => DB_PASS, "dbname" => DB_NAME ) ); }); $app = new Micro($di); // 根路径端点 $app->get( '/', function () use ($dbConn) { $sql = 'SELECT * FROM `dbversions` WHERE 1 Order By id desc LIMIT 1'; $result_set = mysqli_query($dbConn, $sql); $row = mysqli_fetch_assoc($result_set); echo json_encode($row); } ); // 健康检查端点 $app->get( '/api/healthcheck', function () use ($dbConn) { $data = array("status"=> "success"); echo json_encode($data); } ); $app->handle(); ?>
Apache 主配置 /etc/apache2/apache.conf
<Directory /> Options FollowSymLinks AllowOverride None Require all denied </Directory> <Directory /usr/share> AllowOverride None Require all granted </Directory> <Directory /var/www/> Options Indexes FollowSymLinks AllowOverride None Require all granted </Directory>
Apache 虚拟主机配置 /etc/apache2/site-available/000-default.conf
<VirtualHost *:8081> ServerName domain.com ServerAdmin webmaster@domain.com DocumentRoot /var/www/domain.com/ <Directory /var/www/domain.com> Options -Indexes +FollowSymLinks AllowOverride All </Directory> ErrorLog ${APACHE_LOG_DIR}/error.log CustomLog ${APACHE_LOG_DIR}/access.log combined </VirtualHost>
已安装PHP包
PHP 8.1 安装包
libapache2-mod-php8.1 php8.1 php8.1-cli php8.1-common php8.1-curl php8.1-dev php8.1-fpm php8.1-mbstring php8.1-mysql php8.1-opcache php8.1-phalcon5 php8.1-readline
PHP 5.6 安装包
libapache2-mod-php5.6 php5.6 php5.6-cli php5.6-common php5.6-curl php5.6-dev php5.6-fpm php5.6-json php5.6-mbstring php5.6-mysql php5.6-opcache php5.6-phalcon3 php5.6-readline
日志信息
Nginx 访问日志
100.250.01.01 - - [26/Oct/2023:01:38:12 +0000] "GET / HTTP/1.1" 200 85 "-" "PostmanRuntime/7.33.0" 100.250.01.01 - - [26/Oct/2023:01:38:23 +0000] "GET /api/healthcheck HTTP/1.1" 404 240 "-" "PostmanRuntime/7.33.0"
Apache 访问日志
127.0.0.1 - - [26/Oct/2023:01:38:12 +0000] "GET / HTTP/1.0" 200 299 "-" "PostmanRuntime/7.33.0" 127.0.0.1 - - [26/Oct/2023:01:38:23 +0000] "GET /api/healthcheck HTTP/1.0" 404 450 "-" "PostmanRuntime/7.33.0"
排查与修复方案
1. 修复未定义变量问题
两个端点的回调函数均使用了$dbConn变量,但代码中从未定义或初始化该变量。根路径能返回结果可能是环境中存在全局变量,但健康检查端点执行时会因变量未定义抛出错误,导致Phalcon无法正确匹配路由,返回404。
修复方法:
- 根路径端点改用Phalcon注册的数据库服务:
$app->get( '/', function () use ($di) { $db = $di->get('db'); $result = $db->fetchOne('SELECT * FROM `dbversions` WHERE 1 Order By id desc LIMIT 1', \Phalcon\Db::FETCH_ASSOC); echo json_encode($result); } );
- 健康检查端点无需数据库连接,直接移除无用的
use ($dbConn):
$app->get( '/api/healthcheck', function () { $data = array("status"=> "success"); echo json_encode($data); } );
2. 验证Rewrite规则生效
检查Apache的mod_rewrite模块是否启用:
sudo a2enmod rewrite sudo systemctl restart apache2
可在index.php开头添加调试代码,确认请求路径是否正确传递:
var_dump($_GET['_url']); exit;
访问/api/healthcheck,若输出string(16) "/api/healthcheck"则规则生效,否则检查虚拟主机的AllowOverride All配置是否正确应用。
3. 确认PHP与Phalcon版本匹配
系统同时安装了PHP5.6(对应Phalcon3)和PHP8.1(对应Phalcon5),需确保Apache使用的是PHP5.6模块:
sudo a2dismod php8.1 sudo a2enmod php5.6 sudo systemctl restart apache2
4. 检查Nginx反向代理配置
确保Nginx正确转发请求路径,示例配置:
server { listen 80; server_name domain.com; location / { proxy_pass http://127.0.0.1:8081; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } }
内容的提问来源于stack exchange,提问作者Naisarg Parmar
相关产品推荐
相关产品推荐

