Η εξέλιξη του WordPress από μια πλατφόρμα blogging σε ένα ολοκληρωμένο CMS, το μετατρέπει ταυτόχρονα σε ένα στέρεο πλαίσιο για τους προγραμματιστές να δημιουργήσουν εξαιρετικά έργα και εφαρμογές.

Ο πυρήνας του WordPress, εξουσιώνει όχι μόνο τη μηχανή δημοσίευσης των χρηστών αλλά και παρέχει στους προγραμματιστές ένα ισχυρό σύνολο κατηγοριών, API και βοηθών, που έχουν σχεδιαστεί για να καλύπτουν ένα ευρύ φάσμα αναγκών.

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

Το πεδίο του προβλήματος

Θα μπορούσαν να υπάρχουν διάφοροι λόγοι για να θέλεις να γράψεις τοπικά αρχεία στον κώδικα:

  • Καταγραφή συμβάντων ή λειτουργιών
  • Ανταλλαγή δεδομένων με συστήματα που δεν υποστηρίζονται από το WordPress
  • Αντιγράφων ασφαλείας

Ανεξάρτητα από τα κίνητρα, η γραφή τοπικών αρχείων από τον κώδικα PHP μπορεί να είναι μια επικίνδυνη λειτουργία. Τουλάχιστον δύο πολύ σημαντικές παγίδες θα πρέπει να λαμβάνονται υπόψη κατά την εφαρμογή αυτού για ένα WordPress θέμα, plugin ή προσαρμοσμένη εγκατάσταση:

  1. Ασφάλεια. Υπάρχει κίνδυνος λανθασμένης κατοχής αρχείων κατά την εγγραφή τοπικών αρχείων με κωδικό (από τον διακομιστή ιστού). Αυτό το πρόβλημα προκύπτει σε ανεπαρκώς διαμορφωμένα κοινόχρηστα περιβάλλοντα φιλοξενίας και μπορεί να οδηγήσει σε απώλεια ελέγχου των αρχείων.
  2. Συμβατότητα. Λόγω της ποικιλίας των εταιρειών φιλοξενίας εκεί έξω, η διαμόρφωση του συγκεκριμένου χρήστη είναι συνήθως άγνωστη στον προγραμματιστή. Έτσι, ο προγραμματιστής δεν μπορεί να είναι σίγουρος ότι τα δικαιώματα που απαιτούνται για μια λειτουργία γραφής είναι εφικτά από το χρήστη του plugin ή του θέματος.

Εάν ένα plugin του WordPress ή ένα θέμα που χρειάζεται να γράψει τοπικά αρχεία προορίζεται για δημόσια αποδέσμευση, ο προγραμματιστής θα πρέπει συνεχώς να φέρει αυτά τα θέματα στο μυαλό. Τα καλά νέα είναι ότι το ίδιο το WordPress έχει ήδη ένα εργαλείο για την αντιμετώπιση αυτών των προβλημάτων: το API του συστήματος αρχείων.

Εισαγωγή στο API του συστήματος αρχείων WordPress

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

Η λογική πίσω από το API είναι αρκετά απλή. προσπαθεί να γράψει απευθείας τοπικά αρχεία και σε περίπτωση λανθασμένης κατοχής αρχείων αλλάζει σε άλλη μέθοδο που βασίζεται σε FTP. Ανάλογα με τις διαθέσιμες βιβλιοθήκες PHP, βρίσκει έναν κατάλληλο τρόπο για να ρυθμίσετε μια σύνδεση FTP (μέσω υποδοχών επέκτασης ή over-SSH). Γενικά, τα παρακάτω βήματα απαιτούνται για την εργασία με τοπικά αρχεία:

Βήμα 1. Εντοπίστε ποια μέθοδο σύνδεσης είναι διαθέσιμη

Το WordPress χρησιμοποιεί το get_filesystem_method για να ανιχνεύσει τη διαθεσιμότητα των ακόλουθων μεθόδων (από την υψηλότερη προτεραιότητα στη χαμηλότερη) Direct, SSH2, FTP PHP Extension, FTP Sockets.

Βήμα 2. Λάβετε τα διαπιστευτήρια που απαιτούνται για τη μέθοδο που ανιχνεύθηκε

