Writing to local files is one of the functionalities many plugins and themes need for various purposes. Security is the most important issue plugins and themes have to take care of while writing to local file systems. WordPress runs across various hosting services and configurations, therefore it becomes difficult for developers to create plugins and themes which access local file systems to work across all different kinds of environments without compromising security.
In this tutorial, we’ll learn how to use the WordPress Filesystem API to access local file systems which takes care of proper file permissions. In the process, we’ll create a plugin which displays a form with a textarea in an admin page that saves the content of the textarea to a file.
You might be wondering why we don’t just use PHP’s file system functions to read and write local files instead of learning and using a whole new set of APIs?
The issue of using PHP file system APIs is that it doesn’t take care of file permissions automatically. Suppose you’re using a shared hosting service to host your WordPress site and your hosting web server is running as the “admin” operating system account. Whenever you create files using PHP, they’re owned as the “admin” user. Therefore, any other website hosted in the same shared hosting can also access your website files as they’re also running as the “admin” user, posing a security issue to your site. To protect us from this issue, you need to change the file owner and permissions manually using PHP.
But when you login using SSH or FTP/SFTP to create files then they are owned by the operating system user account that you are logged in as. If the FTP server is running as the “admin” user and you’re logged in as the “narayanprusty” user, then newly created files will have an owner as “narayanprusty”, not “admin”.
WordPress introduced the Filesystem API which can automatically takes care of file permissions. The Filesystem API was released in WordPress 2.6. WordPress actually released it to support its plugin, theme and core update system, but later on plugins and themes starting using it for their own purposes.
The Filesystem API can write to file systems using system calls (i.e. direct, ftp, ftp socket or ssh2). It chooses one of the methods based on whichever method creates files with proper file permissions and which PHP extension is available. The Filesystem API first checks the direct method, then ftp and finally ssh2.
While using FTP or SSH, you’ll need to get the credentials from your user. The Filesystem API provides function makes it easier to display a form to take credentials and store them.
Now let’s create our plugin which displays a textarea in a page, where submitting the form saves the contents of the textarea to a local file.
Here’s the directory structure of our plugin:
--filesystem --filesystem.php --filesystem-demo --demo.txt
Create these files and directories in the wp-content/plugins directory of your WordPress installation.
To make the plugin installable, put this code in the filesystem.php file:
<span><span><?php </span></span><span> </span><span><span>/* </span></span><span><span>Plugin Name: Filesystem API </span></span><span><span>Plugin URI: http://www.sitepoint.com </span></span><span><span>Description: A sample plugin to demonstrate Filesystem API </span></span><span><span>Version: 1.0 </span></span><span><span>Author: Narayan Prusty </span></span><span><span>*/</span></span>
Now visit your admin panel and install the plugin.
Next we need a page in our admin where our example will reside. Here’s the code to create this page and display the textarea. Just place this code in the filesystem.php file:
function menu_item() { add_submenu_page("options-general.php", "Demo", "Demo", "manage_options", "demo", "demo_page"); } add_action("admin_menu", "menu_item"); function demo_page() { ?> <span><span><span><div</span> class<span>="wrap"</span>></span> </span> <span><span><span><h1</span>></span>Demo<span><span></h1</span>></span> </span> <span><span><span><form</span> method<span>="post"</span>></span> </span> <span><span><?php </span></span><span> <span>$output = ""; </span></span><span> </span><span> <span>if(isset($_POST["file-data"])) </span></span><span> <span>{ </span></span><span> <span>$output = write_file_demo($_POST["file-data"]); </span></span><span> <span>} </span></span><span> <span>else </span></span><span> <span>{ </span></span><span> <span>$output = read_file_demo(); </span></span><span> <span>} </span></span><span> </span><span> <span>if(!is_wp_error($output)) </span></span><span> <span>{ </span></span><span> <span>?></span> </span> <span><span><span><textarea</span> name<span>="file-data"</span>></span><span><?php echo $output; ?></span><span><span></textarea</span>></span> </span> <span><span><?php wp_nonce_field("filesystem-nonce"); ?></span> </span> <span><span><span><br</span>></span> </span> <span><span><span><input</span> type<span>="submit"</span>></span> </span> <span><span><?php </span></span><span> <span>} </span></span><span> <span>else </span></span><span> <span>{ </span></span><span> <span>echo $output->get_error_message(); </span></span><span> <span>} </span></span><span> <span>?></span> </span> <span><span><span></form</span>></span> </span> <span><span><span></div</span>></span> </span> <span><span><?php </span></span><span><span>}</span></span>
Here’s how the code works:
Note, the above code will break your WordPress site, as we haven’t yet created the read_file_demo and write_file_demo functions. Let’s create them now!
Here’s the implementation of our write_file_demo function:
--filesystem --filesystem.php --filesystem-demo --demo.txt
Here’s how the code works:
Note: If you try to use the $wp_filesystem object’s methods without requesting and verifying credentials then they will not work.
Here is the implementation of the read_file_demo function.
<span><span><?php </span></span><span> </span><span><span>/* </span></span><span><span>Plugin Name: Filesystem API </span></span><span><span>Plugin URI: http://www.sitepoint.com </span></span><span><span>Description: A sample plugin to demonstrate Filesystem API </span></span><span><span>Version: 1.0 </span></span><span><span>Author: Narayan Prusty </span></span><span><span>*/</span></span>
Here is how the code works:
Assuming WordPress has chosen FTP as the suitable method for creating files, here are the screenshots of the whole process:
First when we open the demo page we will see this form:
Here, we need to enter FTP or FTPS credentials and submit it. Once we submit it, we’ll see this form:
An empty textarea was displayed. Enter the text “Hello World!!!” submit the form. You will again see the credentials form.
You have to fill it again because WordPress doesn’t store the FTP password by default (you can do this in wp-config.php, more on that later). So every time your plugin needs to work with a file system, it must ask credentials. Now submitting it will redirect back to the redirect URL with field names and values submitted earlier. Here is how the textarea appears:
Here, we read the contents of the file and display it.
The $wp_filesystem object provides many other methods to perform various other operations on files and directories. We just saw writing and reading n file. You can find the whole list of what you can do at the WP_Filesystem_Base () documentation page.
Let’s check out some of the important ones:
You can find which method of connection is used by WordPress to access filesystem using $wp_filesystem->method public property.
We saw that WordPress doesn’t store the FTP or SSH credentials permanently. It’s not user friendly to ask for details again and again. There is a way to store the credentials permanently using the wp-config.php file.
Use these options to store the FTP and SSH credentials:
In this article we saw the process of designing an admin page that accesses our file system using the WordPress Filesystem API. In case you’re trying to access a file system in a background process (such as using a cron job), then its not possible to display the credentials form if required, in that case you’ll need to make sure you notify your user to place the credential constants in the wp-config.php file. You can go ahead and experiment further with this API and share your experiences with us below.
The WordPress Filesystem API is a set of functions provided by WordPress that allows developers to read, write, and modify files and directories in a standardized way. It is important because it provides a secure and reliable way to interact with the file system on your server. This is crucial for tasks such as creating, modifying, or deleting files and directories, uploading media files, or updating your WordPress installation.
The WordPress Filesystem API works by providing a set of functions that you can use to interact with the file system on your server. These functions abstract the underlying file system operations, providing a consistent interface regardless of the server’s operating system or file system. This means that you can use the same functions to interact with the file system on a Linux server as you would on a Windows server.
To use the WordPress Filesystem API in your own plugins or themes, you first need to include the file ‘wp-admin/includes/file.php’ which contains the API’s functions. After that, you can use the API’s functions to interact with the file system. For example, you can use the ‘WP_Filesystem()’ function to initialize the file system, and then use other functions such as ‘get_contents()’, ‘put_contents()’, or ‘delete()’ to read, write, or delete files.
The main benefit of using the WordPress Filesystem API over traditional PHP file system functions is that the API provides a consistent interface regardless of the server’s operating system or file system. This means that you can write code that works on any server, without having to worry about the differences between different file systems. Additionally, the API provides a higher level of security by ensuring that all file operations are performed with the correct permissions.
Yes, you can use the WordPress Filesystem API to upload files. The API provides a function called ‘wp_handle_upload()’ that handles the entire upload process, including checking the file type, ensuring the file is not too large, and moving the file to the correct directory. This makes it easy to handle file uploads in a secure and reliable way.
The WordPress Filesystem API provides a function called ‘is_wp_error()’ that you can use to check if a function has returned an error. If an error has occurred, you can use the ‘get_error_message()’ function to get a human-readable error message. This makes it easy to handle errors and provide useful feedback to the user.
Yes, you can use the WordPress Filesystem API to modify the .htaccess file. The API provides a function called ‘insert_with_markers()’ that allows you to insert lines into the .htaccess file between specific markers. This makes it easy to add custom rules to the .htaccess file in a safe and reliable way.
Yes, the WordPress Filesystem API is secure. It ensures that all file operations are performed with the correct permissions, and it provides functions to sanitize file names and paths. This helps to prevent common security issues such as directory traversal attacks.
Yes, you can use the WordPress Filesystem API to create directories. The API provides a function called ‘wp_mkdir_p()’ that creates a directory and all necessary parent directories. This makes it easy to create complex directory structures in a reliable way.
Yes, you can use the WordPress Filesystem API to delete files and directories. The API provides a function called ‘delete()’ that can delete both files and directories. This makes it easy to clean up after yourself and ensure that your plugin or theme does not leave unnecessary files on the server.
The above is the detailed content of An Introduction to the WordPress Filesystem API. For more information, please follow other related articles on the PHP Chinese website!