PHPをビルドしてApacheと連携させる方法

January 14,2020 11:55 PM
Category:[Apache]
Tag:[Apache, php]
Permalink

PHPをビルドしてApacheと連携させる方法を紹介します。

1.はじめに

ブラウザからPHPファイルを読み込ませたいため、Linux(CentOS)のApache2.4にPHP5.xを組み込んでみました(Apacheはインストール済)。

# yum install php

インストール後、httpd.confに下記の2行を追記。

LoadModule php5_module /usr/lib64/httpd/modules/libphp5.so
 :
AddType application/x-httpd-php .php

が、Apacheを再起動したところ、下記のエラーが発生しました。

# cd /usr/local/apache2/bin
# ./apachectl restart
httpd: Syntax error on line 150 of /usr/local/apache2/conf/httpd.conf: Cannot load /usr/lib64/httpd/modules/libphp5.so into server: /usr/lib64/httpd/modules/libphp5.so: undefined symbol: unixd_config

追加したLoadModuleディレクティブでひっかかっているようです。

ネットで調べたところ、yumでインストールしたApache2.4とPHP5ではうまく連携できないようです。

Apache2.2に戻せば連携できるようですが、PHPをソースからビルドすれば連携させられることがわかったので、その方法で実施しました。

2.PHPをビルドしてApacheと連携させる

連携させるための仕組みをもう少し説明すると、PHPを手動でインストールする際、Apacheと連携させるためのモジュールlibphp5.soを、Apache2.4にバンドルされているapxsというものを利用して生成します。

yumでインストールしたPHPに含まれていたlibphp5.soは、Apache2.2対応のものだったのかもしれません。

yumでインストールしたPHPを削除

# yum remove php

yumでlibxml2とlibxml2-develをインストール。

# yum install -y libxml2 libxml2-devel

PHP5.x系の最終バージョンをダウンロード

wget http://jp2.php.net/get/php-5.6.40.tar.gz/from/this/mirror -O php-5.6.40.tar.gz

スタンドアローン環境の場合は、https://www.php.net/releases/からphp-5.6.40.tar.gzをダウンロードして、Linuxマシンに転送します。

tar.gzを展開します。

# tar xzf php-5.6.40.tar.gz

展開したディレクトリに移動。

# cd php-5.6.40

Apacheと連携させるためのlibphp5.soを作るために、./configure実行時にapxsを指定します。

# ./configure --with-apxs2=/usr/local/apache2/bin/apxs

これでhttpd.confに

LoadModule php5_module modules/libphp5.so

がビルド時に自動的に設定されます。

後は通常通りのビルドを実施します。

# make
# make test
# make install

ビルド後はApacheを再起動します。

# cd /usr/local/apache2/bin
# ./apachctl restart

/usr/local/apache2/htdocs配下に

<?php phpinfo(); ?>

の内容をindex.phpで作成し、ブラウザでアクセスしてPHPの情報が表示されればOKです。

3.参考

参考サイトは下記です。ありがとうございました。

Comments [0] | Trackbacks [0]

MovableTypeでプラグインの重複チェックができる「DuplicatePluginCheckerプラグイン」

January 7,2020 11:55 PM
Category:[プラグイン管理]
Tag:[DuplicatePluginChecker, MovableType, Plugin]
Permalink

MovableTypeでプラグインの重複チェックができる「DuplicatePluginCheckerプラグイン」を公開します。

1.機能

MTプラグインの重複配置は動作異常になる可能性があります」でご紹介したとおり、同じプラグイン名のプラグインがpluginsディレクトリに置かれていると、期待しない動作になります(どちらか一方のプラグインが優先されるのではなく、予想外の動作になる)。

本プラグインを利用すれば、pluginsディレクトリに同名のプラグインが配置されている場合、管理画面にアクセスした際、次のようなエラーを表示します。

(クリックで拡大)
エラー

2.プラグインのインストール

下記のリンクをクリックして、DuplicatePluginCheckerのプラグインアーカイブをダウンロードします。

