XServerのPHP8環境でPEAR::Mailを使えるようにする

※当サイトでは広告を掲載しています

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パッケージをダウンロードします。

Mail

2024年8月24日時点の最新版は2.0.0。DOWNLOADの下の2.0.0をクリックして、パッケージをダウンロードします。

Mailパッケージをダウンロード

もしクリックしても何も反応がない場合は、2.0.0を右クリックして「名前を付けてリンク先を保存」した後に表示される「安全でないダウンロードがブロックされました」の上にある「保存」をクリックすれば、ダウンロードされます。

ダウンロードがブロックされた場合

ダウンロードされたファイル「Mail-2.0.0.tgz」を、Windowsの場合は管理者モードのコマンドプロンプト(Windows Powe Shell)からコマンドラインで解凍します。

tar zxvf Mail-2.0.0.tgz

Mail-2.0.0.tgzを展開

LinuxやMacOSの場合でも、同じコマンドで解凍できます。

解凍したファイルのうち、Mail.phpとMailディレクトリを、/home/[アカウント]/[ドメイン]/pearの下に転送します。

Net_SMTPパッケージ

メール送信で使用するNet_SMTPパッケージをダウンロードします。

Net_SMTP

2024年8月24日時点の最新版は1.12.1。DOWNLOADの下の1.12.1をクリックして、パッケージをダウンロードします。

Net_SMTPパッケージをダウンロード

クリックしても何も反応がない場合は、Mailパッケージの時と同様、右クリックからのダウンロードで。

ダウンロードされたファイル「Net_SMTP-1.12.1.tgz」を、Windowsの場合は管理者モードのコマンドプロンプト(Windows Powe Shell)からコマンドラインで解凍します。

tar zxvf Net_SMTP-1.12.1.tgz

Net_SMTP-1.12.1.tgzを展開

解凍したファイルのうち、Netディレクトリを、/home/[アカウント]/[ドメイン]/pearの下に転送します。

Net_Socketパッケージ

メール送信で使用するNet_Socketパッケージをダウンロードします。

Net_Socket

2024年8月24日時点の最新版は1.2.2。DOWNLOADの下の1.2.2をクリックして、パッケージをダウンロードします。

Net_Socketパッケージをダウンロード

クリックしても何も反応がない場合は、Mailパッケージの時と同様、右クリックからのダウンロードで。

ダウンロードされたファイル「Net_Socket-1.2.2.tgz」を、Windowsの場合は管理者モードのコマンドプロンプト(Windows Powe Shell)からコマンドラインで解凍します。

tar zxvf Net_Socket-1.2.2.tgz

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ビジネスの環境で行いました。

今日の作業は以上です。お疲れ様でした!

初稿:2024年8月24日

コメント

タイトルとURLをコピーしました