XServer上で運用・管理しているサイトがいくつかありますが、いずれもWordPressを使用しています。
しかし、今回WordPressを使用しないサイトを作成していて、メールフォームを自作したときに行き詰まってしまったのが、PEARのMailパッケージ周りのエラー。
正常に使えるようになるまで手間がかかったので、今後のためにもメモメモ。
XServerではPEARが使えない?
XServerにはPEARが一通りインストールしてあると思って、PEARのMailパッケージを使ってフォームからメールを送信する処理を作りました。
しかし、実際に動かしてみると…。
require_once(Mail.php): failed to open stream: No such file or directory...
Mailパッケージが見つからないようです。
もしかしたら、PEARのパスが通っていないだけなのかもしれないので、PEARのパス「/usr/share/pear」をphp.iniに追加します。XServerのコントロールパネルにログインし、メニューからphp.ini編集をクリック後、「php.ini直接編集」タブで以下を追加してみます。
[pear]
include_path=".:/usr/share/pear"
設定を保存後、数分で設定が反映されるのですが…パスを追加してみても、エラーは消えませんでした。
必要なパッケージを手動でインストール
となれば、Mailパッケージを手動でインストールして、インストールした場所へパスを通すことにしてみます。
インストール先は、/home/[アカウント]/[ドメイン]/pearで、pearディレクトリのパーミッションは755にしておきます。
[アカウント]にはご自身が契約しているアカウントのIDに、[ドメイン]にはご自身が契約しているドメインに置き換えてください。
Mailパッケージ
まずは、Mailパッケージをダウンロードします。
2024年8月24日時点の最新版は2.0.0。DOWNLOADの下の2.0.0をクリックして、パッケージをダウンロードします。
もしクリックしても何も反応がない場合は、2.0.0を右クリックして「名前を付けてリンク先を保存」した後に表示される「安全でないダウンロードがブロックされました」の上にある「保存」をクリックすれば、ダウンロードされます。
ダウンロードされたファイル「Mail-2.0.0.tgz」を、Windowsの場合は管理者モードのコマンドプロンプト(Windows Powe Shell)からコマンドラインで解凍します。
tar zxvf Mail-2.0.0.tgz
LinuxやMacOSの場合でも、同じコマンドで解凍できます。
解凍したファイルのうち、Mail.phpとMailディレクトリを、/home/[アカウント]/[ドメイン]/pearの下に転送します。
Net_SMTPパッケージ
メール送信で使用するNet_SMTPパッケージをダウンロードします。
2024年8月24日時点の最新版は1.12.1。DOWNLOADの下の1.12.1をクリックして、パッケージをダウンロードします。
クリックしても何も反応がない場合は、Mailパッケージの時と同様、右クリックからのダウンロードで。
ダウンロードされたファイル「Net_SMTP-1.12.1.tgz」を、Windowsの場合は管理者モードのコマンドプロンプト(Windows Powe Shell)からコマンドラインで解凍します。
tar zxvf Net_SMTP-1.12.1.tgz
解凍したファイルのうち、Netディレクトリを、/home/[アカウント]/[ドメイン]/pearの下に転送します。
Net_Socketパッケージ
メール送信で使用するNet_Socketパッケージをダウンロードします。
2024年8月24日時点の最新版は1.2.2。DOWNLOADの下の1.2.2をクリックして、パッケージをダウンロードします。
クリックしても何も反応がない場合は、Mailパッケージの時と同様、右クリックからのダウンロードで。
ダウンロードされたファイル「Net_Socket-1.2.2.tgz」を、Windowsの場合は管理者モードのコマンドプロンプト(Windows Powe Shell)からコマンドラインで解凍します。
tar zxvf Net_Socket-1.2.2.tgz
解凍したファイルのうち、Netディレクトリの中にあるSocket.phpを、/home/[アカウント]/[ドメイン]/pear/Netの下に転送します。
ディレクトリ構成
これで必要なパッケージのインストールが完了です。ディレクトリ構成としては、以下のようになっていればOK。
/home/[アカウント]/[ドメイン]/pear/ ├ Mail.php ├ Mail/ │ ├ mail.php │ ├ mock.php │ ├ null.php │ ├ RFC822.php │ ├ sendmail.php │ ├ smtp.php │ └ smtpmx.php └ Net/ ├ SMTP.php └ Socket.php
XServerのphp.ini修正
必要なパッケージのインストールが完了したら、この場所にPEARのパスを通します。
再度XServerのコントロールパネルにログインし、メニューからphp.ini編集をクリック後、「php.ini直接編集」タブでpearの設定を以下のように変更します。
[pear]
include_path=".:/usr/share/pear:/home/[アカウント]/[ドメイン]/pear"
[アカウント]にはご自身が契約しているアカウントのIDに、[ドメイン]にはご自身が契約しているドメインに置き換えてください。
設定を保存後、数分で設定が反映されますが…これで万事解決ではなく、今度は違うエラーが表示されました。
パッケージ内の修正が必要
Mailパッケージをインストールするまでは「No such file or directory」というエラーだったのですが、パッケージをインストールしてパスを通したところ、以下のようなエラーに変わりました。
Fatal error: Uncaught Error: Non-static method PEAR::isError()...
このエラーは、isError()をStaticで参照しようとしているけど、非Staticだから参照できないよ、というもの。Uncaught Errorというのはキャッチされなかったエラーで、Fatal errorというのは致命的なエラーです。つまり、キャッチされなかった致命的なエラーが発生、ということですかね。
これ、PHP7系まではStaticではない関数やメソッドなどをStaticで参照しても動いていたのですが、PHP8系からはより厳格になり、非Staticな関数やメソッドなどをStaticで参照しようとすると致命的なエラーで処理を停止するようになったのが原因です。
今回は「PEAR::isError()」で指摘されているので、おそらくXServer側で用意されているPEARパッケージが古いために、PHP8系でエラーになってしまうのでしょう。
PEARパッケージはこちらで触ることができないので、isError()をStaticにすることは不可能。なら、少々強引な気もしますが、isError()を参照している箇所全てを、インスタンスの参照に書き換えてしまいましょう。
具体的にどうするか…。
関数やメソッド単位でPEARをインスタンス化してから、参照するようにします。例えば、バージョン1.12.1のSMTP.phpの296行目から始まる関数を例に取ると…。
protected function send($data)
{
$this->debug("Send: $data");
$result = $this->socket->write($data);
if (!$result || PEAR::isError($result)) {
$msg = $result ? $result->getMessage() : "unknown error";
return PEAR::raiseError("Failed to write to socket: $msg");
}
return $result;
}
という処理を、以下のように書き換えます。
protected function send($data)
{
$pear = new PEAR();
$this->debug("Send: $data");
$result = $this->socket->write($data);
if (!$result || $pear->isError($result)) {
$msg = $result ? $result->getMessage() : "unknown error";
return $pear->raiseError("Failed to write to socket: $msg");
}
return $result;
}
早い話が、PEARをStaticで参照(PEAR::)している処理が出てくる関数やメソッドは、先頭でPEAR()をインスタンス化してから、アロー演算子(->)を使う形に書き換えてしまえば良さそう。実際にそれで動くようになりました。
この作業は、「Net/SMTP.php」だけでなく、「Mail/smtp.php」でも必要です。
さいごに
ということで、XServer上でPEARのMailパッケージを使うまでの手順でした。
PHP8系では致命的なエラーになってしまう原因は、XServerが用意しているPEAR.phpにあるっぽいですが、これ、もしかしたらPEAR.phpも自分のドメイン配下にインストールして、そちらから読み込むように書き換えれば、もっと楽だったかもしれない…。
今さら思いついても、後の祭りですね。
ちょっと手間がかかりましたが、フォームから正常にメールが送られるようになったので、結果オーライとしておきましょう。
ちなみに、今回の作業は法人向けのXServerビジネスの環境で行いました。
今日の作業は以上です。お疲れ様でした!
コメント