DuplicatePluginChecker_0_01.zip

プラグインアーカイブを展開し、pluginsフォルダにあるDuplicatePluginCheckerフォルダをMovable Typeのアプリケーションディレクトリのpluginsディレクトリにアップロードします。

システム管理画面のプラグイン設定画面で「DuplicatePluginChecker~」が表示されればインストール完了です。

プラグイン設定画面

3.使い方

システム管理画面の「設定」→「プラグイン」を選択したとき、同名のプラグインが配置されていれば冒頭のようなエラーを表示します。

Comments [0] | Trackbacks [0]

MTプラグインの重複配置は動作異常になる可能性があります

December 24,2019 11:59 PM
Category:[プラグイン]
Tag:[MovableType]
Permalink

この記事は Movable Type Advent Calendar 2019 24日目の記事です。

MTプラグインの重複配置は動作異常になる可能性があります、というお話です。

1.はじめに

当方で開発しているMTプラグインを導入頂いたお客様から、「期待通りに動作しない」というご質問を、年に2~3回頂きます。

プラグインのバグもありますが、そうでない場合の原因として最も多いのが「古いバージョンの同じプラグインをpluginsディレクトリに置いている」です。

例えば、Workflowプラグインを購入されたお客様が、プラグインのバージョンアップで、前のバージョンのWorkflowプラグインのディレクトリ名を、"Workflo-backup"のようにリネームして、pluginsディレクトリに置いたままとします。

お客様は、リネームした古いプラグインは動作しないと思われているようですが、リネームしたプラグインは、バージョンアップしたプラグインとは別のプラグインとして登録されてしまいます。

同じ処理が2つ登録されてしまうと、perlとして正常に動作しなくなるようで、これが原因でお問い合わせがくるわけです。

結論から申し上げますと、プラグインのバージョンアップあるいは、プラグインの評価版から製品版に乗り換えられる際、前のプラグインはpluginsディレクトリから必ず削除または移動してください。

2.2つのプラグインが登録されてしまう仕組み

MTのプログラムをトレースして、2つのプラグインが登録されてしまう仕組みを説明します。

ブラウザからMTにアクセスするとinit()が起動します。

lib/MT.pm

