提问人:miken32 提问时间:12/17/2020 更新时间:12/18/2020 访问量:641
Laravel trans_choice PHP 8.0升级后无法正常工作
Laravel trans_choice not working after PHP 8.0 upgrade
问:
我在功能测试中有以下断言:
// just a convenience method to post a CSV file
$this->importData($postdata, $csv)
->assertStatus(200)
->assertExactJson([
"alert" => null,
// response text copied from RoomController::import()
"message" => sprintf(__("%d items were created or updated."), count($csv_data)),
]);
这在 PHP 7.4 中没有问题。在不对应用程序代码进行任何更改的情况下,我更新到 PHP 8.0,现在显示:
Failed asserting that two strings are equal.
--- Expected
+++ Actual
@@ @@
-'{"alert":null,"message":"2 items were created or updated."}'
+'{"alert":null,"message":"2 item was created or updated."}'
有问题的控制器代码如下所示:
if ($errcount === 0) {
$response_code = 200;
$msg = sprintf(
trans_choice(
"{0}No items were created or updated.|{1}%d item was created or updated.|{2,}%d items were created or updated.",
$count
),
$count
);
} else {
// some other stuff
}
return response()->json(["message" => $msg, "alert" => $alert], $response_code);
所以我的问题是,出于某种原因,在 PHP 8.0 中返回单数项。trans_choice
我找不到解释为什么会发生这种情况。回到 PHP 7.4,一切都会再次通过,所以它肯定与 PHP 版本相关联。故障排除很困难,因为当我启动并这样做时,无论我使用的是 PHP 7.4 还是 8.0,我总是得到“bar”。artisan tinker
echo trans_choice("{0}foo|{1}bar|{2,}baz", 3);
Locale 不应该出现这种情况,因为我使用的是原始字符串,但为了记录,和 in 都设置为“en”。locale
locale_fallback
config/app.php
答:
好的,经过大量操作,我能够将不同的行为追溯到 ,并且还意识到我使用了错误的语法。dump
dd
Illuminate\Translation\MessageSelector::extractFromString()
该方法是执行一些正则表达式,然后在条件和值之间进行松散的比较。它在 PHP 7.4 中工作的唯一原因是因为条件 “2” 大致等于 2。在 8.0 中,将字符串与整数进行比较是以更合理的方式完成的,因此该方法在所有情况下都返回 null,并使用单数默认值。
但是,与其使用正则表达式语法,不如这样定义我的字符串:{2,}
"{0}No items were created or updated.|{1}%d item was created or updated.|{2,*}%d items were created or updated."
该函数检测到星号,并将返回短路以给出适当的值。如果我一直在测试除 0、1 或 2 以外的任何值,我的测试在任何版本的 PHP 中都不会通过。
评论