diff --git a/.gitignore b/.gitignore index 5fa5cd36ef..68e6dab8a5 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,7 @@ backend/mirror.gif backend/mirror.png backend/mirror.jpg backend/GeoIP.dat +include/download-instructions/releases.json node_modules/ /test-results/ /playwright-report/ diff --git a/include/download-instructions/windows-downloads.php b/include/download-instructions/windows-downloads.php index d8a86114e3..ea014e2d30 100644 --- a/include/download-instructions/windows-downloads.php +++ b/include/download-instructions/windows-downloads.php @@ -1,3 +1,131 @@ -
-You can find the downloads for Windows on the dedicated downloads page. -
+ [ + 'header' => "User-Agent: web-php/1.1", + 'timeout' => 5, + ], + 'ssl' => [ + 'allow_self_signed' => true, + 'verify_peer_name' => false, + ], + ]); + $json = @file_get_contents($releasesUrl, false, $context); + if ($json === false || $json === null) { + $json = @file_get_contents($fallbackReleasesUrl, false, $context); + } + if ($json !== false && $json !== null) { + $tmp = $cacheFile . '.tmp'; + if (@file_put_contents($tmp, $json) !== false) { + @rename($tmp, $cacheFile); + } + } +} + +$dataStr = @file_get_contents($cacheFile); +$releases = $dataStr ? json_decode($dataStr ?? $json, true) : null; + +if (!is_array($releases)) { + echo 'Windows release index is temporarily unavailable.
'; + if (file_exists($cacheFile)) { + @unlink($cacheFile); + } + return; +} + +if (!isset($releases[$version]) || !is_array($releases[$version])) { + echo 'No Windows builds found for PHP ' . htmlspecialchars($version) . '.
'; + return; +} + +$verBlock = $releases[$version]; +$fullVersion = isset($verBlock['version']) ? $verBlock['version'] : $version; + +$baseDownloads = 'https://downloads.php.net/~windows/releases/'; + +function ws_build_label(string $k, array $entry): string { + $tool = 'VS'; + if (strpos($k, 'vs17') !== false) { $tool .= '17'; } + elseif (strpos($k, 'vs16') !== false) { $tool .= '16'; } + elseif (strpos($k, 'vc15') !== false) { $tool = 'VC15'; } + + $arch = (strpos($k, 'x64') !== false) ? 'x64' : ((strpos($k, 'x86') !== false) ? 'x86' : ''); + $ts = (strpos($k, 'nts') !== false) ? 'Non Thread Safe' : 'Thread Safe'; + if (strncmp($k, 'nts-', 4) === 0) { + $ts = 'Non Thread Safe'; + } elseif (strncmp($k, 'ts-', 3) === 0) { + $ts = 'Thread Safe'; + } + + $mtime = isset($entry['mtime']) ? strtotime($entry['mtime']) : 0; + $mt = $mtime ? gmdate('Y-M-d H:i:s', $mtime) : ''; + return trim(($tool ? $tool . ' ' : '') . ($arch ? $arch . ' ' : '') . $ts . ($mt ? ' ' . $mt . ' UTC' : '')); +} + +echo 'Download source code ' . $verBlock['source']['size'] ?? '' . '
'; +} +if (!empty($verBlock['test_pack']['path'])) { + echo 'Download tests package (phpt) ' . $verBlock['test_pack']['size'] ?? '' . '
'; +} + +$buckets = [ + 'nts-x64' => [], + 'ts-x64' => [], + 'nts-x86' => [], + 'ts-x86' => [], +]; + +$package_names = [ + 'zip' => 'Zip', + 'debug_pack' => 'Debug Pack', + 'devel_pack' => 'Development package (SDK to develop PHP extensions)', +]; + +foreach ($verBlock as $k => $entry) { + if (!is_array($entry)) { continue; } + if (in_array($k, ['version', 'source', 'test_pack'], true)) { continue; } + + $isNts = (strncmp($k, 'nts-', 4) === 0) || (strpos($k, 'nts') !== false); + $arch = (strpos($k, 'x64') !== false) ? 'x64' : ((strpos($k, 'x86') !== false) ? 'x86' : ''); + $bucketKey = ($isNts ? 'nts' : 'ts') . '-' . ($arch !== '' ? $arch : 'other'); + if (!isset($buckets[$bucketKey])) { $bucketKey = 'other'; } + $buckets[$bucketKey][] = [$k, $entry]; +} + +foreach (['nts-x64', 'ts-x64', 'nts-x86', 'ts-x86'] as $bk) { + foreach ($buckets[$bk] as [$k, $entry]) { + $label = ws_build_label($k, $entry); + if ($label === '') { continue; } + + echo '' . $package_names[$type] . ' ' . $entry[$type]['size'] . '
';
+ echo 'sha256: ' . $entry[$type]['sha256'] ?? '' . '