Utvecklingen av WordPress från en bloggplattform till ett heltäckande CMS, samtidigt som det blir en solid ram för utvecklare att bygga utestående projekt och applikationer på.
WordPress-kärnan driver inte bara användarnas förlagsmotor utan ger också utvecklare en robust uppsättning klasser, API och hjälpare, utformade för att tillgodose ett brett utbud av behov.
En av de dolda pärlorna i WordPress som tillåter utvecklare att utföra operationer med det lokala filsystemet på ett säkert och robust sätt är WordPress Filesystem API. Den sammanfattar filmanipuleringsfunktionalitet i en uppsättning vanligt förekommande metoder så att de kan användas säkert i olika värdmiljöer.
Det kan finnas flera skäl att vilja skriva lokala filer i kod:
Oavsett motivationen kan det vara en riskabel skrivning av lokala filer från PHP-kod. Minst två väldigt viktiga fallgropar bör beaktas vid implementering av detta för ett WordPress-tema, plugin eller anpassad installation:
Om ett WordPress-plugin eller ett tema som behöver skriva lokala filer är avsett för offentliggörande, bör utvecklaren ständigt bära dessa problem i åtanke. Den goda nyheten är att WordPress själv redan har ett verktyg för att lösa dessa problem: Filsystem API.
Filsystemet API läggs till i WordPress i version 2.6 för att aktivera WordPress egna uppdateringsfunktion. Den sammanfattar den funktionalitet som behövs för att utföra läs- / skrivoperationer på ett säkert sätt och på en mängd olika värdtyper. Den består av en uppsättning klasser och låter dig automatiskt välja rätt sätt att ansluta till det lokala filsystemet, beroende på individuell värdinställning.
Logiken bakom API: n är ganska enkel; Det försöker skriva lokala filer direkt och om det är felaktigt filinnehåll växlar det till en annan FTP-baserad metod. Beroende på tillgängliga PHP-bibliotek hittar den ett lämpligt sätt att konfigurera en FTP-anslutning (via uttagskontakter eller över SSH). Vanligtvis krävs följande steg för att arbeta med lokala filer:
WordPress använder get_filesystem_method för att upptäcka tillgängligheten av följande metoder (från högsta prioritet till lägsta) Direkt, SSH2, FTP PHP Extension, FTP Sockets.
Om den upptäckta transporten behöver legitimationsuppgifter från en användare använder WordPress funktionen request_filesystem_credentials för att visa ett förfrågningsformulär. Funktionen har ett antal parametrar som gör det möjligt att bevara data mellan formulärinsändningar, be om inloggningsuppgifter flera gånger om anslutningen misslyckades och rikta in på en viss katalog i WordPress-installationen:
request_filesystem_credentials($form_post, $type, $error, $context, $extra_fields);
Genom att leverera en tom $ typparameter till funktionen kunde vi tvinga den att utföra detektering av tillgängliga anslutningsmetoder, så det skulle kallas get_filesystem_method för oss. Samtidigt kan vi tvinga funktionen att använda en viss anslutningstyp genom att ange den med argumentet $ type.
När anslutningsdata som krävs enligt den valda metoden inte anges, skriver funktionen formuläret för att begära det:
Efter den första förfrågan lagrar WordPress FTP-värdnamnet och användarnamnet i databasen för framtida användning, men det lagrar inte lösenordet. Alternativt kan FTP-uppgifter anges i wp-config.php-filen med hjälp av följande konstanter:
FTP_HOST
- värdnamnet på servern för att ansluta till FTP_USER
- användarnamnet att ansluta till FTP_PASS
- lösenordet att ansluta till FTP_PUBKEY
- sökvägen till den allmänna nyckeln som ska användas för SSH2-anslutning FTP_PRIKEY
- sökvägen till den privata nyckeln som ska användas för SSH2-anslutning När denna data lagras i wp-config.php-filen visas inte formuläret för inlämningsuppgifter, men säkerhetsnätena är signifikanta och säkerhetsförfarandena ska triple-checkas med den högsta uppmärksamhet som är möjlig bör betalas till säkerheten för den här filen.
Hjärtat i WordPress Filesystem API är funktionen WP_Filesystem. Den laddar och initialiserar lämplig transportklass, lagrar en erhållen instans i det globala $ wp_filesystemobjektet för vidare användning och försöker ansluta till filsystemet med de angivna referenserna:
WP_Filesystem($args, $context);
Ett korrekt initierat $ wp_filesystemobjekt har en uppsättning metoder för att kommunicera med det lokala filsystemet som kan användas utan ytterligare ångest om anslutningstyp. I synnerhet följer följande vanliga metoder:
Om vi sammanfattar det, låt oss komma fram med ett exempel som utför ovanstående steg i en enkel situation - vi kommer att skriva lite text som skickas i en textarea till en vanlig .txt-fil.
Observera att det här exemplet är för demonstrationsändamål, i en verklig situation skulle du inte lagra enkel textdata i en .txt-fil, det skulle vara en mycket mer robust lösning för att lagra den i databasen istället.
Låt oss paketera vår kod i en separat plugin, som kommer att tilldelas en egen filsystem-demo-mapp. Det ger oss en målmapp för att lagra .txt-filen och kontrollera skrivbehörigheter.
Låt oss först skapa demoversidan för att visa vår form under Verktyg-menyn:
/*** 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 = '';} } annat {// läs från filenif (false === ($ output = filesystem_demo_text_read ($ form_url))) {return; // vi visar uppgiften bildar inget behov av vidare bearbetning} elseif (is_wp_error ($ output)) {$error = $output->get_error_message();$output = '';} } $ output = esc_textarea ($ output); // flyr för utskrift?> Demosidan för filsystem API
När vi visar vår sida (filesystem_demo_screen) kontrollerar vi om det finns tillgång till textinsändning. Om det existerar försöker vi skriva det i en test.txt-fil, annars försöker vi hitta en sådan fil i plugin-mappen och läsa innehållet som ska ingå i textområdet. Slutligen skriver vi ut en grundläggande form för att skriva in text. För läsbarhetens skull separerades dessa skriv- och läsoperationer i sina egna funktioner.
För att undvika dubbelarbete av samma initialiseringssteg har den delade hjälpen skapats. Det kallar request_filesystem_credentials först för att upptäcka den tillgängliga anslutningsmetoden och få inloggningsuppgifter. Om det lyckades kallas då WP_Filesystem för att initiera $ wp_filesystem med givna data.
/*** 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}
Skrivning till filkod ser så här ut:
/*** 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;}
I denna del definierade vi några nödvändiga parametrar:
Därefter initierade vi det globala $ wp_filesystemobjektet med hjälp av hjälparfunktionen som jag beskrivit tidigare. I händelse av framgång upptäcker vi den korrekta sökvägen till målmappen och skriver in den inlämnade texten i den med hjälp av put_contents-metoden för $ wp_filesystem-objektet.
Koden för läsning från filen ser så här ut:
/*** 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;}
Den här funktionen fungerar på samma sätt som tidigare beskrivits, men den använder get_contents för att läsa från målfilen.
När du arbetar med lokala filer kommer en WordPress-teman eller plugins-utvecklare att komma i kontakt med säkerhets- och kompatibilitetsproblem, vilket ger enorm stress på laget och lägger till långa timmar i projektets livscykel. Genom att förlita sig på Filsystem API kan dessa problem sidoprovas på ett effektivt sätt. Så nästa gång du befinner dig skriva in i pluginens kod, anser du att det här alternativet är ett hälsosammare alternativ.
Du kan ladda ner en demo av den här koden här , och anpassa det till dina behov.