Перейти к содержимому
Поиск
Php Разработка

PHP: полный мануал с примерами, функциями и ООП

Практический мануал PHP: от переменных и читаемого кода до безопасных форм, интеграций, базы данных и ООП на примере магазина. Учебный маршрут, поиск функций, подробные примеры, разбор ошибок и исходники для скачивания.

Александр НекрасовИзменено:
Практический мануал PHP: от переменных и функций к объектной модели интернет-магазина
PHP 8.5.11468 глав6256 карточек справочника
Дерево руководства

Глава 406 · После переменных, объектов и файлов

Gmagick: миниатюры целиком, обрезка и запрет увеличения

Выбрать между вписыванием, растяжением и центральной обрезкой; сохранить маленький вход без увеличения.

Вписать альбомное изображение и проверить удаление профиля

Для страницы нужна картинка целиком внутри рамки 160×160. Альбомный вход 320×200 должен сохранить пропорцию: получится 160×100, а не растянутый квадрат.

Вписывание 320×200 в рамку 160×160
Вписывание 320×200 в рамку 160×160
$image = new Gmagick(__DIR__ . "/product.ppm");
$image->thumbnailImage(160, 160, true);
$image->setImageFormat("PNG");
$image->writeImage(__DIR__ . "/fit-landscape.png");

Два числа задают границы рамки, true включает вписывание. Коэффициент масштаба — меньшая из долей 160/320 и 160/200, то есть 0.5. Обе стороны умножаются на него: 160×100. Метод меняет объект; для второго варианта исходного изображения ниже будет использован clone.

Вписать альбомное изображение и проверить удаление профиля

Вписать альбомное изображение и проверить удаление профиляСамостоятельный пример
<?php
declare(strict_types=1);
require __DIR__ . '/gm-fixture.php';
gmRestore();
$image = new Gmagick(__DIR__.'/product.ppm');
$image->setImageProfile('aen','own-test-profile');
$profileBefore = $image->getImageProfile('aen');
$result = $image->thumbnailImage(160,160,true);
$errors = ['removed_profile'=>gmTry(fn()=>$image->getImageProfile('aen'))];
$image->setImageFormat('PNG');
$image->setImageDepth(8);
$image->writeImage(__DIR__.'/fit-landscape.png');

gmReport('gmagick-fit-landscape',["__construct", "setimageprofile", "getimageprofile", "thumbnailimage", "getimagewidth", "getimageheight", "setimageformat", "writeimage", "setimagedepth"],["fit-landscape.png"],
    ['fit_size'=>$image->getImageWidth()===160&&$image->getImageHeight()===100,'same_object'=>$result===$image,'profile_was_present'=>$profileBefore==='own-test-profile','profile_removed'=>$errors['removed_profile']['class']==='GmagickException'],
    $errors ?? [], []);
echo "fit-landscape.png 160x100 profile=removed\n";
Ожидаемый результат
fit-landscape.png 160x100 profile=removed

Распакуйте example.php, gm-fixture.php и два файла .ppm.b64 рядом; php example.php восстановит собственные входы. Проверено: PHP 8.3.6 / Gmagick 2.0.6RC1 / GraphicsMagick 1.3.42 Q16. PNG показывают настоящий результат; metrics.json содержит версии, размеры, хеши, проверки и ошибки.

Точный вывод успешного запуска
fit-landscape.png 160x100 profile=removed

thumbnailImage также удаляет профили. Полная программа добавляет собственный профиль с именем aen и короткими тестовыми байтами, подтверждает чтение, затем получает GmagickException при попытке прочитать его после thumbnail. Это проверка удаления обычного тестового профиля, не обещание корректного преобразования ICC-цветов. Если цветовые профили важны, заранее определите свой порядок управления цветом.

Вписать портретный вход без обрезки

Та же рамка должна корректно принять портретный товар. Изображение сохраняется целиком, но теперь ограничивающей стороной станет высота.

