Я знаю, что PHP не поддерживает 64-разрядные целые числа без знака.
Однако мне просто нужно прочитать беззнаковые 64-битные целочисленные значения из таблицы MySQL через запрос PDO и передать их клиентам (без каких-либо вычислений или сравнений); страница PHP публикует очень простой интерфейс REST для клиентов и должна выводить результат запроса только в виде данных JSON.
Прямо сейчас запрос PDO возвращает нетронутые целые числа, если они имеют ширину 63 бита (без знака), но когда в исходном значении таблицы установлен 64-й бит, драйвер PDO преобразует его в строку (я установил) PDO::ATTR_STRINGIFY_FETCHES
атрибут false, так как я хочу, чтобы типы были сохранены в максимально возможной степени).
Когда я звоню json_encode()
функция, связанные поля обрабатываются одинаково: они становятся строками, если их ширина превышает 63 бита.
Я не хочу оставлять их как строки в выводе json, так как это потребовало бы «взлома» изменений в клиентском коде, чтобы они обрабатывали преобразование json-string в ulong при декодировании.
Есть ли способ как-то настроить поведение json_encode, чтобы вывести их как «UInt64»?
Я посмотрел на JsonSerializable, но, похоже, он не может решить мою проблему.
Я нашел обходной путь к проблеме, не совсем «элегантный», но практичный (и это работает).
Я включил в свой проект пользовательскую библиотеку кодирования json на чистом PHP, найденную на GitHub Вот.
Я объявил этот интерфейс:
interface JSONSerializer
{
public function toJSON();
}
Я реализовал интерфейс в этом простом классе:
class UInt64Raw implements JSONSerializer {
private $value;
public function __construct($number) {
$this->value = $number;
}
public function getValue() { return $this->value; }public function toJSON() {
if (is_null($this->value)) return "null";
if ($this->value) return (string)$this->value;
return "0";
}
}
Я немного изменил стандартное поведение библиотеки кодировщика JSON, чтобы вызывать метод интерфейса всякий раз, когда кодируемый объект реализует этот интерфейс.
Затем я могу получить беззнаковые 64-битные целые числа в виде строк из PDO, обернуть их внутри UInt64Raw
экземпляр объекта и в конечном итоге передать их без кавычек (как числа) через пользовательскую кодировку JSON.
Других решений пока нет …