波打際のブログさん

主に、プログラミング備忘録など。

PHP5.4でLibpuzzleを使って画像の類似度判定を行う

はじめに

 Libpuzzleとは特徴検出のアルゴリズムにより、高速な画像類似度判定を行うことができるライブラリです。しかし、このライブラリをPHP5.4で利用しようとした場合、エクステンションがPHP5.4からロードされた瞬間にセグメンテーション違反(segmentation fault)が発生し強制終了させられます。

 調査した結果、原因はPHP用のエクステンションのメモリ確保方法に問題があると判断しました。そこで、PHP5.4に対応したエクステンションの開発を行いました。今回はそのエクステンションの導入と簡単な動作確認用のPHPプログラムを作成します。

 また、この組み合わせで本家のPHPエクステンションがエラーを履かない場合は、本家を利用したほうが良いと思います。

環境

  • CentOS6.4
  • apache2.4.4
  • PHP5.4.16

Libpuzzleの導入

 PHP用のエクステンション導入の前にLibpuzzleを導入します。

GD2のインストール

 LibpuzzleはGD2を利用して類似度判定を行うので、yumを利用してインストールします。

$ sudo yum install gd gd-devel

Libpuzzleのインストール

 GD2のインストールが終わったら次はLibpuzzle本体をインストールします。本体は本家サイト(Libpuzzle - A library to find similar pictures)からダウンロードします。

$ wget http://download.pureftpd.org/pub/pure-ftpd/misc/libpuzzle/releases/libpuzzle-0.11.tar.bz2
$ tar -jxvf libpuzzle-0.11.tar.bz2

Libpuzzle-0.11 $ ./configure
Libpuzzle-0.11 $ make clean
Libpuzzle-0.11 $ make
Libpuzzle-0.11 $ sudo make install

PHP用エクステンションのインストール

 本来ならば、libpuzzle-0.11.tar.bz2に同梱されている php/Libpuzzle を利用しますが、冒頭で述べたようにPHP5.4でsegfaultを吐いてしまったので、PHP5.4用に開発を行ったphp-libpuzzle5(alfa-jpn/php-libpuzzle5 · GitHub)を利用します。

php-libpuzzle5のインストール

 git-hubのreleaseからバージョン1.0.0をダウンロードしてインストールします。

$ wget https://github.com/alfa-jpn/php-libpuzzle5/archive/1.0.0.tar.gz
$ tar -zxvf php-libpuzzle5-1.0.0.tar.gz

php-libpuzzle5-1.0.0 $ phpize
php-libpuzzle5-1.0.0 $ ./configure
php-libpuzzle5-1.0.0 $ make clean
php-libpuzzle5-1.0.0 $ make
php-libpuzzle5-1.0.0 $ sudo make install

php.iniの設定

 PHPの設定ファイル(/usr/local/lib/php.ini)にエクステンションを読み込む設定を追記します。

extension=libpuzzle5.so

以上でインストール作業は完了です。

テストプログラムを書いてみる

 こんな感じでプログラムを記述します。 $dは0〜1の間の値で、0に近いほど画像が似ていると判定されています。

<?php

$cvec1 = puzzle_fill_cvec_from_file(dirname(__FILE__) . '0.jpg');
$cvec2 = puzzle_fill_cvec_from_file(dirname(__FILE__) . '1.jpg');
$d = puzzle_vector_normalized_distance($cvec1, $cvec2);
echo '類似度は' . $d . 'です。';

?>

 puzzle_fill_cvec_from_fileの引数を絶対パスで指定している点に注意して下さい。PHPから呼び出せる関数は本家のlibpuzzleエクステンションと同様ですので、本家のドキュメントを参照してください。

CentOS6.4でFuelPHPを導入するための下準備

はじめに

 最近流行りのFuelPHPをCentOS6.4に導入した際の備忘録です。今回は導入に必要な環境構築を行います。

前提条件

 次の2つの記事に沿ってApache2.4.4をコンパイルしてインストールし、設定を済ませていること。

環境

  • CentOS6.4
  • Apache2.4.4

本項で導入する環境

  • PHP5.4.16
  • MySQL5.6

表記について

 本記事では、圧縮ファイルをダウンロードした際の解凍コマンドは省略しています。ダウンロード後に、圧縮ファイル名のディレクトリに移動している場合は、解凍してカレントディレクトリを移動したものとみなしてください。


それでは、実際に導入していきます。

