Created
July 14, 2012 12:13
-
-
Save beregond/3110928 to your computer and use it in GitHub Desktop.
Classes to help handle temporary files (also creation of such, but also 'checking' files to be removed after scripts end).
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* File contains two classes to help maintaining temporary files (especially problem of | |
* cleaning up such files) - FileToRemove and TemporaryFile. | |
* | |
* Requires PHP >= 5.3.0 (tested with 5.3.10-1) | |
*/ | |
namespace Vendorname; | |
/** | |
* Class to help maintaining temporary files. | |
* | |
* Very important part of this class is stack, that keeps reference of ALL | |
* temporary files. It also gives possibilities to manipulate the objects, but the main | |
* reason is to keep references to them. Otherwise PHPs garbage collector sometimes would | |
* delete objects the moment they are created (and we don't want this - we want file | |
* to be removed at the end of script execution). | |
* | |
* Usage: | |
* $filename = (...); //Path to file, that has to be removed. | |
* $file = new FileToRemove($filename); | |
* //Or you can forget about references, file won't disappear before the very end. | |
* new FileToRemove($filename2); | |
* | |
* Warning: There is no check if file is indeed deleteable. | |
* | |
* @class FileToRemove | |
*/ | |
class FileToRemove | |
{ | |
/** | |
* Path to attached file. | |
* | |
* @var string | |
*/ | |
protected $filename; | |
/** | |
* Stack to keep references to objects. | |
* | |
* @var array | |
*/ | |
protected static $stack = array(); | |
/** | |
* Constructor. | |
* | |
* @param string|array $filename path (or array of paths) to file(s) | |
* @return null | |
*/ | |
public function __construct($filename) | |
{ | |
if (is_file($filename)) { | |
$this->filename = $filename; | |
self::addToStack($this); | |
} | |
} | |
/** | |
* Gets filename. | |
* | |
* @return string | |
*/ | |
public function getFilename() | |
{ | |
return $this->filename; | |
} | |
/** | |
* Cancels file removal. | |
* | |
* @return null | |
*/ | |
public function cancel() | |
{ | |
$this->filename = null; | |
self::removeFromStack($this); | |
} | |
/** | |
* Force call for removal. | |
* | |
* @return null | |
*/ | |
public function remove() | |
{ | |
$this->__destruct(); | |
$this->cancel(); | |
} | |
/** | |
* Destructor. File is removed. | |
* | |
* @return null | |
*/ | |
public function __destruct() | |
{ | |
if ($this->filename) { | |
@unlink($this->filename); | |
} | |
} | |
/** | |
* Adds file to stack. | |
* | |
* @param FileToRemove $file | |
* @return null | |
*/ | |
protected static function addToStack(self $file) | |
{ | |
static::$stack[] = $file; | |
} | |
/** | |
* Removes file from stack. | |
* | |
* @param FileToRemove $file | |
* @return null | |
*/ | |
protected function removeFromStack(self $file) | |
{ | |
$stack = &static::$stack; | |
foreach ($stack as $key => $item) { | |
if ($item === $file) { | |
unset($stack[$key]); | |
} | |
} | |
} | |
/** | |
* Returns array of assigned files. | |
* | |
* @return array | |
*/ | |
public static function getFiles() | |
{ | |
return static::$stack; | |
} | |
/** | |
* Allows to create many instances of a class in one call. | |
* | |
* @param string|array filename or array of filenames | |
* @return array | |
*/ | |
public static function factory($tab) | |
{ | |
if (!is_array($tab)) { | |
$tab = array($tab); | |
} | |
$result = array(); | |
foreach ($tab as $item) { | |
if ($file = new self($item) and $file->getFilename()) { | |
$result[] = $file; | |
} | |
} | |
return $result; | |
} | |
} | |
/** | |
* Extension of FileToRemove. It beheves like FileToRemove, but also creates | |
* temporary file. | |
* | |
* File will be removed after script end. | |
* | |
* Usage: | |
* $file = new TemporaryFile(); | |
* $h = fopen($file->getFilename()); | |
* //(...) | |
* //More often reference isn't needed, so you can perform static call to get path only. | |
* $h = fopen(TemporaryFile::path()); //It creates new unique file and return its path. | |
* | |
* @class TemporaryFile | |
*/ | |
class TemporaryFile extends FileToRemove | |
{ | |
/** | |
* Prefix for new temporary files. | |
* | |
* @const string | |
*/ | |
const TEMPNAME_PREFIX = 'tmp'; | |
/** | |
* Stack to keep references to objects. | |
* | |
* This parameter MUST be redeclared, so 'late state binding' would affect, | |
* (so class has its own 'stack' to keep files references). | |
* | |
* @var array | |
*/ | |
protected static $stack = array(); | |
/** | |
* Constructor. | |
* | |
* Creates new temporary file, and all pass its name to parent constructor. | |
* | |
* @return null | |
*/ | |
public function __construct() | |
{ | |
$file = tempnam(realpath(sys_get_temp_dir()), self::TEMPNAME_PREFIX); | |
parent::__construct($file); | |
} | |
/** | |
* Returns array with given amount of temporary files. | |
* | |
* It's also implemented again because parent implementation | |
* is nonsense in this context. | |
* | |
* @param int $amount | |
* @return array | |
*/ | |
public static function factory($amount) | |
{ | |
$amount = (int) $amount; | |
$result = array(); | |
for ($x = 0; $x < $amount; $x++) { | |
$result[] = new self(); | |
} | |
return $result; | |
} | |
/** | |
* Creates new, unique temporary file and return its path. | |
* | |
* It shortcut, usually all you want is just path, you don't | |
* need to keep reference to object. | |
* | |
* @return string | |
*/ | |
public static function path() | |
{ | |
$file = new self(); | |
return $file->getFilename(); | |
} | |
} | |
?> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment