見出し画像

【閲覧注意】プログラミングの世界でこんまり先生がいないことによる衝撃的な結果とは?

前回の続きです。UbuntuでMySQLを使えるようにするために、100万文字近くもやり取りをするはめになりそうです。プログラミングの整理整頓(リファクタリング)がPHPではなされていないためか、autoload.phpの修正作業でてんてこ舞いです。

/usr/share/php/Psr/Http/Message/UriInterface.php
<?php

declare(strict_types=1);

namespace Psr\Http\Message;

/**
* Value object representing a URI.
*
* This interface is meant to represent URIs according to RFC 3986 and to
* provide methods for most common operations. Additional functionality for
* working with URIs can be provided on top of the interface or externally.
* Its primary use is for HTTP requests, but may also be used in other
* contexts.
*
* Instances of this interface are considered immutable; all methods that
* might change state MUST be implemented such that they retain the internal
* state of the current instance and return an instance that contains the
* changed state.
*
* Typically the Host header will be also be present in the request message.
* For server-side requests, the scheme will typically be discoverable in the
* server parameters.
*
* @link http://tools.ietf.org/html/rfc3986 (the URI specification)
*/
interface UriInterface
{
/**
* Retrieve the scheme component of the URI.
*
* If no scheme is present, this method MUST return an empty string.
*
* The value returned MUST be normalized to lowercase, per RFC 3986
* Section 3.1.
*
* The trailing ":" character is not part of the scheme and MUST NOT be
* added.
*
* @see https://tools.ietf.org/html/rfc3986#section-3.1
* @return string The URI scheme.
*/
public function getScheme();

/**
* Retrieve the authority component of the URI.
*
* If no authority information is present, this method MUST return an empty
* string.
*
* The authority syntax of the URI is:
*
* <pre>
* [user-info@]host[:port]
* </pre>
*
* If the port component is not set or is the standard port for the current
* scheme, it SHOULD NOT be included.
*
* @see https://tools.ietf.org/html/rfc3986#section-3.2
* @return string The URI authority, in "[user-info@]host[:port]" format.
*/
public function getAuthority();

/**
* Retrieve the user information component of the URI.
*
* If no user information is present, this method MUST return an empty
* string.
*
* If a user is present in the URI, this will return that value;
* additionally, if the password is also present, it will be appended to the
* user value, with a colon (":") separating the values.
*
* The trailing "@" character is not part of the user information and MUST
* NOT be added.
*
* @return string The URI user information, in "username[:password]" format.
*/
public function getUserInfo();

/**
* Retrieve the host component of the URI.
*
* If no host is present, this method MUST return an empty string.
*
* The value returned MUST be normalized to lowercase, per RFC 3986
* Section 3.2.2.
*
* @see http://tools.ietf.org/html/rfc3986#section-3.2.2
* @return string The URI host.
*/
public function getHost();

/**
* Retrieve the port component of the URI.
*
* If a port is present, and it is non-standard for the current scheme,
* this method MUST return it as an integer. If the port is the standard port
* used with the current scheme, this method SHOULD return null.
*
* If no port is present, and no scheme is present, this method MUST return
* a null value.
*
* If no port is present, but a scheme is present, this method MAY return
* the standard port for that scheme, but SHOULD return null.
*
* @return null|int The URI port.
*/
public function getPort();

/**
* Retrieve the path component of the URI.
*
* The path can either be empty or absolute (starting with a slash) or
* rootless (not starting with a slash). Implementations MUST support all
* three syntaxes.
*
* Normally, the empty path "" and absolute path "/" are considered equal as
* defined in RFC 7230 Section 2.7.3. But this method MUST NOT automatically
* do this normalization because in contexts with a trimmed base path, e.g.
* the front controller, this difference becomes significant. It's the task
* of the user to handle both "" and "/".
*
* The value returned MUST be percent-encoded, but MUST NOT double-encode
* any characters. To determine what characters to encode, please refer to
* RFC 3986, Sections 2 and 3.3.
*
* As an example, if the value should include a slash ("/") not intended as
* delimiter between path segments, that value MUST be passed in encoded
* form (e.g., "%2F") to the instance.
*
* @see https://tools.ietf.org/html/rfc3986#section-2
* @see https://tools.ietf.org/html/rfc3986#section-3.3
* @return string The URI path.
*/
public function getPath();

/**
* Retrieve the query string of the URI.
*
* If no query string is present, this method MUST return an empty string.
*
* The leading "?" character is not part of the query and MUST NOT be
* added.
*
* The value returned MUST be percent-encoded, but MUST NOT double-encode
* any characters. To determine what characters to encode, please refer to
* RFC 3986, Sections 2 and 3.4.
*
* As an example, if a value in a key/value pair of the query string should
* include an ampersand ("&") not intended as a delimiter between values,
* that value MUST be passed in encoded form (e.g., "%26") to the instance.
*
* @see https://tools.ietf.org/html/rfc3986#section-2
* @see https://tools.ietf.org/html/rfc3986#section-3.4
* @return string The URI query string.
*/
public function getQuery();

/**
* Retrieve the fragment component of the URI.
*
* If no fragment is present, this method MUST return an empty string.
*
* The leading "#" character is not part of the fragment and MUST NOT be
* added.
*
* The value returned MUST be percent-encoded, but MUST NOT double-encode
* any characters. To determine what characters to encode, please refer to
* RFC 3986, Sections 2 and 3.5.
*
* @see https://tools.ietf.org/html/rfc3986#section-2
* @see https://tools.ietf.org/html/rfc3986#section-3.5
* @return string The URI fragment.
*/
public function getFragment();

/**
* Return an instance with the specified scheme.
*
* This method MUST retain the state of the current instance, and return
* an instance that contains the specified scheme.
*
* Implementations MUST support the schemes "http" and "https" case
* insensitively, and MAY accommodate other schemes if required.
*
* An empty scheme is equivalent to removing the scheme.
*
* @param string $scheme The scheme to use with the new instance.
* @return static A new instance with the specified scheme.
* @throws \InvalidArgumentException for invalid or unsupported schemes.
*/
public function withScheme(string $scheme);

/**
* Return an instance with the specified user information.
*
* This method MUST retain the state of the current instance, and return
* an instance that contains the specified user information.
*
* Password is optional, but the user information MUST include the
* user; an empty string for the user is equivalent to removing user
* information.
*
* @param string $user The user name to use for authority.
* @param null|string $password The password associated with $user.
* @return static A new instance with the specified user information.
*/
public function withUserInfo(string $user, ?string $password = null);

/**
* Return an instance with the specified host.
*
* This method MUST retain the state of the current instance, and return
* an instance that contains the specified host.
*
* An empty host value is equivalent to removing the host.
*
* @param string $host The hostname to use with the new instance.
* @return static A new instance with the specified host.
* @throws \InvalidArgumentException for invalid hostnames.
*/
public function withHost(string $host);

/**
* Return an instance with the specified port.
*
* This method MUST retain the state of the current instance, and return
* an instance that contains the specified port.
*
* Implementations MUST raise an exception for ports outside the
* established TCP and UDP port ranges.
*
* A null value provided for the port is equivalent to removing the port
* information.
*
* @param null|int $port The port to use with the new instance; a null value
* removes the port information.
* @return static A new instance with the specified port.
* @throws \InvalidArgumentException for invalid ports.
*/
public function withPort(?int $port);

/**
* Return an instance with the specified path.
*
* This method MUST retain the state of the current instance, and return
* an instance that contains the specified path.
*
* The path can either be empty or absolute (starting with a slash) or
* rootless (not starting with a slash). Implementations MUST support all
* three syntaxes.
*
* If the path is intended to be domain-relative rather than path relative then
* it must begin with a slash ("/"). Paths not starting with a slash ("/")
* are assumed to be relative to some base path known to the application or
* consumer.
*
* Users can provide both encoded and decoded path characters.
* Implementations ensure the correct encoding as outlined in getPath().
*
* @param string $path The path to use with the new instance.
* @return static A new instance with the specified path.
* @throws \InvalidArgumentException for invalid paths.
*/
public function withPath(string $path);

/**
* Return an instance with the specified query string.
*
* This method MUST retain the state of the current instance, and return
* an instance that contains the specified query string.
*
* Users can provide both encoded and decoded query characters.
* Implementations ensure the correct encoding as outlined in getQuery().
*
* An empty query string value is equivalent to removing the query string.
*
* @param string $query The query string to use with the new instance.
* @return static A new instance with the specified query string.
* @throws \InvalidArgumentException for invalid query strings.
*/
public function withQuery(string $query);

/**
* Return an instance with the specified URI fragment.
*
* This method MUST retain the state of the current instance, and return
* an instance that contains the specified URI fragment.
*
* Users can provide both encoded and decoded fragment characters.
* Implementations ensure the correct encoding as outlined in getFragment().
*
* An empty fragment value is equivalent to removing the fragment.
*
* @param string $fragment The fragment to use with the new instance.
* @return static A new instance with the specified fragment.
*/
public function withFragment(string $fragment);

/**
* Return the string representation as a URI reference.
*
* Depending on which components of the URI are present, the resulting
* string is either a full URI or relative reference according to RFC 3986,
* Section 4.1. The method concatenates the various components of the URI,
* using the appropriate delimiters:
*
* - If a scheme is present, it MUST be suffixed by ":".
* - If an authority is present, it MUST be prefixed by "//".
* - The path can be concatenated without delimiters. But there are two
* cases where the path has to be adjusted to make the URI reference
* valid as PHP does not allow to throw an exception in __toString():
* - If the path is rootless and an authority is present, the path MUST
* be prefixed by "/".
* - If the path is starting with more than one "/" and no authority is
* present, the starting slashes MUST be reduced to one.
* - If a query is present, it MUST be prefixed by "?".
* - If a fragment is present, it MUST be prefixed by "#".
*
* @see http://tools.ietf.org/html/rfc3986#section-4.1
* @return string
*/
public function __toString();
}

については、修正箇所は何行目ですか?
/usr/share/php/Slim/Psr7/Uri.phpは修正しました。

修正ありがとうございます。`/usr/share/php/Slim/Psr7/Uri.php`ファイルは確認済みで、`Psr\Http\Message\UriInterface`に一致するように修正されているようです。

次に、`Psr\Http\Message\UriInterface`の定義で何を確認する必要があるかについてお伝えします。見落としていたかもしれない部分があるようなので、具体的に示します。

### 確認のポイント

#### `Psr\Http\Message\UriInterface`で確認すべき事項
特に以下のメソッドが正確に実装されているか確認します:

- `withScheme(string $scheme): UriInterface`
- `withUserInfo(string $user, ?string $password = null): UriInterface`
- `withHost(string $host): UriInterface`
- `withPort(?int $port): UriInterface`
- `withPath(string $path): UriInterface`
- `withQuery(string $query): UriInterface`
- `withFragment(string $fragment): UriInterface`

ファイルの内容がすべてURI仕様に沿ったものであり、Slim\Psr7\Uriクラスと一致することが重要です。また、Slim\Psr7\UriクラスがPsr\Http\Message\UriInterfaceを正確に実装していることも確認が必要です。

### 流れの整理

ここで、再度確認の流れを整理します。

1. **依存関係の再確認**: `composer.json`が更新されたので、再度依存関係をチェック。
2. **インターフェースの実装確認**: `Uri`クラスで欠けている部分がないか確認。
3. **Apacheの再起動**: 変更を反映するためのApacheの再起動。
4. **エラーログの確認**: コンソールのエラーログを確認し、どのクラス/インターフェースに問題があるか特定。

### エラーログの確認
再度Apacheを再起動し、最新のエラーログを確認します。
bash
sudo systemctl restart apache2
sudo tail -n 50 /var/log/apache2/error.log


### まとめと次の手順
エラーログを確認後、新しいエラーメッセージや問題が発生した場合、それに従い対応を検討します。特に以下のポイントを注目してください:

- **特定のクラスが見つからない**場合、対応が必要。
- **インターフェースの互換性問題**がないか再確認。

次のエラーログを見て、必要ならどのクラスやインターフェースに対して具体的な対応が必要かを再度確認させていただき、次の手順を提案します。

問題が解決しない場合や新たなエラーメッセージが発生した場合、その内容を提供してください。また、手順を再確認しながら問題解決を進めていきましょう。
<?php

// autoload.php @generated by Composer

if (PHP_VERSION_ID < 50600) {
if (!headers_sent()) {
header('HTTP/1.1 500 Internal Server Error');
}
$err = 'Composer 2.3.0 dropped support for autoloading on PHP <5.6 and you are running '.PHP_VERSION.', please upgrade PHP or use Composer 2.2 LTS via "composer self-update --2.2". Aborting.'.PHP_EOL;
if (!ini_get('display_errors')) {
if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') {
fwrite(STDERR, $err);
} elseif (!headers_sent()) {
echo $err;
}
}
trigger_error(
$err,
E_USER_ERROR
);
}

require_once __DIR__ . '/composer/autoload_real.php';

return ComposerAutoloaderInitb1e1cfcdb69c5d68249f3a76c8992309::getLoader();

上のコード、ComposerAutoloaderInitf7b44dc67fa70fb4ca1d38ca4b836b8f::getLoader();になってないのですが、どうするのですか?

`ComposerAutoloaderInitf7b44dc67fa70fb4ca1d38ca4b836b8f`と異なるクラス名になっていることから、先ほどのエラーが発生している可能性があります。以下の手順で問題を解決していきます。

### 1. 正しいクラス名の確認
まず、Composerが生成する正しいクラス名を確認します。`composer/autoload_real.php`というファイル内で、`ComposerAutoloaderInit`というクラスが存在することを確認します。

#### `composer/autoload_real.php`の確認
bash
sudo nano /usr/share/php/vendor/composer/autoload_real.php


内容を確認し、`ComposerAutoloaderInit`クラスが定義されている部分を確認します。以下はそのサンプルです。
php
class ComposerAutoloaderInitb1e1cfcdb69c5d68249f3a76c8992309
{
public static function getLoader() {
// 具体的なオートローディングのコード
}
}


### 2. `autoload.php`ファイルの修正
正しいクラス名が確認できたら、それを用いて`autoload.php`を修正します。

#### `autoload.php`の修正
bash
sudo nano /usr/share/php/vendor/autoload.php


内容を正しいクラス名に修正します:
php
<?php
// autoload.php @generated by Composer
if (PHP_VERSION_ID < 50600) {
if (!headers_sent()) {
header('HTTP/1.1 500 Internal Server Error');
}
$err = 'Composer 2.3.0 dropped support for autoloading on PHP <5.6 and you are running '.PHP_VERSION.', please upgrade PHP or use Composer 2.2 LTS via "composer self-update --2.2". Aborting.'.PHP_EOL;
if (!ini_get('display_errors')) {
if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') {
fwrite(STDERR, $err);
} elseif (!headers_sent()) {
echo $err;
}
}
trigger_error(
$err,
E_USER_ERROR
);
}
require_once __DIR__ . '/composer/autoload_real.php';
return ComposerAutoloaderInitb1e1cfcdb69c5d68249f3a76c8992309::getLoader();


### 3. Apacheの再起動
修正が完了次第、Apacheを再起動します。
bash
sudo systemctl restart apache2


### 4. ブラウザでの確認
再度ブラウザで `http://localhost/phpmyadmin` にアクセスし、問題が解決されたか確認します。

### 5. 再度エラーログの確認
最新のエラーログを確認します。
bash
sudo tail -n 50 /var/log/apache2/error.log


### 結論
上記の手順を実行後、正しいクラス名に修正したことで問題が解決するはずです。問題が解決しない場合や新たなエラーメッセージが発生した場合、その内容を提供してください。再度サポートいたします。
composer/autoload_real.php
<?php

// autoload_real.php @generated by Composer

class ComposerAutoloaderInitb1e1cfcdb69c5d68249f3a76c8992309
{
private static $loader;

public static function loadClassLoader($class)
{
if ('Composer\Autoload\ClassLoader' === $class) {
require __DIR__ . '/ClassLoader.php';
}
}

/**
* @return \Composer\Autoload\ClassLoader
*/
public static function getLoader()
{
if (null !== self::$loader) {
return self::$loader;
}

require __DIR__ . '/platform_check.php';

spl_autoload_register(array('ComposerAutoloaderInitb1e1cfcdb69c5d68249f3a76c8992309', 'loadClassLoader'), true, true);
self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(__DIR__));
spl_autoload_unregister(array('ComposerAutoloaderInitb1e1cfcdb69c5d68249f3a76c8992309', 'loadClassLoader'));

require __DIR__ . '/autoload_static.php';
call_user_func(\Composer\Autoload\ComposerStaticInitb1e1cfcdb69c5d68249f3a76c8992309::getInitializer($loader));

$loader->register(true);

$filesToLoad = \Composer\Autoload\ComposerStaticInitb1e1cfcdb69c5d68249f3a76c8992309::$files;
$requireFile = \Closure::bind(static function ($fileIdentifier, $file) {
if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
$GLOBALS['__composer_autoload_files'][$fileIdentifier] = true;

require $file;
}
}, null, null);
foreach ($filesToLoad as $fileIdentifier => $file) {
$requireFile($fileIdentifier, $file);
}

return $loader;
}
}

owner@Linux-for-owner:/usr/share/php$ sudo nano /usr/share/php/vendor/composer/autoload_real.php
[sudo] owner のパスワード:
owner@Linux-for-owner:/usr/share/php$ sudo systemctl restart apache2
owner@Linux-for-owner:/usr/share/php$ sudo tail -n 10 /var/log/apache2/error.log[Sat Sep 14 12:44:42.002429 2024] [core:notice] [pid 10000] AH00094: Command line: '/usr/sbin/apache2'
[Sat Sep 14 12:44:44.792674 2024] [php:error] [pid 10004] [client ::1:43348] PHP Fatal error: Declaration of Slim\\Psr7\\Uri::withScheme($scheme) must be compatible with Psr\\Http\\Message\\UriInterface::withScheme(string $scheme): Psr\\Http\\Message\\UriInterface in /usr/share/php/Slim/Psr7/Uri.php on line 106
[Sat Sep 14 13:03:50.744943 2024] [mpm_prefork:notice] [pid 10000] AH00170: caught SIGWINCH, shutting down gracefully
[Sat Sep 14 13:03:50.863647 2024] [mpm_prefork:notice] [pid 10410] AH00163: Apache/2.4.58 (Ubuntu) configured -- resuming normal operations
[Sat Sep 14 13:03:50.863726 2024] [core:notice] [pid 10410] AH00094: Command line: '/usr/sbin/apache2'
[Sat Sep 14 13:03:54.341858 2024] [php:error] [pid 10412] [client ::1:54318] PHP Fatal error: Uncaught Error: Class "Slim\\Psr7\\Factory\\ServerRequestFactory" not found in /usr/share/phpmyadmin/libraries/classes/Http/Factory/ServerRequestFactory.php:64\nStack trace:\n#0 /usr/share/phpmyadmin/libraries/classes/Http/Factory/ServerRequestFactory.php(48): PhpMyAdmin\\Http\\Factory\\ServerRequestFactory->createServerRequestFactory()\n#1 /usr/share/phpmyadmin/libraries/classes/Http/Factory/ServerRequestFactory.php(97): PhpMyAdmin\\Http\\Factory\\ServerRequestFactory->__construct()\n#2 /usr/share/phpmyadmin/libraries/classes/Common.php(85): PhpMyAdmin\\Http\\Factory\\ServerRequestFactory::createFromGlobals()\n#3 /usr/share/phpmyadmin/index.php(45): PhpMyAdmin\\Common::run()\n#4 {main}\n thrown in /usr/share/phpmyadmin/libraries/classes/Http/Factory/ServerRequestFactory.php on line 64
[Sat Sep 14 13:53:31.276930 2024] [mpm_prefork:notice] [pid 10410] AH00170: caught SIGWINCH, shutting down gracefully
[Sat Sep 14 13:53:31.398358 2024] [mpm_prefork:notice] [pid 11154] AH00163: Apache/2.4.58 (Ubuntu) configured -- resuming normal operations
[Sat Sep 14 13:53:31.398419 2024] [core:notice] [pid 11154] AH00094: Command line: '/usr/sbin/apache2'
[Sat Sep 14 13:53:33.380823 2024] [php:error] [pid 11156] [client ::1:40862] PHP Fatal error: Declaration of PhpMyAdmin\\Http\\ServerRequest::getServerParams() must be compatible with Psr\\Http\\Message\\ServerRequestInterface::getServerParams(): array in /usr/share/phpmyadmin/libraries/classes/Http/ServerRequest.php on line 180
owner@Linux-for-owner:/usr/share/php$

今、こういう状況です。

現在のエラーログから、PSR-7のインターフェース実装に関する問題がいくつか浮かび上がっています。手順ごとに解決策を見ていきます。

### エラー1: クラス `Slim\Psr7\Factory\ServerRequestFactory` が見つからない

まず、このクラスが存在するか確認し、必要ならば適切なライブラリをインストールします。
bash
sudo nano /usr/share/phpmyadmin/libraries/classes/Http/Factory/ServerRequestFactory.php


#### 解決策:
**修正:**
`Slim\Psr7\Factory\ServerRequestFactory` を呼び出していますが、このクラスが存在しないためエラーが発生しています。以下の手順で解決します。
php
// Slim\Psr7\Factory\ServerRequestFactory ではなく、 Slim\Psr7\Factory\ServerRequestFactoryInterface をインポート
use Psr\Http\Message\ServerRequestInterface;
// クラス定義の確認と修正:
class ServerRequestFactory {
public function createServerRequestFactory() {
return new \Slim\Psr7\Factory\ServerRequestFactory();
}
}


### エラー2: `ServerRequest`のメソッド宣言が一致しない

具体的には、`getServerParams()`の戻り値の型指定に関する問題です。
bash
sudo nano /usr/share/phpmyadmin/libraries/classes/Http/ServerRequest.php


#### 修正:
対応する型を適切に一致させるための修正を行います。
php
// 宣言部分を修正:
class ServerRequest implements \Psr\Http\Message\ServerRequestInterface {
// 既存のコード...
// 修正が必要な部分:
public function getServerParams(): array {
// 実装...
}
// 同様に他の互換性の問題が発生しうるメソッドをチェック:
}


## 次の手順
1. **依存関係の再確認**:
PSR-7のインターフェースと実装の互換性を確認するために、Composerのオートローダーを再生成。
bash
sudo composer dump-autoload



2. **Apacheの再起動**:
依存関係が正しく構成されたことを確認後、Apacheを再起動します。
bash
sudo systemctl restart apache2



3. **ブラウザでの再確認**:
`http://localhost/phpmyadmin`にアクセスし、問題が解決しているか確認します。

4. **エラーログの確認**:
確認後、再度エラーログをチェックし、残りの問題がないか確認。
bash
sudo tail -n 50 /var/log/apache2/error.log


### まとめ
ここまでの修正と再設定で、依存関係の互換性が確保され、正しく動作することが期待されます。もし問題が解決しない、または新しいエラーメッセージが出る場合、その詳細を共有いただければ再度サポートいたします。
/usr/share/phpmyadmin/libraries/classes/Http/Factory/ServerRequestFactory.php
<?php

declare(strict_types=1);

namespace PhpMyAdmin\Http\Factory;

use GuzzleHttp\Psr7\HttpFactory;
use Laminas\Diactoros\ServerRequestFactory as LaminasServerRequestFactory;
use Laminas\Diactoros\UriFactory as LaminasUriFactory;
use Nyholm\Psr7\Factory\Psr17Factory;
use PhpMyAdmin\Http\ServerRequest;
use Psr\Http\Message\ServerRequestFactoryInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Message\UriFactoryInterface;
use Psr\Http\Message\UriInterface;
use Slim\Psr7\Factory\ServerRequestFactory as SlimServerRequestFactory;
use Slim\Psr7\Factory\UriFactory as SlimUriFactory;

use function class_exists;
use function count;
use function current;
use function explode;
use function function_exists;
use function getallheaders;
use function in_array;
use function is_numeric;
use function is_string;
use function parse_url;
use function preg_match;
use function strpos;
use function strstr;
use function substr;

use const PHP_URL_QUERY;

class ServerRequestFactory
{
/** @var ServerRequestFactoryInterface */
private $serverRequestFactory;

/** @var UriFactoryInterface */
private $uriFactory;

public function __construct(
?ServerRequestFactoryInterface $serverRequestFactory = null,
?UriFactoryInterface $uriFactory = null
) {
$this->serverRequestFactory = $serverRequestFactory ?? $this->createServerRequestFactory();
$this->uriFactory = $uriFactory ?? $this->createUriFactory();
}

private function createServerRequestFactory(): ServerRequestFactoryInterface
{
if (class_exists(Psr17Factory::class)) {
/** @var ServerRequestFactoryInterface $factory */
$factory = new Psr17Factory();
} elseif (class_exists(HttpFactory::class)) {
/** @var ServerRequestFactoryInterface $factory */
$factory = new HttpFactory();
} elseif (class_exists(LaminasServerRequestFactory::class)) {
/** @var ServerRequestFactoryInterface $factory */
$factory = new LaminasServerRequestFactory();
} else {
$factory = new SlimServerRequestFactory();
}

return $factory;
}

private function createUriFactory(): UriFactoryInterface
{
if (class_exists(Psr17Factory::class)) {
/** @var UriFactoryInterface $factory */
$factory = new Psr17Factory();
} elseif (class_exists(HttpFactory::class)) {
/** @var UriFactoryInterface $factory */
$factory = new HttpFactory();
} elseif (class_exists(LaminasUriFactory::class)) {
/** @var UriFactoryInterface $factory */
$factory = new LaminasUriFactory();
} else {
$factory = new SlimUriFactory();
}

return $factory;
}

public static function createFromGlobals(): ServerRequest
{
if (class_exists(SlimServerRequestFactory::class)) {
/** @psalm-suppress InternalMethod */
$serverRequest = SlimServerRequestFactory::createFromGlobals();
} elseif (class_exists(LaminasServerRequestFactory::class)) {
/** @var ServerRequestInterface $serverRequest */
$serverRequest = LaminasServerRequestFactory::fromGlobals();
} else {
$creator = new self();
$serverRequest = self::createServerRequestFromGlobals($creator);
}

return new ServerRequest($serverRequest);
}

/**
* @return array<string, string>
*/
protected function getallheaders(): array
{
/** @var array<string, string> $headers */
$headers = function_exists('getallheaders') ? getallheaders() : [];

return $headers;
}

private static function createServerRequestFromGlobals(self $creator): ServerRequestInterface
{
$serverRequest = $creator->serverRequestFactory->createServerRequest(
$_SERVER['REQUEST_METHOD'] ?? 'GET',
$creator->createUriFromGlobals($_SERVER),
$_SERVER
);

foreach ($creator->getallheaders() as $name => $value) {
$serverRequest = $serverRequest->withAddedHeader($name, $value);
}

$serverRequest = $serverRequest->withQueryParams($_GET);

if ($serverRequest->getMethod() !== 'POST') {
return $serverRequest;
}

$contentType = '';
foreach ($serverRequest->getHeader('Content-Type') as $headerValue) {
$contentType = current(explode(';', $headerValue));
}

if (in_array($contentType, ['application/x-www-form-urlencoded', 'multipart/form-data'], true)) {
return $serverRequest->withParsedBody($_POST);
}

return $serverRequest;
}

/**
* Create new Uri from environment.
*
* Initially based on the \Slim\Psr7\Factory\UriFactory::createFromGlobals() implementation.
*
* @param mixed[] $server
*/
private function createUriFromGlobals(array $server): UriInterface
{
$uri = $this->uriFactory->createUri('');

$uri = $uri->withScheme(! isset($server['HTTPS']) || $server['HTTPS'] === 'off' ? 'http' : 'https');

if (isset($server['PHP_AUTH_USER']) && is_string($server['PHP_AUTH_USER']) && $server['PHP_AUTH_USER'] !== '') {
$uri = $uri->withUserInfo(
$server['PHP_AUTH_USER'],
isset($server['PHP_AUTH_PW']) && is_string($server['PHP_AUTH_PW']) ? $server['PHP_AUTH_PW'] : null
);
}

if (isset($server['HTTP_HOST']) && is_string($server['HTTP_HOST'])) {
$uri = $uri->withHost($server['HTTP_HOST']);
} elseif (isset($server['SERVER_NAME']) && is_string($server['SERVER_NAME'])) {
$uri = $uri->withHost($server['SERVER_NAME']);
}

if (isset($server['SERVER_PORT']) && is_numeric($server['SERVER_PORT']) && $server['SERVER_PORT'] >= 1) {
$uri = $uri->withPort((int) $server['SERVER_PORT']);
} else {
$uri = $uri->withPort($uri->getScheme() === 'https' ? 443 : 80);
}

if (preg_match('/^(\[[a-fA-F0-9:.]+])(:\d+)?\z/', $uri->getHost(), $matches)) {
$uri = $uri->withHost($matches[1]);
if (isset($matches[2])) {
$uri = $uri->withPort((int) substr($matches[2], 1));
}
} else {
$pos = strpos($uri->getHost(), ':');
if ($pos !== false) {
$port = (int) substr($uri->getHost(), $pos + 1);
$host = (string) strstr($uri->getHost(), ':', true);
$uri = $uri->withHost($host)->withPort($port);
}
}

if (isset($server['QUERY_STRING']) && is_string($server['QUERY_STRING'])) {
$uri = $uri->withQuery($server['QUERY_STRING']);
}

if (isset($server['REQUEST_URI']) && is_string($server['REQUEST_URI'])) {
$uriFragments = explode('?', $server['REQUEST_URI']);
$uri = $uri->withPath($uriFragments[0]);
if ($uri->getQuery() === '' && count($uriFragments) > 1) {
$query = parse_url('https://www.example.com' . $server['REQUEST_URI'], PHP_URL_QUERY);
if (is_string($query) && $query !== '') {
$uri = $uri->withQuery($query);
}
}
}

return $uri;
}
}

これは、public function createServerRequestFactory() {
return new \Slim\Psr7\Factory\ServerRequestFactory();
}をclass ServerRequestFactory {}に入れればいいですか?


/usr/share/phpmyadmin/libraries/classes/Http/ServerRequest.php
<?php

declare(strict_types=1);

namespace PhpMyAdmin\Http;

use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Message\StreamInterface;
use Psr\Http\Message\UriInterface;

use function is_array;
use function is_object;
use function property_exists;

class ServerRequest implements ServerRequestInterface
{
/** @var ServerRequestInterface */
private $serverRequest;

final public function __construct(ServerRequestInterface $serverRequest)
{
$this->serverRequest = $serverRequest;
}

/**
* @inheritDoc
*/
public function getProtocolVersion()
{
return $this->serverRequest->getProtocolVersion();
}

/**
* @inheritDoc
*/
public function withProtocolVersion($version)
{
$serverRequest = $this->serverRequest->withProtocolVersion($version);

return new static($serverRequest);
}

/**
* @inheritDoc
*/
public function getHeaders()
{
return $this->serverRequest->getHeaders();
}

/**
* @inheritDoc
*/
public function hasHeader($name)
{
return $this->serverRequest->hasHeader($name);
}

/**
* @inheritDoc
*/
public function getHeader($name)
{
return $this->serverRequest->getHeader($name);
}

/**
* @inheritDoc
*/
public function getHeaderLine($name)
{
return $this->serverRequest->getHeaderLine($name);
}

/**
* @inheritDoc
*/
public function withHeader($name, $value)
{
$serverRequest = $this->serverRequest->withHeader($name, $value);

return new static($serverRequest);
}

/**
* @inheritDoc
*/
public function withAddedHeader($name, $value)
{
$serverRequest = $this->serverRequest->withAddedHeader($name, $value);

return new static($serverRequest);
}

/**
* @inheritDoc
*/
public function withoutHeader($name)
{
$serverRequest = $this->serverRequest->withoutHeader($name);

return new static($serverRequest);
}

/**
* @inheritDoc
*/
public function getBody()
{
return $this->serverRequest->getBody();
}

/**
* @inheritDoc
*/
public function withBody(StreamInterface $body)
{
$serverRequest = $this->serverRequest->withBody($body);

return new static($serverRequest);
}

/**
* @inheritDoc
*/
public function getRequestTarget()
{
return $this->serverRequest->getRequestTarget();
}

/**
* @inheritDoc
*/
public function withRequestTarget($requestTarget)
{
$serverRequest = $this->serverRequest->withRequestTarget($requestTarget);

return new static($serverRequest);
}

/**
* @inheritDoc
*/
public function getMethod()
{
return $this->serverRequest->getMethod();
}

/**
* @inheritDoc
*/
public function withMethod($method)
{
$serverRequest = $this->serverRequest->withMethod($method);

return new static($serverRequest);
}

/**
* @inheritDoc
*/
public function getUri()
{
return $this->serverRequest->getUri();
}

/**
* @inheritDoc
*/
public function withUri(UriInterface $uri, $preserveHost = false)
{
$serverRequest = $this->serverRequest->withUri($uri, $preserveHost);

return new static($serverRequest);
}

/**
* @inheritDoc
*/
public function getServerParams()
{
return $this->serverRequest->getServerParams();
}

/**
* @inheritDoc
*/
public function getCookieParams()
{
return $this->serverRequest->getCookieParams();
}

/**
* @inheritDoc
*/
public function withCookieParams(array $cookies)
{
$serverRequest = $this->serverRequest->withCookieParams($cookies);

return new static($serverRequest);
}

/**
* @inheritDoc
*/
public function getQueryParams()
{
return $this->serverRequest->getQueryParams();
}

/**
* @inheritDoc
*/
public function withQueryParams(array $query)
{
$serverRequest = $this->serverRequest->withQueryParams($query);

return new static($serverRequest);
}

/**
* @inheritDoc
*/
public function getUploadedFiles()
{
return $this->serverRequest->getUploadedFiles();
}

/**
* @inheritDoc
*/
public function withUploadedFiles(array $uploadedFiles)
{
$serverRequest = $this->serverRequest->withUploadedFiles($uploadedFiles);

return new static($serverRequest);
}

/**
* @inheritDoc
*/
public function getParsedBody()
{
return $this->serverRequest->getParsedBody();
}

/**
* @inheritDoc
*/
public function withParsedBody($data)
{
$serverRequest = $this->serverRequest->withParsedBody($data);

return new static($serverRequest);
}

/**
* @inheritDoc
*/
public function getAttributes()
{
return $this->serverRequest->getAttributes();
}

/**
* @inheritDoc
*/
public function getAttribute($name, $default = null)
{
return $this->serverRequest->getAttribute($name, $default);
}

/**
* @inheritDoc
*/
public function withAttribute($name, $value)
{
$serverRequest = $this->serverRequest->withAttribute($name, $value);

return new static($serverRequest);
}

/**
* @inheritDoc
*/
public function withoutAttribute($name)
{
$serverRequest = $this->serverRequest->withoutAttribute($name);

return new static($serverRequest);
}

/**
* @param mixed $default
*
* @return mixed
*/
public function getParam(string $param, $default = null)
{
$getParams = $this->getQueryParams();
$postParams = $this->getParsedBody();

if (is_array($postParams) && isset($postParams[$param])) {
return $postParams[$param];
}

if (is_object($postParams) && property_exists($postParams, $param)) {
return $postParams->$param;
}

if (isset($getParams[$param])) {
return $getParams[$param];
}

return $default;
}

/**
* @param mixed $default
*
* @return mixed
*/
public function getParsedBodyParam(string $param, $default = null)
{
$postParams = $this->getParsedBody();

if (is_array($postParams) && isset($postParams[$param])) {
return $postParams[$param];
}

if (is_object($postParams) && property_exists($postParams, $param)) {
return $postParams->$param;
}

return $default;
}

public function isPost(): bool
{
return $this->getMethod() === 'POST';
}
}

こちらは、実装ではなく、全て修正ですか?

`ServerRequestFactory`と`ServerRequest`の2つのクラスに関して、このケースに適用するためのいくつかの修正を提案します。

### 1. `ServerRequestFactory`の修正
まず、`ServerRequestFactory`クラス内の`createServerRequestFactory`メソッドが正しい`ServerRequestFactoryInterface`を返すように修正します。

