モジュール版モードで、セッションエラーが出る理由

レンタルサーバに関する覚え書き

カテゴリー: CGIモード  閲覧数:330 配信日:2010-11-15 12:34


お題


モジュール版モードで、セッションエラーが出る理由
Warning: session_start() [function.session-start]: open(/tmp/sess_○○, O_RDWR) failed: Permission denied in
・モジュール版モードでは、セッションファイルがApacheユーザー権限で書きこまれるが、セッションディレクトリのパーミッションがPHP実行時のユーザーと異なる場合、PHPからセッションファイルの書き込めが行えないため、読み込む際にパーミッションエラーとなる


対策A


・CGIモードにする


対策B


・セッションディレクトリ(セッションファイルの保存ディレクトリ)を作成し、パスを指定

B-1.セッションディレクトリ作成
・PHPのセッションファイルが保存されるディレクトリ(以下セッションディレクトリ)を変更
・具体的には、ユーザーディレクトリ以下にセッションディレクトリを作成することで、正常に動作するようになる
・ユーザーディレクトリ以下の非公開領域にtmpなどのディレクトリを作成し、パーミッションを書き込み可能に変更(705, 755など)
/virtual/ユーザー名/tmp 

B-2.セッションディレクトリ指定
・session.save_pathで、セッションディレクトリを指定
方法a php.iniファイル作成
 session.save_path = /virtual/ユーザー名/tmp
方法b .phpファイルでini設定
 ini_set( 'Sessions.Save_Path' , '/virtual/ユーザー名/ディレクトリー' );
 →うまくいかず 
方法c .htaccess作成
 php_value session.save_path "/virtual/アカウント/public_html/任意ディレクトリ名/tmp"
・モジュール版とCGI版のPHPを合わせて使って、セッションが引き継がれるとエラーが出る
・これはCGI版では、セッションファイルが、/tmp/にて、FTPユーザー権限で書きこまれ、一方モジュール版ではApacheユーザー権限で書きこまれるため
※CGI版PHPで作成されたセッションファイルをモジュール版PHPから読み込む際にパーミッションエラーとなる。逆もまたしかり

自分が試した状況で言うと、
セッションファイルの保存先を、「モジュール版・CGI版」双方ともに、全く同じ場所(ユーザー領域の/tmp/)にしても、
それぞれのモードを変更すると、読み込む際にパーミッションエラーとなるってことかな。
理由は、
・モジュール版 … Apacheユーザー権限で書きこまれる
・CGI版 … FTPユーザー権限で書きこまれる

久しぶりに、.htaccessで、php_value session.save_pathを作成したら、
うまくいかなかった。
tmp/以下にセッションファイルが保存されているのになんで、
と思ったら、保存時間を設定していないから?
php_value session.save_path /virtual/ユーザー名/ディレクトリー
php_value session.name SES1
php_value session.cookie_lifetime 3600
でいけた

今日の結論
.htaccessに記述する際は、「session.name」も必要
理由⇒不明

動作する例
php_value session.save_path /virtual/ユーザー名/lib/tmp
php_value session.name hoge
php_value session.cookie_lifetime 3600

動作する例
php_value session.save_path /virtual/ユーザー名/lib/tmp
php_value session.name hoge

<動作しない例>
php_value session.save_path /virtual/ユーザー名/lib/tmp

動作しない例
php_value session.save_path /virtual/ユーザー名/lib/tmp
php_value session.cookie_lifetime 3600

php.iniも試したが、エラー消えず。
PHPファイル自体にも記述してみたが、エラー消えず。

今回、PHPファイルで「session.name」の挙動を確かめたかったのだが、
モジュール版(セーフモード)で動作させようとすると、
.htaccessにセッション名を直書きする羽目に陥るため、確かめられない。

結局、いつものように、CGIモードでいくこととなった…



▼22:11追記
PHPファイルに、普通に
session_save_path( "/virtual/ユーザー名/lib/tmp" );
って書いたら、セッションデータ保存先が変更された。

ini_set とか、いらんやん!
ここら辺、いつまで経っても使い方が分からんわ。

だけど、ファイルに書いてくと、
違うところで、保存先が、デフォルトの/tmpとぶつかりそうな気がする。

ファイルに書いてる=「そのファイルのときだけ、セッションデータ保存先が変更された」
=「それ以外はデフォルトのまま」
って気もするんだけど…。

後、ネットで、CGIモードとモジュール版とで、
同じセッションでも、保存先が変わってたら、セッション情報が引き継がれない、
てのを見かけた気がするのだが、それとはちょっと違う現象に遭遇。

具体的には、同じ保存先でも、CGIモードで保存したセッション情報は、モジュール版に引き継がれない。
逆もまた然り。

こんな感じ。

<CGIモード>
・session_save_path( "/virtual/ユーザー名/lib/tmp" );で、セッションデータ保存先を変更
・.htaccessで、CGIモードを解除したら、open(/virtual/ユーザー名/lib/tmp/sess_○○, O_RDWR) failed: Permission deniedエラー

<モジュール版>
・session_save_path( "/virtual/ユーザー名/lib/tmp" );で、セッションデータ保存先を変更
・.htaccessで、CGIモードへ変更すると、open(/virtual/ユーザー名/lib/tmp/sess_○○, O_RDWR) failed: Permission deniedエラー


