Automatyczne sortowanie JSON przez Operę i Chrome

Niedawno napotkałem na dość ciekawy problem. Pobierałem sobie ajaxem dane w postaci JSON a następnie wyświetlałem je w takiej kolejności, w jakiej otrzymałem. Jednak pewnego dnia klient zgłosił mi błąd, że dane wyświetlają się odwrotnie pod Chrome. Jak się później okazało podobny problem był również z Operą. A by przedstawić Wam dokładnie problem, pokażę przykładowy kod i dane, które powodują błąd.

Kod js:

$.ajax({
  url: 'testjs.php',
  dataType : 'json',
  success: function( data ) {
    for (var i in data) alert(i);
  }
});

oraz plik testjs.php

<?php
$ar = array(3=>'bla',2=>'ola',1=>'costam');
echo json_encode($ar);
?>

Jak widzicie, plik testjs.php generuje mi dane w kolejności 3,2,1. Niestety Opera i Chrome odbiera te dane w kolejności posortowanej 1,2,3. FireFox czy też IE nie sortują danych.

Rozwiązaniem tej sytuacji okazało się niestosowanie indeksów numerycznych tylko tekstowych, np.

<?php
$ar = array('c3'=>'bla','c2'=>'ola','c1'=>'costam');
echo json_encode($ar);
?>

Zamiast literki 'c' można wstawić dowolny tekst. Jeśli jednak ktoś z różnych przyczyn nie może zrobić takiego obejścia, to pozostaje jedynie sortowanie danych w js.

Komentarze

 

2011-09-27 21:24 gość_szagi3891

Rany, co za kicha.

2011-09-28 08:14 gość_Bartek

Przecież dane JSON są z założenia danymi NIEUPORZĄDKOWANYMI, więc nigdy nie masz pewności w jakiej kolejności je otrzymasz, a co za tym idzie, w jakiej je wyświetlisz. Żeby mieć 100% pewności, zawsze musisz posortować dane po stronie JS.

2011-09-28 08:32 nospor

Przyznam szczerze iż pierwszy raz słyszę o takim założeniu i mocno mnie ono dziwi/smuci. Wcześniej używałem XML ale odkąd poznałem JSON uznałem to za lepszą alternatywę dla XML. Założenie o nieuporządkowaniu psuje tę "lepszość"

2011-09-28 08:48 gość_Bartek

Polecam: http://json.org/json-pl.html - i cytat dla leniwych: "Obiekt jest nieuporządkowanym zbiorem par nazwa/wartość. Opis obiektu rozpoczyna { (lewa klamra) a kończy } (prawa klamra). Po każdej nazwie następuje : (dwukropek) oraz pary nazwa/wartość, oddzielone , (przecinkiem)."

2011-09-28 09:14 nospor

W linku co podałeś mamy też:
Tabela jest uporządkowanym zbiorem wartości. Opis tabeli rozpoczyna znak [ (lewy nawias kwadratowy) a kończy znak ] (prawy nawias kwadratowy). Poszczegóne wartości rozdialane są znakiem , (przecinek).
Czyli, żeby JSON był w takiej kolejności jaki ma być, to należy przekazywać mu dane w postaci tabeli a nie obiektu. Czyli u mnie to by miało być:
<?php
$ar = array('bla','ola','costam');
?>

Ale wówczas tracę informacje na temat indeksów. Należy więc wówczas indeksy przenieść do wartości, tworząc poprostu tablicę w wartościach. I to też jest w sumie dobre rozwiązanie problemu. Trzeba tylko o tym pamiętać.

2011-09-28 09:18 nospor

W zasadzie sądziłem, że gdy podaję indeksy numeryczne, to automatycznie jest tworzona tablica JSON a nie obiekt. Nie zwróciłem uwagi na to, że jednak taki JSON jest z { a nie [. Nauczka na przyszłość

2011-09-28 09:18 gość_B3k

Nie do końca zgadzam się z podanym rozwiązaniem i tezą problemu.

Niedawno też miałem identyczny problem, jednak musisz przyjrzeć się też funkcji json_encode(), która w przypadku tablic nieasocjacyjnych zwraca ci tablicę, która jest już zbiorem posortowanym wg. klucza. Aby wymusić na json_encode() aby zwracał zawsze obiekt należy użyć opcji JSON_FORCE_OBJECT.

2011-09-28 09:34 nospor

No właśnie nie. json_encode mi nic nie sortuje. Jak daję tak ono zwraca. dopiero decodowanie JSON w js powoduje sortowanie.

2011-09-28 09:48 gość_Bartek

Dodam jeszcze, że nie powinieneś używać konstrukcji for(elem in array) {...} do iterowania po elementach tablicy. Tej konstrukcji używaj tylko do iterowania po obiektach. Do iterowania po tablicy używaj: for(i, len = array.length; i < len; i++){...}. Źródło: http://javascript.crockford.com/code.html, sekcja: Statements -> for statement. Dlaczego tak? A no dlatego, że gdy dodasz sobie metodę do tablicy: Array.prototype.mojaWypasionaMetoda = function(){...} to może się zdarzyć, że w pętli for będziesz iterował również po tej metodzie, a tego byś nie chciał.

2011-09-28 10:01 nospor

Tak, wiem o tym. Ale ja nie dodaję metod do tablic
Poza tym problem który opisałeś równie dobrze może wystąpić w obiektach. Jak dodam metodę do obiektu to też w iteracji pojawi mi się raczej ta metoda.

2011-09-28 18:28 gość_B3k

No właśnie nie. json_encode mi nic nie sortuje. Jak daję tak ono zwraca. dopiero decodowanie JSON w js powoduje sortowanie.

Zgadza się, json_encode() nic nie sortuje. Ale jeśli przyjrzysz się działaniu tej funkcji to dowiesz się ,że wstawienie tablicy(PHP) nieasocjacyjnej do json_encode(), spowoduje że otrzymasz javascriptową tablicę - która już jest sortowana.

2011-09-28 18:30 gość_B3k

Nawiązując do mojego porpzedniego posta:
.. która już jest sortowana.

Oczywiście sortuje ją JavaScript po stronie przeglądarki.

2011-09-29 08:00 nospor

No tak, przecież już od paru postów była o tym mowa, a ty znowu o tym samym piszesz

Dodaj komentarz

 

Dostępne bbcode: b, u, i, url, code, php, css, html, sql, js

Ostatnio komentowane

  1. Pager 2.5.1 oraz EPa... Na szybko2
  2. Pager 2.5.1 oraz EPa... Sławek
  3. Mysql - FAQ Piotr
  4. Liczba dni roboczych Na szybko2
  5. Liczba dni roboczych Naszybko
  6. Klasa widoku nospor
  7. Klasa widoku freebox

Ostatnio na forum

  1. programista php-webm... pracamatysart
  2. Programista PHP/ Mag... Create Magento 2 Marketplace
  3. Baza Danych gosc
  4. Baza Danych YankeS
  5. Baza Danych gosc
  6. Baza Danych YankeS
  7. Problem z bazą danyc... Baza Danych

Skrypty użytkowników

  1. Klasa obsługi szablo... Lirdoner
  2. Sekcje user76
  3. Klasa walidująca for... user76
  4. Licznik Gości online korey
  5. Form Builder Comandeer
  6. Dynamiczny licznik z... korey
  7. Captcha Comandeer