PHP構成修正

This commit is contained in:
ry.yamafuji 2025-04-03 09:02:08 +09:00
parent bee2265fc6
commit 990cf276a4
12 changed files with 284 additions and 14212 deletions

View File

@ -1,15 +1,19 @@
version: '3'
version: '3.9'
services:
php:
build:
context: ./docker
container_name: php-xdebug
stdin_open: true
tty: true
ports:
- '80:80'
context: .
dockerfile: docker/php/Dockerfile
volumes:
- ./src:/var/www/html
- ./docker/php.ini:/usr/local/etc/php/php.ini
web:
image: nginx:alpine
ports:
- "8080:80"
volumes:
- ./src:/var/www/html
- ./docker/nginx/default.conf:/etc/nginx/conf.d/default.conf
depends_on:
- app

View File

@ -1,21 +0,0 @@
FROM php:7.4-apache
RUN apt-get update && apt-get install -y \
libyaml-dev \
vim \
zip \
unzip
# composerのインストール
RUN cd /usr/bin && curl -s http://getcomposer.org/installer | php && ln -s /usr/bin/composer.phar /usr/bin/composer
# install xdebug
RUN pecl install xdebug-2.9.8 \
&& docker-php-ext-enable xdebug
# install yaml
RUN pecl install yaml \
&& docker-php-ext-enable yaml

18
docker/nginx/default.conf Normal file
View File

@ -0,0 +1,18 @@
server {
listen 80;
server_name localhost;
root /var/www/html;
index index.php index.html;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
fastcgi_pass php:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
}

30
docker/php/Dockerfile Normal file
View File

@ -0,0 +1,30 @@
FROM php:8.3-fpm-alpine
# 必要パッケージのインストール
RUN apk add --no-cache \
imagemagick \
imagemagick-dev \
libpng-dev \
libjpeg-turbo-dev \
libheif \
freetype-dev \
unzip \
curl \
autoconf \
gcc \
g++ \
make
RUN docker-php-ext-configure gd \
--with-freetype --with-jpeg \
&& docker-php-ext-install gd
RUN pecl install imagick \
&& docker-php-ext-enable imagick \
&& apk del autoconf gcc g++ make # ビルド系は後で削除して軽量化
# Composerの追加公式composerイメージから取得
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
WORKDIR /var/www/html

View File

@ -1,9 +0,0 @@
<?php
class TestCase{
public string $type;
public string $title;
}

View File

@ -1,5 +0,0 @@
{
"require": {
"symfony/yaml": "^5.4"
}
}

243
src/composer.lock generated
View File