#### 修正例:`/usr/share/phpmyadmin/libraries/classes/Http/Factory/ServerRequestFactory.php`
以下のコードを参考にして、`ServerRequestFactory`クラスを修正します。
php
<?php
declare(strict_types=1);
namespace PhpMyAdmin\Http\Factory;
use GuzzleHttp\Psr7\HttpFactory;
use Laminas\Diactoros\ServerRequestFactory as LaminasServerRequestFactory;
use Laminas\Diactoros\UriFactory as LaminasUriFactory;
use Nyholm\Psr7\Factory\Psr17Factory;
use PhpMyAdmin\Http\ServerRequest;
use Psr\Http\Message\ServerRequestFactoryInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Message\UriFactoryInterface;
use Psr\Http\Message\UriInterface;
use Slim\Psr7\Factory\ServerRequestFactory as SlimServerRequestFactory;
use Slim\Psr7\Factory\UriFactory as SlimUriFactory;
use function class_exists;
use function count;
use function current;
use function explode;
use function function_exists;
use function getallheaders;
use function in_array;
use function is_numeric;
use function is_string;
use function parse_url;
use function preg_match;
use function strpos;
use function strstr;
use function substr;
use const PHP_URL_QUERY;
class ServerRequestFactory
{
/** @var ServerRequestFactoryInterface */
private $serverRequestFactory;
/** @var UriFactoryInterface */
private $uriFactory;
public function __construct(
?ServerRequestFactoryInterface $serverRequestFactory = null,
?UriFactoryInterface $uriFactory = null
) {
$this->serverRequestFactory = $serverRequestFactory ?? $this->createServerRequestFactory();
$this->uriFactory = $uriFactory ?? $this->createUriFactory();
}
private function createServerRequestFactory(): ServerRequestFactoryInterface
{
if (class_exists(Psr17Factory::class)) {
/** @var ServerRequestFactoryInterface $factory */
$factory = new Psr17Factory();
} elseif (class_exists(HttpFactory::class)) {
/** @var ServerRequestFactoryInterface $factory */
$factory = new HttpFactory();
} elseif (class_exists(LaminasServerRequestFactory::class)) {
/** @var ServerRequestFactoryInterface $factory */
$factory = new LaminasServerRequestFactory();
} else {
/** @var ServerRequestFactoryInterface $factory */
$factory = new SlimServerRequestFactory();
}
return $factory;
}
private function createUriFactory(): UriFactoryInterface
{
if (class_exists(Psr17Factory::class)) {
/** @var UriFactoryInterface $factory */
$factory = new Psr17Factory();
} elseif (class_exists(HttpFactory::class)) {
/** @var UriFactoryInterface $factory */
$factory = new HttpFactory();
} elseif (class_exists(LaminasUriFactory::class)) {
/** @var UriFactoryInterface $factory */
$factory = new LaminasUriFactory();
} else {
/** @var UriFactoryInterface $factory */
$factory = new SlimUriFactory();
}
return $factory;
}
public static function createFromGlobals(): ServerRequest
{
if (class_exists(SlimServerRequestFactory::class)) {
/** @psalm-suppress InternalMethod */
$serverRequest = SlimServerRequestFactory::createFromGlobals();
} elseif (class_exists(LaminasServerRequestFactory::class)) {
/** @var ServerRequestInterface $serverRequest */
$serverRequest = LaminasServerRequestFactory::fromGlobals();
} else {
$creator = new self();
$serverRequest = self::createServerRequestFromGlobals($creator);
}
return new ServerRequest($serverRequest);
}
/**
* @return array<string, string>
*/
protected function getallheaders(): array
{
/** @var array<string, string> $headers */
$headers = function_exists('getallheaders') ? getallheaders() : [];
return $headers;
}
private static function createServerRequestFromGlobals(self $creator): ServerRequestInterface
{
$serverRequest = $creator->serverRequestFactory->createServerRequest(
$_SERVER['REQUEST_METHOD'] ?? 'GET',
$creator->createUriFromGlobals($_SERVER),
$_SERVER
);
foreach ($creator->getallheaders() as $name => $value) {
$serverRequest = $serverRequest->withAddedHeader($name, $value);
}
$serverRequest = $serverRequest->withQueryParams($_GET);
if ($serverRequest->getMethod() !== 'POST') {
return $serverRequest;
}
$contentType = '';
foreach ($serverRequest->getHeader('Content-Type') as $headerValue) {
$contentType = current(explode(';', $headerValue));
}
if (in_array($contentType, ['application/x-www-form-urlencoded', 'multipart/form-data'], true)) {
return $serverRequest->withParsedBody($_POST);
}
return $serverRequest;
}
/**
* Create new Uri from environment.
*
* Initially based on the \Slim\Psr7\Factory\UriFactory::createFromGlobals() implementation.
*
* @param mixed[] $server
*/
private function createUriFromGlobals(array $server): UriInterface
{
$uri = $this->uriFactory->createUri('');
$uri = $uri->withScheme(! isset($server['HTTPS']) || $server['HTTPS'] === 'off' ? 'http' : 'https');
if (isset($server['PHP_AUTH_USER']) && is_string($server['PHP_AUTH_USER']) && $server['PHP_AUTH_USER'] !== '') {
$uri = $uri->withUserInfo(
$server['PHP_AUTH_USER'],
isset($server['PHP_AUTH_PW']) && is_string($server['PHP_AUTH_PW']) ? $server['PHP_AUTH_PW'] : null
);
}
if (isset($server['HTTP_HOST']) && is_string($server['HTTP_HOST'])) {
$uri = $uri->withHost($server['HTTP_HOST']);
} elseif (isset($server['SERVER_NAME']) && is_string($server['SERVER_NAME'])) {
$uri = $uri->withHost($server['SERVER_NAME']);
}
if (isset($server['SERVER_PORT']) && is_numeric($server['SERVER_PORT']) && $server['SERVER_PORT'] >= 1) {
$uri = $uri->withPort((int) $server['SERVER_PORT']);
} else {
$uri = $uri->withPort($uri->getScheme() === 'https' ? 443 : 80);
}
if (preg_match('/^(\[[a-fA-F0-9:.]+])(:\d+)?\z/', $uri->getHost(), $matches)) {
$uri = $uri->withHost($matches[1]);
if (isset($matches[2])) {
$uri = $uri->withPort((int) substr($matches[2], 1));
}
} else {
$pos = strpos($uri->getHost(), ':');
if ($pos !== false) {
$port = (int) substr($uri->getHost(), $pos + 1);
$host = (string) strstr($uri->getHost(), ':', true);
$uri = $uri->withHost($host)->withPort($port);
}
}
if (isset($server['QUERY_STRING']) && is_string($server['QUERY_STRING'])) {
$uri = $uri->withQuery($server['QUERY_STRING']);
}
if (isset($server['REQUEST_URI']) && is_string($server['REQUEST_URI'])) {
$uriFragments = explode('?', $server['REQUEST_URI']);
$uri = $uri->withPath($uriFragments[0]);
if ($uri->getQuery() === '' && count($uriFragments) > 1) {
$query = parse_url('https://www.example.com' . $server['REQUEST_URI'], PHP_URL_QUERY);
if (is_string($query) && $query !== '') {
$uri = $uri->withQuery($query);
}
}
}
return $uri;
}
}


### 2. `ServerRequest`クラスの修正
次に、`ServerRequest`クラスが `ServerRequestInterface` のメソッドを正しく実装していることを確認します。