curlのヘッダファイルをインストール

 PHPコンパイル時に必要なのでyumを使用してヘッダファイルをインストールします。

$ sudo yum install curl-devel

MYSQLのインストール

 今回は最新版を利用する必要があったので、公式サイトからrpmをダウンロードしました。

ダウンロード

 公式サイトから

server client shared develのrpmをダウンロードします。

$ wget http://dev.mysql.com/get/Downloads/MySQL-5.6/MySQL-server-5.6.12-1.el6.i686.rpm/from/http://cdn.mysql.com/
$ wget http://dev.mysql.com/get/Downloads/MySQL-5.6/MySQL-client-5.6.12-1.el6.i686.rpm/from/http://cdn.mysql.com/
$ wget http://dev.mysql.com/get/Downloads/MySQL-5.6/MySQL-shared-5.6.12-1.el6.i686.rpm/from/http://cdn.mysql.com/
$ wget http://dev.mysql.com/get/Downloads/MySQL-5.6/MySQL-devel-5.6.12-1.el6.i686.rpm/from/http://cdn.mysql.com/

古いMYSQLの削除

 デフォルトで入ってるmysqlをアンインストールします。依存関係チェックが動作して削除できないので、--nodepsオプションを使います。yumを使用して強引に削除しようとした場合、他のパッケージも一緒に削除されて大災害が発生するので絶対にやらないでください。

$ sudo rpm -e --nodeps mysql-libs-5.1*

インストール

 先ほどダウンロードしたrpmパッケージをまとめてインストールします。

$ sudo rpm -ivh MySQL-*.rpm

MYSQLの設定

 デフォルトでは文字コードが日本語に対応していないので、/usr/my.cnfを編集してUTF-8に書き換えます。(必要な部分のみ抜粋していますので、現存のmy.cnfに追記・修正をおこなってください。)

[mysqld]
skip-character-set-client-handshake
character-set-server = utf8
collation-server = utf8_general_ci
 
[mysql]
default-character-set = utf8
 
[client]
default-character-set = utf8
 
[mysqldump]
default-character-set = utf8

MCryptのインストール

 PHPMCryptを利用するので導入します。

ダウンロード

 公式サイトからダウンロードしてインストールを行います。

$ wget http://jaist.dl.sourceforge.net/project/mcrypt/Libmcrypt/2.5.8/libmcrypt-2.5.8.tar.gz

コンパイルとインストール

 特に設定せずともすんなり進みました。

libmcrypt-2.5.8 $ ./configure
libmcrypt-2.5.8 $ make
libmcrypt-2.5.8 $ make install

PHPのインストール

 一番の山場です。

ダウンロード

 公式サイトからダウンロードを行います。

$ wget http://jp1.php.net/distributions/php-5.4.16.tar.gz


コンパイルとインストール

 今回は下記オプションでインストールしました。

php-5.4.16 $ ./configure --with-curl --with-curlwrappers --enable-mbstring --with-openssl --with-zlib --with-gd --enable-gd-native-ttf --enable-gd-jis-conv --with-mcrypt --with-apxs2=/usr/local/apache2/bin/apxs --with-jpeg-dir=/usr --with-mysql=/usr
php-5.4.16 $ make
php-5.4.16 $ make install

PHP設定ファイルをコピー

 設定ファイルがソースコードに同梱されているので、所定の場所へコピーします。

php-5.4.16 $ cp php.ini-development /usr/local/lib/php.ini

PECLを使用して必要なライブラリを追加する

 PECLPHP Extension Community Library・ピクル)を利用すると、PHPで利用できる拡張ライブラリを簡単にインストールできます。今回は必要なライブラリをPECLを使用してインストールします。

curl

 phpのソースディレクトリ中にcurlライブラリのpackeageがあるので、そこからインストールします。

php-5.4.16 $ sudo pecl install ext/curl/package.xml

PDO_MYSQL

 PDO_MYSQLのインストールは少々面倒で、mysql-develをrpmでインストールした場合、mysql.h等のヘッダファイルをPECLが見つけてくれません。そこで、コンパイルオプションでヘッダファイルの場所を指定してコンパイル&インストールする必要があります。

 執筆時には下記コマンドで PDO_MYSQL-1.0.2.tar.gz がダウンロードされました。

$ sudo pecl download PDO_MYSQL
  • phpizeコマンドの実行