@ -1,243 +0,0 @@
{
"_readme": [
"This file locks the dependencies of your project to a known state",
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "0c3ba147c0e4705e712772699329c079",
"packages": [
{
"name": "symfony/deprecation-contracts",
"version": "v2.5.2",
"source": {
"type": "git",
"url": "https://github.com/symfony/deprecation-contracts.git",
"reference": "e8b495ea28c1d97b5e0c121748d6f9b53d075c66"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/e8b495ea28c1d97b5e0c121748d6f9b53d075c66",
"reference": "e8b495ea28c1d97b5e0c121748d6f9b53d075c66",
"shasum": ""
},
"require": {
"php": ">=7.1"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "2.5-dev"
},
"thanks": {
"name": "symfony/contracts",
"url": "https://github.com/symfony/contracts"
}
},
"autoload": {
"files": [
"function.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Nicolas Grekas",
"email": "p@tchwork.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "A generic function and convention to trigger deprecation notices",
"homepage": "https://symfony.com",
"support": {
"source": "https://github.com/symfony/deprecation-contracts/tree/v2.5.2"
},
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2022-01-02T09:53:40+00:00"
},
{
"name": "symfony/polyfill-ctype",
"version": "v1.27.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-ctype.git",
"reference": "5bbc823adecdae860bb64756d639ecfec17b050a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/5bbc823adecdae860bb64756d639ecfec17b050a",
"reference": "5bbc823adecdae860bb64756d639ecfec17b050a",
"shasum": ""
},
"require": {
"php": ">=7.1"
},
"provide": {
"ext-ctype": "*"
},
"suggest": {
"ext-ctype": "For best performance"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "1.27-dev"
},
"thanks": {
"name": "symfony/polyfill",
"url": "https://github.com/symfony/polyfill"
}
},
"autoload": {
"files": [
"bootstrap.php"
],
"psr-4": {
"Symfony\\Polyfill\\Ctype\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Gert de Pagter",
"email": "BackEndTea@gmail.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony polyfill for ctype functions",
"homepage": "https://symfony.com",
"keywords": [
"compatibility",
"ctype",
"polyfill",
"portable"
],
"support": {
"source": "https://github.com/symfony/polyfill-ctype/tree/v1.27.0"
},
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2022-11-03T14:55:06+00:00"
},
{
"name": "symfony/yaml",
"version": "v5.4.23",
"source": {
"type": "git",
"url": "https://github.com/symfony/yaml.git",
"reference": "4cd2e3ea301aadd76a4172756296fe552fb45b0b"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/yaml/zipball/4cd2e3ea301aadd76a4172756296fe552fb45b0b",
"reference": "4cd2e3ea301aadd76a4172756296fe552fb45b0b",
"shasum": ""
},
"require": {
"php": ">=7.2.5",
"symfony/deprecation-contracts": "^2.1|^3",
"symfony/polyfill-ctype": "^1.8"
},
"conflict": {
"symfony/console": "<5.3"
},
"require-dev": {
"symfony/console": "^5.3|^6.0"
},
"suggest": {
"symfony/console": "For validating YAML files using the lint command"
},
"bin": [
"Resources/bin/yaml-lint"
],
"type": "library",
"autoload": {
"psr-4": {
"Symfony\\Component\\Yaml\\": ""
},
"exclude-from-classmap": [
"/Tests/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Loads and dumps YAML files",
"homepage": "https://symfony.com",
"support": {
"source": "https://github.com/symfony/yaml/tree/v5.4.23"
},
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2023-04-23T19:33:36+00:00"
}
],
"packages-dev": [],
"aliases": [],
"minimum-stability": "stable",
"stability-flags": [],
"prefer-stable": false,
"prefer-lowest": false,
"platform": [],
"platform-dev": [],
"plugin-api-version": "2.3.0"
}

86
src/example/ImageEdit.php Normal file
View File

@ -0,0 +1,86 @@
<?php
// ImageEdit.php
// 画像をリサイズして変換するPHPWEBアプリケーション
// 画像の最大サイズを指定し、JPEGまたはPNG形式に変換します
function processImage($file, $maxWidth = 400, $maxHeight = 400, $format = 'jpeg')
{
$srcImage = @imagecreatefromstring(file_get_contents($file['tmp_name']));
if (!$srcImage) {
return ['error' => '無効な画像です'];
}
$origWidth = imagesx($srcImage);
$origHeight = imagesy($srcImage);
// サイズ比率を維持してリサイズ
$scale = min($maxWidth / $origWidth, $maxHeight / $origHeight, 1);
$newWidth = (int) ($origWidth * $scale);
$newHeight = (int) ($origHeight * $scale);
$dstImage = imagecreatetruecolor($newWidth, $newHeight);
// 透過画像PNGなどの背景を白にする
$white = imagecolorallocate($dstImage, 255, 255, 255);
imagefilledrectangle($dstImage, 0, 0, $newWidth, $newHeight, $white);
imagecopyresampled($dstImage, $srcImage, 0, 0, 0, 0, $newWidth, $newHeight, $origWidth, $origHeight);
// 出力
ob_start();
if ($format === 'png') {
imagepng($dstImage);
$mime = 'image/png';
} else {
imagejpeg($dstImage, null, 90);
$mime = 'image/jpeg';
}
$data = ob_get_clean();
imagedestroy($srcImage);
imagedestroy($dstImage);
return ['data' => $data, 'mime' => $mime];
}
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>画像変換ツール</title>
</head>
<body>
<h1>画像変換ツール</h1>
<form method="post" enctype="multipart/form-data">
<label>画像を選択:</label><br>
<input type="file" name="image" accept="image/*" required><br><br>
<label>変換形式:</label>
<select name="format">
<option value="jpeg">JPEG</option>
<option value="png">PNG</option>
</select><br><br>
<label>最大サイズ(幅×高さ):</label>
<input type="number" name="maxWidth" value="400" min="1"> ×
<input type="number" name="maxHeight" value="400" min="1"><br><br>
<button type="submit">変換</button>
</form>
<?php
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_FILES['image'])) {
$result = processImage($_FILES['image'], $_POST['maxWidth'] ?? 400, $_POST['maxHeight'] ?? 400, $_POST['format'] ?? 'jpeg');
if (isset($result['error'])) {
echo "<p style='color:red;'>エラー: {$result['error']}</p>";
} else {
$base64 = base64_encode($result['data']);
echo "<h2>変換結果:</h2>";
echo "<img src='data:{$result['mime']};base64,{$base64}'><br>";
echo "<a download='converted.{$result['mime']}' href='data:{$result['mime']};base64,{$base64}'>画像を保存</a>";
}
}
?>
</body>
</html>

View File

@ -0,0 +1,137 @@
<?php
function canUseImagick(): bool {
return class_exists('Imagick');
}
function loadImage($filePath): array {
$mime = mime_content_type($filePath);
// HEIC対応Imagick前提
if (strpos($mime, 'heic') !== false || strpos($mime, 'heif') !== false) {
if (!canUseImagick()) return ['error' => 'HEIC形式にはImagickが必要です'];
$image = new Imagick($filePath);
return ['image' => $image];
}
// 通常の画像読み込みGD
$imgStr = file_get_contents($filePath);
$gdImage = @imagecreatefromstring($imgStr);
if (!$gdImage) return ['error' => '画像の読み込みに失敗しました'];
return ['gd' => $gdImage];
}
function gdToBlob($img, $format, $transparent): array {
ob_start();
if ($format === 'png') {
if ($transparent) {
imagesavealpha($img, true);
$transparentColor = imagecolorallocatealpha($img, 0, 0, 0, 127);
imagefill($img, 0, 0, $transparentColor);
}
imagepng($img);
$mime = 'image/png';
} elseif ($format === 'webp' && function_exists('imagewebp')) {
imagewebp($img);
$mime = 'image/webp';
} else {
imagejpeg($img, null, 90);
$mime = 'image/jpeg';
}
$data = ob_get_clean();
return ['data' => $data, 'mime' => $mime];
}
function imagickToBlob($img, $format): array {
$img->setImageFormat($format);
return ['data' => $img->getImageBlob(), 'mime' => 'image/' . $format];
}
function resizeAndCropGD($img, $maxW, $maxH, $cropX, $cropY, $cropW, $cropH): GdImage {
if ($cropW && $cropH) {
$img = imagecrop($img, ['x' => $cropX, 'y' => $cropY, 'width' => $cropW, 'height' => $cropH]);
}
$srcW = imagesx($img);
$srcH = imagesy($img);
$scale = min($maxW / $srcW, $maxH / $srcH, 1);
$dstW = (int)($srcW * $scale);
$dstH = (int)($srcH * $scale);
$dst = imagecreatetruecolor($dstW, $dstH);
imagecopyresampled($dst, $img, 0, 0, 0, 0, $dstW, $dstH, $srcW, $srcH);
return $dst;
}
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>画像変換ツール</title>
</head>
<body>
<h1>画像変換ツール</h1>
<form method="post" enctype="multipart/form-data">
<label>画像を選択:</label><br>
<input type="file" name="image" accept="image/*" required><br><br>
<label>出力形式:</label>
<select name="format">
<option value="jpeg">JPEG</option>
<option value="png">PNG</option>
<option value="webp">WebP</option>
</select><br><br>
<label>透過背景を保持PNG/WebPのみ:</label>
<input type="checkbox" name="transparent"><br><br>
<label>最大サイズ(幅×高さ):</label>
<input type="number" name="maxWidth" value="400" min="1"> ×
<input type="number" name="maxHeight" value="400" min="1"><br><br>
<label>トリミングX, Y, , 高さ):</label><br>
<input type="number" name="cropX" placeholder="X" min="0">
<input type="number" name="cropY" placeholder="Y" min="0">
<input type="number" name="cropW" placeholder="" min="1">
<input type="number" name="cropH" placeholder="高さ" min="1"><br><br>
<button type="submit">変換</button>
</form>
<?php
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_FILES['image'])) {
$tmp = $_FILES['image']['tmp_name'];
$format = $_POST['format'] ?? 'jpeg';
$transparent = isset($_POST['transparent']);
$maxW = (int)($_POST['maxWidth'] ?? 400);
$maxH = (int)($_POST['maxHeight'] ?? 400);
$cropX = (int)($_POST['cropX'] ?? 0);
$cropY = (int)($_POST['cropY'] ?? 0);
$cropW = isset($_POST['cropW']) ? (int)$_POST['cropW'] : 0;
$cropH = isset($_POST['cropH']) ? (int)$_POST['cropH'] : 0;
$result = loadImage($tmp);
if (isset($result['error'])) {
echo "<p style='color:red;'>エラー: {$result['error']}</p>";
} else {
if (isset($result['gd'])) {
$img = resizeAndCropGD($result['gd'], $maxW, $maxH, $cropX, $cropY, $cropW, $cropH);
$out = gdToBlob($img, $format, $transparent);
} elseif (isset($result['image'])) {
$image = $result['image'];
if ($cropW && $cropH) {
$image->cropImage($cropW, $cropH, $cropX, $cropY);
}
$image->scaleImage($maxW, $maxH, true);
$out = imagickToBlob($image, $format);
}
$base64 = base64_encode($out['data']);
$mime = $out['mime'];
echo "<h2>変換結果:</h2>";
echo "<img src='data:$mime;base64,$base64'><br><br>";
echo "<a download='converted.$format' href='data:$mime;base64,$base64'>画像を保存</a>";
}
}
?>
</body>
</html>

