Σχετικά με την JSON
Εισαγωγή στην JSON
Σήμερα θα μιλήσουμε για το format ανταλλαγής δεδομένων JSON, το οποίο μπορεί κάλλιστα να αντικαταστήσει την XML σε διάφορες χρήσεις.
JSON σημαίνει JavaScript Object Notation και είναι ένα format μορφοποιήσεις δεδομένων σε javascript.
Το format του είναι εξωφρενικά απλό και τυποποιημένο. Έχει απλή ιεραρχική μορφή, ανεξάρτητη από την γλώσσα ή την πλατφόρμα.
Η JSON προσφέρεται ως εναλλακτική λύση στην XML. Φυσικά να αντικαταστήσει την XML 100% δεν μπορεί διότι δεν υποστηρίζει schema validation, δεν μπορεί από μόνη της να ενημερώσει σχετικά με την κωδικοποίησή της και δεν έχει την έννοια των attributes, αλλά όπου αυτά τα ελαττώματα μπορούν να αγνοηθούν η αντικατάσταση θα είναι πολύ εύκολη. Όπως και η XML, η JSON έχει self-documentated format που περιγράφει την δομή των δεδομένων και δεν ασχολείται με την παρουσίασή τους.
Σύγκριση με την XML
Γιατί χρειαζόμαστε ένα νέο format, όταν υπάρχει XML, ρωτάτε;
Το κυριότερο πλεονέκτημα της JSON πάνω στην XML είναι ότι είναι συμπαγές.
Στα πλαίσια του web έχει άλλο ένα πλεονέκτημα: έχει 100% valid JavaScript κώδικα και είναι πολύ εύκολο να το μετατρέψετε από κείμενο σε δεδομένα JavaScript, και οι εργασίες με τις δομές είναι πιο εύκολες και άνετες από την αδέξια, αν και καθολική DOM (Document Object Mode).
Για λόγους σαφήνειας ας εξετάσουμε το ακόλουθο παράδειγμα: σύνολο δομών που αποτελούνται από id και όνομα
XML:
<people> <record> <id>1</id> <surname>Παπανδρέου</surname> <firstname>Γεώργιος </firstname> <patronym>Ανδρέου</patronym> </record> <record> <id>2</id> <surname>Καραμανλής </surname> <firstname>Κωνσταντίνος</firstname> <patronym>Αλεξάνδρου </patronym> </record> </people>
JSON:
[
{
id: 1,
surname: "Παπανδρέου",
firstname: "Γεώργιος ",
patronym: "Ανδρέου"
},
{
id: 2,
surname: "Καραμανλής ",
firstname: "Κωνσταντίνος",
patronym: "Αλεξάνδρου "
}
]Μια γρήγορη ματιά είναι αρκετή για να εξαχθούν συμπεράσματα: πρώτον η JSON είναι πιο συμπαγής, δεύτερον είναι ευκολότερη στο διάβασμα και τρίτων πιο κατατοπιστική επειδή η απαρίθμηση(arrays) και οι ιδιότητες(objects) περιορίζονται με διαφόρων ειδών παρενθέσεων.
Ας πιέσουμε λίγο ακόμα στο μικρο μέγεθος(συμπαγές) και ας προσπαθήσουμε να ξαναγράψουμε το ίδιο πράγμα ξανά, αλλά λίγο μικρότερο.
XML:
<people> <record><id>1</id><surname>Παπανδρέου</surname> <firstname>Γεώργιος </firstname> <patronym>Ανδρέου</patronym></record> <record><id>2</id><surname>Καραμανλής </surname> <firstname>Κωνσταντίνος</firstname> <patronym>Αλεξάνδρου </patronym></record> </people>
JSON:
[
{id:1,surname:"Παπανδρέου",firstname:"Γεώργιος ",patronym:"Ανδρέου"},
{id:2,surname:"Καραμανλής ",firstname:"Κωνσταντίνος",patronym:"Αλεξάνδρου "}
]Ας εξετάσουμε τώρα τα μειονεκτήματα της JSON και να δούμε αν είναι τόσο κρίσιμα και πως να τα παρακάμψουμε.
Ορίστε:
- Δεν υποστηρίζει schema validation
- Δεν μπορεί από μόνη της να ενημερώσει σχετικά με την κωδικοποίησή της
- Δεν έχει την έννοια των attributes
Η ανάγκη του schema validation είναι μάλλον αμφίβολη, δεδομένου οτι ακόμη και στην XML σπάνια το χρησιμοποιούν. Οπότε θα το θεωρήσουμε ως περιορισμό.
Ο client και ο server θα πρέπει να συμφωνήσουν εκ των προτέρων για την δομή των δεδομένων. (σημειώστε ότι η JSON όπως και η XML εύκολα βιώνουν την ανάδειξη νέων πεδίων)
Η αδυναμία να δηλώσει την κωδικοποίηση του εγγράφου αντισταθμίζεται με τρεις τρόπους:
- Το πρότυπο RFC4627 απαιτεί την κωδικοποίηση της JSON μόνο σε Unincode. Η default κωδικοποίηση είναι UTF-8 και επιτρέπετε ακόμα οι UTF-16 και UTF-32 σε μια ποικιλία της BE Και LE (byte order). Ο τύπος της κωδικοποιήσεις καθορίζετε από τον parser αυτόματα με βάση τα 4 πρώτα byte.
- Μπορείτε να χρησιμοποιήσετε μόνο ASCII, και όλες τις άλλες κωδικοποιήσεις να τις παρουσιάζετε σε μορφή escape-sequence: \xXX για 8bit κωδικοποιήσεις και \uXXXX για Unicode, όπου X – ένα δεκαεξαδικό ψηφίο. Αυτός ο τρόπος είναι άβολος επειδή αυξάνει το μέγεθος του κείμενο 3-4 φορές.
- Βασικά, αν δεν ακολουθούμε το πρότυπο, μπορούμε να χρησιμοποιήσουμε οποιαδήποτε κωδικοποίηση: είτε με προηγούμενη συμφωνία μεταξύ client και server ή να βασιστούμε στις ικανότητες κάποιας βιβλιοθήκης του client και το πρωτόκολλο, καθορίζοντας την κωδικοποίηση στο header. Για παράδειγμα σε HTTP
Content-Type: application/json; charset=windows-1251
Default δυνατότητες της PHP
Για πολύ καιρό η PHP δεν είχε την δυνατότητα να δουλέψει με την JSON (υπήρχε όμως στις βιβλιοθήκη PECL).
Από την έκδοση 5.2.0, την βιβλιοθήκη PECL json την ενσωμάτωσαν στον κύριο κώδικα. Ας δούμε τι μπορεί τώρα η PHP
- Να μετατρέπει PHP objects και arrays σε JSON – json_encode()
- Να δημιουργεί PHP objects και arrays από την JSON – json_decode()
Το API είναι πολύ απλό. Αλλά υπάρχει ένα μειονέκτημα το οποίο αναιρεί το κύριο πλεονέκτημα της JSON, το μικρό μέγεθος.
Αυτό είναι επειδη αυτές οι λειτουργίες δουλεύουν μόνο με την UTF-8 και κωδικοποιουν όλους τους χαρακτήρες με την μορφή \uXXXX
κάτι που αυξάνει τον όγκο που καταλαμβάνει το κείμενο περίπου 3 φορές. Και δεν υπάρχει τρόπος να αρνηθούμε από αυτήν την κωδικοποίηση.
Ας προσπαθήσουμε να λύσουμε αυτό το πρόβλημα. Το πρώτο πράγμα που έρχεται στο μυαλό είναι να επιστρέψουμε τα \uXXXX σε δυαδική μορφή. Αλλά αυτή η προσέγγιση έχει ένα μειονέκτημα: αν το αρχικό αντικείμενο του string το οποίο θα κωδικοποιηθεί μέσω της json_encode() περιέχει κείμενο σε μορφή \uXXXX τότε αυτό θα παραμορφωθεί.
Για παράδειγμα:
\u0021
μετά το json_encode() θα γίνει
\\u0021
και μετά την “λύση” μας θα γίνει:
\!
Φτιαχνωντας μια JSON Handler Function
Έγραψα έναν δικό μου κωδικοποιητή, ο οποίος λειτουργεί σύμφωνα με το πρότυπο και δεν κάνει τίποτα επιπλέον,που το πρότυπο δεν απαιτεί. Ο κώδικας λειτουργεί μόνο με την PHP5+
function to_json(array $data) { $isArray = true; $keys = array_keys($data); $prevKey = -1; // Πρέπει να καταλάβουμε τι έχουμε, λίστα ή associative array foreach ($keys as $key) if (!is_numeric($key) || $prevKey + 1 != $key) { $isArray = false; break; } else $prevKey++; unset($keys); $items = array(); foreach ($data as $key => $value) { $item = (!$isArray ? "\"$key\":" : ''); if (is_array($value)) $item .= to_json($value); elseif (is_null($value)) $item .= 'null'; elseif (is_bool($value)) $item .= $value ? 'true' : 'false'; elseif (is_string($value)) $item .= '"' . preg_replace( '%([\\x00-\\x1f\\x22\\x5c])%e', 'sprintf("\\\\u%04X", ord("$1"))', $value ) . '"'; elseif (is_numeric($value)) $item .= $value; else throw new Exception('Wrong argument.'); $items[] = $item; } return ($isArray ? '[' : '{') . implode(',', $items) . ($isArray ? ']' : '}'); }
Το αποτέλεσμα του to_json() χωρίς κανένα πρόβλημα μπορεί δοθεί στην json_decode().
Αυτό ήταν, ευχαριστώ για την προσοχή.
Κάνουμε Like,tweet,+1 και ότι άλλο σκεφτείτε.
Όλα αυτά ενθαρρύνουν εμένα και τους υπόλοιπους συγγραφείς να συνεχίσουμε να γράφουμε.





Γίνετε επεξεργασία, Παρακαλώ περιμένετε...









Κανενα σχολιο