类型提示或将API函数参数强制转换为int的最佳方法是什么



我正在使用Drupal 9并使用OAuth来验证我的DELETE API请求。我有一个函数可以响应DELETE请求,并将student_no作为删除请求URL的参数。例如,当删除请求https://www.myapplicationurl.com/999999发送时,我的函数将接收999999作为student_no。我的功能如下:

public function delete( $student_no) {
$node_array = Drupal::entityTypeManager()->getStorage('node')->loadByProperties(['student_no' => $student_no]);
$node = reset($node_array);
if ($node && ($node->bundle() == 'student')) {
try {
$node->delete();
$response_code = 200;
$response = ["code" => $response_code, "message" => 'deleted', "student_no" => $student_no];
return new JsonResponse($response, $response_code, $headers);
} catch (ClientException | RequestException | TransferException | BadResponseException $exception) {
Drupal::service('myapi.log_service')->api_log("Stiudent Delete API Exception: {$exception}");
$response_code = 405;
$message = json_decode((string) (($exception->getResponse()) ? $exception->getResponse()->getBody() : ''));
$response = ["code" => $response_code, "message" => 'deleted', "student_no" => $student_no];
return new JsonResponse($response, $response_code, $headers);
}
} else {
$response_code = 404;
$response = ["code" => $response_code, "message" => "Student does not exist", "student_no" => $student_no];
return new JsonResponse($response, $response_code, $headers);
}
} 

现在,一切都如预期的那样工作,但问题是在我的回应中,$student_no是以字符串形式出现的"999999";。$response数组的var_dump是:array(3) { ["code"]=> int(200) ["message"]=> string(7) "deleted" ["student_no"]=> string(6) "999999" }如何确保student_id始终是一个数字?我想我可以做两件事:

  1. 我可以将学生编号强制转换为整数,作为函数(如$student_no = (int) $student_no;(的第一步,但这会将正确的字符串强制转换为0,例如,如果https://www.myapplicationurl.com/somerandomstring如果传递,则将在强制转换后有效地将$student_no设置为0。我不确定这样做是否正确。

  2. 我可以键入提示student_no作为一个整数,如public function delete(int $student_no),这看起来很完美,但如果像上面#1中那样在url中传递字符串,它会给出500个内部服务器错误,这是一个很大的否定,因为它会违反我的API合同,该合同只允许我返回200、404或405作为错误代码。为了实现这一点,我需要捕获500异常,我不知道该怎么做,否则,我不得不放弃这种方法。

请提出最佳前进方式。谢谢

您的代码需要一些规范化,如果您明确要求int,那么您应该在接收值的地方(很可能在控制器中(执行所有验证/清理和强制转换。从那个地方开始,该值应该以int的形式出现,或者如果由于任何原因无法正确执行有效值,则应该停止。因此,我建议你在方法中坚持严格的类型提示,因为这是减少潜在问题的好方法。至于导致0值的强制转换问题,首先应该确保这是有效的数字字符串。有一些函数可以做到这一点,其中is_numeric((是第一个要查看的候选者:

$vals = ['1', 1, '', 'foo', true, -5];
foreach($vals as $val) {
var_dump($val);
var_dump(is_numeric($val));
echo PHP_EOL;
}

产生

string(1) "1"
bool(true)
int(1)
bool(true)
string(0) ""
bool(false)
string(3) "foo"
bool(false)
bool(true)
bool(false)
int(-5)
bool(true)

或者,您可以只使用d+模式进行模式匹配,并且仅在输入数据匹配时进行强制转换,更不用说对最终整数值进行一些验证(即,我认为您不允许ID为负值等(。

最新更新