$ids * @return array{kind: 'ids', ids_hash: string, ids_count: int} */ public function fromIds(array $ids): array { $normalized = []; foreach ($ids as $id) { if (is_int($id)) { $normalized[] = (string) $id; continue; } if (! is_string($id)) { continue; } $id = trim($id); if ($id === '') { continue; } $normalized[] = $id; } $normalized = array_values(array_unique($normalized)); sort($normalized); $json = json_encode($normalized, JSON_THROW_ON_ERROR | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE); return [ 'kind' => 'ids', 'ids_hash' => hash('sha256', $json), 'ids_count' => count($normalized), ]; } /** * @param array $queryPayload * @return array{kind: 'query', query_hash: string} */ public function fromQuery(array $queryPayload): array { $json = $this->canonicalJson($queryPayload); return [ 'kind' => 'query', 'query_hash' => hash('sha256', $json), ]; } /** * @param array $payload */ public function canonicalJson(array $payload): string { $normalized = $this->ksortRecursive($payload); return (string) json_encode($normalized, JSON_THROW_ON_ERROR | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE); } private function ksortRecursive(mixed $value): mixed { if (! is_array($value)) { return $value; } $isList = array_is_list($value); if (! $isList) { ksort($value); } foreach ($value as $key => $child) { $value[$key] = $this->ksortRecursive($child); } return $value; } }