/
v.bolshakov
/
AIEcosystem-Testing
Обзор
Документация
Войти
/
v.bolshakov
/
AIEcosystem-Testing
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
dev
common/helpers/FileHelper.php
336 строк
10 KB
Developer
Initial commit
03 авг 2026, 17:43
03 авг 2026, 17:43
7433917
Код
Авторство
О чём код?
<?php namespace common\helpers; use Yii; use yii\helpers\BaseFileHelper; use yii\validators\UrlValidator; /** * Расширение функций для работы с файлами * * @author Dmitry E. Semenov <sde.tomsk@gmail.com> * @copyright Self (c) 2024 */ class FileHelper extends BaseFileHelper { const UTF8_BOM = "\xEF\xBB\xBF"; const UTF8_BOM_LEN = 3; const UTF16BE_BOM = "\xfe\xff"; const UTF16BE_BOM_LEN = 2; const UTF16BE_LF = "\x00\x0a"; const UTF16LE_BOM = "\xff\xfe"; const UTF16LE_BOM_LEN = 2; const UTF16LE_LF = "\x0a\x00"; const UTF32BE_BOM = "\x00\x00\xfe\xff"; const UTF32BE_BOM_LEN = 4; const UTF32BE_LF = "\x00\x00\x00\x0a"; const UTF32LE_BOM = "\xff\xfe\x00\x00"; const UTF32LE_BOM_LEN = 4; const UTF32LE_LF = "\x0a\x00\x00\x00"; private static function guessEncodingTestNoBom( string &$encoding, string &$contents, string $compare, string $setEncoding ): void { if ($encoding === '') { $pos = strpos($contents, $compare); if ($pos !== false && $pos % strlen($compare) === 0) { $encoding = $setEncoding; } } } private static function guessEncodingNoBom(string $filename): string { $encoding = ''; $contents = file_get_contents($filename); self::guessEncodingTestNoBom($encoding, $contents, self::UTF32BE_LF, 'UTF-32BE'); self::guessEncodingTestNoBom($encoding, $contents, self::UTF32LE_LF, 'UTF-32LE'); self::guessEncodingTestNoBom($encoding, $contents, self::UTF16BE_LF, 'UTF-16BE'); self::guessEncodingTestNoBom($encoding, $contents, self::UTF16LE_LF, 'UTF-16LE'); if ($encoding === '' && preg_match('//u', $contents) === 1) { $encoding = 'UTF-8'; } return $encoding; } private static function guessEncodingTestBom( string &$encoding, string $first4, string $compare, string $setEncoding ): void { if ($encoding === '') { if ($compare === substr($first4, 0, strlen($compare))) { $encoding = $setEncoding; } } } private static function guessEncodingBom(string $filename): string { $encoding = ''; $first4 = file_get_contents($filename, false, null, 0, 4); if ($first4 !== false) { self::guessEncodingTestBom($encoding, $first4, self::UTF8_BOM, 'UTF-8'); self::guessEncodingTestBom($encoding, $first4, self::UTF16BE_BOM, 'UTF-16BE'); self::guessEncodingTestBom($encoding, $first4, self::UTF32BE_BOM, 'UTF-32BE'); self::guessEncodingTestBom($encoding, $first4, self::UTF32LE_BOM, 'UTF-32LE'); self::guessEncodingTestBom($encoding, $first4, self::UTF16LE_BOM, 'UTF-16LE'); } return $encoding; } /** * Определить кодировку файла * * @param string $filename * @param string $dflt * @return string */ public static function guessEncoding(string $filename, string $dflt = 'CP1252'): string { $encoding = self::guessEncodingBom($filename); if ($encoding === '') { $encoding = self::guessEncodingNoBom($filename); } return ($encoding === '') ? $dflt : $encoding; } /** * Сконвертировать файл к кодировке по умолчанию (UTF-8) * @param $filename */ public static function conventToDefault($filename) { $encoding = self::guessEncoding($filename); if ($encoding != Yii::$app->charset) { $content = file_get_contents($filename); $content = mb_convert_encoding($content, Yii::$app->charset, $encoding); file_put_contents($filename, $content); } } /** * Получить расширение из Mime-type * * @param $mime * @return bool */ public static function extFromMime($mime) { $mime = strtolower($mime); // исключения для картинок static $mimeTypes = array( 'jpg' => ['image/jpeg'], 'gif' => ['image/gif'], 'png' => ['image/png'], 'wbmp' => ['image/vnd.wap.wbmp'], 'tif' => ['image/tiff'], 'xbm' => ['image/xbm', 'image/x-xbitmap'] ); foreach ($mimeTypes as $ext => $mimeType) { if (in_array($mime, $mimeType)) { return $ext; } } // для всех остальных случаев $ext = parent::getExtensionsByMimeType($mime); if (is_array($ext)) { return array_shift($ext); } return false; } /** * Разделение структуры папок на подпапки * пример 1-100, 101-200, ... 301-400 * * @param $id * @param int $delta * @return string */ public static function subFolder($id, $delta = 100) { $id = abs($id); $d = ceil($id / $delta); $max = $d * $delta; $min = $max - $delta + 1; return $min . '-' . $max . '/' . $id . '/'; } /** * Проверить наличие запрещённых символы в имени файла * * @param string $filename * @param boolean $is_file * @return bool */ public static function validFileName($filename, $is_file = true) { if ($is_file) { $chars = ['\\', '/', ':', '*', '?', '\'\'', '<', '>', '|', '+', '%', '!', '@']; } else { $chars = [':', '*', '?', '\'\'', '<', '>', '|', '+', '%', '!', '@']; } foreach ($chars as $char) { $pos = strpos($filename, $char); if ($pos !== false) { return false; } } return true; } /** * Сконвертировать base64 код в бинарный файл и получить путь к нему * * @param $src_data * @return string */ public static function fromBase64($src_data) { // есть заголовок в содержимом if ($pos = strpos($src_data, ';base64,')) { $img_data = substr($src_data, $pos + 8); $img_data = str_replace(' ', '+', $img_data); if ($data = base64_decode($img_data)) { // получение расширения по типу изображения $mime = substr($src_data, 5, $pos - 5); $ext = self::extFromMime($mime); return self::makeTmpFile($data, $ext); } } else { // нет заголовка if ($data = base64_decode($src_data)) { return self::makeTmpFile($data); } } return false; } /** * очистка от лишних символов * * @param string $path - путь к файлу */ public static function prepare($path) { $v = explode('?', $path); $path = $v[0]; return $path; } /** * Скопировать файл по внешней ссылке в локальную папку * * @param $url * @return bool|mixed */ public static function grabFile($url) { try { if ((new UrlValidator())->validate($url)) { $ext = pathinfo(self::prepare($url), PATHINFO_EXTENSION); // получаем картинку $data = file_get_contents($url); // Сохраняем картинку return FileHelper::makeTmpFile($data, $ext); } else { return $url; } } catch (\Exception $e) { return false; } } /** * Создание временного файла * * @param $data * @param string $ext * @return mixed */ public static function makeTmpFile($data, $ext = null, $tmpfile = null) { try { if ($tmpfile) { parent::createDirectory(dirname($tmpfile)); // Сохраняем картинку file_put_contents($tmpfile, $data); return $tmpfile; } else { $tmpfile = tempnam(sys_get_temp_dir(), md5(microtime(true))); } if ($ext) { $tmpfile .= '.' . $ext; // Сохраняем картинку file_put_contents($tmpfile, $data); return $tmpfile; } else { // Сохраняем картинку file_put_contents($tmpfile, $data); $ext = false; if ($type = exif_imagetype($tmpfile)) { // получаем расширени $ext = image_type_to_extension($type); } if ($ext) { $newfile = $tmpfile . $ext; // меняем расширение if (rename($tmpfile, $newfile)) { return $newfile; } else { return $tmpfile; } } else { return $tmpfile; } } } catch (\Exception $e) { return false; } } /** * Генерируем произвольное имя файла с сохранением расширения * * @param $filename * @return string */ public static function genName($filename, $tmp_dir = false) { $ext = pathinfo($filename, PATHINFO_EXTENSION); $name = TextHelper::random('hexdec') . '.' . strtolower($ext); return $tmp_dir ? sys_get_temp_dir() . '/' . $name : $name; } }