PHP 8 - 未为 GET 请求触发具有路由属性的注释方法
PHP 8 - Annotated method with Route Attribute not triggered for GET request
我正在尝试在运行时动态加载(包含文件)GetRiskSummaryCommandHandler.php(GetRiskSummary\CommandHandler),同时将 Route api/risks
解析为 HandleCommand(属于 class CommandHandler)方法。
我该怎么做?如果不能,我可以修改任何采用的方法,包括修改自动加载器吗?
我的 api class 代码段如下所示:
API.php
<?php
abstract class API
{
public function processRequest()
{
$id1 = $this->requestObj->id1;
//$id2 = $this->requestObj->id2;
$endpoint1 = $this->requestObj->endpoint1;
$endpoint2 = $this->requestObj->endpoint2;
$isDestination = in_array($id1, ['first', 'prev', 'next', 'last']);
$numSetEndpoints = (int)isset($endpoint1) + (int)isset($endpoint2);
switch($numSetEndpoints)
{
case 0:
if ($isDestination)
return json_decode($this->_response("No Endpoint: ", $endpoint1));
return json_decode($this->_response("ProjectAIM API"));
case 1:
$className = $endpoint1.'Controller';
break;
case 2:
$className = $endpoint2.'Controller';
break;
}
$class = "GetRiskSummaryCommandHandler";
$method = "HandleCommand";
if (class_exists($class))
{
if (method_exists($class, $method))
{
$response = (new $class($this->requestObj))->{$method}($this->requestObj);
if ($response['Succeeded'] == false)
{
return $response['Result'];
}
else if ($response['Succeeded'] == true)
{
header("Content-Type: application/json");
return $this->_response($response);
}
else if ($response['Result'])
{
header("Content-Type: text/html");
return $this->_response($response);
}
}
}
}
**命令处理程序片段,使用路由属性
GetRiskSummaryCommandHandler.php
<?php
namespace GetRiskSummary;
use Infrastructure\CommandHandler;
class GetRiskSummaryCommandHandler extends CommandHandler
{
#[Route("/api/risks", methods: ["GET"])]
public function HandleCommand()
{
$qb = $this->getEntityManager()
->createQueryBuilder();
$qb->select('*')
->from('Risks', 'Risks')
->orderBy('RiskID', 'DESC');
$query = $qb->getQuery();
return $query->getResult();
}
}
Autoloader.php
<?php
namespace Autoloader;
class Autoloader
{
private static function rglob($pattern, $flags = 0) {
$files = glob($pattern, $flags);
foreach (glob(dirname($pattern).'/*', GLOB_ONLYDIR|GLOB_NOSORT) as $dir) {
$files = array_merge($files, self::rglob($dir.'/'.basename($pattern), $flags));
}
return $files;
}
public static function ClassLoader($path)
{
$pathParts = explode("\", $path);
$path = $pathParts[array_key_last($pathParts)];
$matches = self::rglob("*/$path*");
foreach ($matches as $name)
{
$filePath = realpath($name);
if (file_exists($filePath))
include $filePath;
}
}
}
spl_autoload_register("AutoLoader\AutoLoader::ClassLoader");
我认为 PHP 属性最大的缺失特征是据我所知 PHP 属性是静态的,不会在 运行 时进行评估。他们只是美化的评论。
如果这是真的,我们可以做一些真正令人惊奇的事情,比如非侵入式附加 pre/post-processing 函数,就像你写的那样。
它们就像在 symfony 或 doctrine 中一样工作。您不能在其中使用变量,您必须编写自己的代码来搜索 php class 树以查找代码中的属性,并使用 php 反射来获取信息和 运行 属性。
老实说这很令人失望,虽然这可能只是第一步,将在 PHP 的后续版本中修复。
但就目前而言,我认为你所要求的是不可能的。因为它们并不像您所要求的那样动态 运行ning。
我正在尝试在运行时动态加载(包含文件)GetRiskSummaryCommandHandler.php(GetRiskSummary\CommandHandler),同时将 Route api/risks
解析为 HandleCommand(属于 class CommandHandler)方法。
我该怎么做?如果不能,我可以修改任何采用的方法,包括修改自动加载器吗?
我的 api class 代码段如下所示:
API.php
<?php
abstract class API
{
public function processRequest()
{
$id1 = $this->requestObj->id1;
//$id2 = $this->requestObj->id2;
$endpoint1 = $this->requestObj->endpoint1;
$endpoint2 = $this->requestObj->endpoint2;
$isDestination = in_array($id1, ['first', 'prev', 'next', 'last']);
$numSetEndpoints = (int)isset($endpoint1) + (int)isset($endpoint2);
switch($numSetEndpoints)
{
case 0:
if ($isDestination)
return json_decode($this->_response("No Endpoint: ", $endpoint1));
return json_decode($this->_response("ProjectAIM API"));
case 1:
$className = $endpoint1.'Controller';
break;
case 2:
$className = $endpoint2.'Controller';
break;
}
$class = "GetRiskSummaryCommandHandler";
$method = "HandleCommand";
if (class_exists($class))
{
if (method_exists($class, $method))
{
$response = (new $class($this->requestObj))->{$method}($this->requestObj);
if ($response['Succeeded'] == false)
{
return $response['Result'];
}
else if ($response['Succeeded'] == true)
{
header("Content-Type: application/json");
return $this->_response($response);
}
else if ($response['Result'])
{
header("Content-Type: text/html");
return $this->_response($response);
}
}
}
}
**命令处理程序片段,使用路由属性
GetRiskSummaryCommandHandler.php
<?php
namespace GetRiskSummary;
use Infrastructure\CommandHandler;
class GetRiskSummaryCommandHandler extends CommandHandler
{
#[Route("/api/risks", methods: ["GET"])]
public function HandleCommand()
{
$qb = $this->getEntityManager()
->createQueryBuilder();
$qb->select('*')
->from('Risks', 'Risks')
->orderBy('RiskID', 'DESC');
$query = $qb->getQuery();
return $query->getResult();
}
}
Autoloader.php
<?php
namespace Autoloader;
class Autoloader
{
private static function rglob($pattern, $flags = 0) {
$files = glob($pattern, $flags);
foreach (glob(dirname($pattern).'/*', GLOB_ONLYDIR|GLOB_NOSORT) as $dir) {
$files = array_merge($files, self::rglob($dir.'/'.basename($pattern), $flags));
}
return $files;
}
public static function ClassLoader($path)
{
$pathParts = explode("\", $path);
$path = $pathParts[array_key_last($pathParts)];
$matches = self::rglob("*/$path*");
foreach ($matches as $name)
{
$filePath = realpath($name);
if (file_exists($filePath))
include $filePath;
}
}
}
spl_autoload_register("AutoLoader\AutoLoader::ClassLoader");
我认为 PHP 属性最大的缺失特征是据我所知 PHP 属性是静态的,不会在 运行 时进行评估。他们只是美化的评论。
如果这是真的,我们可以做一些真正令人惊奇的事情,比如非侵入式附加 pre/post-processing 函数,就像你写的那样。
它们就像在 symfony 或 doctrine 中一样工作。您不能在其中使用变量,您必须编写自己的代码来搜索 php class 树以查找代码中的属性,并使用 php 反射来获取信息和 运行 属性。
老实说这很令人失望,虽然这可能只是第一步,将在 PHP 的后续版本中修复。
但就目前而言,我认为你所要求的是不可能的。因为它们并不像您所要求的那样动态 运行ning。