タグ別アーカイブ: Apache

PHPで正規表現による文字列のパターンマッチングを行う

文字列の中の特定のパターンを検索する方法として、正規表現というものがあります。以前、.htaccessでディレクトリ内の特定文字列を含むファイルへのアクセスを禁止する方法について書いたエントリの中で少し触れたのですが、今回は書式のおさらいと、PHPでの対応する関数の紹介を行います。

まず正規表現の書式ですが、以前紹介したエスケープ(\または¥)、行頭(^)、行末($)、または(|)の他にもいくつか記号があるので、一覧表にしてみます。

記号 意味 使用例 マッチするテキスト
.(ピリオド) 任意の一文字(ワイルドカード) te.t text,tent,te!t
*(アスタリスク) 直前の文字の0回以上の繰り返し te.*t text,texxxt,tet
+(プラス) 直前の文字の1回以上の繰り返し te.+t text,texxxt
?(クエスチョンマーク) 直前の文字が0または1回登場 te.?t text,tet
¥(円マーク) 特殊文字のエスケープ(windows) te¥.¥?t te.?t
\(バックスラッシュ) 特殊文字のエスケープ(windows以外) te\.\?t te.?t
^(カレット) 行頭 ^\.ht .htaccess,.htpasswd
$(ドル) 行末 nt$ tent,plant
[](角括弧) 括弧内に現れる文字のどれか te[xyz]t text,tezt
-(ハイフン)を使った応用編 te[a-z]t tebt,tewt(aからzまで可)
-(ハイフン)を使った応用編 te[1-9]t te3t,te8t(1から9まで可)
^(カレット)は角括弧中で否定の意 te[^nx]t test(text,tentはダメ)
()(丸括弧) グルーピング (te)*xt xt,text,tetext
|(パイプライン) または ([a-z]|[1-9])* aaa,a,9999

PHPで正規表現によるマッチングを行うには、PCRE関数というPerlでの正規表現に準拠した関数群を使います。preg_という接頭辞がついたこの関数群に正規表現のパターンを与える時は、パターン文字列の前後をスラッシュで囲むという約束事があります。基本的なpreg_match関数で例を見てみましょう。

<?php
$teststring = "Hello!";
preg_match("/He[a-z]+/",$teststring);
?>

引数1にパターン文字列、引数2に検索対象を与えています。引数3、4、5もあるのですが、省略可です。 パターン文字列にマッチしたものがあると、preg_match関数は返り値として1を返します。ちなみに返り値として検索がマッチした回数を返してくれる、preg_match_allという関数もあります。
その他、検索置換機能を備えたpreg_replaceや、配列を精査してくれるpreg_grepという関数もありますので、それらの活用例もいずれエントリでアップできればと思っています。


サイトC:000webhostで頻発するwordpressアップデートエラーを回避する

このサイトで契約しているサーバ000webhostですが、無料であることに加え、MySQLのデータベースを2つ使える、設定パネルとしてcPanelの簡易版が使える、広告が入らない、商用可などのメリットがあり、他と比べてもかなり条件の良いサーバであると個人的に思っています。特にMySQLデータベースが2つまで使えるということは、データベースをまるまる1つ占有してしまうwordpressなどのCMSを気兼ねなく導入できるということで、CMSの実験用として契約するユーザも多数存在するのではないかと予想できます。

一見するとCMSとの相性が良さそうに見えるこのレンタルサーバでは、しかしCMS自体の機能を使ったアップデートやプラグインの導入などの際に、エラーが発生してしまうということが多々あります。加えて、ユーザのアップロードが成功せず何回もトライを続けていると、負荷の低減のためかあるいは不正使用と誤認してなのか判りませんが、当該IPアドレスでのアクセスをしばらく禁止されてしまいます。それにより総合的なユーザエクスペリエンスが最低となり、実験用に契約した場合でも、「このサーバは使えない」という結論に繋がってしまう可能性があります。
そこで、そもそもこういった負の連鎖の原因となるアップロード失敗の原因を突き止め、問題を回避する方法を考えましょう。
結論から言いますと、アップデート時のエラーが頻発するのはサーバ側でPHPプログラムの動作を制限して軽い処理しかできないようにしているためで、000webhostのように.htaccessが使える場合、あるいは他の安サーバでもphp.iniが使える場合、それらの設定を変更することでエラー回避の道が開ける場合もあるというのは知っておいて損のない知識です。具体的に000webhostの場合で見てみましょう。