PDO_MYSQL-1.0.2 $ phpize
  • コンパイルとインストール

 CPPFLAGSにヘッダファイルの場所を指定してコンパイルします。

PDO_MYSQL-1.0.2 $ ./configure CPPFLAGS='-I/usr/include/mysql/'
PDO_MYSQL-1.0.2 $ make
PDO_MYSQL-1.0.2 $ make install

  • php.iniの設定

 PDO_MYSQLのモジュールをロードするために、次の1行をphp.iniに追記します。

extension=pdo_mysql.so

Apacheの設定

 ApacheからPHPを実行する設定を行います。/usr/local/apache2/conf/httpd.confの390行目付近に設定を追記します。

AddType application/x-httpd-php .php

あとがき

 以上でFuelPHPを動作させるために必要な環境が整いました。次回はFuelPHPを実際に導入した手順についてまとめる・・・予定です。

 また、この記事は導入の際の備忘録を元に執筆しております。なので、無意識に他のパッケージなどをインストールしてしまった場合などがあるかもしれません。もし、必要なパッケージなどを発見した場合、コメント欄からご指摘いただければ幸いです。

CentOS6.4でsambaを使用してWindowsとファイル共有を行う。

はじめに

 CentOS6.4上でsambaを使用してファイルサーバを構築する際にいくつか手間取ったポイントがあったので備忘録としてまとめておきます。

環境

  • CentOS6.4
  • samba3.6

sambaのインストール

 パッケージはyumを使用してインストールします。

sudo yum install samba

sambaの設定

ファイアウォールの設定

 sambaでは次のポートを使用します、予めファイアウォールの設定を行い通信を許可する必要があります。

自動起動の設定

 samba本体と、Windowsのファイル共有で使用されるNetBIOS名を解決するためのnmbdを自動で起動するように設定します。

sudo chkconfig smb on
sudo chkconfig nmb on

samba用ユーザの追加

 sambaにログインするためのユーザを作成します。ここで作成するユーザー名は、Linuxのユーザー名と合わせておきます。もし、Linuxのユーザー名と異なるユーザ(Linuxに存在しないユーザ名)を作成する場合は、 /etc/samba/smbusers でユーザー名のマッピング設定を記述する必要があります。

sudo smbpasswd -a [共有させるユーザ名]

共有するディレクトリの作成

 Linux上で共有するディレクトリを生成します。

sudo mkdir /samba/nyaruko -p
sudo chown [共有させるユーザ名]:[共有させるユーザ名] /samba/nyaruko
sudo chcon -t samba_share_t /samba/nyaruko -R

 最後に実行しているchconコマンドに注意してください。SELinuxが有効な環境ではこのコマンドを実行して、ディレクトリへsambaによるアクセスポリシーを付与する必要があります。もし、このコマンドを実行しないと「アクセス許可がありません。ネットワーク管理者にアクセス許可を要求してください。」と言ったエラーメッセージが表示されアクセスできません。

設定ファイルの修正

 先程作成したディレクトリを共有するために、 /etc/samba/smb.conf を修正します。

[global]
	# 共有の設定
	workgroup = Nyaruko 
	server string = "いつもニコニコあなたの隣に這い寄る混沌、ニャルラトホテプ、です!" 
	
	# ログの設定
	log file = /var/log/samba/log.%m
	max log size = 50
	
	# ユーザ認証の設定
	security = user
	passdb backend = tdbsam
 
	# プリンタ関連の設定
	load printers = no 
	cups options = raw
 
 
#============================ Share Definitions ==============================
	
[Nyaruko]
	# 共有するフォルダに関する設定
	path = /samba/nyaruko
	comment = "いつもニコニコあなたの隣に這い寄る混沌、ニャルラトホテプ、です!"
	writable = yes
	valid users = [共有させるユーザ名]

Windowsからのログイン

 サーバーにエクスプローラからアクセスすると、認証ダイアログが表示されます。smb.confで指定したワークグループが、Windowsに設定されているワークグループ名と異なる場合、ワークグループ名を指定してログインする必要があります。

Apache Solr でデータインポートハンドラを使ってMySQLと同期する。

はじめに

 Apache Solrを初めて使用したので備忘録です。Apache Solrを設定し、検索用のデータをMySQLと同期する方法を紹介します。

Apache Solrとは

 Apache Solr(ソーラ)とは、オープンソース検索エンジンです。これで具体的に何をしたいかというと、外部のシステムから、