View File

@ -1,70 +1,2 @@
<?php
$timer_start = microtime(true);// 実行開始速度
require __DIR__ . '/vendor/autoload.php';
/**
* load_yaml_file
*
* yamlファイルを読み込む関数
*
* @param string $filename
* @return false | mixed
*/
function load_yaml_file(string $filename){
$result = yaml_parse_file($filename);
return $result;
#$input = file_get_contents($filename);
#$result = \Symfony\Component\Yaml\Yaml::parse($input);
}
/**
* set_yaml2testcase
*
* yamlからテストケースオブジェクトを生成する
*
* @param array $ymal
* @return void
*/
function set_yaml2testcase($yaml){
echo '-------------------------------'.PHP_EOL;
echo 'openapi='.$yaml['openapi'].PHP_EOL;
foreach($yaml['paths'] as $path => $data){
// パラメータのテストケース
// echo 'openapi='.$yaml['openapi'].PHP_EOL;
// getの場合のテストケース
// echo 'openapi='.$yaml['openapi'].PHP_EOL;
// post・putの場合のテストケース
// echo 'openapi='.$yaml['openapi'].PHP_EOL;
// deleteの場合のテストケース
break;
}
# echo 'path='.$yaml['paths'][0][0].PHP_EOL;
echo '-------------------------------'.PHP_EOL;
return ;
}
$filename = 'openapi.yaml';
$yaml = yaml_parse_file($filename);
if(!$yaml){
print 'ERROR Purse OpenApiFile'.PHP_EOL ;
return -1;
}
set_yaml2testcase($yaml);
$timer_end = microtime(true);// 実行終了速度
$timer = $timer_end - $timer_start;
echo '実行速度:'.ceil($timer*1000)."ms: $timer".PHP_EOL;
echo "Hello, World!";

File diff suppressed because it is too large Load Diff