Nette\Utils\Json::encode a JSON_FORCE_OBJECT
- Ajax
- Člen | 59
Ahoj!
Potřebuju vrátit JSON s textovými indexy pole. Pochopil jsem, že nette na to nemá response, napsal jsem si vlastní:
class JsonTextKeysResponse implements \Nette\Application\IResponse
{
/** @var array|\stdClass */
private $payload;
/** @var string */
private $contentType;
public function __construct($payload, $contentType = NULL) {
if(!is_array($payload) && !is_object($payload)) {
throw new Nette\InvalidArgumentException(sprintf('Payload must be array or object class, %s given.', gettype($payload)));
}
$this->payload = $payload;
$this->contentType = $contentType ? $contentType : 'application/json';
}
public function send(Nette\Http\IRequest $httpRequest, Nette\Http\IResponse $httpResponse) {
$httpResponse->setContentType($this->contentType);
$httpResponse->setExpiration(FALSE);
echo Nette\Utils\Json::encode($this->payload, JSON_FORCE_OBJECT);
}
}
Problém je, že nette Nette\Utils\Json::encode nebere ten flag
JSON_FORCE_OBJECT
. Nevíte jak to obejít?
- integer
- Člen | 6
Nejlepší by bylo asi poslat PR do Nette, který tuhle volbu umožní. Podle zdrojáků by to nejspíš byla úprava na jeden řádek (podobný tomuto https://api.nette.org/…son.php.html#33 ) a testy.
Jinak generování objektu místo prázdného pole by ti mělo zařídit
přetypování prázdného pole na object pomocí
(object) $emptyPayloadPart
, ale vyžaduje si to nějaké ruční
úpravy a procházení payloadu.
Takže nejrychlejší řešení je asi místo
\Nette\Utils\Json::encode()
zavolat syrové
json_encode
přímo z PHP. Pokud aplikace neběží na nějaké
historické verzi php, tak by to neměl být větší problém.
- Pavel Kravčík
- Člen | 1196
https://github.com/…ils/pull/152, https://github.com/…ils/pull/106
Asi nejlepší bude použít standardní php json jak píše @integer. Nette se v tomhle chová trochu nestandardně – tj. jinak než dokumentace.
- Jan Tvrdík
- Nette guru | 2595
@Ajax JSON_FORCE_OBJECT je antipattern. Správné řešení je tam
místo []
dát (object) []
.
- Ajax
- Člen | 59
Jan Tvrdík napsal(a):
@Ajax JSON_FORCE_OBJECT je antipattern. Správné řešení je tam místo
[]
dát(object) []
.
Problém je, že to nevyřeší můj problém. Potřebuju aby číselné indexy polí byly číslo-string, tedy
[
1 => 'aaa',
2 => 'bbb'
]
se do jsonu přepsalo takto
{
"1": "aaa",
"2": "bbb"
}
Toto mi konstrukce (object)$this->payload
neudělá…
Editoval Ajax (19. 10. 2017 21:08)
- CZechBoY
- Člen | 3608
Vůbec nechápu tvůj aktuální problém
https://3v4l.org/RR3ZS
https://3v4l.org/U7QGX
- Ajax
- Člen | 59
Tohle:
echo json_encode((object)["set" => "set1", "version" => 1, "categories" => [0 => "abc", 1 => "def"]]);
{"set":"set1","version":1,"categories":["abc","def"]}
Neboli, „abc“ a „def“ nemají index, tohle chovaní potřebuju:
echo json_encode(["set" => "set1", "version" => 1, "categories" => [0 => "abc", 1 => "def"]], JSON_FORCE_OBJECT);
{"set":"set1","version":1,"categories":{"0":"abc","1":"def"}}
Editoval Ajax (23. 10. 2017 18:29)
- Jan Tvrdík
- Nette guru | 2595
To co chceš je antipattern. Správně je to
echo json_encode(["set" => "set1", "version" => 1, "categories" => (object) [0 => "abc", 1 => "def"]]);