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.
Key Takeaways
- The WordPress Filesystem API provides a secure method for plugins and themes to write to local file systems, automatically handling file permissions, which is important given the variety of hosting services and configurations WordPress operates across.
- The API can write to file systems via system calls, choosing the most suitable method based on file permissions and available PHP extensions. It can also store user credentials for FTP or SSH connections.
- The tutorial demonstrates how to create a plugin using the API. The plugin displays a form in an admin page, saving the content of a textarea to a file. The tutorial provides codes for creating plugin files and directories, creating an admin page, and writing to and reading from a file.
- The $wp_filesystem object, an instance of the WP_Filesystem class, exposes methods for reading, creating, writing, and deleting files. Other methods available include delete, mkdir, move, size, and chmod.
- WordPress does not store FTP or SSH credentials permanently by default, but they can be stored permanently using the wp-config.php file. This avoids the need to re-enter credentials each time the plugin interacts with the file system.
Why Use the WordPress Filesystem API?
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.
How Does the Filesystem API work?
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.
Creating Our Plugin Files and Directory
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></span>
Now visit your admin panel and install the plugin.
Creating an Admin Page
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> class<span>="wrap"</span>> <span><span><span><h1 id="gt">></h1></span>Demo<span><span></span>></span> </span> <span><span><span><form> method<span>="post"</span>></form></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> name<span>="file-data"</span>></textarea></span><span><?php echo $output; ?></span><span><span></span>></span> </span> <span><span><?php wp_nonce_field("filesystem-nonce"); ?></span> </span> <span><span><span><br>></span> </span> <span><span><span><input> 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></span>></span> </span> <span><span><span></span></span></span></span></span></span></span></span></span></span> </div></span>></span> </span> <span><span><?php </span></span><span><span>}</span></span></span>
Here’s how the code works:
- First we added a page to the “Settings” menu. demo_page is the callback for displaying the page content.
- Inside the page we’re displaying a HTML form with a textarea and nonce field. There’s also a submit button to submit the form. The textarea name is file-data. The nonce is added to prevent a CSRF attack.
- When the page is open, then we’re retrieving the stored file data using the read_file_demo function. When the form is submitted, we’re storing the content of the textarea into a file using the write_file_demo function.
- If read_file_demo or write_file_demo returns an instance of the WP_Error object, then we’ll display an error message instead.
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!
Writing to a File
Here’s the implementation of our write_file_demo function:
--filesystem --filesystem.php --filesystem-demo --demo.txt
Here’s how the code works:
- First we referenced the global $wp_filesystem object inside the function. This object is an instance of the WP_Filesystem class. It’s responsible for exposing various methods for reading, creating, writing and deleting files.
- Next, we’re creating a nonce URL of our form page and an array with the field names of our form.
- Finally, we connect to the filesystem using the connect_fs function.
- connect_fs uses the request_filesystem_credentials function provided by WordPress to find an appropriate method to connect to the file system (direct, FTP or SSH). In case of FTP or SSH it will echo a form to ask for the credentials from the user. In the case of direct method, it simply returns true.
- When the textarea form is submitted and the request_filesystem_credentials chooses FTP or SSH method then we display the credentials form and hides the file-data field in the credentials form.
- request_filesystem_credentials function’s first parameter takes an URL where to redirect once it has got the correct credentials. The redirect is of type POST request. The request_filesystem_credentials last parameter is an array of the field names to post to the redirect URL.
- Once the credentials form is submitted, then it redirects back to the original form submit URL with proper field names and the values that were entered by the user.
- Again, the whole process starts and we execute the write_file_demo. This time request_filesystem_credentials has the credentials therefore it will simply return true.
- Then we use $wp_filesystem->find_folder to reference to the folder. Then we build the complete path of the demo.txt file.
- We used $wp_filesystem->put_contents to write data to the file.
Note: If you try to use the $wp_filesystem object’s methods without requesting and verifying credentials then they will not work.
Reading a File
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></span>
Here is how the code works:
- While reading the demo.txt file, we first connect to the file system using the request_filesystem_credentials function.
- This time we aren’t passing any form fields in the last parameter because the form is not submitted. We’re just passing the redirect URL so that it’s redirected once the credentials are retrieved.
- We’re then checking if the file exists using the $wp_filesystem->exists function. It file doesn’t exist we display an error. Otherwise we’re reading the file using the $wp_filesystem->get_contents function and returning the content.
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.
Other Methods of the $wp_filesystem Object
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:
- $wp_filesystem->delete: delete is used to delete a file or directory. You need to pass a string representing the path.
- $wp_filesystem->mkdir: mkdir is used to create a directory. It takes a string representing the parent directory.
- $wp_filesystem->move: move is used to move file It takes two parameters i.e., the first one is the path of the file and second one is the directory where to move it to.
- $wp_filesystem->size: size returns the size of a file in bytes. You need to pass path of a file.
- $wp_filesystem->chmod: chmod is used to change permissions of a file. It takes three arguments i.e., path of the file, the permission octal number and boolean representing recursion.
You can find which method of connection is used by WordPress to access filesystem using $wp_filesystem->method public property.
Storing Credentials Permanently
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:
- FTP_HOST: The host name of the server.
- FTP_USER: The username to use while connecting.
- FTP_PASS: The password to use while connecting
- FTP_PUBKEY: The path of the public key which will be used while using SSH2 connection.
- FTP_PRIKEY: The path of the private key which will be used while using SSH2 connection.
Conclusion
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.
Frequently Asked Questions (FAQs) about WordPress Filesystem API
What is the WordPress Filesystem API and why is it important?
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.
How does the WordPress Filesystem API work?
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.
How can I use the WordPress Filesystem API in my own plugins or themes?
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.
What are the benefits of using the WordPress Filesystem API over traditional PHP file system functions?
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.
Can I use the WordPress Filesystem API to upload files?
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.
How can I handle errors when using the WordPress Filesystem API?
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.
Can I use the WordPress Filesystem API to modify the .htaccess file?
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.
Is the WordPress Filesystem API secure?
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.
Can I use the WordPress Filesystem API to create directories?
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.
Can I use the WordPress Filesystem API to delete files and directories?
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!

