This commit is contained in:
2026-07-08 15:39:43 +08:00
parent 1bca442f55
commit 614f21b240
+159 -124
View File
@@ -9,146 +9,181 @@ class File
{ {
private string $name; private string $name;
private string $tmp_name; private string $tmp_name;
private int $error; private int $error;
private string $type; private string $type;
private int $size; private int $size;
private int $limit = 1024000; private int $limit = 1024000;
private int $offset = 0; private int $offset = 0;
/** /**
* @param array $array * @param array $array
*/ */
public function __construct(array $array) public function __construct(array $array)
{ {
$this->name = $array['name']; $this->name = $array['name'];
$this->tmp_name = $array['tmp_name']; $this->tmp_name = $array['tmp_name'];
$this->error = $array['error']; $this->error = $array['error'];
$this->type = $array['type']; $this->type = $array['type'];
$this->size = $array['size']; $this->size = $array['size'];
} }
const array errorInfo = [ const array errorInfo = [
0 => 'UPLOAD_ERR_OK.', 0 => 'UPLOAD_ERR_OK.',
1 => 'The uploaded file exceeds the upload_max_filesize directive in php.ini.', 1 => 'The uploaded file exceeds the upload_max_filesize directive in php.ini.',
2 => 'The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form.', 2 => 'The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form.',
3 => 'The uploaded file was only partially uploaded.', 3 => 'The uploaded file was only partially uploaded.',
4 => 'No file was uploaded.', 4 => 'No file was uploaded.',
6 => 'Missing a temporary folder.', 6 => 'Missing a temporary folder.',
7 => 'Failed to write file to disk.', 7 => 'Failed to write file to disk.',
8 => 'A PHP extension stopped the file upload.' 8 => 'A PHP extension stopped the file upload.',
]; ];
/** /**
* @param string $path * @param string $path
* @return bool * @return bool
* @throws * @throws
*/ */
public function saveTo(string $path): bool public function saveTo(string $path): bool
{ {
if ($this->hasError()) { if ($this->hasError()) {
throw new Exception($this->getErrorInfo()); throw new Exception($this->getErrorInfo());
} }
@move_uploaded_file($this->tmp_name, $path); @move_uploaded_file($this->tmp_name, $path);
if (!file_exists($path)) { if (!file_exists($path)) {
return false; return false;
} }
return true; return true;
} }
/** /**
* @return string * @return string
* @throws * @throws
*/ */
public function rename(): string public function rename(): string
{ {
if (!empty($this->newName)) return $this->newName; if (!empty($this->newName))
if (!file_exists($this->getTmpPath())) { return $this->newName;
throw new Exception('(' . $this->name . ')Failed to open stream: No such file or directory'); if (!file_exists($this->getTmpPath())) {
} throw new Exception('(' . $this->name . ')Failed to open stream: No such file or directory');
}
$hash = md5_file($this->getTmpPath()); $hash = md5_file($this->getTmpPath());
$later = match ($this->type) {
'image/jpeg', 'image/jpg' => '.jpeg',
'image/gif' => '.gif',
'image/png' => '.png',
default => '.' . $this->exif_imageType(),
};
$later = '.' . exif_imagetype($this->getTmpPath()); $match = '/(\w{12})(\w{5})(\w{9})(\w{6})/';
$tmp = preg_replace($match, '$1-$2-$3-$4', $hash);
$match = '/(\w{12})(\w{5})(\w{9})(\w{6})/'; return $this->name = strtoupper($tmp) . $later;
$tmp = preg_replace($match, '$1-$2-$3-$4', $hash); }
return $this->name = strtoupper($tmp) . $later; /**
} * @return int|null
* @throws Exception
/** */
* @return string private function exif_imageType(): ?int
*/ {
public function getType(): string return match (\exif_imagetype($this->tmp_name)) {
{ IMAGETYPE_GIF => '.gif',
return $this->type; IMAGETYPE_JPEG => '.jpg',
} IMAGETYPE_PNG => '.png',
IMAGETYPE_SWF => '.swf',
IMAGETYPE_PSD => '.psd',
IMAGETYPE_BMP => '.bmp',
IMAGETYPE_TIFF_II, IMAGETYPE_TIFF_MM => '.tiff',
IMAGETYPE_JPC => '.jpc',
IMAGETYPE_JP2 => '.jp2',
IMAGETYPE_JPX => '.jpx',
IMAGETYPE_JB2 => '.jb2',
IMAGETYPE_SWC => '.swc',
IMAGETYPE_IFF => '.iff',
IMAGETYPE_WBMP => '.wbmp',
IMAGETYPE_XBM => '.xbm',
IMAGETYPE_ICO => '.ico',
IMAGETYPE_WEBP => '.webp',
IMAGETYPE_AVIF => '.avif',
default => throw new Exception('未知的图片类型'),
};
}
/** /**
* @return int * @return string
*/ */
public function getSize(): int public function getType(): string
{ {
return $this->size; return $this->type;
} }
/** /**
* @return string * @return int
* @throws */
*/ public function getSize(): int
public function getContent(): string {
{ return $this->size;
$open = fopen($this->getTmpPath(), 'r'); }
$content = '';
while ($file = fread($open, $this->limit)) {
$content .= $file;
fseek($open, $this->offset);
if ($this->offset >= $this->getSize()) {
break;
}
$this->offset += $this->limit;
}
fclose($open);
$this->offset = 0;
return $content;
}
/** /**
* @return string * @return string
*/ * @throws
public function getTmpPath(): string */
{ public function getContent(): string
return $this->tmp_name; {
} $open = fopen($this->getTmpPath(), 'r');
$content = '';
while ($file = fread($open, $this->limit)) {
$content .= $file;
fseek($open, $this->offset);
if ($this->offset >= $this->getSize()) {
break;
}
$this->offset += $this->limit;
}
fclose($open);
$this->offset = 0;
return $content;
}
/**
* @return bool
*
* check file have error
*/
public function hasError(): bool
{
return $this->error !== 0;
}
/** /**
* @return mixed * @return string
* */
* get upload error info public function getTmpPath(): string
*/ {
public function getErrorInfo(): mixed return $this->tmp_name;
{ }
if (!isset(self::errorInfo[$this->error])) {
return 'Unknown upload error.';
}
return self::errorInfo[$this->error];
}
} /**
* @return bool
*
* check file have error
*/
public function hasError(): bool
{
return $this->error !== 0;
}
/**
* @return mixed
*
* get upload error info
*/
public function getErrorInfo(): mixed
{
if (!isset(self::errorInfo[$this->error])) {
return 'Unknown upload error.';
}
return self::errorInfo[$this->error];
}
}