BIGINT создан как INT в MySQL

У меня есть таблица базы данных mysql в WordPress, где я без проблем объявляю поле BIGINT.

Но когда я создаю ту же таблицу в MySQL, установленной на моем собственном компьютере, большие числа сохраняются как 2147483647, что в максимальном размере INT.

Есть идеи, почему это происходит?

Вот таблица,

CREATE TABLE inPxUtBI_follow_data_tokens (
id int(20) unsigned NOT NULL,
screen_name varchar(15) NOT NULL,
token tinytext,
secret tinytext,
time_data_cursor datetime DEFAULT '0000-00-00 00:00:00' NOT NULL,
friends_cursor bigint(20) NOT NULL DEFAULT -1,
followers_cursor bigint(20) NOT NULL DEFAULT -1,
datetime_created datetime DEFAULT '0000-00-00 00:00:00' NOT NULL,
time_data_cursor_index smallint(10) unsigned NOT NULL,
PRIMARY KEY  (screen_name)
) ;

РЕДАКТИРОВАТЬ: Информация о версии

mysql> \s
--------------
C:\Program Files\MySQL\MySQL Server 5.7\bin\mysql.exe  Ver 14.14 Distrib 5.7.22,
for Win64 (x86_64)

Connection id:          2
Current database:
Current user:           root@localhost
SSL:                    Not in use
Using delimiter:        ;
Server version:         5.7.22-log MySQL Community Server (GPL)
Protocol version:       10
Connection:             localhost via TCP/IP
Server characterset:    latin1
Db     characterset:    latin1
Client characterset:    cp850
Conn.  characterset:    cp850
TCP port:               3306
Uptime:                 30 min 3 sec

Threads: 1  Questions: 7  Slow queries: 0  Opens: 109  Flush tables: 1  Open tab
les: 102  Queries per second avg: 0.003
--------------

РЕДАКТИРОВАТЬ: Данные информация

Вот обновление sql,

update inPxUtBI_follow_data_tokens set followers_cursor = %d WHERE screen_name = '%s' ["1599757792260458963","xxx"]
update inPxUtBI_follow_data_tokens set friends_cursor = %d WHERE screen_name = '%s' ["1600189794255483463","xxx"]

и вот обновленная строка,

id,screen_name,token,secret,time_data_cursor,friends_cursor,followers_cursor,datetime_created,time_data_cursor_index
111,xxx,yyy,zzz,"2018-05-13 15:37:06",2147483647,2147483647,"2018-05-13 11:59:57",9

РЕДАКТИРОВАТЬ: PHP-код

public static function setUserCursor($table, $field, $screen_name, $next_cursor) {
flog(DEBUG, 'setUserCursor', $next_cursor);
$update_count = 0;
if ($next_cursor > 0) {
global $wpdb;
$sql = "update $table set $field = %d WHERE screen_name = '%s'";
$sqldata = array($next_cursor, $screen_name);
flog(DEBUG, 'setUserCursor', $sql . ' ' . json_encode($sqldata));

$update_count = $wpdb->query($wpdb->prepare($sql, $sqldata));
}
return $update_count;
}

РЕДАКТИРОВАТЬ: предложение @Progman подбрасывает что-то любопытное

На моей локальной машине я получаю,

update inPxUtBI_follow_data_tokens set friends_cursor = %d WHERE screen_name = '%s' ["1557868487712412145","xxx"]
update inPxUtBI_follow_data_tokens set friends_cursor = 2147483647 WHERE screen_name = 'xxx'

все же на удаленном сервере я получаю,

update inPxUtBI_follow_data_tokens set friends_cursor = %d WHERE screen_name = '%s' [1600189862942848368,"xxx"]
update inPxUtBI_follow_data_tokens set friends_cursor = 1600189862942848368 WHERE screen_name = 'xxx'

Обратите внимание на кавычки вокруг значения «1557868487712412145» в первой строке.

Я прикрепил вещи к этой функции, где данные JSON извлекаются.