Вписывание 200×320 в ту же рамку
Вписывание 200×320 в ту же рамку
$image = new Gmagick(__DIR__ . "/portrait.ppm");
$image->thumbnailImage(160, 160, true);
$image->setImageFormat("PNG");
$image->writeImage(__DIR__ . "/fit-portrait.png");

У исходника 200×320, поэтому меньшая доля — 160/320=0.5. Результат 100×160. У самого файла нет полей до 160×160: он действительно имеет ширину 100. Свободное место карточки оформляет HTML/CSS, если интерфейсу нужен квадратный контейнер.

Вписать портретный вход без обрезки

Вписать портретный вход без обрезкиСамостоятельный пример
<?php
declare(strict_types=1);
require __DIR__ . '/gm-fixture.php';
gmRestore();
$image = new Gmagick(__DIR__.'/portrait.ppm');
$image->thumbnailImage(160,160,true);
$image->setImageFormat('PNG');
$image->setImageDepth(8);
$image->writeImage(__DIR__.'/fit-portrait.png');

gmReport('gmagick-fit-portrait',["__construct", "thumbnailimage", "getimagewidth", "getimageheight", "setimageformat", "writeimage", "setimagedepth"],["fit-portrait.png"],
    ['fit_size'=>$image->getImageWidth()===100&&$image->getImageHeight()===160],
    $errors ?? [], []);
echo "fit-portrait.png 100x160 whole-image=yes\n";
Ожидаемый результат
fit-portrait.png 100x160 whole-image=yes

Распакуйте example.php, gm-fixture.php и два файла .ppm.b64 рядом; php example.php восстановит собственные входы. Проверено: PHP 8.3.6 / Gmagick 2.0.6RC1 / GraphicsMagick 1.3.42 Q16. PNG показывают настоящий результат; metrics.json содержит версии, размеры, хеши, проверки и ошибки.

Точный вывод успешного запуска
fit-portrait.png 100x160 whole-image=yes

Сравните обе миниатюры: цветные края остаются видны. Полезное обещание режима — сохранение целого изображения и пропорций в заданной рамке. Оно отличается от заполнения всей рамки и от запрета увеличивать слишком маленький вход; оба решения разберём дальше.

Сравнить пропорции с принудительным квадратом

Иногда внешняя система требует точные стороны, а иногда важнее сохранить форму товара. Сравним эти требования на двух копиях одной картинки.

Сохранение пропорций при resizeImage
Сохранение пропорций при resizeImage
Растяжение до заданных сторон
Растяжение до заданных сторон
$source = new Gmagick(__DIR__ . "/product.ppm");
$fit = clone $source;
$stretch = clone $source;
$fit->resizeImage(160,160,Gmagick::FILTER_LANCZOS,1.0,true);
$stretch->resizeImage(160,160,Gmagick::FILTER_LANCZOS,1.0,false);

clone создаёт независимую копию состояния. FILTER_LANCZOS выбирает фильтр пересчёта, 1.0 — коэффициент blur. В пятом аргументе true сохраняет пропорции, false задаёт обе стороны непосредственно. Слово «фильтр» здесь означает способ вычисления новых пикселей, а не художественный эффект.

Сравнить пропорции с принудительным квадратом

Сравнить пропорции с принудительным квадратомСамостоятельный пример
<?php
declare(strict_types=1);
require __DIR__ . '/gm-fixture.php';
gmRestore();
$source = new Gmagick(__DIR__.'/product.ppm');
$fit = clone $source;
$stretch = clone $source;
$fit->resizeImage(160,160,Gmagick::FILTER_LANCZOS,1.0,true);
$stretch->resizeImage(160,160,Gmagick::FILTER_LANCZOS,1.0,false);
$fit->setImageFormat('PNG');
$fit->setImageDepth(8);
$fit->writeImage(__DIR__.'/resize-fit.png');
$stretch->setImageFormat('PNG');
$stretch->setImageDepth(8);
$stretch->writeImage(__DIR__.'/resize-stretch.png');