まずはphpinfo関数でphpの設定を調べて下さい。エラーに関係する項目のみ挙げますが、000webhostの場合デフォルトでmax_execution_timeが10、memory_limitが64M、post_max_sizeが2M、upload_max_filesizeが2Mとなっています。それぞれPHPスクリプトがタイムアウトになるまでの秒数、確保するメモリ容量、POSTで渡せる最大ファイルサイズ、アップロードできる最大ファイルサイズを表しています。
参考までに、サイトAのために契約しているWebhostingPadではこの値が30、128M、8M、2Mになっています。つまり000webhostではこれらの値を厳し目に設定することで、無料ユーザを総合した負荷を抑えるようにしているというわけのようです。
これらの変更を、ユーザのルートディレクトリに置く.htaccessで行いましょう。具体的には、max_execution_timeを少し長めの180秒程度にする、postやuploadのmaxサイズをmemoryリミットの制限内で上げるなどです。.htaccessまたはphp.iniでどのように書けばよいかは、少し前に上げたエントリ(php.ini.htaccess)を参考にして下さい。あまり詳しく言及すると000webhostの勘気に触れるのではないかという個人的な危惧があります(笑)

少しの欠点がありますが、対処を覚えれば便利なサーバーですね。いちユーザの意見としてポジティブに評価しておきましょう。

