Автоматическое добавление атрибутов ширины и высоты к тегам ‹img› с помощью функции PHP

Что мне нужно, так это функция, которую я могу запускать на основе пользовательского ввода, которая будет интеллектуально находить и добавлять атрибуты width и height к любому тегу <img> в BLOB-объекте HTML, чтобы избежать проблем с перекомпоновкой страницы во время загрузки изображений.

Я пишу сценарий публикации для PHP-форума, где пользовательский ввод дезинфицируется и обычно делается лучше, прежде чем записывать его в базу данных для последующего отображения. В качестве примера того, что я делаю, чтобы сделать вещи лучше, у меня есть скрипт, который вставляет атрибуты alt в изображения следующим образом:

Here are two images: <img src="http://example.com/image.png"> <img src="http://example.com/image2.png">

который после санации скриптом публикации становится

Here are two images: <img src="http://example.com/image.png" alt="Posted image"> <img src="http://example.com/image2.png" alt="Posted image">

(Это делает его валидацию строгим в соответствии с HTML 4, но, возможно, это не соответствует духу атрибута alt — увы!)

Итак, для моей функции у меня есть смутное представление о том, что серверу нужно будет запускать getimagesize() для каждого внешнего изображения, которое он находит в блоке HTML, а затем применять атрибуты, которые генерирует функция, к каждому тегу <img>, с которым он сталкивается. Я предполагаю, что эта функция была написана раньше, но мне не повезло с документами Google или php.net. Должен ли я начинать с нуля, или кто-то знает (относительно) надежную функцию, которую я могу использовать или адаптировать для выполнения этой работы?


person SuitCase    schedule 01.07.2010    source источник
comment
Я считаю, что вам нужно будет получить и записать изображение в файл, а затем запустить для него getimagesize(), чтобы получить его ширину и высоту. Как только вы закончите с этим, вы можете отменить связь ($ pathToFile), чтобы удалить его.   -  person Fanis Hatzidakis    schedule 01.07.2010
comment
Что-то более эффективное было бы иметь макет, который не ломается/перекомпоновывается при загрузке изображений; или, возможно, использовать сценарии на стороне клиента для управления атрибутами ширины и высоты.   -  person quantumSoup    schedule 01.07.2010


Ответы (3)


Вы правы насчет getimagesize(). Вы можете просто сделать что-то вроде этого:

$img = 'image2.png';
$info = getimagesize($img);
printf('<img src="%s" %s>', $img, $info[3]);

Если изображение размещено в удаленном месте, вам придется загрузить все изображения (функция позаботится об этом), поэтому вы можете кэшировать результат, чтобы ускорить последующие запросы.

Изменить: только что увидел, что у вас есть строка, содержащая различные элементы <img>. Это должно помочь:

<?php
$html = <<<EOF
something <img src="https://www.google.com/images/logos/ssl_logo_lg.gif"> hello <img src="https://mail.google.com/mail/images/2/5/logo1.png">
EOF;

$dom = new DOMDocument();
$dom->loadHTML($html);

foreach ($dom->getElementsByTagName('img') as $img) {
    list($width, $height) = getimagesize($img->getAttribute('src'));
    $img->setAttribute('width', $width);
    $img->setAttribute('height', $height);
}

$xpath = new DOMXpath($dom);
$newDom = new DOMDocument();
foreach ($xpath->query('//body/p')->item(0)->childNodes as $node) {
    $newDom->appendChild($newDom->importNode($node, true));
}

$newHtml = $newDom->saveHTML();
?>
person Daniel Egeberg    schedule 01.07.2010
comment
на самом деле кэширование результатов — хорошая идея, независимо от того, где хранятся изображения. - person Gordon; 01.07.2010
comment
Я очень благодарен вам за то, что вы прошли через процесс DOM, так как это меня напугало. Сейчас попробую использовать этот код. - person SuitCase; 01.07.2010
comment
Я медленно реализую это и в настоящее время ломаю голову над проверкой if(), которая гарантирует, что я не получу width="" height="", если PHP не сможет получить изображение. Я также заметил, что если моя строка HTML просто <img ...> <img ...> <img ...> , ничего не возвращается в $newHTML. Я обойду это своим ужасным способом, вставив фиктивное слово в начало и конец строки и удалив его после обработки. Это замечательно, однако. Спасибо. - person SuitCase; 01.07.2010

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

И, сделав это, вы можете отправить работу в браузер, используя кешируемый javascript, который устанавливает размеры изображения и вызывается встроенным в конце html (преимущество которого заключается в том, что вам не нужно проталкивать весь html через ваш PHP-код для перезаписи). Подсказка: перебрать document.images[]

ХТН

C.

person symcbean    schedule 01.07.2010
comment
В качестве альтернативы это неплохая идея. Это не было бы концом света, если бы кто-то, например, обошел этот javascript, поэтому не критично, чтобы PHP делал это. - person SuitCase; 01.07.2010

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

person allixsenos    schedule 01.07.2010
comment
Действительно ли кэширование является проблемой, когда PHP должен выполнять только тяжелую работу по загрузке удаленного изображения и его проверке после того, как пользователь разместит изображение на сайте? Его не нужно будет вызывать при каждой загрузке страницы, поскольку он изменит HTML-код, записанный в базу данных, который извлекается и дословно вставляется в сценарий отображения потока. Изображения можно публиковать только несколько раз в день. - person SuitCase; 01.07.2010