sub init {
    my $mt    = shift;
    my %param = @_;
 
    $mt->bootstrap() unless $MT_DIR;
    $mt->{mt_dir}     = $MT_DIR;
    $mt->{config_dir} = $CFG_DIR;
    $mt->{app_dir}    = $APP_DIR;
 
    $mt->init_callbacks();
 
    ## Initialize the language to the default in case any errors occur in
    ## the rest of the initialization process.
    $mt->init_config( \%param ) or return;
    $mt->init_lang_defaults(@_) or return;
    require MT::Plugin;
    $mt->init_addons(@_) or return;
    $mt->init_config_from_db( \%param ) or return;
    $mt->init_debug_mode;
    $mt->init_plugins(@_) or return;★

★でinit_plugins()が起動されます。

sub init_plugins {
    my $mt = shift;
 
    # Load compatibility module for prior version
    # This should always be MT::Compat::v(MAJOR_RELEASE_VERSION - 1).
    if ( MT->config('RequiredCompatibility') < 4.0 ) {
        require MT::Compat::v3;
    }
 
    my $cfg          = $mt->config;
    my $use_plugins  = $cfg->UsePlugins;
    my @PluginPaths  = $cfg->PluginPath;
    my $PluginSwitch = $cfg->PluginSwitch || {};
    my $plugin_sigs  = join ',', sort keys %$PluginSwitch;
    $mt->_init_plugins_core( $PluginSwitch, $use_plugins, \@PluginPaths );★

★で_init_plugins_core()が起動されます。

    sub _init_plugins_core {
        my $mt = shift;
        my ( $PluginSwitch, $use_plugins, $PluginPaths ) = @_;
 
        my $timer;
        if ( $mt->config->PerformanceLogging ) {
            $timer = $mt->get_timer();
        }
 
        foreach my $PluginPath (@$PluginPaths) {
            my $plugin_lastdir = $PluginPath;
            $plugin_lastdir =~ s![\\/]$!!;
            $plugin_lastdir =~ s!^.*[\\/]!!;

if ( opendir my $DH, $PluginPath ) {
my @p = readdir $DH;★

ここが原因の根本(悪い意味ではなく実装上の仕様)ですが、★のreaddirで、指定されたプラグインパス(デフォルトはplugins)配下のディレクトリをすべて読み込みます。

先の例であれば、

$VAR1 = [ '.', '..', 'BlockEditor', 'Comments', 'FacebookCommenters', 'FormattedText', 'FormattedTextForTinyMCE', 'GoogleAnalytics', 'Markdown', 'OpenID', 'spamlookup', 'Textile', 'TinyMCE', 'Trackback', 'WidgetManager', 'Workflow', 'Workflow-backup', 'WXRImporter' ];

のように、'Workflow'と'Workflow-backup'の2つが含まれます。

このあとの処理で、yaml形式のプラグインであれば、

                closedir $DH;
                for my $plugin (@p) {
                    next if ( $plugin =~ /^\.\.?$/ || $plugin =~ /~$/ );
 
                    $plugin_full_path
                        = File::Spec->catfile( $PluginPath, $plugin );
                    if ( -f $plugin_full_path ) {
                        $plugin_envelope = $plugin_lastdir;
                        __load_plugin( $mt, $timer, $PluginSwitch,
                            $use_plugins, $plugin_full_path, $plugin )
                            if $plugin_full_path =~ /\.pl$/;
                        next;
                    }
 
                    my $plugin_dir = $plugin;
                    $plugin_envelope = "$plugin_lastdir/" . $plugin;
 
                    foreach my $lib (qw(lib extlib)) {
                        my $plib
                            = File::Spec->catdir( $plugin_full_path, $lib );
                        unshift @INC, $plib if -d $plib;
                    }
 
                    # handle config.yaml
                    my $yaml = File::Spec->catdir( $plugin_full_path,
                        'config.yaml' );
 
                    if ( -f $yaml ) {
                        __load_plugin_with_yaml( $use_plugins, $PluginSwitch,
                            $plugin_dir );★
                        next;
                    }

★で__load_plugin_with_yaml()が実行され、

    sub __load_plugin_with_yaml {
        my ( $use_plugins, $PluginSwitch, $plugin_dir ) = @_;
        my $pclass
            = $plugin_dir =~ m/\.pack$/
            ? 'MT::Component'
            : 'MT::Plugin';
 
        # Don't process disabled plugin config.yaml files.
        if ($pclass eq 'MT::Plugin'
            && (!$use_plugins
                || ( exists $PluginSwitch->{$plugin_dir}
                    && !$PluginSwitch->{$plugin_dir} )
            )
            )
        {
            $Plugins{$plugin_dir}{full_path} = $plugin_full_path;
            $Plugins{$plugin_dir}{enabled}   = 0;
            return;
        }
        return if exists $Plugins{$plugin_dir};
        my $id = lc $plugin_dir;
        $id =~ s/\.\w+$//;
        my $p = $pclass->new(
            {   id       => $id,
                path     => $plugin_full_path,
                envelope => $plugin_envelope
            }
        );
 
        # rebless? based on config?
        local $plugin_sig = $plugin_dir;
        $PluginSwitch->{$plugin_sig} = 1;
        MT->add_plugin($p);
        $p->init_callbacks();
    }

プラグインとして追加されてしまうようです(これ以降トレースしていないので認識誤りでしたらお許しを)。

なお、システム管理画面のプラグイン一覧には、リネームしたプラグインは新しいプラグインと(コンフィグの設定が)同じなので、2つ表示されることはありません。

ということで、旧プラグインはリネームではなく、別のディレクトリに移動しましょう。

この記事には続きがありますが、時間切れなのでこの辺で。

Comments [0] | Trackbacks [0]
 1  |  2  |  3  |  4  |  5  | All pages