Εάν η ανιχνευθείσα μεταφορά έχει διαπιστευτήρια από έναν χρήστη, το WordPress χρησιμοποιεί τη λειτουργία request_filesystem_credentials για να εμφανίσει μια φόρμα αιτήματος. Η συνάρτηση έχει πολλές παραμέτρους που της επιτρέπουν να διατηρεί δεδομένα μεταξύ των υποβολών της φόρμας, να ζητάει πιστοποιήσεις αρκετές φορές αν η σύνδεση απέτυχε και να στοχεύσει σε έναν συγκεκριμένο κατάλογο μέσα στην εγκατάσταση του WordPress:

request_filesystem_credentials($form_post, $type, $error, $context, $extra_fields);

Παρέχοντας μια κενή παράμετρο τύπου $ στη λειτουργία θα μπορούσαμε να την αναγκάσουμε να εκτελέσει την ανίχνευση των διαθέσιμων μεθόδων σύνδεσης, γι 'αυτό θα ονομάσει το get_filesystem_method για μας. Ταυτόχρονα, μπορούμε να αναγκάσουμε τη συνάρτηση να χρησιμοποιήσει οποιοδήποτε συγκεκριμένο τύπο σύνδεσης καθορίζοντάς την χρησιμοποιώντας το όρισμα τύπου $.

Όταν δεν παρέχονται τα δεδομένα σύνδεσης που απαιτούνται από την επιλεγμένη μέθοδο, η λειτουργία εκτυπώνει τη φόρμα για να την ζητήσει:

Conneciton information

Μετά την πρώτη αίτηση, το WordPress αποθηκεύει το όνομα κεντρικού υπολογιστή FTP και το όνομα χρήστη στη βάση δεδομένων για μελλοντική χρήση, αλλά δεν αποθηκεύει τον κωδικό πρόσβασης. Εναλλακτικά, τα διαπιστευτήρια FTP θα μπορούσαν να καθοριστούν στο αρχείο wp-config.php χρησιμοποιώντας τις ακόλουθες σταθερές:

  • FTP_HOST - το όνομα κεντρικού υπολογιστή του διακομιστή για σύνδεση
  • FTP_USER - το όνομα χρήστη με το οποίο θα συνδεθείτε
  • FTP_PASS - τον κωδικό πρόσβασης για τη σύνδεση
  • FTP_PUBKEY - τη διαδρομή προς το δημόσιο κλειδί για σύνδεση SSH2
  • FTP_PRIKEY - τη διαδρομή προς το ιδιωτικό κλειδί για σύνδεση SSH2

Όταν αυτά τα δεδομένα αποθηκεύονται στο αρχείο wp-config.php, η φόρμα αίτησης διαπιστευτηρίων δεν εμφανίζεται, αλλά τα μειονεκτήματα ασφαλείας είναι σημαντικά και οι διαδικασίες ασφαλείας πρέπει να ελέγχονται τριπλάσια, με την μεγαλύτερη προσοχή που πρέπει να δοθεί στην ασφάλεια αυτού του αρχείου.

Βήμα 3. Αρχικοποιήστε την κλάση του συστήματος αρχείων WordPress και συνδεθείτε στο σύστημα αρχείων

Η καρδιά του API του WordPress Filesystem είναι η λειτουργία WP_Filesystem. Το σύστημα φορτώνει και αρχικοποιεί την κατάλληλη κλάση μεταφοράς, αποθηκεύει μια λαμβανόμενη παρουσία στο παγκόσμιο αντικείμενο $ wp_filesystem για περαιτέρω χρήση και προσπαθεί να συνδεθεί στο σύστημα αρχείων με τα παρεχόμενα διαπιστευτήρια:

WP_Filesystem($args, $context);

Βήμα 4. Χρησιμοποιήστε τις μεθόδους του συστήματος αρχείων WordPress για να εκτελέσετε λειτουργίες ανάγνωσης / εγγραφής

Ένα σωστά αρχικοποιημένο αντικείμενο $ wp_filesystem έχει ένα σύνολο μεθόδων επικοινωνίας με το τοπικό σύστημα αρχείων που θα μπορούσε να χρησιμοποιηθεί χωρίς περαιτέρω ανησυχία σχετικά με τον τύπο σύνδεσης. Συγκεκριμένα, υπάρχουν οι ακόλουθες κοινές μέθοδοι:

  • get_contents - διαβάζει το αρχείο σε μια συμβολοσειρά
  • put_contents - γράφει μια συμβολοσειρά σε ένα αρχείο
  • mkdir - δημιουργεί έναν κατάλογο
  • mdir - καταργεί έναν κατάλογο
  • wp_content_dir - επιστρέφει τη διαδρομή στο τοπικό σύστημα αρχείων στο φάκελο wp-content
  • wp_plugins_dir - επιστρέφει τη διαδρομή στο τοπικό σύστημα αρχείων στο φάκελο plugins
  • wp_themes_dir - επιστρέφει τη διαδρομή στο τοπικό σύστημα αρχείων στο φάκελο των θεμάτων