gmReport('gmagick-resize-modes',["__construct", "resizeimage", "getimagewidth", "getimageheight", "setimageformat", "writeimage", "setimagedepth"],["resize-fit.png", "resize-stretch.png"],
    ['fit'=>$fit->getImageWidth()===160&&$fit->getImageHeight()===100,'stretch'=>$stretch->getImageWidth()===160&&$stretch->getImageHeight()===160,'original'=>$source->getImageWidth()===320&&$source->getImageHeight()===200],
    $errors ?? [], []);
echo "resize-fit.png 160x100 resize-stretch.png 160x160\n";
Ожидаемый результат
resize-fit.png 160x100 resize-stretch.png 160x160

Распакуйте example.php, gm-fixture.php и два файла .ppm.b64 рядом; php example.php восстановит собственные входы. Проверено: PHP 8.3.6 / Gmagick 2.0.6RC1 / GraphicsMagick 1.3.42 Q16. PNG показывают настоящий результат; metrics.json содержит версии, размеры, хеши, проверки и ошибки.

Точный вывод успешного запуска
resize-fit.png 160x100 resize-stretch.png 160x160

Получены 160×100 и 160×160. Во втором случае геометрия центрального рисунка искажена. Исходник остался 320×200. Нельзя назвать один результат всегда лучшим: решение зависит от требования. Для фиксированного квадрата без искажения есть другая цена — потеря части изображения при обрезке.

Заполнить квадрат ценой обрезки краёв

Для квадратной плитки товара нужно заполнить всю область без растяжения. Центральная обрезка даст нужный размер, но часть исходного изображения исчезнет.

Центральная обрезка: боковые цветные полосы потеряны
Центральная обрезка: боковые цветные полосы потеряны
$image = new Gmagick(__DIR__ . "/product.ppm");
$image->cropThumbnailImage(120, 120);
$image->setImageFormat("PNG");
$image->writeImage(__DIR__ . "/crop-card.png");

cropThumbnailImage получает две стороны конечного файла. Для нашего входа сначала получается достаточно крупное изображение, затем вырезается центральная область. Красная и зелёная полосы обозначали края исходника: теперь их нет. Центральный объект сохранил форму.

Заполнить квадрат ценой обрезки краёв

Заполнить квадрат ценой обрезки краёвСамостоятельный пример
<?php
declare(strict_types=1);
require __DIR__ . '/gm-fixture.php';
gmRestore();
$image = new Gmagick(__DIR__.'/product.ppm');
$result = $image->cropThumbnailImage(120,120);
$image->setImageFormat('PNG');
$image->setImageDepth(8);
$image->writeImage(__DIR__.'/crop-card.png');

gmReport('gmagick-crop-card',["__construct", "cropthumbnailimage", "getimagewidth", "getimageheight", "setimageformat", "writeimage", "setimagedepth"],["crop-card.png"],
    ['square'=>$image->getImageWidth()===120&&$image->getImageHeight()===120,'same_object'=>$result===$image],
    $errors ?? [], []);
echo "crop-card.png 120x120 center-crop=yes\n";
Ожидаемый результат
crop-card.png 120x120 center-crop=yes

Распакуйте example.php, gm-fixture.php и два файла .ppm.b64 рядом; php example.php восстановит собственные входы. Проверено: PHP 8.3.6 / Gmagick 2.0.6RC1 / GraphicsMagick 1.3.42 Q16. PNG показывают настоящий результат; metrics.json содержит версии, размеры, хеши, проверки и ошибки.

Точный вывод успешного запуска
crop-card.png 120x120 center-crop=yes

Этот режим не определяет смысл изображения и не знает расположение лица, логотипа или текста. Если важная часть у края, нужен выбор области кадрирования. Отдельная проба также показала увеличение маленького входа до требуемого квадрата; формулировка «thumbnail» не означает автоматическое ограничение увеличения.

Сделать явную политику «не увеличивать»

Маленькую картинку нельзя превратить в детальную большую простым изменением размеров. Введём ясное правило сервиса: уменьшать при необходимости, оставлять маленький вход как есть.

