TailTemplate Build stunning websites faster with our pre-designed Tailwind CSS templates

Copying images from URL with Flysystem

Flysystem is one of awesome packages provided byPHP League, a group of developers who have banded together to build solid, well tested PHP packages using modern coding standards.

Flysystem Introduction

We had the need to move images from our legacy server to a new server for one of our projects. Instead of downloading hundreds of images manually, which was too tedious. We used Flysystem to do the job for us.

Flysystem provides an abstraction for various filesystems. Currently it supports:

  • Local Disk
  • Azure
  • AWS S3
  • Copy.com
  • Dropox
  • FTP
  • GridFS
  • Memory
  • Rackspace
  • ReplicateAdapter
  • SFTP
  • WebDAV
  • PHPCR
  • ZipArchive

What does this mean is that we can treat all the filesystems above as if they are the same. The benefits are obvious. We can switch between the filesystems without much of trouble. And we can move a file from one filesystem to another in a breeze.

Building RemoteCopy class

Back to our project, our requirement is to read a file remotely from a URL and then copy it to a local disk.

First let's create a class RemoteCopy with a static method copy, which takes two parameters $remote and $desDir. Parameter $remote is a string pointing to a remote URL and $desDir is a string containing the destination directory where you want to store the downloaded images.

The class signature looks like this:

class RemoteCopy
{
    public static function copy($remote, $desDir)
    {
 
    }
}

Next we instantiate an Flysystem object with Local adapter:

class RemoteCopy
{
    public static function copy($remote, $desDir)
    {
        $adapter = new Local($desDir);
 
        $filesystem = new Filesystem($adapter);
    }
}

Then we bind the remote image to a stream using PHP's native function fopen():

class RemoteCopy
{
    public static function copy($remote, $desDir)
    {
        $adapter = new Local($desDir);
 
        $filesystem = new Filesystem($adapter);
 
        $pathInfo = pathinfo($remote);
 
        $stream = fopen($remote, 'r');
    }
}

Next we use the method putStream of Flysystem object to read the content of remote image and put it into our local disk. At the end, we close the remote stream:

class RemoteCopy
{
    public static function copy($remote, $desDir)
    {
        $adapter = new Local($desDir);
 
        $filesystem = new Filesystem($adapter);
 
        $pathInfo = pathinfo($remote);
 
        $stream = fopen($remote, 'r');
 
        $filesystem->putStream($pathInfo['basename'], $stream);
 
        fclose($stream);
    }
}

That is basically it. Now this simple code snippet can be used to download image from a remote URL and store in a defined local directory.

To make the function to return a more useful value, It makes sense to have method copy return a directory path of the downloaded file. If the method fails due to unexpected reasons, it will just return NULL.

The final code:

namespace App\Utility;
 
use League\Flysystem\Adapter\Local;
use League\Flysystem\Filesystem;
 
class RemoteCopy
{
    public static function copy($remote, $desDir)
    {
        $adapter = new Local($desDir);
 
        $filesystem = new Filesystem($adapter);
 
        $pathInfo = pathinfo($remote);
 
        $stream = fopen($remote, 'r');
 
        if ($filesystem->putStream($pathInfo['basename'], $stream)) {
 
            fclose($stream);
 
            return trim($desDir) . DIRECTORY_SEPARATOR . $pathInfo['basename'];
        }
 
        return null;
    }
}

The End

We hope you found this tutorial useful. If you have any question, do leave a comment below. If you like our tutorial, please tweet and share it on Facebook.

Hopefully this simple tutorial helped you with your development . If you like our post, please follow us on Twitter and help spread the word . We need your support to continue. If you have questions or find our mistakes in above tutorial, do leave a comment below to let us know .