http://localhost/solr/select?q=ほげほげ

こんな感じでSolrへクエリを投げて、その検索結果外部システムが受け取って使うということを実現したいのです。

環境

準備

必要なファイルのダウンロード

Apache Solr本体

 Apache Solrの本体を公式サイトからダウンロードして解凍します。今回は 3.6.2 を使用します。
Apache Lucene - Apache Solr

$ wget http://ftp.kddilabs.jp/infosystems/apache/lucene/solr/3.6.2/apache-solr-3.6.2.tgz
$ tar -zxvf apache-solr-3.6.2.tgz
MySQLJDBCドライバ

 同様にMySQLJDBCドライバもダウンロードして解凍します。
MySQL :: MySQL Community Downloads

$ wget http://dev.mysql.com/get/Downloads/Connector-J/mysql-connector-java-5.1.25.tar.gz/from/http://cdn.mysql.com/
$ tar -zxvf mysql-connector-java-5.1.25.tar.gz.tgz

データベースの準備

 検索対象のデータを格納するデータベースとテーブルを構築します。

mysql> create database nyaruko;
mysql> create table bbs (id int not null auto_increment, name varchar(32), body varchar(1024), updated timestamp not null default current_timestamp on update current_timestamp, primary key (id));
 
mysql> insert into bbs (name, body) values ('ニャルラトホテプ', 'いつもニコニコあなたの隣に這い寄る混沌、ニャルラトホテプ、です!');
mysql> insert into bbs (name, body) values ('クトゥグア', 'お爺ちゃんが言ってた。ニャルラトホテプを愛するクトゥグアがいてもいい。自由とはそういうものだって。');
 
mysql> create user 'solr@localhost' identified BY 'password';
mysql> revoke all privileges on *.* from solr;
mysql> grant all on nyaruko.* to solr;

 テーブルbbsのidはautoincrementによる自動割り当て、updateも生成時に自動で値がセットされるようにします。また、solrからデータベースを操作するためのユーザを作成し、権限を設定します。

exampleをコピー

 0からSolrを設定するには、とてつもなく時間がかかりそうなので、今回は先ほど解凍した apache-solr-3.6.2 の中の examples をコピーしてそれをベースに編集していきます。(本番開発でもexampleをベースに編集していくスタイルでいいのでしょうか?疑問です。)

$ cp example/ ~/solrtest

 ホームディレクトリ直下に solrtest にリネームして配置しています。今後の説明はこの ~/solrtest を前提に行います。

ライブラリのコピー

 先ほどダウンロードした mysql-connector-java-5.1.25 と、apache-solr-3.6.2 に同梱されている、データインポートハンドラに必要なライブラリをコピーします。

$ cp -r dist/ ~/solrtest
$ cp -r contrib/ ~/solrtest
 
$ cp mysql-connector-java-5.1.25-bin.jar ~/solrtest/lib

Solrの設定ファイル構成

 Apache Solrの設定ファイルは、主に次の3つです。

solr.xml (solr/solr.xml)

 Solrのコア関連の設定を記述します。

schema.xml (solr/conf/schema.xml)

 Solrで取り扱うデータの定義を記述します。

solrconfig.xml (solr/conf/solrconfig.xml)

 Solrで読み込むライブラリや、Solrの構成を記述します。

設定

solr.xmlの設定

 solr/solr.xmlの設定を変更します。行末にあるコア名をアプリケーションに合わせた任意の名前に変更します。(変更しなくとも動きます。)

<cores adminPath="/admin/cores" defaultCoreName="UchuCQC">
  <core name="UchuCQC" instanceDir="." />
</cores>

schema.xmlの設定

 検索に使用するデータを solr/conf/schema.xmlで定義します。既存のものは記述量が多くて読みにくいので、新しく作りなおしています。

<?xml version="1.0" encoding="UTF-8" ?>
<schema name="ニャルラトホテプ" version="1.4">
 
