PHP 8.5が必須になった
諏訪子 <suwako@076.moe>、2026-05-06 03:46
コミット 18fe4030a391ad556957d78d66260163bdc6657b
・親 0223951
・ファイルを見る
5個のファイル、+20 -25
| @@ -39,6 +39,7 @@ | ||
| 39 | 39 | |
| 40 | 40 | use Std\Lib\Curl; |
| 41 | 41 | use LogType; |
| 42 | +use Uri\Rfc3986; | |
| 42 | 43 | |
| 43 | 44 | /** |
| 44 | 45 | * ActivityPubプロトコルの実装クラス |
| @@ -445,10 +446,10 @@ | ||
| 445 | 446 | $body = json_encode($activity, JSON_UNESCAPED_SLASHES); |
| 446 | 447 | $digest = base64_encode(hash('sha256', $body, true)); |
| 447 | 448 | $date = gmdate('D, d M Y H:i:s \G\M\T'); |
| 448 | - $host = parse_url($inboxUrl, PHP_URL_HOST); | |
| 449 | + $uri = new Uri($inboxUrl); | |
| 449 | 450 | |
| 450 | 451 | $headers = [ |
| 451 | - 'Host' => $host, | |
| 452 | + 'Host' => $uri->getHost().($uri->getPort() ? ':'.$uri->getPort() : ''), | |
| 452 | 453 | 'Date' => $date, |
| 453 | 454 | 'Content-Type' => 'application/activity+json', |
| 454 | 455 | 'Digest' => "SHA-256=$digest", |
| @@ -38,6 +38,7 @@ | ||
| 38 | 38 | namespace Std\Lib; |
| 39 | 39 | |
| 40 | 40 | use Result; |
| 41 | +use Uri\Rfc3986; | |
| 41 | 42 | |
| 42 | 43 | /** |
| 43 | 44 | * php_curlへの依存を排除するための独自のCURL実装 |
| @@ -354,19 +355,18 @@ | ||
| 354 | 355 | fwrite($this->stderr, "* 接続中: {$currentUrl}\n"); |
| 355 | 356 | } |
| 356 | 357 | |
| 357 | - $parsed = parse_url($currentUrl); | |
| 358 | - if (!$parsed) { | |
| 358 | + $uri = new Uri($currentUrl); | |
| 359 | + if (!$uri) { | |
| 359 | 360 | $this->responseError = "無効なURL: {$currentUrl}"; |
| 360 | 361 | return Result::Error($this->responseError); |
| 361 | 362 | } |
| 362 | 363 | |
| 363 | - $scheme = isset($parsed['scheme']) ? strtolower($parsed['scheme']) : 'http'; | |
| 364 | - $host = $parsed['host']; | |
| 365 | - $port = isset($parsed['port']) | |
| 366 | - ? $parsed['port'] : ($scheme === 'https' ? 443 : 80); | |
| 367 | - $path = isset($parsed['path']) ? $parsed['path'] : '/'; | |
| 368 | - if (isset($parsed['query'])) { | |
| 369 | - $path .= '?'.$parsed['query']; | |
| 364 | + $scheme = $uri->getScheme() ?? 'http'; | |
| 365 | + $port = $uri->getPort() ?? ($scheme === 'https' ? 443 : 80); | |
| 366 | + $path = $uri->getPath(); | |
| 367 | + if ($path === '') $path = '/'; | |
| 368 | + if (isset($uri->getQuery())) { | |
| 369 | + $path .= '?'.$uri->getQuery(); | |
| 370 | 370 | } |
| 371 | 371 | |
| 372 | 372 | // 認証 |
| @@ -404,7 +404,7 @@ | ||
| 404 | 404 | } |
| 405 | 405 | |
| 406 | 406 | $request = "{$method} {$path} HTTP/1.1\r\n"; |
| 407 | - $request .= "Host: {$host}\r\n"; | |
| 407 | + $request .= "Host: {$uri->getHost()}\r\n"; | |
| 408 | 408 | $request .= "User-Agent: {$this->userAgent}\r\n"; |
| 409 | 409 | $request .= "{$accept}\r\n"; |
| 410 | 410 | $request .= "Connection: close\r\n"; |
| @@ -462,7 +462,7 @@ | ||
| 462 | 462 | $context = stream_context_create(['ssl' => $sslOptions]); |
| 463 | 463 | |
| 464 | 464 | $socket = @stream_socket_client( |
| 465 | - "tls://{$host}:{$port}", | |
| 465 | + "tls://{$uri->getHost()}:{$port}", | |
| 466 | 466 | $errno, |
| 467 | 467 | $errstr, |
| 468 | 468 | $this->timeout, |
| @@ -470,7 +470,7 @@ | ||
| 470 | 470 | $context |
| 471 | 471 | ); |
| 472 | 472 | } else { |
| 473 | - $socket = @fsockopen($host, $port, $errno, $errstr, $this->timeout); | |
| 473 | + $socket = @fsockopen($uri->getHost(), $port, $errno, $errstr, $this->timeout); | |
| 474 | 474 | } |
| 475 | 475 | |
| 476 | 476 | if (!$socket) { |
| @@ -637,9 +637,9 @@ | ||
| 637 | 637 | |
| 638 | 638 | if (strpos($redirectUrl, 'http') !== 0) { |
| 639 | 639 | if ($redirectUrl[0] === '/') { |
| 640 | - $parsed = parse_url($currentUrl); | |
| 641 | - $redirectUrl = $parsed['scheme'].'://'.$parsed['host'] | |
| 642 | - .(isset($parsed['port']) ? ':'.$parsed['port'] : '') | |
| 640 | + $uri = new Uri($currentUrl); | |
| 641 | + $redirectUrl = $uri->getScheme().'://'.$uri->getHost() | |
| 642 | + .(isset($uri->getPort()) ? ':'.$uri->getPort() : '') | |
| 643 | 643 | .$redirectUrl; |
| 644 | 644 | } else { |
| 645 | 645 | $redirectUrl = dirname($currentUrl).'/'.$redirectUrl; |
| @@ -407,6 +407,7 @@ | ||
| 407 | 407 | */ |
| 408 | 408 | public function assertArrayHasKey(mixed $key, array $array, |
| 409 | 409 | ?string $message = null): Tester { |
| 410 | + if (NULL === $key) throw new AssertionFailedException("配列鍵がありません"); | |
| 410 | 411 | if (!is_array($array) && !($array instanceof \ArrayAccess)) { |
| 411 | 412 | throw new AssertionFailedException( |
| 412 | 413 | '第2引数は配列又はArrayAccessを実装している必要があります'); |
変更
util.php
| @@ -471,10 +471,3 @@ | ||
| 471 | 471 | while ($lower * 2 <= $val) $lower *= 2; |
| 472 | 472 | return $lower; |
| 473 | 473 | } |
| 474 | - | |
| 475 | -// PHP 8.3と8.4の場合 | |
| 476 | -if (!function_exists('array_last')) { | |
| 477 | - function array_last(array $array): mixed { | |
| 478 | - return $array === [] ? null : $array[array_key_last($array)]; | |
| 479 | - } | |
| 480 | -} |
| @@ -20,7 +20,7 @@ | ||
| 20 | 20 | {@ endif @} |
| 21 | 21 | {@ endif @} |
| 22 | 22 | <meta name="description" content="{{ $description }}" /> |
| 23 | - <meta name="keywords" content="{{ SITEINFO['tags'].(isset($meta->category) ? ',' : '') }}{@ if (isset($meta) && isset($meta->category)) @}{@ foreach ($meta->category as $k => $cat) @}{{ $cat.($k === array_key_last($meta->category) ? '' : ',') }}{@ endforeach @}{@ endif @}" /> | |
| 23 | + <meta name="keywords" content="{{ SITEINFO['tags'].(isset($meta->category) ? ',' : '') }}{@ if (isset($meta) && isset($meta->category)) @}{@ foreach ($meta->category as $k => $cat) @}{{ $cat.($k === array_last($meta->category) ? '' : ',') }}{@ endforeach @}{@ endif @}" /> | |
| 24 | 24 | |
| 25 | 25 | <meta property="og:title" content="{{ SITEINFO['title'] }}: {{ $pagetit }}" /> |
| 26 | 26 | <meta property="og:description" content="{{ $description }}" /> |