Маленький вход сохранён без увеличения
Маленький вход сохранён без увеличения
Большой вход уменьшен
Большой вход уменьшен
Прямой thumbnailImage увеличил маленький вход
Прямой thumbnailImage увеличил маленький вход
$width = $image->getImageWidth();
$height = $image->getImageHeight();
if ($width > 160 || $height > 160) {
    $image->thumbnailImage(160, 160, true);
}

if выполняет блок только при истинном условии. Оператор || означает логическое «или»: достаточно превышения хотя бы одной стороны. Прямой thumbnailImage(160,160,true) увеличил наш 80×50 до 160×100. Проверка до вызова нужна именно для собственной политики, а не для исправления арифметики библиотеки.

Сделать явную политику «не увеличивать»

Сделать явную политику «не увеличивать»Самостоятельный пример
<?php
declare(strict_types=1);
require __DIR__ . '/gm-fixture.php';
gmRestore();
function previewWithoutEnlarging(Gmagick $input,int $maxWidth,int $maxHeight):Gmagick
{
    if ($maxWidth<1 || $maxHeight<1) {
        throw new InvalidArgumentException('Positive maximum dimensions required');
    }
    $copy = clone $input;
    if ($copy->getImageWidth()>$maxWidth || $copy->getImageHeight()>$maxHeight) {
        $copy->thumbnailImage($maxWidth,$maxHeight,true);
    }
    return $copy;
}
$large = new Gmagick(__DIR__.'/product.ppm');
$small = clone $large;
$small->resizeImage(80,50,Gmagick::FILTER_LANCZOS,1.0);
$unchanged = previewWithoutEnlarging($small,160,160);
$reduced = previewWithoutEnlarging($large,160,160);
$default = clone $small;
$default->thumbnailImage(160,160,true);
$blank = new Gmagick();
$blank->newImage(80,50,'#244f65','png');
$errors = ['zero'=>gmTry(fn()=>previewWithoutEnlarging($blank,0,160))];
foreach (['policy-small.png'=>$unchanged,'policy-large.png'=>$reduced,'default-upscale.png'=>$default] as $name=>$image) {
    $image->setImageFormat('PNG');
$image->setImageDepth(8);$image->writeImage(__DIR__.'/'.$name);
}

gmReport('gmagick-size-policy',["__construct", "newimage", "resizeimage", "thumbnailimage", "getimagewidth", "getimageheight", "setimageformat", "writeimage", "setimagedepth"],["policy-small.png", "policy-large.png", "default-upscale.png"],
    ['small_kept'=>$unchanged->getImageWidth()===80&&$unchanged->getImageHeight()===50,'large_reduced'=>$reduced->getImageWidth()===160&&$reduced->getImageHeight()===100,'default_enlarged'=>$default->getImageWidth()===160&&$default->getImageHeight()===100,'zero_rejected'=>$errors['zero']['class']==='InvalidArgumentException'],
    $errors ?? [], []);
echo "policy-small.png 80x50 policy-large.png 160x100 default-upscale.png 160x100\n";
Ожидаемый результат
policy-small.png 80x50 policy-large.png 160x100 default-upscale.png 160x100

Распакуйте example.php, gm-fixture.php и два файла .ppm.b64 рядом; php example.php восстановит собственные входы. Проверено: PHP 8.3.6 / Gmagick 2.0.6RC1 / GraphicsMagick 1.3.42 Q16. PNG показывают настоящий результат; metrics.json содержит версии, размеры, хеши, проверки и ошибки.

Точный вывод успешного запуска
policy-small.png 80x50 policy-large.png 160x100 default-upscale.png 160x100

Полная функция получает объект и две положительные границы, делает копию и возвращает результат. Нулевая граница отвергается как InvalidArgumentException. Это правило функции: сама библиотека в ограниченной пробе принимала один ноль для расчёта пропорции, но (0,0) вызывало ошибку. Рядом сохранены маленький результат 80×50, уменьшенный большой 160×100 и увеличенный прямым вызовом 160×100.