<types>
  <fieldType name="long" class="solr.LongField" omitNorms="true" />
  <fieldType name="string" class="solr.StrField" sortMissingLast="true" omitNorms="true" />
  <fieldType name="timestamp" class="solr.TrieDateField" />
  <fieldType name="text_cjk" class="solr.TextField">
    <analyzer class="org.apache.lucene.analysis.cjk.CJKAnalyzer" />
  </fieldType>
  <fieldType name="text_ja" class="solr.TextField">
      <analyzer> 
        <tokenizer class="solr.JapaneseTokenizerFactory" mode="search"/>
        <filter class="solr.JapaneseBaseFormFilterFactory"/>
        <filter class="solr.JapanesePartOfSpeechStopFilterFactory" tags="lang/stoptags_ja.txt" enablePositionIncrements="true"/>
        <filter class="solr.CJKWidthFilterFactory"/>
        <filter class="solr.StopFilterFactory" ignoreCase="true" words="lang/stopwords_ja.txt" enablePositionIncrements="true" />
        <filter class="solr.JapaneseKatakanaStemFilterFactory" minimumLength="4"/>
        <filter class="solr.LowerCaseFilterFactory"/>
      </analyzer>  
  </fieldType>
</types>
 
<fields>
  <field name="id" type="long" indexed="true" stored="true" required="true" />
  <field name="name" type="text_ja" indexed="true" stored="true" termVectors="true" termPositions="true" />
  <field name="body" type="text_cjk" indexed="true" stored="true" termVectors="true" termPositions="true" />
  <field name="updated" type="timestamp" indexed="true" stored="true" termVectors="true" termPositions="true" />
</fields>
 
<uniqueKey>id</uniqueKey>
<defaultSearchField>body</defaultSearchField>
<solrQueryParser defaultOperator="AND" />
 
</schema>
  • types

 types エレメントに囲まれたブロックはフィールド内で使用するデータ型を定義しています。text_cjk型は形態素解析をする文字列型、text_ja型はN-gram解析をする文字列型となります。


  • fields

 fields エレメントに囲まれたブロックはフィールド定義になります。定義したいフィールド名と、そのフィールドの型として types で定義した型を設定します。

solrconfig.xmlの設定

インポートするライブラリの設定

 solr/conf/solrconfig.xml の80行目付近に、JDBCドライバーを読み込む設定を追記します。また、データインポートハンドラのライブラリの位置を、コピーしたディレクトリに合わせて修正しています。

<lib dir="../lib/" regex="mysql-connector-java-\d.*\.jar" />
  
 
<lib dir="../dist/" regex="apache-solr-dataimporthandler-\d.*\.jar" />
<lib dir="../contrib/dataimporthandler/lib/" regex=".*\.jar" />
検索設定の修正

 フィールドの種類を指定せずにクエリを投げた場合の、デフォルトの検索フィールドを設定します。730行目付近のtextをbodyに修正します。

<lst name="defaults">
  <str name="echoParams">explicit</str>
  <int name="rows">10</int>
  <str name="df">body</str>
</lst>
データインポートハンドラの定義

 ファイルの末尾(と言っても configure エレメント内)にデータインポートハンドラの定義を追記します。データインポートハンドラ名と、設定ファイルの場所を指定します。

<requestHandler name="/dataimport-nyarukobbs" class="org.apache.solr.handler.dataimport.DataImportHandler">
  <lst name="defaults">
    <str name="config">nyarukobbs-data-import.xml</str>
  </lst>
</requestHandler>

データインポートハンドラ(nyarukobbs-data-import.xml)の設定

 データインポートハンドラの設定ファイル solr/conf/nyarukobbs-data-import.xml を作成します。

<dataConfig>
  <dataSource name="ratings" driver="com.mysql.jdbc.Driver" url="jdbc:mysql://localhost:3306/nyaruko" user="solr" password="password" />
 
  <document>
    <entity name="bbs"
     query="select * from bbs"
     deltaQuery="select id from bbs where updated >= '${dataimporter.last_index_time}'"
     deltaImportQuery="select * from bbs where id=${dataimporter.delta.id}">
      <field column="id" name="id" />
      <field column="title" name="title" />
      <field column="body" name="body" />
      <field column="updated" name="updated" />
    </entity>
  </document>
  
</dataConfig>
dataSourceエレメント

 dataSourceエレメントでは、属性値としてJDBCドライバやMySQLに接続するための設定を記述しています。

entityエレメント

 entity エレメントでは、インポートに使用するSQL文とパーサーを定義しています。entityの属性値として、query、 deltaQuery、 deltaImportQuery と、3つのSQL文を定義しています。

  • query

 全てのデータをインポートする時に実行するSQL文を記述します。

select * from bbs

  • deltaQuery

 差分インポート時に、インポート対象のデータを選択するSQL文を記述します。dataimporter.last_index_timeには、solrがデータベースに最終アクセスした時間が格納されているので、${dataimporter.last_index_time}で最終アクセス日時をSQL文に埋め込むことができます。

