Merge pull request 'PHP 8.5が必須になった' (#33) from php85 into master

Reviewed-on: http://192.168.10.104:3000/suwako/LittleBeast/pulls/33
This commit is contained in:
2026-05-06 03:51:03 +09:00
9 changed files with 34 additions and 38 deletions

View File

@@ -1,5 +1,6 @@
# 0.5 (2026年??月??日)
* OpenProviderライブラリ
* PHP 8.5以上が必須になった
# ローリング・リリース (2025年01月01日)
* 最初プライベートリリース

View File

@@ -7,7 +7,7 @@
サンプル:[https://lbdemo.technicalsuwako.moe/](https://lbdemo.technicalsuwako.moe/)
## Little Beast とは?
Little Beast は PHP 8.3 以上向けのフレームワークで、076.moeゲーム開発会社と technicalsuwako.moe社長のブログ向けに作られました。\
Little Beast は PHP 8.5 以上向けのフレームワークで、076.moeゲーム開発会社と technicalsuwako.moe社長のブログ向けに作られました。\
メイン考え方は「必要な物だけ拡張し、不要な物は削除する」です。\
各コア機能はライブラリに分割されている為、必要な物だけを選び易い設計になっています。\
全てのモジュールはゼロから書かれており、データベースは一切必要ありません。
@@ -68,9 +68,9 @@ HTTP サーバーを設定して `/public` をルートとして `php-fpm` で
### OpenBSD サーバー
```sh
pkg_add php-8.4.14 php-gmp-8.4.14
rcctl enable php84_fpm httpd relayd
rcctl start php84_fpm httpd relayd
pkg_add php-8.5.5 php-gmp-8.5.5
rcctl enable php85_fpm httpd relayd
rcctl start php85_fpm httpd relayd
```
#### httpd

View File

@@ -7,7 +7,7 @@ Simple, Pragmatic, Anti-bloat
Demo installation: [https://lbdemo.technicalsuwako.moe/](https://lbdemo.technicalsuwako.moe/)
## What is Little Beast?
Little Beast is a PHP 8.3 or above framework made for 076.moe (game developer company) and technicalsuwako.moe (CEO's blog).\
Little Beast is a PHP 8.5 or above framework made for 076.moe (game developer company) and technicalsuwako.moe (CEO's blog).\
The core mentality is to extend what you need, and remove what you don't need.\
Each core feature is split into libraries, so it is easy to choose what you need.\
All modules are written from scratch, nothing is to be require a database.
@@ -68,9 +68,9 @@ That's all!
### OpenBSD server
```sh
pkg_add php-8.4.14 php-gmp-8.4.14
rcctl enable php84_fpm httpd relayd
rcctl start php84_fpm httpd relayd
pkg_add php-8.5.5 php-gmp-8.5.5
rcctl enable php85_fpm httpd relayd
rcctl start php85_fpm httpd relayd
```
#### httpd

View File

@@ -66,7 +66,7 @@ $routes = [
];
if (ACTIVITYPUB_ENABLED) {
$routes[] = Route::add('GET', '.well-known/webfinger', Home::class.'@apfinger');
$routes[] = Route::add('GET', '.well-known/webfinger', Fediverse::class.'@apfinger');
$routes[] = Route::add('GET', 'ap/following', Fediverse::class.'@apfollowing');
$routes[] = Route::add('GET', 'ap/followers', Fediverse::class.'@apfollowers');
$routes[] = Route::add('GET', 'ap/outbox', Fediverse::class.'@apoutbox');

View File

@@ -39,6 +39,7 @@ namespace Std\Lib;
use Std\Lib\Curl;
use LogType;
use Uri\Rfc3986\Uri;
/**
* ActivityPubプロトコルの実装クラス
@@ -298,14 +299,14 @@ class ActivityPub {
*/
public function getWebfinger(): string {
if (!ACTIVITYPUB_ENABLED) return '';
$domain = str_replace(['http://', 'https://'], '', $this->domain);
$uri = new Uri($this->domain);
$webfinger = [
'subject' => "acct:{$this->actor}@{$domain}",
'subject' => "acct:{$this->actor}@{$uri->getHost()}",
'links' => [
[
'rel' => 'self',
'type' => 'application/activity+json',
'href' => "{$domain}/ap/actor",
'href' => "{$this->domain}/ap/actor",
],
],
];
@@ -445,10 +446,10 @@ class ActivityPub {
$body = json_encode($activity, JSON_UNESCAPED_SLASHES);
$digest = base64_encode(hash('sha256', $body, true));
$date = gmdate('D, d M Y H:i:s \G\M\T');
$host = parse_url($inboxUrl, PHP_URL_HOST);
$uri = new Uri($inboxUrl);
$headers = [
'Host' => $host,
'Host' => $uri->getHost().($uri->getPort() ? ':'.$uri->getPort() : ''),
'Date' => $date,
'Content-Type' => 'application/activity+json',
'Digest' => "SHA-256=$digest",

View File

@@ -38,6 +38,7 @@ OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
namespace Std\Lib;
use Result;
use Uri\Rfc3986\Uri;
/**
* php_curlへの依存を排除するための独自のCURL実装
@@ -354,19 +355,18 @@ class Curl {
fwrite($this->stderr, "* 接続中: {$currentUrl}\n");
}
$parsed = parse_url($currentUrl);
if (!$parsed) {
$uri = new Uri($currentUrl);
if (!$uri) {
$this->responseError = "無効なURL: {$currentUrl}";
return Result::Error($this->responseError);
}
$scheme = isset($parsed['scheme']) ? strtolower($parsed['scheme']) : 'http';
$host = $parsed['host'];
$port = isset($parsed['port'])
? $parsed['port'] : ($scheme === 'https' ? 443 : 80);
$path = isset($parsed['path']) ? $parsed['path'] : '/';
if (isset($parsed['query'])) {
$path .= '?'.$parsed['query'];
$scheme = $uri->getScheme() ?? 'http';
$port = $uri->getPort() ?? ($scheme === 'https' ? 443 : 80);
$path = $uri->getPath();
if ($path === '') $path = '/';
if (NULL !== $uri->getQuery()) {
$path .= '?'.$uri->getQuery();
}
// 認証
@@ -404,7 +404,7 @@ class Curl {
}
$request = "{$method} {$path} HTTP/1.1\r\n";
$request .= "Host: {$host}\r\n";
$request .= "Host: {$uri->getHost()}\r\n";
$request .= "User-Agent: {$this->userAgent}\r\n";
$request .= "{$accept}\r\n";
$request .= "Connection: close\r\n";
@@ -462,7 +462,7 @@ class Curl {
$context = stream_context_create(['ssl' => $sslOptions]);
$socket = @stream_socket_client(
"tls://{$host}:{$port}",
"tls://{$uri->getHost()}:{$port}",
$errno,
$errstr,
$this->timeout,
@@ -470,7 +470,7 @@ class Curl {
$context
);
} else {
$socket = @fsockopen($host, $port, $errno, $errstr, $this->timeout);
$socket = @fsockopen($uri->getHost(), $port, $errno, $errstr, $this->timeout);
}
if (!$socket) {
@@ -637,9 +637,9 @@ class Curl {
if (strpos($redirectUrl, 'http') !== 0) {
if ($redirectUrl[0] === '/') {
$parsed = parse_url($currentUrl);
$redirectUrl = $parsed['scheme'].'://'.$parsed['host']
.(isset($parsed['port']) ? ':'.$parsed['port'] : '')
$uri = new Uri($currentUrl);
$redirectUrl = $uri->getScheme().'://'.$uri->getHost()
.(NULL !== $uri->getPort() ? ':'.$uri->getPort() : '')
.$redirectUrl;
} else {
$redirectUrl = dirname($currentUrl).'/'.$redirectUrl;

View File

@@ -407,6 +407,7 @@ class Tester {
*/
public function assertArrayHasKey(mixed $key, array $array,
?string $message = null): Tester {
if (NULL === $key) throw new AssertionFailedException("配列鍵がありません");
if (!is_array($array) && !($array instanceof \ArrayAccess)) {
throw new AssertionFailedException(
'第2引数は配列又はArrayAccessを実装している必要があります');

View File

@@ -471,10 +471,3 @@ function align_down(int $val): int {
while ($lower * 2 <= $val) $lower *= 2;
return $lower;
}
// PHP 8.3と8.4の場合
if (!function_exists('array_last')) {
function array_last(array $array): mixed {
return $array === [] ? null : $array[array_key_last($array)];
}
}

View File

@@ -20,7 +20,7 @@
{@ endif @}
{@ endif @}
<meta name="description" content="{{ $description }}" />
<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 @}" />
<meta name="keywords" content="{{ SITEINFO['tags'].(isset($meta->category) ? ','.implode(',', $meta->category) : '') }}" />
<meta property="og:title" content="{{ SITEINFO['title'] }}: {{ $pagetit }}" />
<meta property="og:description" content="{{ $description }}" />