Обработка больших идентификаторов пользователей, возвращаемых FQL в PHP
Я использую FQL для получения списка пользователей из Facebook. Для согласованности я получаю результат в виде JSON. Это вызывает проблему - поскольку возвращаемый JSON кодирует идентификаторы пользователей в виде чисел, json_decode() преобразует эти числа в значения с плавающей запятой, потому что некоторые из них слишком велики, чтобы поместиться в int; конечно, мне нужны эти идентификаторы в виде строк.
Поскольку json_decode() делает свое дело, не принимая никаких флагов поведения, я в растерянности. Есть какие-нибудь предложения о том, как это решить?
6 answers
Json_decode() может преобразовывать большие целые числа в строки, если вы укажете флаг в вызове функции:
$array = json_decode($json, true, 512, JSON_BIGINT_AS_STRING)
Я решил проблему, добавив &format=json-strings
на мой вызов api FQL, вот так:
$myQuery = "SELECT uid2 FROM friend WHERE uid1=me()";
$facebook->api("/fql?q=" . urlencode($myQuery) . "&format=json-strings")
Это говорит facebook заключать все числа в кавычки, что приводит к тому, что json_decode не использует ни int-s, ни плавающие значения.
Поскольку я боялся, что эта проблема не ограничивается FQL, но всеми вызовами API graph, которые предпочитают представлять некоторые идентификаторы в виде БОЛЬШИХ чисел, я зашел так далеко, что немного исправил PHP SDK facebook, чтобы заставить Facebook возвращать все свои номера как струнные.
Я добавил эту строку в функцию _graph
.
Это будет строка 738 в facebook_base.php, версия 3.1.1
$params['format'] = 'json-strings';
Обязательно исправьте
У меня была аналогичная проблема, когда json_decode
преобразовывал последние идентификаторы twitter/твитов в экспоненциальные числа.
Ответ Бьорна хорош, если вы хотите, чтобы ваш BIGINT стал строкой - и имел PHP 5.3+. Если ни то, ни другое не соответствует действительности, другой вариант - повысить точность PHP с плавающей точкой. Это можно сделать несколькими разными способами...
- найдите значение
precision
в вашем php.ini и измените его наprecision = 20
- добавьте
ini_set('precision', 20);
в свое PHP-приложение - добавьте
php_value precision 20
в свое приложение .htaccess или файл виртуального хоста
Быстрый и грязный, похоже, пока работает:
$sJSON = preg_replace('/:(\d+)/', ':"${1}"', $sJSON);
Я использую это, и это работает почти отлично.
json_decode(preg_replace('/("\w+"):(\d+)/', '\\1:"\\2"', $jsonString), true)
Json прерывается, когда в него включены географические данные, например. {"lat":54.2341}
приводит к "lat":"54".2341
Решение:
$json = preg_replace('/("\w+"):(\d+)(.\d+)?/', '\\1:"\\2\\3"', $json);
Это (preg_replace('/("\w+"):(\d+)(.\d+)?/', '\\1:"\\2\\3"', $json);)
сработало для меня (для анализа результатов из api facebook)