select id from bbs where updated >= '${dataimporter.last_index_time}'
  • deltaImportQuery

 差分インポート時に、deltaQueryにより選出されたデータに基づき、インポートするデータを選択するSQL文を記述します。deltaQueryの実行結果が、dataimporter.deltaに格納されています。

select * from bbs where id=${dataimporter.delta.id}"
  • パーサー

 entityエレメント内のブロックではパーサーの定義を行なっています。インポート時に実行されるSQLクエリの結果と、schema.xmlで定義したフィールドがどのように一致するのかを指定します。fieldエレメントの属性として、columnはSQL側の列名、nameはschema.xmlで定義したフィールド名を指定します。

確認

起動

アプリケーションのディレクトリ(今回は、solrtest)に移動して、下記コマンドを実行します。

$ java -jar start.java

起動確認

http://localhost:[ポート番号]/solr/admin/dataimport.jsp

 にアクセスし、定義したデータインポートハンドラ(dataimport-nyarukobbs)が表示されていれば構文にエラーはない状態です。500が表示された場合は設定に誤りがあるので、修正が必要です。(ポート番号は起動時に表示されるポート番号です。 )

データのインポート

 dataimport-nyarukobbs をクリックし、管理パネルを開きます。管理パネルのFull-Importではデーターベースをすべてインポートし、Delta-Importは差分をインポートします。まずは、Full-Import を試してみてください。(クリックしてすぐには反映されないので、数分待つ必要があります。作業状況はStatusから確認ができます。)

正常にインポートされれば

http://localhost:[ポート番号]/solr/admin/

からデータを検索できます。

差分データのインポート

 Delta-Importが正常に動作することを確認するためには、MySQLのnyarukoデーターベースで、

mysql> insert into bbs (name, body) values ('ハスター', 'えっと、僕にも真尋君ニウムが作れないかなって。');

といったSQL文を実行してデータを追加し、Delta-Importを実行します。

追記

2014年7月4日

 id:sisidovskiさんにschema.xmlの誤りを教えていただき修正しました。ありがとうございます。

参考サイト

Solr Tutorial

CentOS6.4にインストールしたApacheを設定する。

はじめに

前回(CentOS6.4にApacheをコンパイルしてインストールする - 波打ち際のブログさん)、インストールしたApacheの設定を行い、バーチャルホスト機能で複数のホストごとのサイトを用意します。


