上传到服务器后,输出的所有数字json都是字符串

After upload to server, all numbers outputed json is string

我正在使用 Laravel 5.5.13。

我在我的 loclahost 上成功测试了所有内容。我现在上传到服务器了。

我在我的本地主机(XAMPP、Windows 10)中使用默认设置从 phpMyAdmin 进行了导出,然后使用默认设置在远程 phpMyAdmin 上进行了导入。

当访问远程主机时,它现在会提供我在迁移中设置的所有字段,如下所示:

$table->integer('extension_id')->unsigned();

作为一个字符串,这很奇怪,因为在本地主机上,它给出的是一个数字。

在下面的数据中,请注意,在 localhost 中,displayname_idextensions_id 值没有用引号引起来。但是 id 不是,我不明白,它也是未签名的。我的目标是使 id 列成为字符串(或者如果不可能,则使 *_id 变回数字)。

这是来自远程的:

[
    {
        "id": 2,
        "name": "Stencil",
        "kind": "cws",
        "created_at": "2017-11-11 00:26:52",
        "updated_at": "2017-11-11 00:26:52",
        "thumbs_count": "1",
        "thumbs_yes_count": "0",
        "latest_comment": {
            "id": 1,
            "body": "huh?",
            "displayname_id": "1",
            "extension_id": "2",
            "created_at": "2017-11-11 00:26:56",
            "updated_at": "2017-11-11 00:26:56"
        }
    }
]

这是来自本地主机:

[
    {
        "id": 2,
        "name": "Stencil",
        "kind": "cws",
        "created_at": "2017-11-11 00:26:52",
        "updated_at": "2017-11-11 00:26:52",
        "thumbs_count": "1",
        "thumbs_yes_count": "0",
        "latest_comment": {
            "id": 1,
            "body": "huh?",
            "displayname_id": 1,
            "extension_id": 2,
            "created_at": "2017-11-11 00:26:56",
            "updated_at": "2017-11-11 00:26:56"
        }
    }
]

这是我的 phpMyAdmin 的截图:

我的远程 phpMyAdmin 是这个 -

我的本地是这样的 -

这是 table 结构的屏幕截图,请注意 id 列也是未签名的,但是它们没有被 json_encode 转换为字符串。

导出截图如下:https://screenshots.firefoxusercontent.com/images/51d1e47f-fe78-4cdc-8de4-b113d4b576a9.png

这里是导入截图:https://screenshots.firefoxusercontent.com/images/ff112f86-1c1c-4554-b03c-4b15307c042a.png

当然,这个问题来自您的数据库或 php < 5.2.9

的旧版本

但是你可以尝试将 JSON_NUMERIC_CHECK 选项传递给你的 json_encode 就完成了,它会自动将代表数字的字符串转换为数字:

原生PHP解决方案:

echo json_encode($a, JSON_NUMERIC_CHECK);

在线Example

Laravel解法:

return response()->json($a, 200, [], JSON_NUMERIC_CHECK);

区别在于您的 MySQL 客户端驱动程序。您的本地计算机正在使用 MySQL 本机驱动程序 (mysqlnd),而您的远程服务器正在使用 MySQL 客户端库 (libmysql)。

本机驱动程序 (mysqlnd) 会将数据库中的所有整数视为 PHP 中的整数。但是,客户端库 (libmysql) 会将所有字段视为 PHP.

中的字符串

id 字段在两台服务器上显示为整数的原因是一些 Laravel 魔术。 Laravel 使用模型的 $casts 属性 在访问时将特定字段转换为特定类型。如果您的模型上的 $incrementing 属性 是 true(默认情况下),Laravel 会自动将主键字段(默认 id)添加到$casts 属性 与 $keyType 属性 定义的类型(默认 int)。因此,每当您访问 id 字段时,它将是一个 PHP 整数。

如果您希望整数字段被视为整数,您可以在远程服务器上安装 MySQL 本机驱动程序 (mysqlnd)。

如果这不是一个选项,或者不合需要,您可以使用 $casts 属性:

指定将这些字段视为整数
protected $casts = [
    'displayname_id' => 'int',
    'extension_id' => 'int',
];

现在,无论使用何种 MySQL 驱动程序,这两个字段都将被视为整数。

如果您希望 id 被视为字符串,您有几个选择。

首先,您可以将 $keyType 值更改为 string,但这可能会产生意想不到的后果。例如,BelongsTo class 上的 relationHasIncrementingId 检查键是否递增以及键类型是否为 int,因此此方法将 return false 如果您将 $keyType 更改为 string

其次,您可以直接将 'id' => 'string' 添加到 $casts 数组,因为在访问属性时 $casts 值优先于 $keyType 值。这比更改 $keyType 值更安全,语义上更正确。

第三,如果您希望 id 被视为仅用于 JSON 转换的字符串,您可以覆盖模型上的 jsonSerialize() 方法。

public function jsonSerialize()
{
    $data = parent::jsonSerialize();

    if (isset($data[$this->primaryKey])) {
        $data[$this->primaryKey] = $this->castAttribute('string', $data[$this->primaryKey]);
    }

    return $data;
}