Introduction
Welcome everyone to this second How-To about the Elementary Framework (for those who have missed the first How-To, check it here).
In this article we will talk about the creation of a file watcher, a console app which will watch files in a directory and report to us any changes made to these files (deletion, creation, modification), written in the PHP language using FireFS, a part of my framework.
Creating a file watcher it's just a possibility of FireFS between much more others.
Prerequisites
Before start, make sure you have:
- A PHP IDE or editor: You can download Visual Studio Code, it's a free and powerful code editor which can support many languages (including PHP).
- Composer: Composer is a dependencies manager for PHP projects. You can download it at https://getcomposer.org/
Part 1 - Preparing the project
The first thing we have to do is to create our new project. Create a new folder with the name you want, and open a terminal into it.
FireFS is a composer package, so we need first to prepare our project to use composer. In the terminal you previuously opened, type:
composer init
This will initialize our project with composer support. Follow the initialization process to the end.
Now, in the same terminal, we can install FireFS with the command:
composer require elementaryframework/fire-fs
And wait the process finish, this will download the source code of the FireFS project and install it in your own. When the installation succeed, type again:
composer dump-autoload -o
This will generate an optimized autoloader file (useful for production). For a normal autoload file, just omit the -o
switch.
Once FireFS is installed, we can now create the command line tool to watch our files. Create a file named watch
inside your project folder and insert into it:
#!/usr/bin/env php
<?php
// Require composer autoload file
require "./vendor/autoload.php";
// Print a message to the console
print "Hello world, this is a file watcher!";
What we are doing ?
- We first require the autoloader file from composer
- We print a message to the console output
To test if everything is working, just type in the terminal (while the working directory is the same as our project):
php watch
The console will print the text "Hello world, this is a file watcher!" before exit.
Note that the file name is watch (without any extension), and not watch.php
Part 2 - Our file watcher
Building a file watcher with FireFS is very easy, we just have to create a new FileSystemWatcher
object, follow the build pattern and start it, easy, right?
The FireFS
object
In FireFS, instances of the FireFS
class represent a file system, and manage every files and folders in the given root directory. When creating a file watcher we have first to create a file system:
// We use the FireFS class
use ElementaryFramework\FireFS\FireFS;
// We create a new file system on the current directory
$fs = new FireFS();
This will create a file system at the same path than our watch
file (to change the root path, just define your prefered path as the first parameter of the FireFS class constructor).
The watched folder
Now we have to create the folder which will be watched. We can let our console app do it itself by using the great FireFS API:
// Check if the directory to watch exists
if (!$fs->exists("files_to_watch")) {
// If not, create the directory
$fs->mkdir("files_to_watch");
}
This will create the directory files_to_watch
only if it not exists at each run of our file watcher.
The IFileSystemListener
object
Before enjoying our file watcher, we have to create a class implementing the IFileSystemListener
interface. This class is used by the watcher to execute specific actions following the watch event (create, delete, update).
// We use the IFileSystemWatcher interface
use ElementaryFramework\FireFS\Listener\IFileSystemListener;
// We use the FileSystemEvent class
use ElementaryFramework\FireFS\Events\FileSystemEvent;
// Our listener
class WatcherListener implements IFileSystemListener
{
/**
* Action executed on any event.
* The returned boolean will define if the
* specific event handler (onCreated, onModified, onDeleted)
* have to be called after this call.
*/
public function onAny(FileSystemEvent $event): bool
{
$eventType = $event->getEventType();
$date = date("d/m/Y H:i:s");
if ($eventType === FileSystemEvent::EVENT_UNKNOWN) {
return true;
}
switch ($eventType) {
case FileSystemEvent::EVENT_CREATE:
print "{$date} - [Created] {$event->getPath()}\n";
break;
case FileSystemEvent::EVENT_MODIFY:
print "{$date} - [Updated] {$event->getPath()}\n";
break;
case FileSystemEvent::EVENT_DELETE:
print "{$date} - [Deleted] {$event->getPath()}\n";
break;
}
return false;
}
/**
* Action executed when a file/folder is created.
*/
public function onCreated(FileSystemEvent $event)
{ }
/**
* Action executed when a file/folder is updated.
*/
public function onModified(FileSystemEvent $event)
{ }
/**
* Action executed when a file/folder is deleted.
*/
public function onDeleted(FileSystemEvent $event)
{ }
}
The FileSystemWatcher
object
Once we have a file system object and we know the directory (or the file) we want to watch, we can create the file watcher:
// We use the FileSystemWatcher class
use ElementaryFramework\FireFS\Watcher\FileSystemWatcher;
// Create the file watcher
$watcher = new FileSystemWatcher($fs);
The next step is to configure our watcher. The configuration is done by calling some methods:
-
setListener(IFileSystemListener)
: Defines theIFileSystemListener
instance used to execute specific actions on each files updates ; -
setPath(string)
: Defines the path of directory/file to watch ; -
setRecursive(bool)
: Defines if the watcher will watch for files recursively (works only if the watched entity is a directory) ; -
addPattern(Regex)
: Add a files-to-watch pattern ; -
addExcludePattern(Regex)
: Add a files-to-exclude pattern ; -
setPattern(array)
: Set an array of files-to-watch patterns. This will overwrite any existing pattern ; -
setExcludePattern(array)
: Set an array of files-to-exclude patterns. This will overwrite any existing pattern ; -
setWatchInterval(int)
: Set the interval in milliseconds in which the watcher will process a watch event.
So we will build our watcher like this:
$watcher
->setListener(new WatcherListener)
->setRecursive(true)
->setPath("./files_to_watch")
->setWatchInterval(250)
->build(); // It's important to call build to validate the configuration
Important to know: The
FileSystemWatcher
class have some default exclude patterns, check them here
At this time, everything is set! Now the last thing to do is to start the watcher:
// Start the file watcher
$watcher->start();
The complete watch
file
We just have finished to create our file watcher, there is the complete file content:
#!/usr/bin/env php
<?php
// Require composer autoloader
require_once __DIR__ . '/vendor/autoload.php';
// We use the FireFS class
use ElementaryFramework\FireFS\FireFS;
// We use the IFileSystemWatcher interface
use ElementaryFramework\FireFS\Listener\IFileSystemListener;
// We use the FileSystemEvent class
use ElementaryFramework\FireFS\Events\FileSystemEvent;
// We use the FileSystemWatcher class
use ElementaryFramework\FireFS\Watcher\FileSystemWatcher;
// We create a new file system on the current directory
$fs = new FireFS();
// Check if the directory to watch exists
if (!$fs->exists("files_to_watch")) {
// If not, create the directory
$fs->mkdir("files_to_watch");
}
// Our listener
class WatcherListener implements IFileSystemListener
{
/**
* Action executed on any event.
* The returned boolean will define if the
* specific event handler (onCreated, onModified, onDeleted)
* have to be called after this call.
*/
public function onAny(FileSystemEvent $event): bool
{
$eventType = $event->getEventType();
$date = date("d/m/Y H:i:s");
if ($eventType === FileSystemEvent::EVENT_UNKNOWN) {
return true;
}
switch ($eventType) {
case FileSystemEvent::EVENT_CREATE:
print "{$date} - [Created] {$event->getPath()}\n";
break;
case FileSystemEvent::EVENT_MODIFY:
print "{$date} - [Updated] {$event->getPath()}\n";
break;
case FileSystemEvent::EVENT_DELETE:
print "{$date} - [Deleted] {$event->getPath()}\n";
break;
}
return false;
}
/**
* Action executed when a file/folder is created.
*/
public function onCreated(FileSystemEvent $event)
{ }
/**
* Action executed when a file/folder is updated.
*/
public function onModified(FileSystemEvent $event)
{ }
/**
* Action executed when a file/folder is deleted.
*/
public function onDeleted(FileSystemEvent $event)
{ }
}
// Create the file watcher
$watcher = new FileSystemWatcher($fs);
$watcher
->setListener(new WatcherListener)
->setPath("./files_to_watch")
->setWatchInterval(250)
->build(); // It's important to call build to validate the configuration
// Start the file watcher
$watcher->start();
Now run this file using the command php watch
, a new folder files_to_watch
is directly created and the console wait for files changes. Try to create, delete or edit files inside the files_to_watch
folder and you will be directly notified for these actions inside the console!
php watch
26/07/2019 15:53:20 - [Created] D:\AliensGroup\Hyde\hyde-cli\files_to_watch\composer.json
26/07/2019 15:54:24 - [Created] D:\AliensGroup\Hyde\hyde-cli\files_to_watch\composer.lock
26/07/2019 15:54:24 - [Created] D:\AliensGroup\Hyde\hyde-cli\files_to_watch\hyde
26/07/2019 15:54:29 - [Deleted] D:\AliensGroup\Hyde\hyde-cli\files_to_watch\composer.lock
26/07/2019 15:54:47 - [Updated] D:\AliensGroup\Hyde\hyde-cli\files_to_watch\hyde
Conclusion
With this article, we have learn How to create a file watcher with PHP and the Elementary Framework. Using the FireFS module of the framework, we have seen steps by steps how it's very easy to implement a functionality like this. Now with the knowledge you have you can create more than a simple event reporting app, from crons on your webserver, to your own Jekyll PHP edition ;-), you have everything you need to go further.
What next?
- Browse the FireFS source code on GitHub - and give a star if you like it - ;
- Checkout other Elementary Framework modules
ElementaryFramework / FireFS
Easily manage your filesystem through PHP
FireFS
Manage your file system easily, through php
FireFS is a library allowing you to write/read/delete files and folders of your file system, safely and easily.
It can be used for web applications as well for console applications, without any requirements.
Example
<?php
use ElementaryFramework\FireFS\FireFS;
// Create a new file system instance at the given path
$fs = new FireFS("./app"); // /root/var/www/htdocs/app/
// Check if the path "/root/var/www/htdocs/app/images/" exists
if ($fs->exists("images")) {
// Change the working directory to the images folder
$fs->setWorkingDirectory("./images");
// Create a new file in the working directory
$fs->mkfile("./logo.png"); // /root/var/www/htdocs/app/images/logo.png
// Read file from the file system root path
$logo = $fs->read("logo.png"
…
Top comments (0)