* @version 1 */ class Uploader { private array $width = ['min' => 0, 'max' => 0]; private array $height = ['min' => 0, 'max' => 0]; private int $maxFileSizeMb; private string $savePath; private string $extensions = 'jpg|png|jpeg|gif'; private array $extMatches = []; private array $file; private string $customName; public static string $error; /** * @param string $customName */ public function setCustomName(string $customName): void { $this->customName = $customName; } public function __construct($name) { if (!isset($_FILES[$name])) { return; } $this->file = $_FILES[$name]; } /** * @param int $max * @param int|null $min * @return void */ public function setWidth(int $max, ?int $min = null) { $this->width['min'] = is_null($min) ? $max : $min; $this->width['max'] = $max; } /** * @param int $max * @param int|null $min * @return void */ public function setHeight(int $max, ?int $min = null) { $this->height['min'] = is_null($min) ? $max : $min; $this->height['max'] = $max; } /** * @param $megabytes * @return void */ public function setMaxFileSize($megabytes) { $this->maxFileSizeMb = $megabytes; } /** * @param string $path путь от корня до конечной папки без открывающего слеша. * @return void */ public function setSavePath(string $path) { $this->savePath = $_SERVER['DOCUMENT_ROOT'] . '/' . $path; } /** * @param string|array $ext * @return void */ public function setExtentions($ext) { if (is_array($ext)) { $arr = $ext; } else { $arr[] = $ext; } if (!$arr) { return; } $this->extensions = implode('|', $arr); } /** * @param int $width * @param int $height * @return void */ public function setDimensions(int $width, int $height) { $this->setWidth($width); $this->setHeight($height); } private function hasNormalDimensions(): bool { [$width, $height] = getimagesize($this->file['tmp_name']); if (!$width || !$height) { self::$error = 'Не подтянулись размеры файла.'; return false; } if ( ($width < $this->width['min'] || $width > $this->width['max']) || ($height < $this->height['min'] || $height > $this->height['max']) ) { self::$error = 'Требования к размеру: '; if ($this->width['min'] !== $this->width['max'] || $this->height['min'] !== $this->height['max']) { self::$error .= "от [{$this->width['min']} x {$this->height['min']}] до "; } self::$error .= "[{$this->width['max']} x {$this->height['max']}]."; self::$error .= " Текущий размер [$width x $height]"; return false; } return true; } private function hasNormalFileSize(): bool { if (!$this->maxFileSizeMb) { $this->setMaxFileSize(2); } if ($this->file['size'] > $this->maxFileSizeMb * (1024 * 1024) || $this->file['size'] <= 0) { self::$error = 'Неверный размер файла. Максимальный размер файла ' . $this->maxFileSizeMb . ' МБ'; return false; } return true; } private function hasNormalType(): bool { if ( !preg_match('/\.(' . $this->extensions . ')$/i', $this->file['name'], $this->extMatches) || !preg_match('/image/i', $this->file['type']) ) { self::$error = 'Неверный тип файла. Допустимые типы : ' . $this->extensions; return false; } return true; } private function hasNormalFilePath(): bool { if (!$this->savePath || !is_dir($this->savePath)) { self::$error = 'Ошибка загрузки: нет такой папки.'; return false; } return true; } private function upload() { $this->extMatches[1] = strtolower($this->extMatches[1]); $fn = uniqid('f_', true) . '.' . $this->extMatches[1]; $fn2 = uniqid('f_', true) . '.gif'; if ($this->customName) { $fn = $this->customName . '.' . pathinfo($this->file['name'], PATHINFO_EXTENSION); $fn2 = $this->customName; } if (!move_uploaded_file($this->file['tmp_name'], $this->savePath . $fn)) { self::$error = 'Ошибка загрузки файла'; return false; } var_dump([$fn2, $fn, $this->savePath . $fn]); return [$fn2, $fn, $this->savePath . $fn]; } private function uploadToDatabase(): int { $id = time(); Db::sql('insert into images (mime_type, img, id) VALUES (?,?,?)', [$this->file['type'], file_get_contents($this->file['tmp_name']), $id]); return $id; } public function saveimg() { return $this->hasNormalFilePath() && $this->hasNormalDimensions() && $this->hasNormalFileSize() && $this->hasNormalType() ? $this->upload() : false; } public function saveToDb() { return $this->hasNormalDimensions() && $this->hasNormalFileSize() && $this->hasNormalType() ? $this->uploadToDatabase() : false; } }