Правильное сопоставление имени каждого файла изображения [PHP]

Я заменяю ссылки на изображения в тексте следующим форматом.

{#img='xxxx-xxxx-xxxx-xxxx.abc', alt=''}

Перед изменением я получаю часть src по ссылкам на изображения и загружаю ее на сервер с помощью CURL. Я называю UUID для каждого загруженного изображения.

Пока все хорошо!

$newImageName = create_uuid();
$ch = curl_init($img->getAttribute('src'));
$fp = fopen('/PATH_SAMPLE/' . $newImageName . '.jpg', 'wb');
curl_setopt($ch, CURLOPT_FILE, $fp);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_exec($ch);
curl_close($ch);
fclose($fp);

Однако; у каждого изображения свой UUID, но в результате переформатирования окончательный UUID отрисовывается в текст; например так;

asdasd {#img='19a1cb87-009b-4495-be22-68fb08db8a76', alt=''} asdasd {#img='19a1cb87-009b-4495-be22-68fb08db8a76', alt=''}

Весь код;

$jsonFile = "asdasd <img src='https://example.com/image_1.png'> asdasd <img src='https://example.com/image_1.jpg'>";
    $dom = new DOMDocument;
    $dom->loadHTML($jsonFile);
    $imgs = $dom->getElementsByTagName('img');
    $imgURLs = []; 
    foreach ($imgs as $img) {
        if (!$img->hasAttribute('src')) {
            continue;
        } else {
            $newImageName = create_uuid();
            $ch = curl_init($img->getAttribute('src'));
            $fp = fopen('/PATH_SAMPLE/' . $newImageName . '.jpg', 'wb');
            curl_setopt($ch, CURLOPT_FILE, $fp);
            curl_setopt($ch, CURLOPT_HEADER, 0);
            curl_exec($ch);
            curl_close($ch);
            fclose($fp);
            $str = preg_replace('/<img[^>]*src=([\'"])(.*?)\1>/', "{#img='" . $newImageName . "', alt=''}", $jsonFile);
            
        }
    }

Как я могу решить проблему UUID для изображений?

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
0
0
48
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий
$newImageName = create_uuid().'.jpg';

предполагая, что вы согласны с неправильным наименованием файлов png как jpg.

Кстати, могу ли я предложить вместо uuid, если вы сделаете

curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$image_binary=curl_exec($ch);
$image_name=hash('sha224',$image_binary).'.jpg';
$image_path = '/PATH_SAMPLE/' . $image_name;
if (!file_exists($image_path)){
    file_put_contents($image_path,$image_binary);
}

вы избежите сохранения дубликатов изображений, занимающих место на диске. (также этот параметр можно оптимизировать, чтобы не сохранять все изображение в оперативной памяти, используя tmpfile() + CURLOPT_FILE + hash_file() + rename(stream_get_meta_data($tmpfile)['uri']), если вы действительно беспокоитесь об использовании памяти ^ ^)

также, вырезать это дерьмо

$str = preg_replace('/<img[^>]*src=([\'"])(.*?)\1>/', "{#img='" . $newImageName . "', alt=''}", $jsonFile);

просто сделайте $img->setAttribute("src",$image_name); вместо этого, и когда вы будете готовы обновить $jsonFile, сделайте $jsonFile=$dom->saveHTML(); вместо этого.

лично я, вероятно, написал бы это так

    $jsonFile = "asdasd <img src='https://example.com/image_1.png'> asdasd <img src='https://example.com/image_1.jpg'>";
    $dom = new DOMDocument ();
    $rootName = "root" . bin2hex ( random_bytes ( 10 ) );
    $dom->loadHTML ( "<?xml encoding=\"UTF-8\"><{$rootName}>{$jsonFile}</{$rootName}>" );
    $imgs = $dom->getElementsByTagName ( 'img' );
    $imgURLs = [ ];
    $ch = curl_init ();
    foreach ( $imgs as $img ) {
        if (!$img->hasAttribute ( 'src' )) {
            continue;
        } else {
            $tmphandle = tmpfile ();
            $tmpfile = stream_get_meta_data ( $tmphandle ) ['uri'];
            curl_setopt_array ( $ch, array (
                    CURLOPT_FILE => $tmphandle,
                    CURLOPT_URL => $img->getAttribute ( "src" )
            ) );
            curl_exec ( $ch );
            // optimization note: the file hashing could be done incrementally in-ram by using CURLOPT_WRITEFUNCTION+hash_init()+hash_update() instead of hash_file()
            $image_name = hash_file ( 'sha224', $tmpfile ) . '.jpg';
            $fp = '/PATH_SAMPLE/' . $image_name;
            if (file_exists ( $fp )) {
                // this is a duplicate image
            } else {
                if (PHP_OS_FAMILY === "Windows") {
                    // optimization note, on pretty much every OS except Windows, you can move files with open handles, but not on Windows..
                    // this is slower, but Windows-compatible
                    copy ( $tmpfile, $fp );
                } else {
                    // this is faster, but not Windows-compatible
                    rename ( $tmpfile, $fp );
                }
            }
            fclose ( $tmpfile );
            $img->setAttribute ( "src", $image_name );
        }
    }
    $str = $dom->saveHTML ( $dom->getElementsByTagName ( $rootName )->item ( 0 ) );
    $str = substr ( $str, strlen ( "<{$rootName}>" ), -strlen ( "</{$rootName}>" ) );
    curl_close ( $ch );

Комплексная структура кода! Я просмотрел каждую строчку вашего кода. Это было действительно поучительно для меня. Спасибо за помощь с этим замечательным кодом.

Emre6 21.03.2022 15:40

Другие вопросы по теме