function getFollowersIDs($user, $count, $cursor) {
$url = $this->api . '1.1/followers/ids.json';
$getfield = '?screen_name=' . $user . '&skip_status=1&count=' . $count . '&cursor=' . $cursor;
$requestMethod = 'GET';
$twitter = new TwitterAPIExchange($this->settings);
$data = $twitter->setGetfield($getfield)->buildOauth($url, $requestMethod)->performRequest();
$rtn = json_decode($data, true, 512, JSON_BIGINT_AS_STRING);
flog(VERBOSE, 'getFollowersIDs', $data);
flog(DEBUG, 'getFollowersIDs', 'CURSOR: ' . json_encode(array($rtn['next_cursor'])));
flog(DEBUG, 'getFollowersIDs', is_string($rtn['next_cursor']) ? $rtn['next_cursor'] . ' IS string' : $rtn['next_cursor'] . ' IS NOT string');

return $rtn;
}

Журналы для них, соответственно, для локального и удаленного,

[getFollowersIDs] {"ids":[1492183206,913536285461147649,825717050538618880,961964711720910848,591132453,248777189,232207153,400934967,77967828,443634207],"next_cursor":1600147168522111920,"next_cursor_str":"1600147168522111920","previous_cursor":0,"previous_cursor_str":"0"}
[getFollowersIDs] CURSOR: ["1600147168522111920"]
[getFollowersIDs] 1600147168522111920 IS string

а также

[getFollowersIDs] {"ids":[59150726,901375444934635520,385097832,331067377,194220828,540223123,2746743156,2271848935,819196471845253121,963324881906511877],"next_cursor":1597756074201108094,"next_cursor_str":"1597756074201108094","previous_cursor":-1597922052519508811,"previous_cursor_str":"-1597922052519508811"}
[getFollowersIDs] CURSOR: [1597756074201108094]
[getFollowersIDs] 1597756074201108094 IS NOT string

Итак, почему json_decode возвращает строку на одном компьютере и bigint на другом?

0

Решение

Похоже, что ваша локальная машина использует 4-байтовое целое число (32 или 64-битное PHP), а удаленная использует 8-байтовое целое число (64-битное PHP). Размер целого числа определяет, насколько велик BIGINT:

$a = json_decode('{"n":1600147168522111920}', true, 512, JSON_BIGINT_AS_STRING);
var_dump(PHP_INT_SIZE, PHP_INT_MAX, $a);

// local machine output
int(4)
int(2147483647)
array(1) {
["n"]=>
string(19) "1600147168522111920"}

// remote machine output
int(8)
int(9223372036854775807)
array(1) {
["n"]=>
int(1600147168522111920)
}

Как видите, значение 1600147168522111920 не может поместиться внутри 4-байтового целого числа и, следовательно, преобразовывается в строку.

Теперь я не знаю, основная реализация wpdb::prepare, но, видимо, он будет пытаться конвертировать %d целочисленное для платформы целое число, усечение 1600147168522111920 в 2147483647:

echo sprintf("%d", "1600147168522111920");
// 2147483647

Решение состоит в том, чтобы изменить %d в %s, Но прежде чем сделать это, убедитесь, что рассматриваемое значение выглядит как правильное, большое целое число.

1

Другие решения

После долгих исследований я обнаружил, что мой локальный php был 32-битным.

Установка 64-битного php решила проблему.

Итак, с этими данными,

[{"ids":[59150726,901375444934635520,385097832,331067377,194220828,540223123,2746743156,2271848935,819196471845253121,963324881906511877],"next_cursor":1597756074201108094,"next_cursor_str":"1597756074201108094","previous_cursor":-1597922052519508811,"previous_cursor_str":"-1597922052519508811"}]

этот код,

echo 'CURSOR: ' . json_encode(array($rtn[0]['next_cursor']))."\n";

производит этот результат (без кавычек вокруг значения),

CURSOR: [1597756074201108094],

Я полагаю, довольно неясная и вводящая в заблуждение разница между различными версиями!

Спасибо @Progman за то, что привел меня к решению.

1