Συνεδρίες
Το HTTP είναι ένα πρωτόκολλο χωρίς κατάσταση, αλλά σχεδόν κάθε εφαρμογή χρειάζεται να διατηρεί κατάσταση μεταξύ των αιτήσεων, π.χ. το περιεχόμενο ενός καλαθιού αγορών. Γι' αυτό το σκοπό χρησιμοποιείται η σύνοδος. Ας δούμε
- πώς να χρησιμοποιήσετε συνεδρίες
- πώς να αποφύγετε συγκρούσεις ονομάτων
- πώς να ορίσετε τη λήξη
Όταν χρησιμοποιείτε συνεδρίες, κάθε χρήστης λαμβάνει ένα μοναδικό αναγνωριστικό που ονομάζεται αναγνωριστικό συνεδρίας, το οποίο περνάει σε ένα cookie. Αυτό χρησιμεύει ως κλειδί για τα δεδομένα της συνεδρίας. Σε αντίθεση με τα cookies, τα οποία αποθηκεύονται στην πλευρά του προγράμματος περιήγησης, τα δεδομένα συνόδου αποθηκεύονται στην πλευρά του διακομιστή.
Διαμορφώνουμε τη σύνοδο στη διαμόρφωση, η επιλογή του χρόνου λήξης είναι σημαντική.
Η διαχείριση της συνεδρίας γίνεται από το αντικείμενο Nette\Http\Session, το οποίο λαμβάνετε
περνώντας το με τη χρήση dependency injection.
Στους παρουσιαστές απλά καλούμε το $session = $this->getSession()
.
Έναρξη συνεδρίας
Από προεπιλογή, η Nette θα ξεκινήσει αυτόματα μια συνεδρία τη στιγμή που
θα αρχίσουμε να διαβάζουμε από αυτήν ή να γράφουμε δεδομένα σε αυτήν.
Για να ξεκινήσετε χειροκίνητα μια σύνοδο, χρησιμοποιήστε το
$session->start()
.
Η PHP στέλνει επικεφαλίδες HTTP που επηρεάζουν την προσωρινή αποθήκευση κατά την έναρξη της συνεδρίας, βλέπε session_cache_limiter, και ενδεχομένως ένα cookie με το αναγνωριστικό συνεδρίας. Επομένως, είναι πάντα απαραίτητο να ξεκινάτε τη σύνοδο πριν στείλετε οποιαδήποτε έξοδο στο πρόγραμμα περιήγησης, διαφορετικά θα εκπέμπεται μια εξαίρεση. Επομένως, αν γνωρίζετε ότι μια σύνοδος θα χρησιμοποιηθεί κατά την απόδοση της σελίδας, ξεκινήστε την χειροκίνητα πριν, για παράδειγμα στον παρουσιαστή.
Στη λειτουργία προγραμματιστή, το Tracy εκκινεί τη σύνοδο επειδή τη χρησιμοποιεί για να εμφανίζει τις μπάρες ανακατεύθυνσης και αιτήσεων AJAX στη γραμμή Tracy.
Τμήμα
Στην καθαρή PHP, η αποθήκευση δεδομένων συνόδου υλοποιείται ως πίνακας
προσβάσιμος μέσω μιας παγκόσμιας μεταβλητής $_SESSION
. Το πρόβλημα
είναι ότι οι εφαρμογές συνήθως αποτελούνται από έναν αριθμό
ανεξάρτητων τμημάτων, και αν όλα έχουν μόνο έναν ίδιο πίνακα διαθέσιμο,
αργά ή γρήγορα θα συμβεί σύγκρουση ονομάτων.
Το Nette Framework λύνει το πρόβλημα χωρίζοντας ολόκληρο το χώρο σε τμήματα (αντικείμενα Nette\Http\SessionSection). Κάθε μονάδα χρησιμοποιεί τότε το δικό της τμήμα με ένα μοναδικό όνομα και δεν μπορούν να προκύψουν συγκρούσεις.
Παίρνουμε το τμήμα από τον διαχειριστή συνόδου:
$section = $session->getSection('unique name');
Στον παρουσιαστή αρκεί να καλέσουμε το getSession()
με την
παράμετρο:
// $this is Presenter
$section = $this->getSession('unique name');
Η ύπαρξη του τμήματος μπορεί να ελεγχθεί με τη μέθοδο
$session->hasSection('unique name')
.
Το ίδιο το τμήμα είναι πολύ εύκολο να δουλέψει κανείς με τις μεθόδους
set()
, get()
και remove()
:
// γράψιμο μεταβλητών
$section->set('userName', 'franta');
// ανάγνωση μιας μεταβλητής, επιστρέφει null αν δεν υπάρχει
echo $section->get('userName');
// αφαίρεση μεταβλητής
$section->remove('userName');
Είναι δυνατόν να χρησιμοποιήσετε τον κύκλο foreach
για να λάβετε
όλες τις μεταβλητές από το τμήμα:
foreach ($section as $key => $val) {
echo "$key = $val";
}
Πώς να ορίσετε τη λήξη
Η λήξη μπορεί να οριστεί για μεμονωμένα τμήματα ή ακόμη και για μεμονωμένες μεταβλητές. Μπορούμε να αφήσουμε τη σύνδεση του χρήστη να λήξει σε 20 λεπτά, αλλά να θυμόμαστε ακόμα τα περιεχόμενα ενός καλαθιού αγορών.
// η ενότητα θα λήξει μετά από 20 λεπτά
$section->setExpiration('20 minutes');
Η τρίτη παράμετρος της μεθόδου set()
χρησιμοποιείται για τον
ορισμό της λήξης μεμονωμένων μεταβλητών:
// η μεταβλητή 'flash' λήγει μετά από 30 δευτερόλεπτα
$section->set('flash', $message, '30 seconds');
Θυμηθείτε ότι ο χρόνος λήξης ολόκληρης της συνεδρίας (βλ. διαμόρφωση συνεδρίας) πρέπει να είναι ίσος ή μεγαλύτερος από τον χρόνο που έχει οριστεί για μεμονωμένα τμήματα ή μεταβλητές.
Η ακύρωση της λήξης που έχει οριστεί προηγουμένως μπορεί να
επιτευχθεί με τη μέθοδο removeExpiration()
. Η άμεση διαγραφή ολόκληρου
του τμήματος θα εξασφαλιστεί με τη μέθοδο remove()
.
Γεγονότα $onStart, $onBeforeWrite
Το αντικείμενο Nette\Http\Session
έχει γεγονότα $onStart
a $onBeforeWrite
,
έτσι ώστε να μπορείτε να προσθέσετε callbacks που καλούνται μετά την έναρξη
της συνεδρίας ή πριν αυτή εγγραφεί στο δίσκο και στη συνέχεια
τερματιστεί.
$session->onBeforeWrite[] = function () {
// εγγραφή δεδομένων στη σύνοδο
$this->section->set('basket', $this->basket);
};
Διαχείριση συνόδου
Επισκόπηση των μεθόδων της κλάσης Nette\Http\Session
για τη διαχείριση
συνόδου:
start(): void
Ξεκινά μια συνεδρία.
isStarted(): bool
Ξεκίνησε η συνεδρία;
close(): void
Τερματίζει τη συνεδρία. Η συνεδρία τερματίζεται αυτόματα με το τέλος της δέσμης ενεργειών.
destroy(): void
Τερματίζει και διαγράφει τη συνεδρία.
exists(): bool
Περιέχει η αίτηση HTTP ένα cookie με αναγνωριστικό συνεδρίας;
regenerateId(): void
Δημιουργεί ένα νέο τυχαίο αναγνωριστικό συνεδρίας. Τα δεδομένα παραμένουν αμετάβλητα.
getId(): string
Επιστρέφει το αναγνωριστικό συνεδρίας.
Διαμόρφωση
Διαμορφώνουμε τη σύνοδο στη διαμόρφωση. Αν γράφετε μια εφαρμογή που δεν χρησιμοποιεί ένα DI container, χρησιμοποιήστε αυτές τις μεθόδους για να τη διαμορφώσετε. Πρέπει να κληθούν πριν από την έναρξη της συνεδρίας.
setName(string $name): static
Ορίζει το όνομα του cookie που χρησιμοποιείται για τη μετάδοση του
αναγνωριστικού συνεδρίας. Το προεπιλεγμένο όνομα είναι PHPSESSID
.
Αυτό είναι χρήσιμο εάν εκτελείτε πολλές διαφορετικές εφαρμογές στον
ίδιο ιστότοπο.
getName(): string
Επιστρέφει το όνομα του cookie συνεδρίας.
setOptions(array $options): static
Διαμορφώνει τη σύνοδο. Είναι δυνατόν να οριστούν όλες οι οδηγίες συνόδου PHP (σε μορφή camelCase,
π.χ. γράψτε savePath
αντί για session.save_path
) και επίσης readAndClose.
setExpiration(?string $time): static
Ορίζει το χρόνο αδράνειας μετά τον οποίο λήγει η σύνοδος.
setCookieParameters(string $path, ?string $domain=null, ?bool $secure=null, ?string $samesite=null): static
Ορίζει παραμέτρους για τα cookies. Μπορείτε να αλλάξετε τις προεπιλεγμένες τιμές των παραμέτρων στο configuration.
setSavePath(string $path): static
Ορίζει τον κατάλογο όπου αποθηκεύονται τα αρχεία συνεδρίας.
setHandler(\SessionHandlerInterface $handler): static
Ορίζει προσαρμοσμένο χειριστή, βλ. τεκμηρίωση PHP.
Πρώτα η ασφάλεια
Ο διακομιστής θεωρεί ότι επικοινωνεί με τον ίδιο χρήστη εφόσον οι αιτήσεις περιέχουν το ίδιο αναγνωριστικό συνεδρίας. Το καθήκον των μηχανισμών ασφαλείας είναι να διασφαλίσουν ότι αυτή η συμπεριφορά λειτουργεί πραγματικά και ότι δεν υπάρχει δυνατότητα αντικατάστασης ή κλοπής ενός αναγνωριστικού.
Γι' αυτό το λόγο το Nette Framework ρυθμίζει κατάλληλα τις οδηγίες της PHP ώστε να μεταφέρει το αναγνωριστικό συνόδου μόνο σε cookies, να αποφεύγεται η πρόσβαση από JavaScript και να αγνοούνται τα αναγνωριστικά στη διεύθυνση URL. Επιπλέον, σε κρίσιμες στιγμές, όπως η είσοδος του χρήστη, δημιουργεί ένα νέο αναγνωριστικό συνεδρίας.
Η συνάρτηση ini_set χρησιμοποιείται για τη διαμόρφωση της PHP, αλλά δυστυχώς η χρήση της απαγορεύεται σε ορισμένες υπηρεσίες φιλοξενίας ιστοσελίδων. Αν είναι η περίπτωσή σας, προσπαθήστε να ζητήσετε από τον πάροχο φιλοξενίας σας να σας επιτρέψει αυτή τη λειτουργία ή τουλάχιστον να ρυθμίσει σωστά τον διακομιστή του.