(2012.6追記:勝手にページを非公開にされ、コンテンツの返還に有料契約を要求された事件があり、現在このサーバは他人にお薦めしません。少し詳しい経緯などはこちら


サイトC:PHPの各種設定をphp.iniではなく.htaccessで行う

以前php.iniを使ったPHPの各種設定変更方法を書きました。しかしながら、レンタルサーバによってはユーザがphp.iniファイルを作成する事を許可してない場合があります。当方の場合、まさにサイトC(このサイト)を設置している000webhostがそうだったのですが、そういったケースではphp.iniファイルを使わず.htaccessファイルで設定の変更を行います。
.htaccessでPHPの設定を変更する場合、変更する値のタイプによって書き方が2種類存在します。具体的には、論理値を指定する場合に使うphp_flagと、それ以外の値を指定する場合に使うphp_valueです。そこで実際サイトCにおいて私が行った設定を例にしながら、2種類の書式を見てみましょう。

論理値を指定するタイプ

論理値を指定する場合というのは、PHPのオプション機能の有効/無効を指定する場合で、書式は次のようになります。

php_flag 設定項目 On
php_flag 設定項目 Off

繰り返しになりますが、文の最後には改行が必要です。実例として、PHPプログラムでエラーが発生した際の、エラーメッセージをブラウザに出力する設定をアクティブにしてみます。

php_flag display_errors On

このオプションが有効になっていると、実行したプログラムの何行目でどのようなエラーが起こったかを親切に表示してくれます。もちろんサイト訪問者側からもエラー内容が見えてしまうことになるので、必要の無いときにはOffを指定しておきましょう。

他の値(文字列、数値)を指定するタイプ

文字列や数値を指定する場合には、以下の書式を使います。

php_value 設定項目 設定内容

実例としてはphp.iniの解説で挙げたデフォルト文字コードの指定があります。これは.htaccessで設定する場合以下のようになります。

php_value default_charset UTF-8

UTF-8の部分をダブルクォーテーションで囲んでも適用されるようです。
数値の例としては、処理がタイムアウトになるまでの秒数であるmax_execution_timeを挙げます。

php_value max_execution_time 60

その他の設定項目も、この2種類の書式で指定することができます。どのような項目があるかはphpinfo()やPHPパッケージ付属のphp.iniで知ることができます。ただしレンタルサーバによっては特定の項目のユーザー側からの変更をブロックしている場合がありますので、そういう場合についてはあきらめて別の方法を模索しましょう。


サイトB:MAMPの導入と複数サイト運用のための設定

MacOSX上のローカル環境につくる予定のサイトBですが、ローカル環境の構築にはMAMPというアプリケーションを使用します。このMAMPというアプリケーションはOSに影響を与えることなくApache、MySQL、PHPのテスト環境を提供するソフトウェアで、windows用のソフトウェアとして有名なXAMPPと同等のものです。現在ではXAMPPがOSX、Linuxにも対応していますが、MAMPの場合はMacOS用のリリースを以前から行っていたため、OSXの仮想環境ソフトウェアとしてユーザーが多くリファレンスも充実しています。

早速導入をしてみましょう。MAMPのトップページの左側のDownload nowボタンをクリックすると、最新版のダウンロードが始まります。右側で紹介されているMAMP PROは60ドル程度の有料版で、こちらは複数サイトの運営が標準機能として搭載されています。その他にも機能差が存在するのですが、無料版の方もいわゆる機能限定デモのような圧倒的に痒いところに手が届かないという体ではないので安心して使えます。
以前のMAMPは解凍したアプリケーションを手動でアプリケーションフォルダに移す必要がありましたが、現在の最新ヴァージョンではインストーラ形式になっています。便利な反面、販促の為か標準インストールで勝手にMAMP PROまでインストールする仕様になっています。不要ならばカスタムインストールのオプションでMAMP PROのチェックボックスを外しましょう。
インストールが終わったら、アプリケーションフォルダに作成されたMAMPのフォルダを開きMAMPアプリケーションを立ち上げます。

(この部分の画像は000webhostに接収されました)

この画面が出たら正常に起動しています。左下のウインドウにはサーバのステータスが表示されます。また、環境設定のボタンから各種設定をすることができます。

さて、デフォルトの状態でのドキュメントルートは、MAMPフォルダの一階層下のhtdocsフォルダになっています。このままですとサイトを一つしかテストできないので、サイトを複数作成・テストする場合にはhtdocsフォルダの下にフォルダを作成して、そこをドキュメントルートとみなしファイル構成を行います。

(この部分の画像は000webhostに接収されました)

ここではフォルダeをドキュメントルートとしたサイトと、フォルダlをドキュメントルートとしたサイトの2サイトの運用を想定します。フォルダ構成が済んだら、先程の環境設定ボタンで現れるフローティングウィンドウのApacheタブを選択して下さい。そこに記載されたパスがサイトのドキュメントルートになるので、それぞれチェックするサイトのルートフォルダを指定し、その都度MAMPを再起動して下さい。指定したフォルダに、MAMP起動時に現れるページの、アドレス後半部の/MAMP/?language=Japaneseを削ったアドレスでアクセスできるようになります。

(この部分の画像は000webhostに接収されました)

設定を変更後再起動という面倒臭さはあるものの、一応これで複数サイトの運営が可能になります。公開しないローカル環境であることの強みを生かして、実験的なサイトをいくつも作ってしまいましょう。


.htaccessの書式とよく使う設定

Apacheの設定ファイル.htaccessを使用してできることは多岐にわたります。その中でも代表的で、サイト制作には割合必須な機能の紹介を、書式の説明と並行して行いましょう。

トップページにindex.html以外のファイルを指定する

たとえばhttp://www.○○○.com/というアドレスのサイトで、http://www.○○○.com/とだけアドレスバーに打ち込んで表示されるページは、ドキュメントルートに置かれたindex.htmlというファイルです。これは下位のディレクトリでも同様で、http://www.○○○.com/page/というアドレスで表示されるのは、ドキュメントルートに存在するpageディレクトリに置かれたindex.html、といったように、指定されたディレクトリに置かれたindex.htmlを探して表示するというのがhtml文書での約束事です。
一方、ページ中にPHPプログラムを含む場合に、ファイルの拡張子を.phpにしなければならないという約束事も存在します。トップページにPHPプログラムを置きたい場合など、ファイル名をindex.phpとしてしまうとブラウザでアクセスしてもよくわからないリストページが現れるだけで、柔軟に解釈してindex.phpを表示してくれたりはしません。そこでディレクトリ名のみをアドレス指定された場合に探すファイルを、以下のような記述で設定します。

DirectoryIndex index.php index.html

DirectoryIndexの部分が設定項目名、index.php index.htmlの部分が設定したい値です。つまり.htaccessの書式は以下のようになります。

設定項目名 値1 値2

php.iniの場合と異なり、設定項目と値の間を半角スペースで区切り、イコールはつけません。設定したい値が複数ある場合は、値同士をやはり半角スペースで区切ります。そして文の終わりには、たとえ設定項目が1つであったとしても改行が必要です。ちなみにコメントアウトは以前書いた通り#を使います。
DirectoryIndexの説明に戻りますと、値として指定された名称のファイルを、ディレクトリ名でアクセスされた場合表示します。さらに後ろに続けて値を与えると、最初に与えた値のファイル名が無かった場合に、次に探すべきファイル名と解釈します。上の例ならば、まずindex.phpを探して、無かったらindex.htmlを探して表示ということですね。ちなみに.htaccessの設定は下位ディレクトリにも反映されますので、こういった設定をドキュメントルートでしてしまうとわかりやすいです。

DirectoryIndexで指定されたファイルが存在しなかったときリスト表示になるのを避ける

先にindex.html無しでディレクトリのアドレスを入力してみたときの、よくわからないリストの出現を抑える方法です。

Options -Indexes

セキュリティの為にも、ファイル構成が外部から筒抜けになってしまうのは避けたいところです。公開サイトを段階的に大きくしていくケースでも、この設定は最優先でしてしまいましょう。

ディレクトリへのアクセスにパスワードをかける(Basic認証)

外部からアクセスされては困るディレクトリに、ユーザ名とパスワードを要求するタイプのプロテクトをかける事もできます。パスワードは.htpasswdというファイルに保存して、そのファイルへの参照を.htaccessで指定します。.htpasswdファイルはドキュメントルートより上の階層に置いて、まかり間違ってもそちらに外部からアクセスされないようにする必要があります。ユーザ名user、パスワードpassという例で書き方を説明します。

user:pass

こちらが.htpasswdファイルへの記述です。複数ユーザにも対応可能ですのでその場合は同ファイル内に羅列して書いてしまって構いません。そしてこちらも文の終わりの改行が必須です。

AuthName "hidden"
AuthUserFile "/home/usr/.htpasswd"
AuthType Basic
require valid-user

こちらが.htaccessの記述です。AuthNameという項目は、パスワードを求める領域の名称で、ダイアログの本文に現れます。特に意味はないので好きな名称を設定してください。AuthUserFileには.htpasswdファイルへのパスを与えます。なお.htpasswdのファイル名は自由に決められるようですので、パスの指定もそれに即して変えてください。AuthType Basicは認証の種類で、この他にDigestという値もとり得ますが、対応ブラウザが狭い、Apacheのヴァージョンにより書式が異なる部分が出るなどの問題があり、あまり積極的に採用されていないようです。最後のrequireでは複数ユーザが登録されていた場合に、アクセスを許すユーザを名指しで指定するというものです。vaLid-userにしておけば、全登録ユーザを許可します。
このBasic認証は少し面倒くさいでしょうか。ちなみに、cPanelではこのBasic認証の設定をPassword Protected DirectoriesというアイコンからGUIで行えます。ちゃんと.htpasswdをドキュメントルートより上に保存してくれるので便利です。

アクセスのリダイレクトを行う

指定されたパスにアクセスがあったとき、そのアクセスを別のアドレスに振り向けます。

Redirect permanent / http://www.google.com/

この例では、Redirect permanentの部分が設定項目名で、その後ろに値を2つ与えています。1つ目の値はただのスラッシュですが、これはドキュメントルートを指定して与えていると読んで下さい。もしドキュメントルート直下のpageディレクトリを与えたいなら/page/となります。2つ目の値はリダイレクト先のhttp://から始まるアドレスです。つまりこの例では、ホームページにアクセスされたらgoogle.comにジャンプするという結果になります。ホームページ移転などがあったときに、この設定を使って新ページにリダイレクトしましょう。

特定の拡張子のファイルへのアクセスを禁止する

さて、長々と説明してきてやっと前回予告した機能の説明に入ります。最後になってしまったのは、書式がこれまでのものといくらか異なるからです。拡張子.iniのファイルへのアクセスを禁止する例を見てみましょう。

<Files ~ "\.ini$">
deny from all
</Files>

htmlのような、タグで挟んだ書式になっています。しかし異なるのは、タグの終わりと文の終わりに改行を必要とするため、3行で1セットということです。最初のタグの中にあるバックスラッシュは、正規表現でのエスケープを表しています。windows環境では¥マークになりますね。正規表現全般については説明を省きますが、この項目でよく使いそうな指定としては、”または”を表す|(縦の一本棒)、前方一致を表す^、後方一致の$などがあります。それらを使って、拡張子が.iniおよびファイル名の先頭が.htのファイル(.htaccess、.htpasswd)へのアクセスを禁止してみます。

<Files ~ "\.ini$|^\.ht">
deny from all
</Files>

他にも特定プロバイダからのアクセス禁止や、カスタムエラーページの参照などできることは沢山あるのですが、ひとまずここでは解説を省きます。また.htaccessを使ったPHPの設定変更(php.iniを使用しない)については、独立したエントリに書くつもりです。


.htaccessを使ってphp.iniの有効範囲を拡張する

前回の続きです。ユーザ側で用意したphp.iniは、レンタルサーバ側で特別な設定をしていない限りその有効範囲が同ディレクトリ内に制限されます。つまりディレクトリを多数用意するサイト作りではユーザが作成するフォルダ毎にphp.iniを用意せねばならず、ファイル構成が冗長になってしまいます。そこでApacheの設定ファイルである.htaccessを使用して、任意の箇所に配置されたphp.iniファイルの設定が.htaccessファイルを置いたディレクトリと下位のディレクトリに適用されるように変更してみましょう。

.htaccessファイルの名前は拡張子も含めて.htaccessになります。テキストエディタなどで保存するとOSによっては不可視ファイルの扱いになってしまうので、適当な名前で保存してサーバにアップロードした後にFTPクライアントの機能でリネームするという方法が便利です。そして作成した.htaccessという名前のファイルにこのような記述をして、文の最後に改行を忘れずに入れて保存してください。

suPHP_ConfigPath /home/user/public_html/settings/

この例での/home/user/public_html/settings/の部分は、用意したphp.iniを置いているディレクトリのパスという設定です。各々のケースに合ったパスへと置換して下さい。このように設定しておくと、.htaccessを置いたパスと、それより下位のディレクトリで実行されたプログラムに/home/user/public_html/settings/に置いたphp.iniの設定が適用されるようになります。

なお.htaccessファイルもphp.iniファイルもただのテキストファイルですので、ブラウザからアクセスすると現在の設定内容が丸見えになってしまいます。それを避ける為にはApacheの特定の拡張子をもったファイルへのアクセスを禁止する機能を使うのですが、やはりそれも.htaccessファイルで設定することになります。次回はそれを含めた.htaccessの代表的な機能と書式を紹介することにします。


プログラム・設定ファイルのコメント書式一覧

個人的によく使うプログラミング言語・設定ファイルのコメント書式を、まとめてメモしておこうと思います。

コメント書式一覧
言語・設定名 コメントの書式 備考
XHTML(HTML)・HTML5 <!‐‐ ここにコメントを書く ‐‐> 複数行も可能です。コメント中の連続したハイフン(‐‐)の使用は禁止されています。
CSS /* ここにコメントを書く */ 複数行も可能です。
PHP // ここにコメントを書く 一行のコメント。複数行はダメ。C++形式。
#ここにコメントを書く 一行のコメント。複数行はダメ。ShellやPerl形式。
/* ここにコメントを書く */ 複数行も可能です。
JavaScript・ActionScript // ここにコメントを書く 一行のコメント。複数行はダメ。C++形式。
/* ここにコメントを書く */ 複数行も可能です。
Objective-C・Swift // ここにコメントを書く 一行のコメント。複数行はダメ。C++形式。
/* ここにコメントを書く */ 複数行も可能です。
SQL ‐‐ ここにコメントを書く 一行のコメント。複数行はダメ。
/* ここにコメントを書く */ 複数行も可能です。
php.ini(PHPの設定ファイル) ; ここにコメントを書く 一行のコメント。複数行はダメ。
.htaccess(サーバアプリケーションの設定ファイル) # ここにコメントを書く 一行のコメント。複数行はダメ。

これからもうちょっと複雑なWEB制作を始めたら、表の項目が増えていく可能性もあります。そして、間違っている箇所を発見したら指摘していただけると非常に助かります。