Get file’s local path from its URL

I needed some nifty solution in Yii2 that would allow me to delete an image (a file) no matter, if:

  • I have an URL that points to it, used by regular user in a browser,
  • I have a local path on server, used internally by my Yii application.

Here it is.

Suppose that I have an image:

https://img.apmcdn.org/98d1c30f63eb74ce2f54cb8f1044e88ccec2eeef/uncropped/483af8-20090421-shopping.jpg

And this image is assigned to some model that I want to delete:

$someModel->image_url = 'https://img.apmcdn.org/uncropped/483af8-20090421-shopping.jpg'
$someModel->delete()

Then in beforeDelete() I have:

Yii::$app->api->imageDelete($this->image_url);

Which code is:

/**
* Delete files based on either URL or an actual path to file on server
* This function will detect whether $pathOrUrl is a path or URL address
*
* @param string|array $pathOrUrl Path (or table of paths) to a file on server
*                                or an URL of a file to be deleted.
*
* @return boolean true, if file was successfully deleted.
*/
public function imageDelete($pathOrUrl)
{
    if (is_array($pathOrUrl)) {
        foreach ($pathOrUrl as $file) {
            $this->imageDelete($file);
        }
    }
    else $this->imageDelete($pathOrUrl);
}

Where getImagePathFromUrl() does the magic:

/**
* Returns path to pliku which we can later use i.e. to delete it.
* Path is resolved out of URL that points to file.
*
* @return string Server-side path to a file
*/
public function getImagePathFromUrl($fileUrl)
{
    $fileName = basename($fileUrl);
    $dirName = basename(pathinfo($fileUrl, PATHINFO_DIRNAME));
    $imageUploadDirPath = Yii::getAlias('@upload') . DIRECTORY_SEPARATOR . static::$imageUploadDir;

    return $imageUploadDirPath . DIRECTORY_SEPARATOR . $dirName . DIRECTORY_SEPARATOR . $fileName;
}

This allows me to delete files in both scenarios (referenced locally and via URL).

Leave a Reply