Как решить проблему белого экрана в библиотеке GD? - PullRequest
0 голосов
/ 30 мая 2020

У меня проблема в библиотеке GD PHP. Когда я отправляю изображение на виртуальную машину localhost, изображение обычно создается на экране, но когда я пытаюсь сделать это на VPS, я не генерирую изображение, и экран белый. Я уже проверил, одинакова ли библиотека GD на обеих машинах, и вроде бы все в порядке.

Ниже приведен код, с помощью которого я генерирую изображение на экране:

    $image = imagecreatefrompng((isset($_SERVER['HTTPS']) ? "https" : "http") . "://$_SERVER[HTTP_HOST]" . "/wp-content/uploads/cart1.png");

    $imageCart = imagecreatefrompng($perfil);

    $titleColor = imagecolorallocate($image, 255, 255, 255);
    $gray = imagecolorallocate($image, 100, 100, 100);
    $black = imagecolorallocate($image, 0, 0, 0);

    imagecopymerge($image, $imageCart, 60, 177, 0, 0, imagesx($imageCart), imagesy($imageCart), 100);

    imagestring($image, 5, 170, 175, "NOME  " . strtoupper($nomeCompleto), $titleColor);
    imagestring($image, 5, 170, 205, "CPF  " . $cpf, $titleColor);
    imagestring($image, 5, 170, 235, "MATRICULA  " . $matricula, $titleColor);
    imagestring($image, 5, 170, 263, "DT NASCIMENTO " . $dtnacimento, $titleColor);

    header("Content-type: image/png");

    imagepng($image);
    imagepng($imageCart);

    imagedestroy($image);
    imagedestroy($imageCart);

1 Ответ

0 голосов
/ 31 мая 2020

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

Итак, первая проблема здесь:

imagepng($image);
imagepng($imageCart);

Функция imagepng() берет двоичные данные изображения и отправляет их на /dev/stdout, где он будет захвачен веб-сервером и передан запрашивающему клиенту. Наличие двух из них может привести к странному результату, поскольку браузер увидит два объединенных изображения PNG. Как упоминалось в комментариях, это может работать для некоторых браузеров, а может не работать для других - другими словами, мы не можем полагаться на его работу. Лучше всего отправлять только действительный вывод, даже если в некоторых случаях мы сможем заставить его работать (там, где это сработало, браузер, вероятно, использовал первый и отбросил второй). Итак, первое, что нужно было сделать, это отправить только одно изображение.

Следующая проблема была в этой строке, обнаруженная при отладке:

$image = imagecreatefrompng((isset($_SERVER['HTTPS']) ? "https" : "http") .
    "://$_SERVER[HTTP_HOST]" .
    "/wp-content/uploads/cart1.png");

По сути, это загружает исходное изображение PNG через HTTP. / HTTPS. При этом используется функция PHP, которая позволяет использовать URL-адреса вместо путей к файлам. Из руководства :

URL-адрес может использоваться в качестве имени файла с этой функцией, если были включены оболочки fopen . См. fopen () для получения более подробной информации о том, как указать имя файла. См. Поддерживаемые протоколы и оболочки для получения ссылок на информацию о возможностях различных оболочек, примечания об их использовании и информацию о любых предопределенных переменных, которые они могут предоставить.

Я бы хотел Тогда вы рискуете предположить, что ваш allow_url_fopen истинен на вашем локальном компьютере и ложен или не установлен на вашем VPS. Это можно было бы заставить работать, изменив его удаленно, но исправление, которое было сделано, вероятно, было лучше - а именно загрузка его напрямую из файловой системы.

Если вы используете оболочку fopen, то что вы на самом деле делает запрос к веб-серверу, который загружает изображение с диска, а затем возвращает его через curl. Таким образом, получая изображение напрямую, используя его имя файла, вы «убираете посредника» и получаете его более эффективно.

В этих случаях нормально использовать оператор обхода каталогов для создания относительного пути в каталог скрипта. Было использовано совершенно хорошее решение:

imagecreatefrompng("../../../wp-content/uploads/cart1.png")

Вы также можете использовать переменную magi c (при условии, что сценарий находится на три уровня ниже проекта root):

$projectDir = realpath(__DIRECTORY__ . "/../../..");
imagecreatefrompng($projectDir . "/wp-content/uploads/cart1.png")

Вероятно, вы обнаружите, что WordPress устанавливает некоторые из собственных констант каталога проекта, поэтому их можно было использовать и в этом случае.

...