Recently, we showed you how to create a personalized experience for users by allowing users to save their favorite posts in a personalized library. You can take personalized results to another level by using their names in some places (i.e., welcome screens). Fortunately, WordPress makes it very easy to get information about logged in users. In this article, we will show you how to retrieve information related to the currently logged in user. We will use the get_currentuserinfo(); function. This can be used anywhere in the theme (header, footer, sidebar, page template, etc.). In order for it to work, the user must be logged in. So we need to use

Do you want to know how to display child categories on the parent category archive page? When you customize a classification archive page, you may need to do this to make it more useful to your visitors. In this article, we will show you how to easily display child categories on the parent category archive page. Why do subcategories appear on parent category archive page? By displaying all child categories on the parent category archive page, you can make them less generic and more useful to visitors. For example, if you run a WordPress blog about books and have a taxonomy called "Theme", you can add sub-taxonomy such as "novel", "non-fiction" so that your readers can

One of our users asked other websites how to display the number of queries and page loading time in the footer. You often see this in the footer of your website, and it may display something like: "64 queries in 1.248 seconds". In this article, we will show you how to display the number of queries and page loading time in WordPress. Just paste the following code anywhere you like in the theme file (e.g. footer.php). queriesin

In the past, we have shared how to use the PostExpirator plugin to expire posts in WordPress. Well, when creating the activity list website, we found this plugin to be very useful. We can easily delete expired activity lists. Secondly, thanks to this plugin, it is also very easy to sort posts by post expiration date. In this article, we will show you how to sort posts by post expiration date in WordPress. Updated code to reflect changes in the plugin to change the custom field name. Thanks Tajim for letting us know in the comments. In our specific project, we use events as custom post types. Now

Do you want to move your blog from WordPress.com to WordPress.org? Many beginners start with WordPress.com but quickly realize their limitations and want to switch to the self-hosted WordPress.org platform. In this step-by-step guide, we will show you how to properly move your blog from WordPress.com to WordPress.org. Why migrate from WordPress.com to WordPress.org? WordPress.com allows anyone to create an account

Are you looking for ways to automate your WordPress website and social media accounts? With automation, you will be able to automatically share your WordPress blog posts or updates on Facebook, Twitter, LinkedIn, Instagram and more. In this article, we will show you how to easily automate WordPress and social media using IFTTT, Zapier, and Uncanny Automator. Why Automate WordPress and Social Media? Automate your WordPre

Just a few days ago, one of our users reported an unusual problem. The problem is that he reaches the limit of custom menu items. Any content he saves after reaching the menu item limit will not be saved at all. We've never heard of this issue, so we decided to give it a try on our local installation. More than 200 menu items were created and saved. The effect is very good. Move 100 items to the drop-down list and save them very well. Then we knew it had to do with the server. After further research, it seems that many others have encountered the same problem. After digging deeper, we found a trac ticket ( #14134 ) that highlighted this issue. Read very

Do you need to add custom metafields to custom taxonomy in WordPress? Custom taxonomy allows you to organize content besides categories and tags. Sometimes it is useful to add other fields to describe them. In this article, we will show you how to add other metafields to the taxonomy they create. When should custom metafields be added to custom taxonomy? When you create new content on your WordPress site, you can organize it using two default taxonomy (category and tag). Some websites benefit from the use of custom taxonomy. These allow you to sort content in other ways. For example,


Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

Atom editor mac version download
The most popular open source editor

Dreamweaver CS6
Visual web development tools

mPDF
mPDF is a PHP library that can generate PDF files from UTF-8 encoded HTML. The original author, Ian Back, wrote mPDF to output PDF files "on the fly" from his website and handle different languages. It is slower than original scripts like HTML2FPDF and produces larger files when using Unicode fonts, but supports CSS styles etc. and has a lot of enhancements. Supports almost all languages, including RTL (Arabic and Hebrew) and CJK (Chinese, Japanese and Korean). Supports nested block-level elements (such as P, DIV),

SublimeText3 Chinese version
Chinese version, very easy to use

MantisBT
Mantis is an easy-to-deploy web-based defect tracking tool designed to aid in product defect tracking. It requires PHP, MySQL and a web server. Check out our demo and hosting services.