何れの場合も、「Permission denied」ってことで、セッションデータのパーミッションを変更しようとするも、
これが変らないんだな全く、600から。

きっと、セッションファイルが、Apacheユーザー権限で書きこまれるから、とか何か理由があるのかもしれないが、
セッションディレクトリのパーミッションをいくら上げても、ファイル自体のパーミッションは変えらないのね。

ここら辺が共有サーバの限界かな、と思ったり、
…思わなかったり…、
はっきり言って、何がどうなっているのか、よく分かりません…。

あー、そうだ。
セッションファイルの容量が0で、ダウンロードできない理由も、分からないなァー



まあ、いいや、

いずれにしても、この辺り、
共有サーバの限界ということにして、
先へ進もう



2012/4/23
CGIモードを回避したいサイトがあったので、このエントリーを見ながら再度挑戦。
1.セッション保存ディレクトリを、ユーザー領域へ作成
  /virtual/ユーザ名/lib/sessiontmp/

2.パミッション777「sessiontmp」ディレクトリ

3.「.htaccess」作成 … ドキュメントルート直下
php_value session.save_path /virtual/ユーザ名/lib/sessiontmp
php_value session.name セッション名
php_value session.cookie_lifetime 3600
※セッション名が必要な理由は、恐らく、(自分の)他サイトとの競合を避けるため。
  save_pathを変更すれば、セッション名を指定しなくても良いかどうかは、未確認

これで取りあえずうまくいったっぽいのだが、
作成されたファイル名は、「sess_6l844hakk2e2r6h2qafvaf3hr0」。
セッション名は指定した名前に変更されていないし、32文字じゃないし、
おまけに中身を確認しようにもダウロードも表示もできない。それこそ、FileZillaでもFFFTPでも…。
どゆこと?

作成されたセッションファイルが、削除は出来てもFTPダウンロード出来ない理由は、
オーナーがapacheなためらしい。

権限変更できないの?
ちょっと落として、中身を確認してみたいんだよねー。

滅多にログインしない「ファイルマネージャ」へアクセスして、権限変更したつもりが、
エラーが発生しました:
Unable to execute site command chmod 0777 /lib/sessiontmp/sess_6l844hakk2e2r6h2qafvaf3hr0. Note that the CHMOD command is only available on Unix FTP servers, not on Windows FTP servers.
だって…。

「ツール」「ファイル所有者の修正」クリック。
しばらく待ってたら、ようやくダウンロードできた。

気になる中身は、と言うと、普通にセッションの中身だった。
SCRIPTQUIZ|a:1:{s:7:"modules";a:1:{s:3:"mcq";s:15:"modules/mcq.php";}}

つまり、セッション名が変更されない理由は不明。

何れにせよ、セッション名が変更されないのなら、わざわざ書く必要ないやんね。
試しに外してみる。

今度は、「sess_leoavujtn4gc5s5nlad1ls39i4」が作成された。

で、今、
「sess_6l844hakk2e2r6h2qafvaf3hr0」
「sess_leoavujtn4gc5s5nlad1ls39i4」
があるのだが、この意味は、二つのセッションが有効、ということなのだろうか?

「セッションファイル」が作成されるタイミングが、もう一つ良く分からない。

ちょっと待って。
今、何か、目の前で、自分のイメージと全然違うコトが展開されているんだけど。

整理
<自分のイメージ>
・「php_value session.save_path」ファイル名(指定したセッション名+32文字列)のファイルが、指定ディレクリへ保存されると思っていた

<現状>
・指定ディレクリへ保存されているファイル名は、「sess_○○」

PHPファイルに直書<?=session_name()?>
・「.htaccess」に、「php_value session.name」記入 … その名前
・未記入 … デフォ(PHPSESSID)

Chromeで調べてると、
Cookiesの名前が、それぞれ「session_name」に該当している。

頭が混乱してきた。
落ち着け、オレ。

まず、「php_value session.save_path」でファイルが作成されるのは、
「session.save_handler」のデフォルトがfileなため。
つまり、/virtual/ユーザ名/lib/sessiontmp/へ作成されたファイルは、
「セッション情報を格納したセッションファイル」。

次に、「セッション情報を格納したセッションファイル」のデフォルトファイル名は、
「sess_セッションID」。
つまり、「session.nameで指定したセッション名」とは全く関係がない。

ちなみに、「変更したセッション名」がどこへ格納されているか、と言うと、

と言うか、そもそも「セッション名」とは、
セッションを開始した際にクライアントのクッキー名として利用される名前。
つまり、「セッション名」=「(特定の)クッキー名」なんだね。
だから、「セッション名」は、「セッションファイル」のファイル名にもならないし、
ましてや、その中身に記述されるわけでもない。だって、クッキーなんだもん。
マジッすか。
「セッション名」が単なる「クッキー名」だったことに、非常に驚く
※デフォルトでは「PHPSESSID」。デフォルト値はphp.iniで設定

とりあえず、下記で整理。
セッション基本用語一覧

後、セッションクッキーなのに、意味なく保存期間を設けるのもどうよ? と思い、この記述は外す
php_value session.cookie_lifetime 3600