SafeStream: ασφαλής πρόσβαση σε αρχεία

Το Nette SafeStream εγγυάται ότι κάθε ανάγνωση και εγγραφή σε αρχείο πραγματοποιείται απομονωμένα. Αυτό σημαίνει ότι κανένα νήμα δεν θα αρχίσει να διαβάζει ένα αρχείο που δεν έχει γραφτεί πλήρως ακόμα, ή πολλαπλά νήματα δεν θα αντικαθιστούν το ίδιο αρχείο.

Εγκατάσταση:

composer require nette/safe-stream

Σε τι χρησιμεύει;

Σε τι χρησιμεύουν οι απομονωμένες λειτουργίες στην πραγματικότητα; Ας ξεκινήσουμε με ένα απλό παράδειγμα που γράφει επανειλημμένα σε ένα αρχείο και στη συνέχεια διαβάζει το ίδιο string από αυτό:

$s = str_repeat('Long String', 10000);

$counter = 1000;
while ($counter--) {
	file_put_contents('file', $s); // γράψε το
	$readed = file_get_contents('file'); // διάβασε το
	if ($s !== $readed) { // έλεγξε το
		echo 'τα strings διαφέρουν!';
	}
}

Μπορεί να φαίνεται ότι η κλήση echo 'τα strings διαφέρουν!' δεν μπορεί ποτέ να συμβεί. Το αντίθετο ισχύει. Δοκιμάστε επίτηδες να εκτελέσετε αυτό το script σε δύο καρτέλες του προγράμματος περιήγησης ταυτόχρονα. Το σφάλμα θα εμφανιστεί πρακτικά αμέσως.

Μία από τις καρτέλες θα διαβάσει το αρχείο τη στιγμή που η άλλη δεν έχει προλάβει να το γράψει ολόκληρο, οπότε το περιεχόμενο δεν θα είναι πλήρες.

Ο παραπάνω κώδικας λοιπόν δεν είναι ασφαλής αν εκτελείται πολλές φορές ταυτόχρονα (δηλαδή σε πολλαπλά νήματα). Κάτι που στο διαδίκτυο δεν είναι καθόλου ασυνήθιστο, συχνά ο διακομιστής απαντά σε μεγάλο αριθμό χρηστών ταυτόχρονα. Έτσι, η εξασφάλιση ότι η εφαρμογή σας λειτουργεί αξιόπιστα ακόμα και όταν εκτελείται σε πολλαπλά νήματα (thread-safe) είναι πολύ σημαντική. Διαφορετικά, θα υπάρξει απώλεια δεδομένων και εμφάνιση δύσκολα εντοπίσιμων σφαλμάτων.

Όπως βλέπετε όμως, οι εγγενείς συναρτήσεις PHP για ανάγνωση και εγγραφή αρχείων δεν είναι απομονωμένες και ατομικές.

Πώς να χρησιμοποιήσετε το SafeStream;

Το SafeStream δημιουργεί ένα ασφαλές πρωτόκολλο μέσω του οποίου μπορείτε να διαβάζετε και να γράφετε αρχεία απομονωμένα χρησιμοποιώντας τυπικές συναρτήσεις PHP. Αρκεί να αναφέρετε το nette.safe:// πριν από το όνομα του αρχείου:

file_put_contents('nette.safe://file', $s);
$s = file_get_contents('nette.safe://file');

Το SafeStream εξασφαλίζει ότι μόνο ένα νήμα μπορεί να γράφει στο αρχείο τη φορά. Τα άλλα νήματα περιμένουν στην ουρά. Αν κανένα νήμα δεν γράφει, οποιοσδήποτε αριθμός νημάτων μπορεί να διαβάζει το αρχείο παράλληλα.

Με το πρωτόκολλο μπορείτε να χρησιμοποιείτε όλες τις κοινές συναρτήσεις PHP, για παράδειγμα:

// το 'r' σημαίνει άνοιγμα μόνο για ανάγνωση
$handle = fopen('nette.safe://file.txt', 'r');

$ini = parse_ini_file('nette.safe://translations.neon');
έκδοση: 3.0