Упражнение: вписать 320×200 в 120×120 без обрезки. Ответ: 120×75; обе стороны умножаются на 0.375. Чтобы получить именно 120×120, выберите растяжение или осознанную обрезку. Упражнение: вход 80×50, предел 160×160 и запрет увеличения. Ответ: оставить 80×50, как делает наша функция. Количество пикселей и размер ядра фильтра влияют на стоимость обработки; сравнение с другой программой требует одинаковых входов, кодеров и настроек, а не общего обещания скорости.

Из реальных вопросов разработчиков

Why is gmagick::thumbnailimage slower than exec(gm)?: Thumbnail в PHP кажется медленнее похожей команды, хотя параметры чтения различаются. Объясняем стоимость чтения и обработки и необходимость сравнить одинаковые входы и настройки; не заявляем универсального преимущества скорости.

Gmagick thumbnail for multi-page PDF: Разработчик путает миниатюру одного изображения с обработкой многостраничного PDF. Отделяем выбор геометрии миниатюры от последовательности страниц и внешнего декодера; PDF не входит в результаты этого пакета.

Функции и методы этой темы

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

Gmagick::cropthumbnailimageПолучить заполненную миниатюру фиксированного размера

PECL gmagick >= Unknown · gmagick

Gmagick::cropthumbnailimage(int $width, int $height): Gmagick
Gmagick::cropthumbnailimage(int $width, int $height): Gmagick

width и height — обязательные размеры миниатюры. Метод масштабирует изображение и вырезает центральную часть, возвращая Gmagick. Центральная обрезка не понимает, где лицо или важная надпись: на нашем входе исчезли боковые цветные полосы. Описание говорит об уменьшении, но отдельная проверка 80×50→120×120 показала, что маленький вход также может увеличиваться.

ПараметрТип и обязательностьНазначение
$widthint; обязательныйШирина в пикселях.
$heightint; обязательныйВысота в пикселях.

Официальный результат: объект Gmagick. Методы обработки изменяют состояние объекта; для независимого результата используйте clone.

Официальная отметка версии: PECL gmagick >= Unknown. Значение Unknown в каталоге PHP.net не задаёт точную минимальную версию. Проверенная среда этой главы — PHP 8.3.6, Gmagick 2.0.6RC1, GraphicsMagick 1.3.42 Q16; её нельзя автоматически переносить на Windows PHP 8.5 или другой выпуск расширения.

Документированная ошибка — GmagickException. Ошибка типа аргумента может произойти раньше и дать TypeError; её не следует смешивать с отказом декодера или файловой системы. Конкретные обработанные случаи отмечены в примерах.

Два различных применения: Заполнить квадрат ценой обрезки краёв; Собрать четыре превью из двух способов чтения. В этих разделах есть полный скачиваемый код, настоящий результат и точный вывод.

Gmagick::resizeimageПересчитать размеры с выбранным фильтром

PECL gmagick >= Unknown · gmagick

Gmagick::resizeimage(int $width, int $height, int $filter, float $blur, bool $fit = false): Gmagick
Gmagick::resizeimage(int $width, int $height, int $filter, float $blur, bool $fit = false): Gmagick

width и height — стороны; filter — константа фильтра; blur — дробный коэффициент; fit — необязательный bool, по умолчанию false. В документации blur больше 1 описан как более размытый, меньше 1 — как более резкий. Пример явно выбирает FILTER_LANCZOS и 1.0. При fit=true рамка 160×160 дала 160×100, при false — 160×160 с изменёнными пропорциями. Возвращается Gmagick.

ПараметрТип и обязательностьНазначение
$widthint; обязательныйШирина в пикселях.
$heightint; обязательныйВысота в пикселях.
$filterint; обязательныйКонстанта фильтра Gmagick::FILTER_*.
$blurfloat; обязательныйКоэффициент размытия фильтра.
$fitbool; необязательный; default falseВписать в указанную рамку с сохранением пропорций; default false.

Официальный результат: объект Gmagick. Методы обработки изменяют состояние объекта; для независимого результата используйте clone.