Q.なぜいきなりバーチャルホストなの!?
A.とりあえず起動した時点で普通に動いているので、細かい設定は本家ドキュメントを(キリッ
 (すみません、あまりメモしてなかったので。。。。機会があればその他の細かい設定紹介します。)

環境

  • CentOS6.4
  • Apache2.4.4

Apacheをサービスとして登録する

serviceコマンドを使って、起動と終了ができるようにするために、起動スクリプトを設定します。

起動スクリプトのコピー

前回makeを実行したディレクトリの中に起動スクリプトが含まれているので、それをinit.dにコピーします。

$ cp /usr/local/src/httpd-2.4.4/build/rpm/httpd.init /etc/rc.d/init.d/httpd

ソースコードのディレクトリ下の build/rpm/httpd.init を httpd にリネームしてコピーしています。

起動スクリプトの設定

コピーした起動スクリプトはそのままでは動作しないので編集します。
configureで特に設定せずにインストールした場合、apacheのデフォルトインストールパスは /usr/local/apache2 になっています。今回はデフォルトのインストールパスを想定して記述していきます。

apache本体のパスを修正
httpd=${HTTPD-/usr/local/apache2/bin/httpd}

60行目でapache本体のパスを修正します。

制御用スクリプトのパスを追加
apachectl=/usr/local/apache2/bin/apachectl

本体パスのすぐ下に追加しました。

pidファイルのパスを修正
pidfile=${PIDFILE-/usr/local/apache2/logs/${prog}.pid}

62行目のpidfileのパスを修正します。

設定ファイルのパスを修正
CONFFILE=/usr/local/apache2/conf/httpd.conf 

68行目の設定ファイルのパスを修正します。

起動終了

以上でserviceコマンドでapacheを制御可能です。

// 起動
$ service httpd start

// 再起動
$ service httpd restart

// 終了
$ service httpd stop

バーチャルホストの設定をする

httpd.confの修正

デフォルトではバーチャルホスト設定が読み込まれないようになっているので、読み込まれるように修正します。

# Virtual hosts
Include conf/extra/httpd-vhosts.conf  # この行がコメントアウトされています。

バーチャルホスト設定の記述

extra/httpd-vhosts.conf にバーチャルホストの設定を記述します。

<VirtualHost *:80>
    DocumentRoot "/htdocs/main"
    ServerName vm-main

    # 誰でもアクセスができるように設定
    <Directory "/htdocs/main">
        Require all granted
    </Directory>
</VirtualHost>
 
<VirtualHost *:80>
    DocumentRoot "/htdocs/virtual"
    ServerName vm-virtual
 
    # ローカルホスト以外はアクセスできないように設定
    <Directory "/htdocs/virtual">
        Require ip 127.0.0.1
        Require all denied 
    </Directory>
</VirtualHost>

apache2.4以前ではDirectoryごとのアクセス制限に Order allow,deny を使用した記述を使用していましたが、それ以降は Require を使用する記述に変更されました。(筆者はこれに引っかかって1時間くらい時間を無駄に・・・orz)

Requireの記述方法ちょいまとめ

基本

# 全て許可
Require all granted

# 全て拒否
Require all denied

# 指定したIPを許可
Require ip 127.0.0.1

# 指定したIPを拒否(※要注意、下記参照)
Require not ip 127.0.0.1

指定したIPを拒否する場合には注意が必要です。Requireは "どれかにマッチすれば許可する" という挙動なので、

<Directory "/hogehoge">
    Require not ip 127.0.0.1
    Require all granted
</Directory>

と記述しても、正常に動作しません。(おそらくconfファイルのチェックが通りません。)

もし指定したIPだけ拒否したい場合には RequireAllエレメントで囲みます。

<Directory "/hogehoge">
    <RequireAll>
        Require not ip 127.0.0.1
        Require all granted
    </RequireAll>
</Directory>

RequireAllエレメントで囲まれたブロック全ての条件が満たされた場合のみ許可されます。

CentOS6.4にApacheをコンパイルしてインストールする

はじめに

CentOS6.4にApacheソースコードをコンパイルしてインストールする方法を備忘録として残しておきます。

使用するソフトウェアのバージョン

  • CentOS6.4
  • Apache2.4.4

コンパイル環境構築

コンパイラ(gcc)のインストール

yumを使用して一括でインストールを行いました。

$ sudo yum install gcc*

openssl-develのインストール

開発用コードを等含むopenssl-develのインストールをyumから行います。
apachesslをモジュールを使用しない場合は不要です。

$ sudo yum install openssl-devel

必須ファイルの準備

ソースコード本体と、破損・改変チェック用のMD5チェックサムをダウンロードします。

ダウンロード

apache本体

Welcome! - The Apache HTTP Server Project

$ wget http://mirrors.go-part.com/apache//httpd/httpd-2.4.4.tar.gz
$ wget http://www.apache.org/dist/httpd/httpd-2.4.4.tar.gz.md5
apr及びapr-util

Welcome! - The Apache Portable Runtime Project

$ wget http://ftp.kddilabs.jp/infosystems/apache//apr/apr-1.4.8.tar.gz
$ wget http://ftp.kddilabs.jp/infosystems/apache//apr/apr-util-1.5.2.tar.gz
$ wget http://www.apache.org/dist/apr/apr-1.4.8.tar.gz.md5
$ wget http://www.apache.org/dist/apr/apr-util-1.5.2.tar.gz.md5
pcre

PCRE - Perl Compatible Regular Expressions

$ wget ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre-8.33.tar.gz

破損チェック

pcre以外のアーカイブにはMD5チェックサムが用意されているので、ダウンロード後に破損チェクを行います。

$ md5sum -c *.md5

コマンド実行後、 完了 と表示されたファイルは正常にダウンロードできています。

コンパイル

依存関係があるため、pcre → apr → apr-util → apache の順番でコンパイル&インストールを行います。

解凍

ダウンロードしてきたフォルダをtarコマンドで全て解凍します。

tar -zxvf httpd-2.4.4.tar.gz
tar -zxvf apr-1.4.8.tar.gz
tar -zxvf apr-util-1.5.2.tar.gz
tar -zxvf pcre-8.33.tar.gz

pcre

pcreはconfigureで設定せずに、そのままコンパイルとインストールをします。

$ cd pcre-8.33
$ ./configure
$ make
$ make install

apr

aprもそのまま、コンパイルとインストール。

$ cd apr-1.4.8
$ ./configure
$ make
$ make install

apr-util

apr-utilは、先程インストールしたaprのパスを指定し、コンパイルとインストールを行います。

$ cd apr-1.4.8
$ ./configure –with-apr=/usr/local/apr
$ make
$ make install

apache

apacheはapr、apr-utilのパスを指定し、モジュールの設定をおこなってインストールを行いました。

$ cd apr-1.4.8
$ ./configure -enable-mods-shared="all ssl proxy" -with-apr=/usr/local/apr -with-apr-util=/usr/local/apr
$ make
$ make install

enable-mods-shared="all ssl proxy" というオプションを指定して、明示する必要がない全てのモジュールを有効にしています。また、明示が必要なモジュールとしてsslとproxyを指定しました。

このあたりは、利用する環境に合わせた設定になると思います。

Playframework2.0でカッコ良くAjax通信を実装する方法

はじめに

javascript(jQuery)からPlayframeworkへのAjax通信は、通常のAjax通信の方法で実装することができます。

通常の実装方法で特に問題はありませんが、もしサーバー側の仕様を変えることになってAjaxのリクエスト先が変わってしまった場合、javascriptを変更する手間が発生します。

その手間を惜しむ人向けの javascriptRouter という機能がplayframeworkには存在していました。
今回はjavascriptRouterを使用し、カッコ良くAjax通信をしてみます。

コーディング

Application.java

Ajax通信用のgetTest、postTest、javascriptRouter生成用のgetJSRoutesアクションを定義します。

package controllers;
import play.Routes;
import play.mvc.Controller;
import play.data.DynamicForm;
import views.html.index;
public class Application extends Controller {
  
	public static Result index() {
		return ok(index.render());
	}
    
	public static Result getTest(String message) {
		return ok("get:" + message);
	}
  
	public static Result postTest() {
		DynamicForm form =  new DynamicForm().bindFromRequest();
		return ok("post" + form.get("message"));
	}
    
	public static Result getJSRoutes() {
		return ok(
			Routes.javascriptRouter("jsRoutes", 
				controllers.routes.javascript.Application.getTest(),
				controllers.routes.javascript.Application.postTest()
			)
		);
                
	}
}

getTestとpostTestはそれぞれ、get/postでアクセスし、リクエスト中のmessageを取得し、頭にメソッド名をつけてオウム返しにしています。

getJSRoutesアクションでは、javascriptRouter を jsRoutes という名前で生成し、レスポンスとして返しています。
第一引数はルータ名、第二引数以降はルーティングしたいアクションを
controllers.routes.javascript.コントローラー.アクション()
という形で追加できます。

conf/routes

作成したアクションのルートを定義します。

# Routes
GET	/				controllers.Application.index()
GET	/getTest/:message		controllers.Application.getTest(message:String)
POST	/postTest			controllers.Application.postTest()
GET	/assets/javascripts/routes	controllers.Application.getJSRoutes()

# Map static resources from the /public folder to the /assets URL path
GET	/assets/*file			controllers.Assets.at(path="/public", file)

getJSRoutesのルート定義を /assets/javascripts/routes に設定していますが、 /assets/javascripts を指定せずに /routes でも問題なく動作します。

index.scala.html

生成された javascriptRouter(jsRoutes) を埋め込み、ajax通信を行います。

<!DOCTYPE html>
<html>
	<head>
		<title>Ajaxテスト</title>
		<script type="text/javascript" src="@routes.Application.getJSRoutes()"></script>
		<script src="@routes.Assets.at("javascripts/jquery-1.9.0.min.js")" type="text/javascript"></script>
	</head>
	<body>
		<script>
			jsRoutes.controllers.Application.getTest('テスト').ajax({
				'success' : function(data){
					alert(data);
				}
			});
			
			jsRoutes.controllers.Application.postTest().ajax({
				'data'	: { 'message' : 'テスト' },
				'success' : function(data){
					alert(data);
				}
			});
		</script>
	</body>
</html>	

scriptタグのsrcに @routes.Application.getJSRoutes() を指定して javascriptRouter(jsRoutes) を埋め込みます。

bodyのscriptタグ内で、jsRoutes を使ってカッコ良くajax通信を実装しました。

参考サイト

JavaGuide5