Skip to content

Commit 34c41d9

Browse files
committed
Add PHP 8.4, 8.5, GD, Node 20/22/24, and Tracy examples
Add new deployment examples for PHP 8.4 and 8.5 with GitHub workflows, plus examples for GD extension, Node.js 20/22/24 integration, and Tracy debugger integration.
1 parent 7c03c71 commit 34c41d9

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+1222
-0
lines changed
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
name: Deploy php 8.4
2+
3+
on:
4+
push:
5+
paths:
6+
- 'php-8.4/**'
7+
branches:
8+
- "master"
9+
10+
concurrency:
11+
group: php-${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
12+
cancel-in-progress: true
13+
14+
jobs:
15+
deploy:
16+
name: Deploy
17+
uses: ./.github/workflows/vercel.yml
18+
secrets: inherit
19+
with:
20+
projectId: "prj_PLACEHOLDER_8_4"
21+
projectPath: "php-8.4"
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
name: Deploy php 8.5
2+
3+
on:
4+
push:
5+
paths:
6+
- 'php-8.5/**'
7+
branches:
8+
- "master"
9+
10+
concurrency:
11+
group: php-${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
12+
cancel-in-progress: true
13+
14+
jobs:
15+
deploy:
16+
name: Deploy
17+
uses: ./.github/workflows/vercel.yml
18+
secrets: inherit
19+
with:
20+
projectId: "prj_PLACEHOLDER_8_5"
21+
projectPath: "php-8.5"

php-8.4/.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# Vercel
2+
.vercel

php-8.4/api/index.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<?php declare(strict_types = 1);
2+
3+
if (isset($_GET['all'])) {
4+
phpinfo();
5+
} else {
6+
phpinfo(INFO_ALL & ~INFO_ENVIRONMENT & ~INFO_CONFIGURATION & ~INFO_VARIABLES);
7+
}

php-8.4/vercel.json

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{
2+
"functions": {
3+
"api/index.php": {
4+
"runtime": "vercel-php@0.8.0"
5+
}
6+
},
7+
"routes": [
8+
{ "src": "/(.*)", "dest": "/api/index.php" }
9+
],
10+
"build": {
11+
"env": {
12+
"NOW_PHP_DEBUG": "1"
13+
}
14+
}
15+
}

php-gd/.gitignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# Vercel
2+
.vercel
3+
4+
# Composer
5+
vendor/
6+
composer.lock

php-gd/api/gd.php

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
<?php
2+
3+
// Check if GD extension is available
4+
if (!extension_loaded('gd')) {
5+
header('Content-Type: application/json');
6+
http_response_code(500);
7+
echo json_encode([
8+
'error' => 'GD extension is not available',
9+
'message' => 'The GD library is required for this example'
10+
]);
11+
exit;
12+
}
13+
14+
// Create a new image (800x600)
15+
$width = 800;
16+
$height = 600;
17+
$image = imagecreatetruecolor($width, $height);
18+
19+
// Allocate colors
20+
$white = imagecolorallocate($image, 255, 255, 255);
21+
$black = imagecolorallocate($image, 0, 0, 0);
22+
$red = imagecolorallocate($image, 255, 0, 0);
23+
$green = imagecolorallocate($image, 0, 255, 0);
24+
$blue = imagecolorallocate($image, 0, 0, 255);
25+
$yellow = imagecolorallocate($image, 255, 255, 0);
26+
$purple = imagecolorallocate($image, 128, 0, 128);
27+
28+
// Fill background with white
29+
imagefill($image, 0, 0, $white);
30+
31+
// Draw a rectangle
32+
imagerectangle($image, 50, 50, 250, 150, $red);
33+
34+
// Draw a filled rectangle
35+
imagefilledrectangle($image, 300, 50, 500, 150, $green);
36+
37+
// Draw an ellipse
38+
imageellipse($image, 150, 300, 200, 150, $blue);
39+
40+
// Draw a filled ellipse
41+
imagefilledellipse($image, 400, 300, 200, 150, $yellow);
42+
43+
// Draw lines
44+
imageline($image, 550, 50, 750, 150, $purple);
45+
imageline($image, 550, 150, 750, 50, $purple);
46+
47+
// Draw a polygon (without deprecated $num_points parameter)
48+
$points = [
49+
100, 450, // Point 1
50+
200, 500, // Point 2
51+
150, 550, // Point 3
52+
50, 550, // Point 4
53+
0, 500 // Point 5
54+
];
55+
imagepolygon($image, $points, $red);
56+
57+
// Draw a filled polygon (without deprecated $num_points parameter)
58+
$filledPoints = [
59+
300, 450,
60+
450, 450,
61+
500, 550,
62+
400, 550,
63+
250, 550
64+
];
65+
imagefilledpolygon($image, $filledPoints, $blue);
66+
67+
// Add text using built-in font
68+
imagestring($image, 5, 50, 200, 'PHP GD Example', $black);
69+
imagestring($image, 3, 50, 230, 'Vercel PHP Runtime', $blue);
70+
71+
// Try to add text with TTF font if available
72+
if (function_exists('imagettftext')) {
73+
// Note: TTF fonts would need to be included in the project
74+
// For now, we'll just use the built-in fonts
75+
imagestring($image, 4, 50, 260, 'TTF support: Available', $green);
76+
} else {
77+
imagestring($image, 4, 50, 260, 'TTF support: Not available', $red);
78+
}
79+
80+
// Add PHP and GD info text
81+
imagestring($image, 2, 50, 290, 'PHP Version: ' . PHP_VERSION, $black);
82+
$gdInfo = gd_info();
83+
imagestring($image, 2, 50, 310, 'GD Version: ' . $gdInfo['GD Version'], $black);
84+
imagestring($image, 2, 50, 330, 'PNG Support: ' . ($gdInfo['PNG Support'] ? 'Yes' : 'No'), $black);
85+
imagestring($image, 2, 50, 350, 'JPEG Support: ' . ($gdInfo['JPEG Support'] ? 'Yes' : 'No'), $black);
86+
87+
// Set content type header
88+
header('Content-Type: image/png');
89+
90+
// Output the image as PNG
91+
imagepng($image);
92+
93+
// Memory is automatically freed when the script ends
94+
// Note: imagedestroy() has no effect since PHP 8.0 and is deprecated in 8.5

php-gd/api/index.php

Lines changed: 222 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,222 @@
1+
<?php
2+
3+
/**
4+
* OG Image Generator using Intervention/Image v3
5+
*
6+
* Official documentation: https://image.intervention.io/v3
7+
*
8+
* This example demonstrates:
9+
* - Creating images with Intervention/Image
10+
* - Using GD driver for image manipulation
11+
* - Combining Intervention/Image API with native GD functions for drawing
12+
* - Generating Open Graph images (1200x630)
13+
*/
14+
15+
require_once __DIR__ . '/../vendor/autoload.php';
16+
17+
use Intervention\Image\ImageManager;
18+
use Intervention\Image\Drivers\Gd\Driver;
19+
20+
// Check if GD extension is available
21+
if (!extension_loaded('gd')) {
22+
header('Content-Type: application/json');
23+
http_response_code(500);
24+
echo json_encode([
25+
'error' => 'GD extension is not available',
26+
'message' => 'The GD library is required for this example'
27+
]);
28+
exit;
29+
}
30+
31+
try {
32+
// OG Image standard dimensions (Open Graph image size)
33+
$width = 1200;
34+
$height = 630;
35+
36+
// Get parameters from query string
37+
$title = $_GET['title'] ?? 'PHP GD';
38+
$subtitle = $_GET['subtitle'] ?? 'Image Generation with Intervention/Image';
39+
40+
// Create image manager with GD driver
41+
// See: https://image.intervention.io/v3/basics/configuration-drivers
42+
$manager = new ImageManager(new Driver());
43+
44+
// Create new image using Intervention/Image API
45+
// See: https://image.intervention.io/v3/basics/read-create-images
46+
$image = $manager->create($width, $height);
47+
48+
// Fill with initial background color using Intervention/Image
49+
$image->fill('f0f5ff'); // Light blue background
50+
51+
// Get GD resource for advanced drawing operations
52+
// Intervention/Image v3 focuses on image manipulation, so we use
53+
// native GD functions for complex drawing (gradients, shapes, text)
54+
$gdResource = $image->core()->native();
55+
56+
// Create gradient background (light blue to white)
57+
// This uses GD directly as Intervention/Image doesn't have built-in gradient support
58+
for ($y = 0; $y < $height; $y++) {
59+
$ratio = $y / $height;
60+
$r = (int)(240 + ($ratio * 15)); // 240-255
61+
$g = (int)(245 + ($ratio * 10)); // 245-255
62+
$b = (int)(255); // 255
63+
$color = imagecolorallocate($gdResource, $r, $g, $b);
64+
imageline($gdResource, 0, $y, $width, $y, $color);
65+
}
66+
67+
// Draw subtle decorative shapes in background
68+
$lightBlue = imagecolorallocatealpha($gdResource, 100, 150, 255, 30);
69+
$lightPurple = imagecolorallocatealpha($gdResource, 200, 150, 255, 25);
70+
71+
// Large circles for visual interest
72+
imagefilledellipse($gdResource, 1000, 150, 400, 400, $lightBlue);
73+
imagefilledellipse($gdResource, 200, 500, 350, 350, $lightPurple);
74+
imagefilledellipse($gdResource, 1100, 450, 200, 200, $lightBlue);
75+
76+
// Draw main content card with solid white background
77+
$cardX = 100;
78+
$cardY = 80;
79+
$cardWidth = $width - 200;
80+
$cardHeight = 470;
81+
82+
// White card background
83+
$cardBg = imagecolorallocate($gdResource, 255, 255, 255);
84+
imagefilledrectangle($gdResource, $cardX, $cardY, $cardX + $cardWidth, $cardY + $cardHeight, $cardBg);
85+
86+
// Card shadow effect for depth
87+
$shadowColor = imagecolorallocatealpha($gdResource, 0, 0, 0, 50);
88+
for ($i = 0; $i < 10; $i++) {
89+
imagefilledrectangle($gdResource, $cardX + $i, $cardY + $i, $cardX + $cardWidth + $i, $cardY + $cardHeight + $i, $shadowColor);
90+
}
91+
// Redraw card on top of shadow
92+
imagefilledrectangle($gdResource, $cardX, $cardY, $cardX + $cardWidth, $cardY + $cardHeight, $cardBg);
93+
94+
// Card border
95+
$borderColor = imagecolorallocate($gdResource, 220, 220, 230);
96+
imagerectangle($gdResource, $cardX, $cardY, $cardX + $cardWidth, $cardY + $cardHeight, $borderColor);
97+
98+
// Allocate text colors (dark for visibility on white)
99+
$titleColor = imagecolorallocate($gdResource, 20, 30, 50);
100+
$subtitleColor = imagecolorallocate($gdResource, 80, 100, 140);
101+
$textColor = imagecolorallocate($gdResource, 100, 120, 150);
102+
$accentColor = imagecolorallocate($gdResource, 50, 120, 200);
103+
$white = imagecolorallocate($gdResource, 255, 255, 255);
104+
105+
// Draw title with multiple passes for bold effect
106+
$titleY = $cardY + 120;
107+
$titleFontSize = 5; // Largest built-in font
108+
$titleText = strtoupper($title);
109+
$titleWidth = imagefontwidth($titleFontSize) * strlen($titleText);
110+
$titleX = $cardX + ($cardWidth - $titleWidth) / 2;
111+
112+
// Draw title with shadow for depth
113+
$shadowOffset = 2;
114+
imagestring($gdResource, $titleFontSize, $titleX + $shadowOffset, $titleY + $shadowOffset, $titleText, imagecolorallocate($gdResource, 200, 200, 200));
115+
imagestring($gdResource, $titleFontSize, $titleX, $titleY, $titleText, $titleColor);
116+
// Draw again slightly offset for bold effect
117+
imagestring($gdResource, $titleFontSize, $titleX + 1, $titleY, $titleText, $titleColor);
118+
119+
// Draw subtitle
120+
$subtitleY = $titleY + 80;
121+
$subtitleFontSize = 3;
122+
$subtitleText = $subtitle;
123+
$subtitleWidth = imagefontwidth($subtitleFontSize) * strlen($subtitleText);
124+
$subtitleX = $cardX + ($cardWidth - $subtitleWidth) / 2;
125+
imagestring($gdResource, $subtitleFontSize, $subtitleX, $subtitleY, $subtitleText, $subtitleColor);
126+
127+
// Draw decorative line under subtitle
128+
$lineY = $subtitleY + 50;
129+
$lineX1 = $cardX + 150;
130+
$lineX2 = $cardX + $cardWidth - 150;
131+
imageline($gdResource, $lineX1, $lineY, $lineX2, $lineY, imagecolorallocate($gdResource, 230, 235, 240));
132+
imageline($gdResource, $lineX1, $lineY + 1, $lineX2, $lineY + 1, imagecolorallocate($gdResource, 240, 245, 250));
133+
134+
// Draw info badges with better visibility
135+
$infoY = $subtitleY + 120;
136+
$infoFontSize = 2;
137+
$badgeSpacing = 15;
138+
$badgeY = $infoY;
139+
$badgeHeight = imagefontheight($infoFontSize) + 12;
140+
$badgeX = $cardX + 80;
141+
142+
// PHP Version badge
143+
$phpVersion = 'PHP ' . PHP_VERSION;
144+
$phpWidth = imagefontwidth($infoFontSize) * strlen($phpVersion);
145+
$phpBadgeBg = imagecolorallocate($gdResource, 50, 150, 100);
146+
imagefilledrectangle($gdResource, $badgeX, $badgeY, $badgeX + $phpWidth + 20, $badgeY + $badgeHeight, $phpBadgeBg);
147+
imagestring($gdResource, $infoFontSize, $badgeX + 10, $badgeY + 6, $phpVersion, $white);
148+
149+
// GD Version badge
150+
$gdInfo = gd_info();
151+
$gdVersion = 'GD ' . $gdInfo['GD Version'];
152+
$gdX = $badgeX + $phpWidth + $badgeSpacing + 20;
153+
$gdWidth = imagefontwidth($infoFontSize) * strlen($gdVersion);
154+
$gdBadgeBg = imagecolorallocate($gdResource, 150, 80, 200);
155+
imagefilledrectangle($gdResource, $gdX, $badgeY, $gdX + $gdWidth + 20, $badgeY + $badgeHeight, $gdBadgeBg);
156+
imagestring($gdResource, $infoFontSize, $gdX + 10, $badgeY + 6, $gdVersion, $white);
157+
158+
// Vercel badge
159+
$vercelText = 'Vercel Runtime';
160+
$vercelX = $gdX + $gdWidth + $badgeSpacing + 20;
161+
$vercelWidth = imagefontwidth($infoFontSize) * strlen($vercelText);
162+
$vercelBadgeBg = imagecolorallocate($gdResource, 0, 0, 0);
163+
imagefilledrectangle($gdResource, $vercelX, $badgeY, $vercelX + $vercelWidth + 20, $badgeY + $badgeHeight, $vercelBadgeBg);
164+
imagestring($gdResource, $infoFontSize, $vercelX + 10, $badgeY + 6, $vercelText, $white);
165+
166+
// Draw additional info text
167+
$infoTextY = $badgeY + $badgeHeight + 40;
168+
$infoText = 'Intervention/Image v3 • PHP 8.5 Compatible';
169+
$infoTextWidth = imagefontwidth($infoFontSize) * strlen($infoText);
170+
$infoTextX = $cardX + ($cardWidth - $infoTextWidth) / 2;
171+
imagestring($gdResource, $infoFontSize, $infoTextX, $infoTextY, $infoText, $textColor);
172+
173+
// Draw footer text with better visibility
174+
$footerY = $height - 50;
175+
$footerText = 'Generated with PHP GD + Intervention/Image';
176+
$footerFontSize = 2;
177+
$footerWidth = imagefontwidth($footerFontSize) * strlen($footerText);
178+
$footerX = ($width - $footerWidth) / 2;
179+
180+
// Footer with background for visibility
181+
// Alpha must be 0-127 (0=opaque, 127=transparent). Converting 200/255 opacity to ~28 alpha
182+
$footerBg = imagecolorallocatealpha($gdResource, 255, 255, 255, 28);
183+
imagefilledrectangle($gdResource, $footerX - 15, $footerY - 5, $footerX + $footerWidth + 15, $footerY + imagefontheight($footerFontSize) + 5, $footerBg);
184+
imagestring($gdResource, $footerFontSize, $footerX, $footerY, $footerText, $textColor);
185+
186+
// Draw decorative corner elements
187+
$cornerColor = imagecolorallocate($gdResource, 100, 150, 255);
188+
$cornerSize = 40;
189+
$cornerThickness = 4;
190+
191+
// Top-left corner
192+
for ($i = 0; $i < $cornerThickness; $i++) {
193+
imageline($gdResource, $cardX, $cardY + $i, $cardX + $cornerSize, $cardY + $i, $cornerColor);
194+
imageline($gdResource, $cardX + $i, $cardY, $cardX + $i, $cardY + $cornerSize, $cornerColor);
195+
}
196+
197+
// Bottom-right corner
198+
for ($i = 0; $i < $cornerThickness; $i++) {
199+
imageline($gdResource, $cardX + $cardWidth - $cornerSize, $cardY + $cardHeight - $i, $cardX + $cardWidth, $cardY + $cardHeight - $i, $cornerColor);
200+
imageline($gdResource, $cardX + $cardWidth - $i, $cardY + $cardHeight - $cornerSize, $cardX + $cardWidth - $i, $cardY + $cardHeight, $cornerColor);
201+
}
202+
203+
// Use Intervention/Image for final output
204+
// See: https://image.intervention.io/v3/basics/image-output
205+
$finalImage = $manager->read($gdResource);
206+
207+
// Set headers for OG image
208+
header('Content-Type: image/png');
209+
header('Cache-Control: public, max-age=3600');
210+
211+
// Output the image as PNG using Intervention/Image API
212+
// See: https://image.intervention.io/v3/basics/image-output
213+
echo $finalImage->toPng();
214+
215+
} catch (Exception $e) {
216+
header('Content-Type: application/json');
217+
http_response_code(500);
218+
echo json_encode([
219+
'error' => 'Image processing failed',
220+
'message' => $e->getMessage()
221+
]);
222+
}

0 commit comments

Comments
 (0)