HTML 特殊字符和表情符号在 Laravel 网页上显示不正确
HTML Special Characters and Emojis Showing up Incorrectly on Laravel Webpage
我可能正在做一些愚蠢的事情,并且认为这会非常简单。我正在从外部 API 提取数据并通过 Eloquent 模型将其直接存储到数据库中 我是 creating/saving.
保存到数据库字段中的数据如下所示:
I Can't Believe It's A
- 该字段正在使用 utf8mb4_unicode_ci
排序规则。
我的网页有以下元数据:
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
我通过我的 Laravel blade 模板显示它,如下所示:
<td>{{ $company->type->name }}</td>
我有点困惑我在这里做错了什么?从文档和其他 Whosebug 问题来看,我似乎做得对。我的 config/database.php
有以下内容:
'mysql' => [
'driver' => 'mysql',
'url' => env('DATABASE_URL'),
'host' => env('DB_HOST', '127.0.0.1'),
'port' => env('DB_PORT', '3306'),
'database' => env('DB_DATABASE', 'forge'),
'username' => env('DB_USERNAME', 'forge'),
'password' => env('DB_PASSWORD', ''),
'unix_socket' => env('DB_SOCKET', ''),
'charset' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci',
'prefix' => '',
'prefix_indexes' => true,
'strict' => true,
'engine' => 'InnoDB',
'options' => extension_loaded('pdo_mysql') ? array_filter([
PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'),
]) : [],
],
我相信这一切都是正确的。我在这里缺少什么吗?切换到使用未转义的 {!! !!}
似乎导致内容仍然显示相同。我正在使用 Laravel v7.13.0
另外 Google Chrome 报告它是 UTF-8 呈现的:
> document.characterSet
"UTF-8"
编辑:
这是获取响应以及返回的 JSON 名称的示例:
>>> $response = Http::withOptions(
[
'verify' => false,
'base_uri' => config('custom.torn_api_base'),
'timeout' => 5.0
]
)->get(
"company/79831",
[
'selections' => 'profile',
'key' => config('custom.torn_api_key')
]
);
=> Illuminate\Http\Client\Response {#3393
+"cookies": GuzzleHttp\Cookie\CookieJar {#3379},
+"transferStats": GuzzleHttp\TransferStats {#3418},
}
>>> $response->json()['company']['name'];
=> " Button Mashers™"
^ 你可以在上面看到他们的 API 给我提供了与他们网站上使用的 UTF-8 编码相同的字符串。
这是我创建模型并将其保存到数据库的过程:
$company = Company::updateOrCreate(
[
'id' => $tornPlayerData['job']['company_id']
],
[
'name' => $tornPlayerData['job']['company_name'],
'player_id' => $this->player->id,
'isOwner' => true
]
);
我也在记录回复,下面是带有表情符号的行之一:
Log::info("Updating company '{$company->name}'' now", ['company' => $company]);
laravel.log│[2020-06-22 00:43:52] staging.INFO: Updating company '👾 Button Mashers™'' now {"company":{"App\Company":{"id":79831,"name":"👾 Button Mashers™","player_id":2141091,"updated_at":"2020-06-22T04:43:52.000000Z","created_at":"2020-06-22T04:43:52.000000Z"}}}
编辑 2:
我只是手动将 Button Mashers™
的 Tinker 输出复制并粘贴到关联数据库行中的 name
。现在网站显示手动调整一个正确。所以看起来 Laravel 在存储数据时对来自 API 的数据做了一些奇怪的事情,我不确定为什么会这样。
编辑 3:
使用用户在回答中提出的 HEX
查询。
SELECT id,name,HEX(name) FROM `companies` WHERE id=60335
(60335, 'Pokey's Play House!', '506F6B657926233033393B7320506C617920486F75736521');
(60335, ''', '26233033393B');
第二个结果是我将 Pokey's Play House!
修改为 '
这样您就可以看到撇号的结果。
编辑 4:
blade 模板:
<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Company Directory</title>
<!-- Fonts -->
{{-- <link href="https://fonts.googleapis.com/css?family=Nunito:200,600" rel="stylesheet">--}}
<!-- Styles -->
** Snipped some minor CSS away from here **
</style>
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.20/css/jquery.dataTables.css">
<!-- Scripts -->
<script type="text/javascript" charset="utf8" src="https://code.jquery.com/jquery-3.5.1.slim.min.js"></script>
<script type="text/javascript" charset="utf8" src="https://cdn.datatables.net/1.10.20/js/jquery.dataTables.js"></script>
<script type="text/javascript" charset="utf8">
**removed some datatables code from here for this paste**
</script>
</head>
<body>
<table id='directory-table' class='display'>
<thead>
<tr>
<th>Player Name</th>
<th>Company Name</th>
<th>Type</th>
<th>Rank</th>
<th>Positions</th>
</tr>
</thead>
<tbody>
@forelse ($companies as $company)
<tr>
<td>
<a href='https://www.example.
net/profiles.php?XID={{ $company->player->id }}'>
{{ $company->player->name }}
</a>
</td>
<td>
<a href='https://www.example.net/joblist.php#/p=corpinfo&userID={{ $company->id }}'>
{{ $company->name }}
</a>
</td>
<td>{{ $company->type->name }}</td> //THIS IS THE PROBLEM STRING HERE BEING OUTPUTTED
<td> {{ $company->rank }}</td>
<td> {{ $company->hired_employees }}/{{ $company->max_employees }}</td>
</tr>
@empty
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
@endforelse
</tbody>
</table>
</body>
</html>
"HTML 个实体"(例如 '
)对网页很有用,但不应该是将内容存储到数据库中的方式。
可能是你转了两次实体,一次是存储数据前,一次是展示在网页上。要进一步诊断问题,请获取字符串的 SELECT HEX(..) ...
。
在您的 blade 中,尝试使用以下语句进行打印:
{!! html_entity_decode($company->name) !!}
或
<?php echo $company->name; ?>
关于 printing data in blade 的官方文档。
我觉得是编码问题。
您需要打开 AppServiceProvider
并在 boot method
中添加以下代码:
Blade::setEchoFormat('e(utf8_encode(%s))');
希望这对你有用!!
我可能正在做一些愚蠢的事情,并且认为这会非常简单。我正在从外部 API 提取数据并通过 Eloquent 模型将其直接存储到数据库中 我是 creating/saving.
保存到数据库字段中的数据如下所示:
I Can't Believe It's A
- 该字段正在使用 utf8mb4_unicode_ci
排序规则。
我的网页有以下元数据:
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
我通过我的 Laravel blade 模板显示它,如下所示:
<td>{{ $company->type->name }}</td>
我有点困惑我在这里做错了什么?从文档和其他 Whosebug 问题来看,我似乎做得对。我的 config/database.php
有以下内容:
'mysql' => [
'driver' => 'mysql',
'url' => env('DATABASE_URL'),
'host' => env('DB_HOST', '127.0.0.1'),
'port' => env('DB_PORT', '3306'),
'database' => env('DB_DATABASE', 'forge'),
'username' => env('DB_USERNAME', 'forge'),
'password' => env('DB_PASSWORD', ''),
'unix_socket' => env('DB_SOCKET', ''),
'charset' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci',
'prefix' => '',
'prefix_indexes' => true,
'strict' => true,
'engine' => 'InnoDB',
'options' => extension_loaded('pdo_mysql') ? array_filter([
PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'),
]) : [],
],
我相信这一切都是正确的。我在这里缺少什么吗?切换到使用未转义的 {!! !!}
似乎导致内容仍然显示相同。我正在使用 Laravel v7.13.0
另外 Google Chrome 报告它是 UTF-8 呈现的:
> document.characterSet
"UTF-8"
编辑:
这是获取响应以及返回的 JSON 名称的示例:
>>> $response = Http::withOptions(
[
'verify' => false,
'base_uri' => config('custom.torn_api_base'),
'timeout' => 5.0
]
)->get(
"company/79831",
[
'selections' => 'profile',
'key' => config('custom.torn_api_key')
]
);
=> Illuminate\Http\Client\Response {#3393
+"cookies": GuzzleHttp\Cookie\CookieJar {#3379},
+"transferStats": GuzzleHttp\TransferStats {#3418},
}
>>> $response->json()['company']['name'];
=> " Button Mashers™"
^ 你可以在上面看到他们的 API 给我提供了与他们网站上使用的 UTF-8 编码相同的字符串。
这是我创建模型并将其保存到数据库的过程:
$company = Company::updateOrCreate(
[
'id' => $tornPlayerData['job']['company_id']
],
[
'name' => $tornPlayerData['job']['company_name'],
'player_id' => $this->player->id,
'isOwner' => true
]
);
我也在记录回复,下面是带有表情符号的行之一:
Log::info("Updating company '{$company->name}'' now", ['company' => $company]);
laravel.log│[2020-06-22 00:43:52] staging.INFO: Updating company '👾 Button Mashers™'' now {"company":{"App\Company":{"id":79831,"name":"👾 Button Mashers™","player_id":2141091,"updated_at":"2020-06-22T04:43:52.000000Z","created_at":"2020-06-22T04:43:52.000000Z"}}}
编辑 2:
我只是手动将 Button Mashers™
的 Tinker 输出复制并粘贴到关联数据库行中的 name
。现在网站显示手动调整一个正确。所以看起来 Laravel 在存储数据时对来自 API 的数据做了一些奇怪的事情,我不确定为什么会这样。
编辑 3:
使用用户在回答中提出的 HEX
查询。
SELECT id,name,HEX(name) FROM `companies` WHERE id=60335
(60335, 'Pokey's Play House!', '506F6B657926233033393B7320506C617920486F75736521');
(60335, ''', '26233033393B');
第二个结果是我将 Pokey's Play House!
修改为 '
这样您就可以看到撇号的结果。
编辑 4:
blade 模板:
<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Company Directory</title>
<!-- Fonts -->
{{-- <link href="https://fonts.googleapis.com/css?family=Nunito:200,600" rel="stylesheet">--}}
<!-- Styles -->
** Snipped some minor CSS away from here **
</style>
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.20/css/jquery.dataTables.css">
<!-- Scripts -->
<script type="text/javascript" charset="utf8" src="https://code.jquery.com/jquery-3.5.1.slim.min.js"></script>
<script type="text/javascript" charset="utf8" src="https://cdn.datatables.net/1.10.20/js/jquery.dataTables.js"></script>
<script type="text/javascript" charset="utf8">
**removed some datatables code from here for this paste**
</script>
</head>
<body>
<table id='directory-table' class='display'>
<thead>
<tr>
<th>Player Name</th>
<th>Company Name</th>
<th>Type</th>
<th>Rank</th>
<th>Positions</th>
</tr>
</thead>
<tbody>
@forelse ($companies as $company)
<tr>
<td>
<a href='https://www.example.
net/profiles.php?XID={{ $company->player->id }}'>
{{ $company->player->name }}
</a>
</td>
<td>
<a href='https://www.example.net/joblist.php#/p=corpinfo&userID={{ $company->id }}'>
{{ $company->name }}
</a>
</td>
<td>{{ $company->type->name }}</td> //THIS IS THE PROBLEM STRING HERE BEING OUTPUTTED
<td> {{ $company->rank }}</td>
<td> {{ $company->hired_employees }}/{{ $company->max_employees }}</td>
</tr>
@empty
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
@endforelse
</tbody>
</table>
</body>
</html>
"HTML 个实体"(例如 '
)对网页很有用,但不应该是将内容存储到数据库中的方式。
可能是你转了两次实体,一次是存储数据前,一次是展示在网页上。要进一步诊断问题,请获取字符串的 SELECT HEX(..) ...
。
在您的 blade 中,尝试使用以下语句进行打印:
{!! html_entity_decode($company->name) !!}
或
<?php echo $company->name; ?>
关于 printing data in blade 的官方文档。
我觉得是编码问题。
您需要打开 AppServiceProvider
并在 boot method
中添加以下代码:
Blade::setEchoFormat('e(utf8_encode(%s))');
希望这对你有用!!