Κάνοντας όλα μαζί, ας βρούμε ένα παράδειγμα που εκτελεί τα παραπάνω βήματα σε μια απλή κατάσταση - θα γράψουμε κάποιο κείμενο που θα υποβληθεί σε textarea σε ένα απλό αρχείο .txt.

Σημειώστε ότι αυτό το παράδειγμα είναι για σκοπούς επίδειξης, σε μια κατάσταση πραγματικού κόσμου που δεν θα αποθηκεύσατε απλά δεδομένα κειμένου σε ένα αρχείο .txt, θα ήταν μια πολύ πιο ισχυρή λύση για την αποθήκευση στην βάση δεδομένων.

Το API του συστήματος αρχείων WordPress σε δράση

Ας τυλίξουμε τον κώδικα μας σε ένα ξεχωριστό plugin, στο οποίο θα διατεθεί ο δικός του φάκελος demo του συστήματος αρχείων. Αυτό μας παρέχει ένα φάκελο προορισμού για να αποθηκεύσετε το αρχείο .txt και να ελέγξετε τα δικαιώματα εγγραφής.

Πρώτα απ 'όλα, ας δημιουργήσουμε τη σελίδα επίδειξης για να εμφανίσετε τη φόρμα μας στο μενού Εργαλεία:

/*** Create Demo page (under Tools menu)***/add_action('admin_menu', 'filesystem_demo_page');function filesystem_demo_page() {add_submenu_page( 'tools.php', 'Filesystem API Demo page', 'Filesystem Demo', 'upload_files', 'filesystem_demo', 'filesystem_demo_screen' );}function filesystem_demo_screen() {$form_url = "tools.php?page=filesystem_demo";$output = $error = '';/*** write submitted text into file (if any)* or read the text from file - if there is no submission**/if(isset($_POST['demotext'])){//new submissionif(false === ($output = filesystem_demo_text_write($form_url))){return; //we are displaying credentials form - no need for further processing}  elseif (is_wp_error ($ output)) {$error = $output->get_error_message();$output = '';}  } else {// ανάγνωση από fileif (false === ($ output = filesystem_demo_text_read ($ form_url))) {επιστροφή;  // εμφανίζουμε τα διαπιστευτήρια που δεν χρειάζονται περαιτέρω επεξεργασία} elseif (is_wp_error ($ output)) {$error = $output->get_error_message();$output = '';}  } $ output = esc_textarea (έξοδος $).  // διαφυγή για εκτύπωση;> 

Σελίδα επίδειξης API συστήματος αρχείων

Όταν εμφανίζουμε τη σελίδα μας (filesystem_demo_screen) ελέγξουμε τη διαθεσιμότητα της υποβολής κειμένου. Αν υπάρχει, προσπαθούμε να το γράψουμε σε ένα αρχείο test.txt, αλλιώς προσπαθούμε να βρούμε ένα τέτοιο αρχείο στο φάκελο plugin και να διαβάσουμε το περιεχόμενό του για να συμπεριληφθεί στο textarea. Τέλος, εκτυπώνουμε μια βασική φόρμα για την εισαγωγή κειμένου. Για χάρη της αναγνωσιμότητάς τους, αυτές οι λειτουργίες γραφής και ανάγνωσης χωρίστηκαν στις δικές τους λειτουργίες.

Filesystem API demo

Για να αποφευχθεί η επανάληψη των ίδιων βημάτων αρχικοποίησης, δημιουργήθηκε ο κοινόχρηστος βοηθός. Καλεί πρώτα το request_filesystem_credentials να ανιχνεύσει τη διαθέσιμη μέθοδο σύνδεσης και να λάβει διαπιστευτήρια. Εάν αυτό ήταν επιτυχές, τότε καλεί το WP_Filesystem να ξεκινήσει το $ wp_filesystem με δεδομένα δεδομένα.

/*** Initialize Filesystem object** @param str $form_url - URL of the page to display request form* @param str $method - connection method* @param str $context - destination folder* @param array $fields - fileds of $_POST array that should be preserved between screens* @return bool/str - false on failure, stored text on success**/function filesystem_init($form_url, $method, $context, $fields = null) {global $wp_filesystem;/* first attempt to get credentials */if (false === ($creds = request_filesystem_credentials($form_url, $method, false, $context, $fields))) {/*** if we comes here - we don't have credentials* so the request for them is displaying* no need for further processing**/return false;}/* now we got some credentials - try to use them*/if (!WP_Filesystem($creds)) {/* incorrect connection data - ask for credentials again, now with error message */request_filesystem_credentials($form_url, $method, true, $context);return false;}return true; //filesystem object successfully initiated}

Το γράψιμο στον κώδικα αρχείου μοιάζει με αυτό:

/*** Perform writing into file** @param str $form_url - URL of the page to display request form* @return bool/str - false on failure, stored text on success**/function filesystem_demo_text_write($form_url){global $wp_filesystem;check_admin_referer('filesystem_demo_screen');$demotext = sanitize_text_field($_POST['demotext']); //sanitize the input$form_fields = array('demotext'); //fields that should be preserved across screens$method = ''; //leave this empty to perform test for 'direct' writing$context = WP_PLUGIN_DIR . '/filesystem-demo'; //target folder$form_url = wp_nonce_url($form_url, 'filesystem_demo_screen'); //page url with nonce valueif(!filesystem_init($form_url, $method, $context, $form_fields))return false; //stop further processign when request form is displaying/** now $wp_filesystem could be used* get correct target file first**/$target_dir = $wp_filesystem->find_folder($context);$target_file = trailingslashit($target_dir).'test.txt';/* write into file */if(!$wp_filesystem->put_contents($target_file, $demotext, FS_CHMOD_FILE))return new WP_Error('writing_error', 'Error when writing file'); //return error objectreturn $demotext;}

Σε αυτό το μέρος ορίσαμε κάποιες απαραίτητες παραμέτρους:

  • $ demotext - υποβάλλεται κείμενο για εγγραφή
  • $ form_fields - στοιχείο στη συστοιχία $ _POST που αποθηκεύει το κείμενό μας και πρέπει να διατηρηθεί
  • $ μέθοδος - μέθοδος μεταφοράς, αφήνουμε κενό για να ανιχνεύσουμε αυτόματα
  • $ context - φάκελος στόχος (το plugin είναι ένα)

Μετά από αυτό ξεκινήσαμε το παγκόσμιο αντικείμενο $ wp_filesystem χρησιμοποιώντας τη λειτουργία helper που περιγράψαμε προηγουμένως. Σε περίπτωση επιτυχίας εντοπίζουμε τη σωστή διαδρομή προς το φάκελο προορισμού και γράφουμε το κείμενο που υποβλήθηκε σε αυτό χρησιμοποιώντας τη μέθοδο put_contents του αντικειμένου $ wp_filesystem.

Ο κώδικας ανάγνωσης από το αρχείο μοιάζει με αυτόν τον τύπο:

/*** Read text from file** @param str $form_url - URL of the page where request form will be displayed* @return bool/str - false on failure, stored text on success**/function filesystem_demo_text_read($form_url){global $wp_filesystem;$demotext = '';$form_url = wp_nonce_url($form_url, 'filesystem_demo_screen');$method = ''; //leave this empty to perform test for 'direct' writing$context = WP_PLUGIN_DIR . '/filesystem-demo'; //target folderif(!filesystem_init($form_url, $method, $context))return false; //stop further processing when request forms displaying/** now $wp_filesystem could be used* get correct target file first**/$target_dir = $wp_filesystem->find_folder($context);$target_file = trailingslashit($target_dir).'test.txt';/* read the file */if($wp_filesystem->exists($target_file)){ //check for existence$demotext = $wp_filesystem->get_contents($target_file);if(!$demotext)return new WP_Error('reading_error', 'Error when reading file'); //return error object}return $demotext;}

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

συμπέρασμα

Όταν εργάζεστε με τοπικά αρχεία, ένας προγραμματιστής θεμάτων WordPress ή plugins θα έρθει σε επαφή με ζητήματα ασφάλειας και συμβατότητας, θέτοντας τεράστια πίεση στην ομάδα και προσθέτοντας πολλές ώρες στον κύκλο ζωής του έργου. Βασιζόμενοι στο API του συστήματος αρχείων, αυτά τα προβλήματα μπορούν να προχωρήσουν με τρόπο αποτελεσματικό. Έτσι, την επόμενη φορά που θα βρεθείτε εγγράφως σε κώδικα του plugin σας, θεωρήστε αυτή την εναλλακτική λύση την πιο υγιεινή επιλογή.

Μπορείς κατεβάστε εδώ μια επίδειξη αυτού του κώδικα , και να την προσαρμόσετε στις ανάγκες σας.