Официальная отметка версии: PECL gmagick >= Unknown. Значение Unknown в каталоге PHP.net не задаёт точную минимальную версию. Проверенная среда этой главы — PHP 8.3.6, Gmagick 2.0.6RC1, GraphicsMagick 1.3.42 Q16; её нельзя автоматически переносить на Windows PHP 8.5 или другой выпуск расширения.

Документированная ошибка — GmagickException. Ошибка типа аргумента может произойти раньше и дать TypeError; её не следует смешивать с отказом декодера или файловой системы. Конкретные обработанные случаи отмечены в примерах.

В текущем runtime и upstream исходниках есть дополнительный необязательный legacy=false, которого нет в краткой сигнатуре PHP.net: он выбирает прежнее поведение расчёта размеров до 2.0.1. В рабочих программах он не передаётся. Ограниченная проба маленького входа дала одинаковое увеличение при default/false/true; это не доказательство равенства режимов для всех размеров. При одном нулевом размере thumbnail может вычислить его по пропорции; проба 320×200 с (0,100) дала 160×100, (0,0) вызвало исключение. Политика нашего обработчика требует обе положительные границы.

Два различных применения: Сравнить пропорции с принудительным квадратом; Сделать явную политику «не увеличивать». В этих разделах есть полный скачиваемый код, настоящий результат и точный вывод.

Gmagick::thumbnailimageПодготовить уменьшенное изображение для страницы

PECL gmagick >= Unknown · gmagick

Gmagick::thumbnailimage(int $width, int $height, bool $fit = false): Gmagick
Gmagick::thumbnailimage(int $width, int $height, bool $fit = false): Gmagick

width и height — стороны; необязательный fit по умолчанию false. При true они задают пределы рамки, а пропорции сохраняются. Метод также удаляет связанные профили: собственный тестовый профиль был доступен до вызова и отсутствовал после. Возвращается Gmagick. В этой сборке маленький вход 80×50 увеличился до 160×100: fit не означает «только уменьшать». Для запрета увеличения нужна отдельная проверка.

ПараметрТип и обязательностьНазначение
$widthint; обязательныйШирина в пикселях.
$heightint; обязательныйВысота в пикселях.
$fitbool; необязательный; default falseВписать в указанную рамку с сохранением пропорций; default false.

Официальный результат: объект Gmagick. Методы обработки изменяют состояние объекта; для независимого результата используйте clone.

Официальная отметка версии: PECL gmagick >= Unknown. Значение Unknown в каталоге PHP.net не задаёт точную минимальную версию. Проверенная среда этой главы — PHP 8.3.6, Gmagick 2.0.6RC1, GraphicsMagick 1.3.42 Q16; её нельзя автоматически переносить на Windows PHP 8.5 или другой выпуск расширения.

Документированная ошибка — GmagickException. Ошибка типа аргумента может произойти раньше и дать TypeError; её не следует смешивать с отказом декодера или файловой системы. Конкретные обработанные случаи отмечены в примерах.

В текущем runtime и upstream исходниках есть дополнительный необязательный legacy=false, которого нет в краткой сигнатуре PHP.net: он выбирает прежнее поведение расчёта размеров до 2.0.1. В рабочих программах он не передаётся. Ограниченная проба маленького входа дала одинаковое увеличение при default/false/true; это не доказательство равенства режимов для всех размеров. При одном нулевом размере thumbnail может вычислить его по пропорции; проба 320×200 с (0,100) дала 160×100, (0,0) вызвало исключение. Политика нашего обработчика требует обе положительные границы.

Два различных применения: Вписать альбомное изображение и проверить удаление профиля; Вписать портретный вход без обрезки. В этих разделах есть полный скачиваемый код, настоящий результат и точный вывод.

Источники и обсуждения

Код и руководство с собой

Скачайте самостоятельные примеры с исходными данными, инструкциями и ожидаемыми результатами. Примеры HTTP и фрагменты для проекта помечены отдельно: им нужно указанное окружение.

Код не исполняется на сайте. Скачайте нужный пример и запускайте его в своём локальном окружении.

Материалы сверены 2026-10-12. Примеры и объяснения написаны для этого руководства; источники и обсуждения доступны в каждой главе.