#### 修正例:`/usr/share/phpmyadmin/libraries/classes/Http/ServerRequest.php`
以下のコードを参考に、 `ServerRequest` クラスを修正します:
php
<?php
declare(strict_types=1);
namespace PhpMyAdmin\Http;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Message\StreamInterface;
use Psr\Http\Message\UriInterface;
use function is_array;
use function is_object;
use function property_exists;
class ServerRequest implements ServerRequestInterface
{
/** @var ServerRequestInterface */
private $serverRequest;
final public function __construct(ServerRequestInterface $serverRequest)
{
$this->serverRequest = $serverRequest;
}
/**
* @inheritDoc
*/
public function getProtocolVersion(): string
{
return $this->serverRequest->getProtocolVersion();
}
/**
* @inheritDoc
*/
public function withProtocolVersion($version): self
{
$serverRequest = $this->serverRequest->withProtocolVersion($version);
return new static($serverRequest);
}
/**
* @inheritDoc
*/
public function getHeaders(): array
{
return $this->serverRequest->getHeaders();
}
/**
* @inheritDoc
*/
public function hasHeader($name): bool
{
return $this->serverRequest->hasHeader($name);
}
/**
* @inheritDoc
*/
public function getHeader($name): array
{
return $this->serverRequest->getHeader($name);
}
/**
* @inheritDoc
*/
public function getHeaderLine($name): string
{
return $this->serverRequest->getHeaderLine($name);
}
/**
* @inheritDoc
*/
public function withHeader($name, $value): self
{
$serverRequest = $this->serverRequest->withHeader($name, $value);
return new static($serverRequest);
}
/**
* @inheritDoc
*/
public function withAddedHeader($name, $value): self
{
$serverRequest = $this->serverRequest->withAddedHeader($name, $value);
return new static($serverRequest);
}
/**
* @inheritDoc
*/
public function withoutHeader($name): self
{
$serverRequest = $this->serverRequest->withoutHeader($name);
return new static($serverRequest);
}
/**
* @inheritDoc
*/
public function getBody(): StreamInterface
{
return $this->serverRequest->getBody();
}
/**
* @inheritDoc
*/
public function withBody(StreamInterface $body): self
{
$serverRequest = $this->serverRequest->withBody($body);
return new static($serverRequest);
}
/**
* @inheritDoc
*/
public function getRequestTarget(): string
{
return $this->serverRequest->getRequestTarget();
}
/**
* @inheritDoc
*/
public function withRequestTarget($requestTarget): self
{
$serverRequest = $->with(->withUri($uri, $preserveHost);
return new static($serverRequest);
}
/**
* @inheritDoc
*/
public function get-serverRequest->withQueryParams(array $query): self
{
$serverRequest = $this->serverRequest->withQueryParams($query);
return new static($serverRequest);
}
/**
* @inheritDoc
*/
public function getUploadedFiles(): array
{
return $this->serverRequest->getUploadedFiles();
}
/**
* @inheritDoc
*/
public function withUploadedFiles(array $uploadedFiles): self
{
$serverRequest = $this->serverRequest->withUploadedFiles($uploadedFiles);
return new static($serverRequest);
}
/**
* @inheritDoc
*/
public function getParsedBody(): array
{
return $this->serverRequest->getParsedBody();
}
/**
* @inheritDoc
*/
public function withParsedBody($data): self
{
$serverRequest = $this->serverRequest->withParsedBody($data);
return new static($serverRequest);
}
/**
* @inheritDoc
*/
public function getAttributes(): array
{
return $this->serverRequest->getAttributes();
}
/**
* @inheritDoc
*/
public function getAttribute($name, $default = null)
{
return $this->serverRequest->getAttribute($name, $default);
}
/**
* @inheritDoc
*/
public function withAttribute($name, $value): self
{
$serverRequest = $this->serverRequest->withAttribute($name, $value);
return new static($serverRequest);
}
/**
* @inheritDoc
*/
public function withoutAttribute($name): self
{
$serverRequest = $this->serverRequest->withoutAttribute($name);
return new static($serverRequest);
}
/**
* @param mixed $default
*
* @return mixed
*/
public function getParam(string $param, $default = null)
{
$getParams = $this->getQueryParams();
$postParams = $this->getParsedBody();
if (is_array($postParams) && isset($postParams[$param])) {
return $postParams[$param];
}
if (is_object($postParams) && property_exists($postParams, $param)) {
return $postParams->$param;
}
if (isset($getParams[$param])) {
return $getParams[$param];
}
return $default;
}
/**
* @param mixed $default
*
* @return mixed
*/
public function getParsedBodyParam(string $param, $default = null)
{
$postParams = $this->getParsedBody();
if (is_array($postParams) && isset($postParams[$param])) {
return $postParams[$param];
}
if (is_object($postParams) && property_exists($postParams, $param)) {
return $postParams->$param;
}
return $default;
}
public function isPost(): bool
{
return $this->getMethod() === 'POST';
}
}


### 修正後の手順

修正が完了したら、以下の手順を実行します。

### Apacheの再起動
修正が完了次第、Apacheを再起動します。
bash
sudo systemctl restart apache2


### ブラウザでの確認
再度ブラウザで `http://localhost/phpmyadmin` にアクセスし、問題が解決されているか確認します。

### エラーログの確認
最新のエラーログを確認します。
bash
sudo tail -n 50 /var/log/apache2/error.log


修正が完了し次第、問題が解決されたかどうか再確認してください。問題が解決しない、または新たなエラーメッセージが発生した場合、そのエラーメッセージを提供してください。再度、サポートを提供します。
/usr/share/phpmyadmin/libraries/classes/Http/ServerRequest.php
134~139
public function withRequestTarget($requestTarget): self
{
$serverRequest = $this->serverRequest->withRequestTarget($requestTarget);

return new static($serverRequest);
}⇛【$this->serverRequest->withRequestTarget($requestTarget);】を【$->with(->withUri($uri, $preserveHost);】に変更でしょうか?
141-219
/**
* @inheritDoc
*/
public function getMethod()
{
return $this->serverRequest->getMethod();
}

/**
* @inheritDoc
*/
public function withMethod($method)
{
$serverRequest = $this->serverRequest->withMethod($method);

return new static($serverRequest);
}

/**
* @inheritDoc
*/
public function getUri()
{
return $this->serverRequest->getUri();
}

/**
* @inheritDoc
*/
public function withUri(UriInterface $uri, $preserveHost = false)
{
$serverRequest = $this->serverRequest->withUri($uri, $preserveHost);

return new static($serverRequest);
}

/**
* @inheritDoc
*/
public function getServerParams()
{
return $this->serverRequest->getServerParams();
}

/**
* @inheritDoc
*/
public function getCookieParams()
{
return $this->serverRequest->getCookieParams();
}

/**
* @inheritDoc
*/
public function withCookieParams(array $cookies)
{
$serverRequest = $this->serverRequest->withCookieParams($cookies);

return new static($serverRequest);
}

/**
* @inheritDoc
*/
public function getQueryParams()
{
return $this->serverRequest->getQueryParams();
}

/**
* @inheritDoc
*/
public function withQueryParams(array $query)
{
$serverRequest = $this->serverRequest->withQueryParams($query);

return new static($serverRequest);
}⇛ 【 /**
* @inheritDoc
*/
public function get-serverRequest->withQueryParams(array $query): self
{
$serverRequest = $this->serverRequest->withQueryParams($query);

return new static($serverRequest);
}】に差し替えでしょうか?

以下に修正すべき具体的な手順を示します。

### 1. `ServerRequestFactory`の修正
`ServerRequestFactory`クラスで、`Slim\Psr7\Factory\ServerRequestFactory`を適切に扱うための修正を行います。また、クラスの自動生成されたエラーメッセージが発生しないように確認します。

### 2. `ServerRequest`の修正
`ServerRequestInterface`のメソッドが正しく実装されているか確認します。

#### ケース1: `ServerRequest`での`withRequestTarget`メソッド
まず、エラーログを見て、インターフェースに一致するように以下のメソッドを修正します。
php
public function withRequestTarget($requestTarget): self
{
// Provided method is correct, don't change to erroneous code.
$serverRequest = $this->serverRequest->withRequestTarget($requestTarget);
return new static($serverRequest);
}


#### ケース2: `withQueryParams`メソッドの修正
次に、正しいインターフェースを守るために簡潔に`ServerRequestInterface`を継承しています。
php
public function withQueryParams(array $query): self
{
$serverRequest = $this->serverRequest->withQueryParams($query);
return new static($serverRequest);
}


#### ケース3: 他のメソッドも同様にチェック
他のメソッドも同様にインターフェースに対して修正を加えます。
php
public function getServerParams(): array
{
return $this->serverRequest->getServerParams();
}
public function withCookieParams(array $cookies): self
{
$serverRequest = $this->serverRequest->withCookieParams($cookies);
return new static($serverRequest);
}


### `ServerRequest`クラス最終修正例
以下のように`ServerRequest`クラス全体を見直します。
php
<?php
declare(strict_types=1);
namespace PhpMyAdmin\Http;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Message\StreamInterface;
use Psr\Http\Message\UriInterface;
use function is_array;
use function is_object;
use function property_exists;
class ServerRequest implements ServerRequestInterface
{
/** @var ServerRequestInterface */
private $serverRequest;
final public function __construct(ServerRequestInterface $serverRequest)
{
$this->serverRequest = $serverRequest;
}
public function getProtocolVersion(): string
{
return $this->serverRequest->getProtocolVersion();
}
public function withProtocolVersion($version): self
{
$serverRequest = $this->serverRequest->withProtocolVersion($version);
return new static($serverRequest);
}
public function getHeaders(): array
{
return $this->serverRequest->getHeaders();
}
public function hasHeader($name): bool
{
return $this->serverRequest->hasHeader($name);
}
public function getHeader($name): array
{
return $this->serverRequest->getHeader($name);
}
public function getHeaderLine($name): string
{
return $this->serverRequest->getHeaderLine($name);
}
public function withHeader($name, $value): self
{
$serverRequest = $this->serverRequest->withHeader($name, $value);
return new static($serverRequest);
}
public function withAddedHeader($name, $value): self
{
$serverRequest = $this->serverRequest->withAddedHeader($name, $value);
return new static($serverRequest);
}
public function withoutHeader($name): self
{
$serverRequest = $this->serverRequest->withoutHeader($name);
return new static($serverRequest);
}
public function getBody(): StreamInterface
{
return $this->serverRequest->getBody();
}
public function withBody(StreamInterface $body): self
{
$serverRequest = $this->serverRequest->withBody($body);
return new static($serverRequest);
}
public function getRequestTarget(): string
{
return $this->serverRequest->getRequestTarget();
}
public function withRequestTarget($requestTarget): self
{
$serverRequest = $this->serverRequest->withRequestTarget($requestTarget);
return new static($serverRequest);
}
public function getMethod(): string
{
return $this->serverRequest->getMethod();
}
public function withMethod($method): self
{
$serverRequest = $this->serverRequest->withMethod($method);
return new static($serverRequest);
}
public function getUri(): UriInterface
{
return $this->serverRequest->getUri();
}
public function withUri(UriInterface $uri, $preserveHost = false): self
{
$serverRequest = $this->serverRequest->withUri($uri, $preserveHost);
return new static($serverRequest);
}
public function getServerParams(): array
{
return $this->serverRequest->getServerParams();
}
public function getCookieParams(): array
{
return $this->serverRequest->getCookieParams();
}
public function withCookieParams(array $cookies): self
{
$serverRequest = $this->serverRequest->withCookieParams($cookies);
return new static($serverRequest);
}
public function getQueryParams(): array
{
return $this->serverRequest->getQueryParams();
}
public function withQueryParams(array $query): self
{
$serverRequest = $this->serverRequest->withQueryParams($query);
return new static($serverRequest);
}
public function getUploadedFiles(): array
{
return $this->serverRequest->getUploadedFiles();
}
public function withUploadedFiles(array $uploadedFiles): self
{
$serverRequest = $this->serverRequest->withUploadedFiles($uploadedFiles);
return new static($serverRequest);
}
public function getParsedBody()
{
return $this->serverRequest->getParsedBody();
}
public function withParsedBody($data): self
{
$serverRequest = $this->serverRequest->withParsedBody($data);
return new static($serverRequest);
}
public function getAttributes(): array
{
return $this->serverRequest->getAttributes();
}
public function getAttribute($name, $default = null)
{
return $this->serverRequest->getAttribute($name, $default);
}
public function withAttribute($name, $value): self
{
$serverRequest = $this->serverRequest->withAttribute($name, $value);
return new static($serverRequest);
}
public function withoutAttribute($name): self
{
$serverRequest = $this->serverRequest->withoutAttribute($name);
return new static($serverRequest);
}
public function getParam(string $param, $default = null)
{
$getParams = $this->getQueryParams();
$postParams = $this->getParsedBody();
if (is_array($postParams) && isset($postParams[$param])) {
return $postParams[$param];
}
if (is_object($postParams) && property_exists($postParams, $param)) {
return $postParams->$param;
}
if (isset($getParams[$param])) {
return $getParams[$param];
}
return $default;
}
public function getParsedBodyParam(string $param, $default = null)
{
$postParams = $this->getParsedBody();
if (is_array($postParams) && isset($postParams[$param])) {
return $postParams[$param];
}
if (is_object($postParams) && property_exists($postParams, $param)) {
return $postParams->$param;
}
return $default;
}
public function isPost(): bool
{
return $this->getMethod() === 'POST';
}
}


### 修正後の確認
修正が完了したら、以下の手順で確認を行います。

### Apacheの再起動
bash
sudo systemctl restart apache2


### ブラウザでの確認
再度ブラウザで `http://localhost/phpmyadmin` にアクセスし、問題が解決されたか確認します。

### エラーログの確認
最新のエラーログを確認します。
bash
sudo tail -n 50 /var/log/apache2/error.log


修正が完了し次第、問題が解決されたかどうか再確認してください。問題が解決しない、または新たなエラーメッセージが発生した場合、そのエラーメッセージを提供してください。再度サポートを提供します。
getParsedBodyはarrayは必要なく裸でいいのですか?

`getParsedBody` メソッドは `Psr\Http\Message\ServerRequestInterface` の一部であり、その戻り値の型は `array` に限定されていません。実際には `array`、`object`、`null` のいずれかが返される可能性があります。このため、`array` 型に限定せずに、元のインターフェースと一致するように修正する必要があります。

### `Psr\Http\Message\ServerRequestInterface` の確認

`getParsedBody` メソッドのインターフェース定義を確認します。
php
namespace Psr\Http\Message;
interface ServerRequestInterface extends RequestInterface
{
// 他のメソッド...
/**
* Retrieve any parameters provided in the request body.
*
* If the request Content-Type is either application/x-www-form-urlencoded
* or multipart/form-data, and the request method is POST, this method MUST
* return the contents of $_POST.
*
* Otherwise, this method may return any results of deserializing
* the request body content; as parsing returns structured content, the
* potential types MUST be arrays or objects only. A null value indicates
* the absence of body content.
*
* @return array|object|null The deserialized body parameters, if any.
*/
public function getParsedBody();
}


### `ServerRequest` クラスの修正

上記のインターフェース定義に基づき、`ServerRequest` クラスの `getParsedBody` メソッドおよび関連メソッドを修正します。

#### 修正例:`/usr/share/phpmyadmin/libraries/classes/Http/ServerRequest.php`
php
<?php
declare(strict_types=1);
namespace PhpMyAdmin\Http;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Message\StreamInterface;
use Psr\Http\Message\UriInterface;
use function is_array;
use function is_object;
use function property_exists;
class ServerRequest implements ServerRequestInterface
{
/** @var ServerRequestInterface */
private ServerRequestInterface $serverRequest;
final public function __construct(ServerRequestInterface $serverRequest)
{
$this->serverRequest = $serverRequest;
}
public function getProtocolVersion(): string
{
return $this->serverRequest->getProtocolVersion();
}
public function withProtocolVersion($version): self
{
$serverRequest = $this->serverRequest->withProtocolVersion($version);
return new static($serverRequest);
}
public function getHeaders(): array
{
return $this->serverRequest->getHeaders();
}
public function hasHeader($name): bool
{
return $this->serverRequest->hasHeader($name);
}
public function getHeader($name): array
{
return $this->serverRequest->getHeader($name);
}
public function getHeaderLine($name): string
{
return $this->serverRequest->getHeaderLine($name);
}
public function withHeader($name, $value): self
{
$serverRequest = $this->serverRequest->withHeader($name, $value);
return new static($serverRequest);
}
public function withAddedHeader($name, $value): self
{
$serverRequest = $this->serverRequest->withAddedHeader($name, $value);
return new static($serverRequest);
}
public function withoutHeader($name): self
{
$serverRequest = $this->serverRequest->withoutHeader($name);
return new static($serverRequest);
}
public function getBody(): StreamInterface
{
return $this->serverRequest->getBody();
}
public function withBody(StreamInterface $body): self
{
$serverRequest = $this->serverRequest->withBody($body);
return new static($serverRequest);
}
public function getRequestTarget(): string
{
return $this->serverRequest->getRequestTarget();
}
public function withRequestTarget($requestTarget): self
{
$serverRequest = $this->serverRequest->withRequestTarget($requestTarget);
return new static($serverRequest);
}
public function getMethod(): string
{
return $this->serverRequest->getMethod();
}
public function withMethod($method): self
{
$serverRequest = $this->serverRequest->withMethod($method);
return new static($serverRequest);
}
public function getUri(): UriInterface
{
return $this->serverRequest->getUri();
}
public function withUri(UriInterface $uri, $preserveHost = false): self
{
$serverRequest = $this->serverRequest->withUri($uri, $preserveHost);
return new static($serverRequest);
}
public function getServerParams(): array
{
return $this->serverRequest->getServerParams();
}
public function getCookieParams(): array
{
return $this->serverRequest->getCookieParams();
}
public function withCookieParams(array $cookies): self
{
$serverRequest = $this->serverRequest->withCookieParams($cookies);
return new static($serverRequest);
}
public function getQueryParams(): array
{
return $this->serverRequest->getQueryParams();
}
public function withQueryParams(array $query): self
{
$serverRequest = $this->serverRequest->withQueryParams($query);
return new static($serverRequest);
}
public function getUploadedFiles(): array
{
return $this->serverRequest->getUploadedFiles();
}
public function withUploadedFiles(array $uploadedFiles): self
{
$serverRequest = $this->serverRequest->withUploadedFiles($uploadedFiles);
return new static($serverRequest);
}
public function getParsedBody()
{
return $this->serverRequest->getParsedBody();
}
public function withParsedBody($data): self
{
$serverRequest = $this->serverRequest->withParsedBody($data);
return new static($serverRequest);
}
public function getAttributes(): array
{
return $this->serverRequest->getAttributes();
}
public function getAttribute($name, $default = null)
{
return $this->serverRequest->getAttribute($name, $default);
}
public function withAttribute($name, $value): self
{
$serverRequest = $this->serverRequest->withAttribute($name, $value);
return new static($serverRequest);
}
public function withoutAttribute($name): self
{
$serverRequest = $this->serverRequest->withoutAttribute($name);
return new static($serverRequest);
}
public function getParam(string $param, $default = null)
{
$getParams = $this->getQueryParams();
$postParams = $this->getParsedBody();
if (is_array($postParams) && isset($postParams[$param])) {
return $postParams[$param];
}
if (is_object($postParams) && property_exists($postParams, $param)) {
return $postParams->$param;
}
if (isset($getParams[$param])) {
return $getParams[$param];
}
return $default;
}
public function getParsedBodyParam(string $param, $default = null)
{
$postParams = $this->getParsedBody();
if (is_array($postParams) && isset($postParams[$param])) {
return $postParams[$param];
}
if (is_object($postParams) && property_exists($postParams, $param)) {
return $postParams->$param;
}
return $default;
}
public function isPost(): bool
{
return $this->getMethod() === 'POST';
}
}


### Apacheの再起動
修正が完了次第、Apacheを再起動します。
bash
sudo systemctl restart apache2


### ブラウザでの確認とエラーログの確認
再度ブラウザで `http://localhost/phpmyadmin` にアクセスし、問題が解決されているか確認します。最新のエラーログを確認します。
bash
sudo tail -n 50 /var/log/apache2/error.log


これらの修正と確認を通じて問題が解決することを期待しています。再度エラーメッセージが発生した場合、その内容を提供してください。再度サポートを提供します。
owner@Linux-for-owner:/usr/share/php$ sudo systemctl restart apache2
[sudo] owner のパスワード:
owner@Linux-for-owner:/usr/share/php$ sudo composer dump-autoload
Do not run Composer as root/super user! See https://getcomposer.org/root for details
Continue as root/super user [yes]?
Generating autoload files
Generated autoload files
owner@Linux-for-owner:/usr/share/php$ sudo systemctl restart apache2
[sudo] owner のパスワード:
owner@Linux-for-owner:/usr/share/php$ sudo tail -n 10 /var/log/apache2/error.log[Sat Sep 14 13:53:31.398419 2024] [core:notice] [pid 11154] AH00094: Command line: '/usr/sbin/apache2'
[Sat Sep 14 13:53:33.380823 2024] [php:error] [pid 11156] [client ::1:40862] PHP Fatal error: Declaration of PhpMyAdmin\\Http\\ServerRequest::getServerParams() must be compatible with Psr\\Http\\Message\\ServerRequestInterface::getServerParams(): array in /usr/share/phpmyadmin/libraries/classes/Http/ServerRequest.php on line 180
[Sat Sep 14 15:48:42.177520 2024] [mpm_prefork:notice] [pid 11154] AH00170: caught SIGWINCH, shutting down gracefully
[Sat Sep 14 15:48:42.286131 2024] [mpm_prefork:notice] [pid 12966] AH00163: Apache/2.4.58 (Ubuntu) configured -- resuming normal operations
[Sat Sep 14 15:48:42.286180 2024] [core:notice] [pid 12966] AH00094: Command line: '/usr/sbin/apache2'
[Sat Sep 14 15:48:46.958323 2024] [php:error] [pid 12968] [client ::1:41392] PHP Fatal error: Uncaught Error: Class "Symfony\\Component\\DependencyInjection\\ContainerBuilder" not found in /usr/share/phpmyadmin/libraries/classes/Core.php:977\nStack trace:\n#0 /usr/share/phpmyadmin/libraries/classes/Common.php(93): PhpMyAdmin\\Core::getContainerBuilder()\n#1 /usr/share/phpmyadmin/index.php(45): PhpMyAdmin\\Common::run()\n#2 {main}\n thrown in /usr/share/phpmyadmin/libraries/classes/Core.php on line 977
[Sat Sep 14 15:49:14.918745 2024] [mpm_prefork:notice] [pid 12966] AH00170: caught SIGWINCH, shutting down gracefully
[Sat Sep 14 15:49:15.050483 2024] [mpm_prefork:notice] [pid 13021] AH00163: Apache/2.4.58 (Ubuntu) configured -- resuming normal operations
[Sat Sep 14 15:49:15.050551 2024] [core:notice] [pid 13021] AH00094: Command line: '/usr/sbin/apache2'
[Sat Sep 14 15:49:17.309111 2024] [php:error] [pid 13023] [client ::1:44396] PHP Fatal error: Uncaught Error: Class "Symfony\\Component\\DependencyInjection\\ContainerBuilder" not found in /usr/share/phpmyadmin/libraries/classes/Core.php:977\nStack trace:\n#0 /usr/share/phpmyadmin/libraries/classes/Common.php(93): PhpMyAdmin\\Core::getContainerBuilder()\n#1 /usr/share/phpmyadmin/index.php(45): PhpMyAdmin\\Common::run()\n#2 {main}\n thrown in /usr/share/phpmyadmin/libraries/classes/Core.php on line 977
owner@Linux-for-owner:/usr/share/php$

今度は977行目の問題と出てますが、これは何ですか?

新たなエラーメッセージを確認したところ、`Symfony\Component\DependencyInjection\ContainerBuilder`クラスが見つからないという問題が発生しています。これは、phpMyAdminが依存するSymonyのDependencyInjectionコンポーネントが適切にロードされていないことを示しています。

次に、この問題を解決するための具体的な手順を示します。

### 1. 必要な依存パッケージのインストール
まず、`Symfony\Component\DependencyInjection\ContainerBuilder`クラスが存在するかどうかを確認し、存在しない場合はComposerを使って必要なパッケージをインストールします。

#### 依存パッケージのインストール
bash
cd /usr/share/php
sudo composer require symfony/dependency-injection


### 2. オートロードファイルの再生成
依存パッケージをインストールした後、オートロードファイルを再生成します。
bash
sudo composer dump-autoload


### 3. Apacheの再起動
変更内容を反映するためにApacheを再起動します。
bash
sudo systemctl restart apache2


### 4. クラスの導入を確認
次に、`/usr/share/phpmyadmin/libraries/classes/Core.php`ファイル内で、必要なクラスをインポートしているか確認します。
bash
sudo nano /usr/share/phpmyadmin/libraries/classes/Core.php


#### クラスのインポートの確認
ファイルの冒頭で以下のインポートが必要です。
php
use Symfony\Component\DependencyInjection\ContainerBuilder;


### 5. ブラウザでの確認とエラーログの確認
再度ブラウザで `http://localhost/phpmyadmin` にアクセスし、問題が解決されたか確認します。最新のエラーログを確認します。
bash
sudo tail -n 50 /var/log/apache2/error.log


### まとめと確認手順
以下の手順を通じて、Symfony\Component\DependencyInjection\ContainerBuilderが正しくロードされることを確認します:

1. 依存パッケージのインストール
bash
sudo composer require symfony/dependency-injection



2. オートロードファイルの再生成
bash
sudo composer dump-autoload



3. Apacheの再起動
bash
sudo systemctl restart apache2



4. クラスのインポートの確認
php
use Symfony\Component\DependencyInjection\ContainerBuilder;



これで問題が解決することを期待しています。再度問題が解決しない場合や新たなエラーメッセージが発生した場合、その内容を提供してください。再度サポートを提供します。
修正作業する前にやってることを確認したいのですが、対処療法でsudo composerを一つ一つやってますよね?エラーを先読みして、想定できるものを全てsudo composerできませんか?

確かに、現状ではエラーメッセージに対して個別に対応を行っており、これによって手間が増えていることがあります。次に、一般的にphpMyAdminが依存する主要なPHPパッケージをまとめてインストールし、依存関係の問題を一括で解決するアプローチを取ることができます。

### 依存パッケージの一括インストール
以下に、phpMyAdminが依存する主要なパッケージをまとめて`composer.json`に追加し、インストールを行います。この方法で、今後発生する可能性のある依存関係の問題を事前に解決します。

### `composer.json` の見直し
`/usr/share/php` にある `composer.json` ファイルを更新します。
json
{
"require": {
"psr/http-message": "^2.0",
"slim/psr7": "^1.4",
"fig/http-message-util": "^1.1",
"symfony/expression-language": "^5.4",
"symfony/polyfill-php80": "^1.23",
"twig/twig": "^3.0",
"laminas/laminas-diactoros": "^2.6",
"nyholm/psr7": "^1.4",
"guzzlehttp/psr7": "^2.0",
"symfony/dependency-injection": "^5.4",
"symfony/config": "^5.4",
"symfony/http-foundation": "^5.4"
}
}


### すべての依存パッケージを再インストール
依存パッケージを一括で再インストールします。
bash
cd /usr/share/php
sudo composer install


### 余計なキャッシュをクリア
Composerのキャッシュをクリアし、依存関係の問題を回避するため、再度インストール前にキャッシュをクリアします。
bash
sudo composer clear-cache


### インストール
依存関係を最新に保ち、必要なパッケージも全てインストールします。
bash
cd /usr/share/php
sudo composer install


### Apacheの再起動
インストール完了後、Apacheを再起動します。
bash
sudo systemctl restart apache2


### ブラウザでの再確認とエラーログの確認
再度ブラウザで `http://localhost/phpmyadmin` にアクセスし、問題が解決されたか確認します。また、エラーログを確認して残っている依存関係の問題がないか確認します。
bash
sudo tail -n 50 /var/log/apache2/error.log


### まとめと確認作業
1. **`composer.json`の修正**: 必要なパッケージをすべて含めるように修正。
2. **依存パッケージの再インストール**:
bash
sudo composer clear-cache
sudo composer install


3. **Apacheの再起動**:
bash
sudo systemctl restart apache2


4. **ブラウザとエラーログの確認**:
bash
sudo tail -n 50 /var/log/apache2/error.log



これで、すべての依存関係が正しくインストールされることを期待しています。問題が解決しない場合や新たなエラーメッセージが発生した場合、その内容を提供してください。再度サポートを提供します。
owner@Linux-for-owner:/usr/share/php$ cd /usr/share/php
sudo composer install
[sudo] owner のパスワード:
Do not run Composer as root/super user! See https://getcomposer.org/root for details
Continue as root/super user [yes]?
Installing dependencies from lock file (including require-dev)
Verifying lock file contents can be installed on current platform.
Warning: The lock file is not up to date with the latest changes in composer.json. You may be getting outdated dependencies. It is recommended that you run `composer update` or `composer update <package name>`.
- Required package "laminas/laminas-diactoros" is not present in the lock file.
- Required package "nyholm/psr7" is not present in the lock file.
- Required package "guzzlehttp/psr7" is not present in the lock file.
- Required package "symfony/dependency-injection" is not present in the lock file.
- Required package "symfony/config" is not present in the lock file.
- Required package "symfony/http-foundation" is not present in the lock file.
This usually happens when composer files are incorrectly merged or the composer.json file is manually edited.
Read more about correctly resolving merge conflicts https://getcomposer.org/doc/articles/resolving-merge-conflicts.md
and prefer using the "require" command over editing the composer.json file directly https://getcomposer.org/doc/03-cli.md#require-r
owner@Linux-for-owner:/usr/share/php$

一括インストールでトラブルが起きているようです。

了解しました。`composer.json`ファイルを手動で更新したため、`composer.lock`ファイルが最新の状態ではなく、依存関係の不整合が発生しています。この問題を解決するために、以下の手順で再度依存関係の整合性を確保します。

### 手順1: `composer.lock` を更新する

`composer.lock`を更新するために、`composer update`コマンドを実行します。
bash
cd /usr/share/php
sudo composer update


`composer.lock`ファイルを更新することで、すべての依存関係が最新になり、`composer.json`に追加した新しいパッケージもインストールされます。

### 手順2: 再度オートロードファイル生成

更新された依存関係を反映するために、再度オートロードファイルを生成します。
bash
sudo composer dump-autoload


### 手順3: Apacheの再起動

変更を反映させるためにApacheを再起動します。
bash
sudo systemctl restart apache2


### 手順4: ブラウザでの確認とエラーログの確認

再度ブラウザで `http://localhost/phpmyadmin` にアクセスし、問題が解決されたか確認します。また、最新のエラーログを確認します。
bash
sudo tail -n 50 /var/log/apache2/error.log


### 具体的な手順のまとめ
1. **依存パッケージの更新**:
bash
sudo composer update


2. **オートロードファイルの再生成**:
bash
sudo composer dump-autoload


3. **Apacheの再起動**:
bash
sudo systemctl restart apache2


4. **ブラウザとエラーログの確認**:
bash
sudo tail -n 50 /var/log/apache2/error.log



これにより、`composer.json`ファイルに追加された新しいパッケージが適切にインストールされ、依存関係の問題が解決されることを期待しています。問題が解決しない場合や新たなエラーメッセージが発生した場合、その内容を提供してください。再度サポートを提供します。
owner@Linux-for-owner:/usr/share/php$ cd /usr/share/php
sudo composer update
[sudo] owner のパスワード:
Do not run Composer as root/super user! See https://getcomposer.org/root for details
Continue as root/super user [yes]?
Loading composer repositories with package information
Updating dependencies
Your requirements could not be resolved to an installable set of packages.

Problem 1
- laminas/laminas-diactoros 2.6.0 requires php ^7.3 || ~8.0.0 -> your php version (8.3.6) does not satisfy that requirement.
- laminas/laminas-diactoros[2.7.0, ..., 2.14.0] require php ^7.3 || ~8.0.0 || ~8.1.0 -> your php version (8.3.6) does not satisfy that requirement.
- laminas/laminas-diactoros[2.15.0, ..., 2.17.0] require php ^7.4 || ~8.0.0 || ~8.1.0 -> your php version (8.3.6) does not satisfy that requirement.
- laminas/laminas-diactoros[2.18.0, ..., 2.25.2] require php ~8.0.0 || ~8.1.0 || ~8.2.0 -> your php version (8.3.6) does not satisfy that requirement.
- laminas/laminas-diactoros 2.26.0 requires psr/http-message ^1.1 -> found psr/http-message[1.1] but it conflicts with your root composer.json require (^2.0).
- Root composer.json requires laminas/laminas-diactoros ^2.6 -> satisfiable by laminas/laminas-diactoros[2.6.0, ..., 2.26.0].

Use the option --with-all-dependencies (-W) to allow upgrades, downgrades and removals for packages currently locked to specific versions.
owner@Linux-for-owner:/usr/share/php$

これはなんのトラブルですか?更新失敗ですか?

このエラーメッセージは、`laminas/laminas-diactoros`パッケージがPHPの指定バージョンに依存しているために発生しています。具体的には、`laminas/laminas-diactoros`パッケージがPHP 8.3.6をサポートしていないため、依存関係の解決ができないことを示しています。

この問題を解決するために、以下のステップを実行します。

### 1. `laminas/laminas-diactoros`のバージョン制約を緩和
まず、`composer.json`ファイルの`laminas/laminas-diactoros`のバージョンを削除します。代わりに、PHP 8.3.6に対応している他のパッケージを使用します。

#### `composer.json`の修正
bash
sudo nano /usr/share/php/composer.json


以下の内容に修正します。
json
{
"require": {
"psr/http-message": "^2.0",
"slim/psr7": "^1.4",
"fig/http-message-util": "^1.1",
"symfony/expression-language": "^5.4",
"symfony/polyfill-php80": "^1.23",
"twig/twig": "^3.0",
"nyholm/psr7": "^1.4",
"guzzlehttp/psr7": "^2.0",
"symfony/dependency-injection": "^5.4",
"symfony/config": "^5.4",
"symfony/http-foundation": "^5.4"
}
}


### 2. 依存パッケージのアップデート
次に、依存関係をアップデートします。
bash
cd /usr/share/php
sudo composer update


### 3. オートロードファイルの再生成
アップデート後、オートロードファイルを再生成します。
bash
sudo composer dump-autoload


### 4. Apacheの再起動
変更内容を反映するためにApacheを再起動します。
bash
sudo systemctl restart apache2


### 5. ブラウザでの再確認とエラーログの確認
再度ブラウザで `http://localhost/phpmyadmin` にアクセスし、問題が解決されたか確認します。また、最新のエラーログを確認します。
bash
sudo tail -n 50 /var/log/apache2/error.log


### まとめ
以下の手順に従って、依存パッケージのバージョン制約を緩和し、再度依存関係をアップデートします。

1. **`composer.json`の修正**:
json
{
"require": {
"psr/http-message": "^2.0",
"slim/psr7": "^1.4",
"fig/http-message-util": "^1.1",
"symfony/expression-language": "^5.4",
"symfony/polyfill-php80": "^1.23",
"twig/twig": "^3.0",
"nyholm/psr7": "^1.4",
"guzzlehttp/psr7": "^2.0",
"symfony/dependency-injection": "^5.4",
"symfony/config": "^5.4",
"symfony/http-foundation": "^5.4"
}
}



2. **依存パッケージのアップデート**:
bash
sudo composer update



3. **オートロードファイルの再生成**:
bash
sudo composer dump-autoload



4. **Apacheの再起動**:
bash
sudo systemctl restart apache2



5. **ブラウザとエラーログの確認**:
bash
sudo tail -n 50 /var/log/apache2/error.log



これで問題が解決することを期待しています。再度問題が解決しない場合や新たなエラーメッセージが発生した場合、その内容を提供してください。再度サポートを提供します。
owner@Linux-for-owner:/usr/share/php$ cd /usr/share/php
sudo composer update
[sudo] owner のパスワード:
Do not run Composer as root/super user! See https://getcomposer.org/root for details
Continue as root/super user [yes]?
Loading composer repositories with package information
Updating dependencies
Lock file operations: 6 installs, 2 updates, 0 removals
- Locking guzzlehttp/psr7 (2.7.0)
- Locking nyholm/psr7 (1.8.2)
- Downgrading psr/container (2.0.2 => 1.1.2)
- Locking symfony/config (v5.4.40)
- Locking symfony/dependency-injection (v5.4.43)
- Locking symfony/filesystem (v6.4.9)
- Locking symfony/http-foundation (v5.4.42)
- Downgrading symfony/service-contracts (v3.5.0 => v2.5.3)
Writing lock file
Installing dependencies from lock file (including require-dev)
Package operations: 6 installs, 2 updates, 0 removals
- Downloading guzzlehttp/psr7 (2.7.0)
- Downloading nyholm/psr7 (1.8.2)
- Downloading symfony/filesystem (v6.4.9)
- Downloading symfony/config (v5.4.40)
- Downloading psr/container (1.1.2)
- Downloading symfony/service-contracts (v2.5.3)
- Downloading symfony/dependency-injection (v5.4.43)
- Downloading symfony/http-foundation (v5.4.42)
- Installing guzzlehttp/psr7 (2.7.0): Extracting archive
- Installing nyholm/psr7 (1.8.2): Extracting archive
- Installing symfony/filesystem (v6.4.9): Extracting archive
- Installing symfony/config (v5.4.40): Extracting archive
- Downgrading psr/container (2.0.2 => 1.1.2): Extracting archive
- Downgrading symfony/service-contracts (v3.5.0 => v2.5.3): Extracting archive
- Installing symfony/dependency-injection (v5.4.43): Extracting archive
- Installing symfony/http-foundation (v5.4.42): Extracting archive
6 package suggestions were added by new dependencies, use `composer suggest` to see details.
Generating autoload files
17 packages you are using are looking for funding.
Use the `composer fund` command to find out more!
No security vulnerability advisories found.
owner@Linux-for-owner:/usr/share/php$ sudo composer dump-autoload
[sudo] owner のパスワード:
Do not run Composer as root/super user! See https://getcomposer.org/root for details
Continue as root/super user [yes]?
Generating autoload files
Generated autoload files
owner@Linux-for-owner:/usr/share/php$ sudo systemctl restart apache2
[sudo] owner のパスワード:
owner@Linux-for-owner:/usr/share/php$ sudo tail -n 15 /var/log/apache2/error.log[Sat Sep 14 13:53:31.398358 2024] [mpm_prefork:notice] [pid 11154] AH00163: Apache/2.4.58 (Ubuntu) configured -- resuming normal operations
[Sat Sep 14 13:53:31.398419 2024] [core:notice] [pid 11154] AH00094: Command line: '/usr/sbin/apache2'
[Sat Sep 14 13:53:33.380823 2024] [php:error] [pid 11156] [client ::1:40862] PHP Fatal error: Declaration of PhpMyAdmin\\Http\\ServerRequest::getServerParams() must be compatible with Psr\\Http\\Message\\ServerRequestInterface::getServerParams(): array in /usr/share/phpmyadmin/libraries/classes/Http/ServerRequest.php on line 180
[Sat Sep 14 15:48:42.177520 2024] [mpm_prefork:notice] [pid 11154] AH00170: caught SIGWINCH, shutting down gracefully
[Sat Sep 14 15:48:42.286131 2024] [mpm_prefork:notice] [pid 12966] AH00163: Apache/2.4.58 (Ubuntu) configured -- resuming normal operations
[Sat Sep 14 15:48:42.286180 2024] [core:notice] [pid 12966] AH00094: Command line: '/usr/sbin/apache2'
[Sat Sep 14 15:48:46.958323 2024] [php:error] [pid 12968] [client ::1:41392] PHP Fatal error: Uncaught Error: Class "Symfony\\Component\\DependencyInjection\\ContainerBuilder" not found in /usr/share/phpmyadmin/libraries/classes/Core.php:977\nStack trace:\n#0 /usr/share/phpmyadmin/libraries/classes/Common.php(93): PhpMyAdmin\\Core::getContainerBuilder()\n#1 /usr/share/phpmyadmin/index.php(45): PhpMyAdmin\\Common::run()\n#2 {main}\n thrown in /usr/share/phpmyadmin/libraries/classes/Core.php on line 977
[Sat Sep 14 15:49:14.918745 2024] [mpm_prefork:notice] [pid 12966] AH00170: caught SIGWINCH, shutting down gracefully
[Sat Sep 14 15:49:15.050483 2024] [mpm_prefork:notice] [pid 13021] AH00163: Apache/2.4.58 (Ubuntu) configured -- resuming normal operations
[Sat Sep 14 15:49:15.050551 2024] [core:notice] [pid 13021] AH00094: Command line: '/usr/sbin/apache2'
[Sat Sep 14 15:49:17.309111 2024] [php:error] [pid 13023] [client ::1:44396] PHP Fatal error: Uncaught Error: Class "Symfony\\Component\\DependencyInjection\\ContainerBuilder" not found in /usr/share/phpmyadmin/libraries/classes/Core.php:977\nStack trace:\n#0 /usr/share/phpmyadmin/libraries/classes/Common.php(93): PhpMyAdmin\\Core::getContainerBuilder()\n#1 /usr/share/phpmyadmin/index.php(45): PhpMyAdmin\\Common::run()\n#2 {main}\n thrown in /usr/share/phpmyadmin/libraries/classes/Core.php on line 977
[Sat Sep 14 16:19:34.080952 2024] [mpm_prefork:notice] [pid 13021] AH00170: caught SIGWINCH, shutting down gracefully
[Sat Sep 14 16:19:34.198845 2024] [mpm_prefork:notice] [pid 13564] AH00163: Apache/2.4.58 (Ubuntu) configured -- resuming normal operations
[Sat Sep 14 16:19:34.198926 2024] [core:notice] [pid 13564] AH00094: Command line: '/usr/sbin/apache2'
[Sat Sep 14 16:19:37.419762 2024] [php:error] [pid 13566] [client ::1:43154] PHP Fatal error: Uncaught Error: Class "PhpMyAdmin\\MoTranslator\\Loader" not found in /usr/share/php/PhpMyAdmin/MoTranslator/functions.php:110\nStack trace:\n#0 /usr/share/phpmyadmin/libraries/classes/Sanitize.php(203): __()\n#1 /usr/share/phpmyadmin/libraries/classes/Message.php(621): PhpMyAdmin\\Sanitize::sanitizeMessage()\n#2 /usr/share/phpmyadmin/libraries/classes/Message.php(686): PhpMyAdmin\\Message::decodeBB()\n#3 /usr/share/phpmyadmin/libraries/classes/Error.php(264): PhpMyAdmin\\Message->getMessage()\n#4 /usr/share/phpmyadmin/libraries/classes/ErrorHandler.php(280): PhpMyAdmin\\Error->getHash()\n#5 /usr/share/phpmyadmin/libraries/classes/ErrorHandler.php(237): PhpMyAdmin\\ErrorHandler->addError()\n#6 [internal function]: PhpMyAdmin\\ErrorHandler->handleException()\n#7 {main}\n thrown in /usr/share/php/PhpMyAdmin/MoTranslator/functions.php on line 110
owner@Linux-for-owner:/usr/share/php$

これはなんのエラーですか?

現在のエラーメッセージから、以下の二つの問題が確認できます:

1. `Symfony\Component\DependencyInjection\ContainerBuilder`クラスが見つからない。
2. `PhpMyAdmin\MoTranslator\Loader`クラスが見つからない。

### エラー1: `Symfony\Component\DependencyInjection\ContainerBuilder`クラスが見つからない
このエラーメッセージは、`symfony/dependency-injection`パッケージが正しくインストールされており、オートローダーが正しく設定されていることを確認する必要があります。

### エラー2: `PhpMyAdmin\MoTranslator\Loader`クラスが見つからない
これは、MoTranslatorのクラスが正しくロードされない時に起こるエラーです。

## 解決手順
まず、これらの依存関係を再確認し、必要な修正を行います。

### Step 1: `composer.json`の確認と修正
`composer.json`に必要な依存関係が正しく含まれているか確認します。
json
{
"require": {
"psr/http-message": "^2.0",
"slim/psr7": "^1.4",
"fig/http-message-util": "^1.1",
"symfony/expression-language": "^5.4",
"symfony/polyfill-php80": "^1.23",
"twig/twig": "^3.0",
"nyholm/psr7": "^1.4",
"guzzlehttp/psr7": "^2.0",
"symfony/dependency-injection": "^5.4",
"symfony/config": "^5.4",
"symfony/http-foundation": "^5.4",
"laminas/laminas-diactoros": "^2.6",
"symfony/filesystem": "^6.0"
}
}


### Step 2: 依存パッケージのアップデート
`composer.lock`と依存関係の整合性を確保するために、再度依存パッケージをアップデートします。
bash
cd /usr/share/php
sudo composer update


### Step 3: オートロードファイルの再生成
依存関係が更新されたら、オートロードファイルを再生成します。
bash
sudo composer dump-autoload


### Step 4: クラスのインポート
以下のクラスをインポートしているかを確認し、必要ならば追加します。

#### `/usr/share/phpmyadmin/libraries/classes/Core.php`
php
use Symfony\Component\DependencyInjection\ContainerBuilder;


#### `/usr/share/php/PhpMyAdmin/MoTranslator/functions.php`
php
use PhpMyAdmin\MoTranslator\Loader;


### Step 5: Apacheの再起動
設定が完了次第、Apacheを再起動します。
bash
sudo systemctl restart apache2


### Step 6: ブラウザでの再確認とエラーログの確認
再度ブラウザで`http://localhost/phpmyadmin`にアクセスし、問題が解決されたか確認します。最新のエラーログを確認します。
bash
sudo tail -n 50 /var/log/apache2/error.log


### まとめ
以下の手順で、依存パッケージの再確認とアップデートを行います。

1. **`composer.json`の確認と修正**:
json
{
"require": {
"psr/http-message": "^2.0",
"slim/psr7": "^1.4",
"fig/http-message-util": "^1.1",
...
"symfony/dependency-injection": "^5.4",
...
}
}



2. **依存パッケージのアップデート**:
bash
sudo composer update



3. **オートロードファイルの再生成**:
bash
sudo composer dump-autoload



4. **Apacheの再起動**:
bash
sudo systemctl restart apache2



5. **ブラウザとエラーログの確認**:
bash
sudo tail -n 50 /var/log/apache2/error.log



これで問題が解決することを期待しています。再度問題が解決しない場合や新たなエラーメッセージが発生した場合、その内容を再度提供してください。再度サポートを提供します。
composer.json
{
"require": {
"fig/http-message-util": "^1.1",
"guzzlehttp/psr7": "^2.0",
"laminas/laminas-diactoros": "^2.6",
"nyholm/psr7": "^1.4",
"psr/http-message": "^2.0",
"slim/psr7": "^1.4",
"symfony/config": "^5.4",
"symfony/dependency-injection": "^5.4",
"symfony/expression-language": "^5.4",
"symfony/filesystem": "^6.0",
"symfony/http-foundation": "^5.4",
"symfony/polyfill-php80": "^1.23",
"twig/twig": "^3.0"
}
}

owner@Linux-for-owner:/usr/share/php$ cd /usr/share/php
sudo composer update
[sudo] owner のパスワード:
Do not run Composer as root/super user! See https://getcomposer.org/root for details
Continue as root/super user [yes]?
Loading composer repositories with package information
Updating dependencies
Your requirements could not be resolved to an installable set of packages.

Problem 1
- laminas/laminas-diactoros 2.6.0 requires php ^7.3 || ~8.0.0 -> your php version (8.3.6) does not satisfy that requirement.
- laminas/laminas-diactoros[2.7.0, ..., 2.14.0] require php ^7.3 || ~8.0.0 || ~8.1.0 -> your php version (8.3.6) does not satisfy that requirement.
- laminas/laminas-diactoros[2.15.0, ..., 2.17.0] require php ^7.4 || ~8.0.0 || ~8.1.0 -> your php version (8.3.6) does not satisfy that requirement.
- laminas/laminas-diactoros[2.18.0, ..., 2.25.2] require php ~8.0.0 || ~8.1.0 || ~8.2.0 -> your php version (8.3.6) does not satisfy that requirement.
- laminas/laminas-diactoros 2.26.0 requires psr/http-message ^1.1 -> found psr/http-message[1.1] but it conflicts with your root composer.json require (^2.0).
- Root composer.json requires laminas/laminas-diactoros ^2.6 -> satisfiable by laminas/laminas-diactoros[2.6.0, ..., 2.26.0].

Use the option --with-all-dependencies (-W) to allow upgrades, downgrades and removals for packages currently locked to specific versions.
owner@Linux-for-owner:/usr/share/php$ ^C
owner@Linux-for-owner:/usr/share/php$

さっきもlaminasを入れて弾かれたと思うのですが、代わりはないのですか?あるいは強引にlaminasで動かす方法はないのですか?

了解しました。現在のPHPバージョン(8.3.6)に`laminas/laminas-diactoros`が対応していないため、依存パッケージのインストールができない状況です。その場合、`laminas/laminas-diactoros`を削除し、別の適切なライブラリを使用するか、強制的にバージョン制約を無視してインストールする方法があります。

### 方法 1: `laminas/laminas-diactoros`の代わりに別のライブラリを使用
`laminas/laminas-diactoros`の代替となるライブラリを使用します。一般的には、`nyholm/psr7`や`guzzlehttp/psr7`が利用されます。

#### `composer.json`の修正
json
{
"require": {
"fig/http-message-util": "^1.1",
"guzzlehttp/psr7": "^2.0",
"nyholm/psr7": "^1.4",
"psr/http-message": "^2.0",
"slim/psr7": "^1.4",
"symfony/config": "^5.4",
"symfony/dependency-injection": "^5.4",
"symfony/expression-language": "^5.4",
"symfony/filesystem": "^6.0",
"symfony/http-foundation": "^5.4",
"symfony/polyfill-php80": "^1.23",
"twig/twig": "^3.0"
}
}


#### 依存パッケージのインストール
bash
cd /usr/share/php
sudo composer update


### 方法 2: 強制インストール
もう一つの方法として、Composerのオプションを使って依存関係のバージョン制約を緩和し、インストールを試みる手段があります。

#### オプションを使用して強制インストール
bash
cd /usr/share/php
sudo composer update --with-all-dependencies


### 手順3: 関連する設定と再起動

1. **オートロードファイルの再生成**:
bash
sudo composer dump-autoload


2. **Apacheの再起動**:
bash
sudo systemctl restart apache2


3. **ブラウザでの再確認とエラーログの確認**:
bash
sudo tail -n 50 /var/log/apache2/error.log


### まとめ
以下の手順に従って、`laminas/laminas-diactoros`の代替ライブラリを使用するか、依存関係を強制する方法を取ります。

1. **`composer.json`の修正**(代替ライブラリを使用):
json
{
"require": {
"fig/http-message-util": "^1.1",
"guzzlehttp/psr7": "^2.0",
"nyholm/psr7": "^1.4",
"psr/http-message": "^2.0",
"slim/psr7": "^1.4",
"symfony/config": "^5.4",
"symfony/dependency-injection": "^5.4",
"symfony/expression-language": "^5.4",
"symfony/filesystem": "^6.0",
"symfony/http-foundation": "^5.4",
"symfony/polyfill-php80": "^1.23",
"twig/twig": "^3.0"
}
}



2. **依存パッケージのインストール**(代替ライブラリを使用):
bash
sudo composer update



または、

1. **強制インストール**(オプション使用):
bash
sudo composer update --with-all-dependencies



これで問題が解決することを期待しています。再度問題が解決しない場合や新たなエラーメッセージが発生した場合、その内容を提供してください。再度サポートを提供します。
composer.json
{
"require": {
"fig/http-message-util": "^1.1",
"guzzlehttp/psr7": "^2.0",
// "laminas/laminas-diactoros": "^2.6",
"nyholm/psr7": "^1.4",
"psr/http-message": "^2.0",
"slim/psr7": "^1.4",
"symfony/config": "^5.4",
"symfony/dependency-injection": "^5.4",
"symfony/expression-language": "^5.4",
"symfony/filesystem": "^6.0",
"symfony/http-foundation": "^5.4",
"symfony/polyfill-php80": "^1.23",
"twig/twig": "^3.0"
}
}

owner@Linux-for-owner:/usr/share/php$ cd /usr/share/php
sudo composer update
[sudo] owner のパスワード:
Do not run Composer as root/super user! See https://getcomposer.org/root for details
Continue as root/super user [yes]?

In JsonFile.php line 375:

"./composer.json" does not contain valid JSON
Lexical error on line 5. Comments are not allowed.
...sr7": "^2.0", // "laminas/laminas
---------------------^


update [--with WITH] [--prefer-source] [--prefer-dist] [--prefer-install PREFER-INSTALL] [--dry-run] [--dev] [--no-dev] [--lock] [--no-install] [--no-audit] [--audit-format AUDIT-FORMAT] [--no-autoloader] [--no-suggest] [--no-progress] [-w|--with-dependencies] [-W|--with-all-dependencies] [-v|vv|vvv|--verbose] [-o|--optimize-autoloader] [-a|--classmap-authoritative] [--apcu-autoloader] [--apcu-autoloader-prefix APCU-AUTOLOADER-PREFIX] [--ignore-platform-req IGNORE-PLATFORM-REQ] [--ignore-platform-reqs] [--prefer-stable] [--prefer-lowest] [-m|--minimal-changes] [-i|--interactive] [--root-reqs] [--] [<packages>...]

owner@Linux-for-owner:/usr/share/php$

これはどういうことですか?

コメントの記法で問題が発生しているようです。JSONフォーマットでは、コメントを使うことが許可されていません。コメント行を削除して再度試みます。

### 修正済みの `composer.json`
json
{
"require": {
"fig/http-message-util": "^1.1",
"guzzlehttp/psr7": "^2.0",
"nyholm/psr7": "^1.4",
"psr/http-message": "^2.0",
"slim/psr7": "^1.4",
"symfony/config": "^5.4",
"symfony/dependency-injection": "^5.4",
"symfony/expression-language": "^5.4",
"symfony/filesystem": "^6.0",
"symfony/http-foundation": "^5.4",
"symfony/polyfill-php80": "^1.23",
"twig/twig": "^3.0"
}
}


### 手順

以下の手順で再度依存パッケージのインストールを試みます。

#### 1. `composer.json`の修正内容を反映
bash
sudo nano /usr/share/php/composer.json


上記の修正済みJSON内容を貼り付けます。

#### 2. 依存パッケージのアップデート
bash
cd /usr/share/php
sudo composer update


#### 3. オートロードファイルの再生成
bash
sudo composer dump-autoload


#### 4. Apacheの再起動
bash
sudo systemctl restart apache2


#### 5. ブラウザでの再確認とエラーログの確認
bash
sudo tail -n 50 /var/log/apache2/error.log


これで問題が解決することを期待しています。再度問題が解決しない場合や新たなエラーメッセージが発生した場合、その内容を提供してください。再度サポートを提供します。

いいなと思ったら応援しよう!

Ubuntu初心者である漫画村の弟子
note限定で、みんなのフォトギャラリーに無償で大量の画像を順次UPする予定です!ですが、ペタバイトクラスで供給するとなると、容量が一杯になり、皆さんのサポートが必要となります!これからも画像をどんどん供給していくので、サポートをお願いします!