セッションの有効期間とか設定とか挙動とかを調べました
PHPでログインページを作ったりするときに、よくセッションを使ったりすると思いますが、
じゃあセッションってどのようになってるのでしょうか。
[参考]セッション固定攻撃
[参考]GPC(GET/POST/cookie)以外の情報を送るアラワザ
[参考]アンダーバーのあるドメインではセッションクッキーは使用できません
セッションの破棄されるタイミング
ガベージコレクト(ガベージコレクション、ガーベッジコレクション、ガーベッジコレクタともいわれます)とは、『ごみ拾い』という意味です。
session_start()が行われたときに、session.gc_probabilityを分子、session.gc_divisorを分母とする確率で、
session.gc_maxlifetimeよりファイル更新日付の古いファイルをsession.save_pathから削除します。
デフォルトでは、1/100の確率で、24分より古いセッションファイルが消えます。
1/100の確率の実際の挙動はコチラ
しかしセッションファイルが消された場合でも$_SESSIONの値は取得できます。
Linuxサーバーでは、それ以外にもcronによる処理があるので、
/tmpは10日、/var/tmpは30日で消えます。
[参考]/tmpや/var/tmpのファイル消えるタイミング
セッションの有効期限を長くする、短くする
セッションの長さを変更するには、session.gc_maxlifetimeを変えればよいと思うかもしれませんが、
時間を長くする場合には、これ以外にも設定が必要です。
同じサーバーでsession.gc_maxlifetimeが短いサイトがあった場合、ドメインが違ったとしても、そのタイミングでセッションは削除されます。
他のサイトやページに影響を受けないようにするには、セッションファイルの保存先session.save_pathを変える必要があります。
セッションはドメインの区別をしていません。
session.save_path = /tmp/example.com
とかです。
ただ/tmp以下は、10日で、またはサーバーの再起動時に削除されてしまうのでそれだと困る場合には
session.save_path = /var/tmp/example.com
とかにします。/var/tmp以下は30日で削除されます。
ただしsave_pathの設定はSAFE MODEが有効になっているときには変更できません。
セッションの有効期限を厳密に決める
セッションが破棄されるまでの時間は、session.gc_maxlifetimeとなりますが、厳密にはそうでありません。
デフォルトでは1/100の確率で、この時間です。
ではこの時間を厳密にするには、ガベージコレクトを毎回行わせる(確率を1にする)ように以下の設定するという方法があります。
session.gc_probability = 1 session.gc_divisor = 1
しかしこの設定はちょっとおかしなところがあります。
そもそもこの確率を設定する理由というのが、『毎アクセスごとにセッションの古いファイルがあるかどうか確認するのは負荷がかかるので』ということです。
そうであれば正しい手法は、セッションのデータにアクセスした時間を記録しておいて、この時間と比較するという方法でしょう。
もちろんこの場合でもsession.gc_maxlifetimeは設定する必要があります。
またセッションの動作を検証した結果は以下のようになっています。
(1)セッションを開始する。
(2)セッションの情報を読む。
(3)ガベージコレクトをする。
(4)セッションファイルを作成したり、ファイル日付を更新したりする。
(5)セッションの情報に変化があれば、その都度データを書き込む。
(6)セッションを閉じる。
(3)と(4)の順番は検証ができないので、確かではありません。
この順番になっているため、セッションが破棄される場合でもデータは読まれています。
session.gc_maxlifetimeだけでは正確に時間を決めることはできないのです。
実験結果
セッションの設定
php.iniで設定するなら、設定値を変えるだけです。
httpd.confや.htaccessに書くなら次のようにします。
php_value session.gc_maxlifetime 1800 php_value session.gc_probability 1 php_value session.gc_divisor 100
またPHPファイルに書くなら
session_save_path("/tmp"); ini_set('session.gc_maxlifetime', 1800); ini_set('session.gc_probability', 1); ini_set('session.gc_divisor', 100);
のように書くのですが、この場合は注意が必要で、必ずsession_start()より前に書く必要があります。
session_start()の際にはキャッシュなどのヘッダー情報が送信されるため、これより前にはブラウザへの出力処理はしてはいけません。
セッションファイルの状態
セッションファイルのファイル名は、sess_【セッションID】のようになっています。
例:sess_4cbdfb3df1bb2f40fb0faa4b17d20966
またファイルの内容は、【セッション名】|s:【セッションの中のID】:【値】のようになります。
数値型なら
$_SESSION["test"]=12345;は
test|i:1:12345;
文字列型なら
$_SESSION["test"]="hoge";は
test|s:1:"hoge";
値が複数なら
$_SESSION["test"]="hoge";
$_SESSION["test2"]="example";は
test|s:1:"hoge";test2|s:2:"example";
書き込む順番によっては
test2|s:1:"example";test|s:3:"hoge";
とか
test2|s:1:"example";test|s:3:"hoge";test|s:1:"example";
ここからも分かるとおり、セッションファイルにはセッションIDとセッションデータ以外のものは保持されていません。つまりはドメインの区別はしていません。
セキュアなセッションの使い方
ログイン処理
クッキーでセッションIDが送られてきてるかもしれないので、 ログインなどでセッションに値を入れ始める前にセッションIDを変更する。
session_regenerate_id(true);
引数にtrueを入れると、既に入っている値も削除されます。
ログアウト処理
session_destroy();としても、それ以降でセッション変数が残っているのでこの値をリセットする。
session_unset();
または
$_SESSION = array();
このセッションIDがクッキーに残るのでクッキーを消す。
setcookie(session_name(), '', time() - 3600, "/");
その他
SSLのページから非SSLのページへは、同じサーバーであれば同じセッションIDで値を引き継ぐことはできますが、絶対にやってはいけません。
どうしてもやらざる得ないときには、都度セッションIDを変更したほうが安全です。
ユーザーページと管理ページが同じドメインのとき
session_name('admin');
上記のようにして、どちらかのセッション名を変更すると別々のセッションIDが発行されるため片方でログアウトしても、もう片方はログアウトされません。
ガベージコレクトの1/100の確率って
1/100の確率というのは実際には、分母にあたるアクセスのカウンターがあって分子の数字より小さかったら実行するって動作ではないです。
0〜1の乱数を生成して、この値が設定されているGCの確率値(1/100)より小さかったらGCを実行するという挙動です。
いろいろな実験
SAFE MODEが無効な状態で、/tmp内も全て削除しておきます。 実行したコードは以下です。
<? //セッションの保存先を明確にします session_save_path("/tmp"); //実験のためセッションが消される時間を10秒と短くします ini_set('session.gc_maxlifetime', 10); //ガベージコレクトを毎回行うようにします ini_set('session.gc_probability', 1); ini_set('session.gc_divisor', 1); //session_start();の前には、出力ができないので後で出力できるようにします $test=""; //session_start();の前のセッション保存ディレクトリを見ます $dir1 = scandir(session_save_path()); //session_start();の前にセッションが読めるか見ます if(isset($_SESSION["test"])) $test.= "session_start()の前<br />"; //ここからセッションを始めます session_start(); //セッションが読めるか、またセッションの内容を見ます if(isset($_SESSION["test"])) $test.= "session_start()の後".$_SESSION["test"]."<br />"; //セッションIDを見ます $test.= session_encode()."<br />"; //セッション保存ディレクトリを見ます $dir2 = scandir(session_save_path()); //セッションに何か値を入れます $_SESSION["test"]=time(); //セッションが読めるか、またセッションの内容を見ます if(isset($_SESSION["test"])) $test.= "値の設定後".$_SESSION["test"]."<br />"; //セッションIDを見ます $test.= session_encode()."<br />"; //セッション保存ディレクトリを見ます $dir3 = scandir(session_save_path()); //結果を出力します echo "<pre>"; print_r($dir1); print_r($dir2); print_r($dir3); echo "</pre>"; echo $test; echo session_id(); ?> <a href="session.php?<?=SID?>">リロード</a>
これを実行すると、次のようになりました。
Array ( [0] => . [1] => .. ) Array ( [0] => . [1] => .. [2] => sess_4cbdfb3df1bb2f40fb0faa4b17d20966 ) Array ( [0] => . [1] => .. [2] => sess_4cbdfb3df1bb2f40fb0faa4b17d20966 ) 値の設定後1232485014 test|i:1232485014; 4cbdfb3df1bb2f40fb0faa4b17d20966
セッションファイルが作成されるタイミングは、session_start()のときのようです。
値の設定後にすぐにファイルに書き込まれるようです。
すぐにテキストリンクをクリックすると
Array ( [0] => . [1] => .. [2] => sess_4cbdfb3df1bb2f40fb0faa4b17d20966 ) Array ( [0] => . [1] => .. [2] => sess_4cbdfb3df1bb2f40fb0faa4b17d20966 ) Array ( [0] => . [1] => .. [2] => sess_4cbdfb3df1bb2f40fb0faa4b17d20966 ) session_start()の後1232485014 test|i:1232485014; 値の設定後1232485022 test|i:1232485022; 4cbdfb3df1bb2f40fb0faa4b17d20966
session_start()の前には値は取れません。
値の設定後にすぐにファイルは変更されるようです。
しばらくしてテキストリンクをクリックすると
Array ( [0] => . [1] => .. [2] => sess_4cbdfb3df1bb2f40fb0faa4b17d20966 ) Array ( [0] => . [1] => .. ) Array ( [0] => . [1] => .. ) session_start()の後1232485022 test|i:1232485022; 値の設定後1232485182 test|i:1232485182; 4cbdfb3df1bb2f40fb0faa4b17d20966
session_start()のときにガベージコレクトがされているようです。
ファイルが無くても、値は取れているので、ガベージコレクトの前に値の取得がされているようです。
ファイルが無くてもsession_encode()の値が変わっているので、これは実際のファイル内容ではないようです。
となると、セッションファイルへの変更情報はsession_encode()に保持され、最後にセッションファイルに書き込まれる、というのが正しいようです。
今度は、session_destroy();を入れてセッションを破棄するように、少しファイル内容を変えてみます。
<? session_save_path("/tmp"); ini_set('session.gc_maxlifetime', 1000); ini_set('session.gc_probability', 1); ini_set('session.gc_divisor', 1); $test=""; $dir1 = scandir(session_save_path()); session_start(); if(isset($_SESSION["test"])) $test.= "session_start()の後".$_SESSION["test"]."<br />"; $test.= session_encode()."<br />"; $dir2 = scandir(session_save_path()); session_destroy(); $dir3 = scandir(session_save_path()); if(isset($_SESSION["test"])) $test.= "session_destroy();の後".$_SESSION["test"]."<br />"; $test.= session_encode()."<br />"; echo "<pre>"; print_r($dir1); print_r($dir2); print_r($dir3); echo "</pre>"; echo $test; echo session_id(); ?> <a href="session.php?<?=SID?>">リロード</a>
これを読み込むと次のようになりました。
Warning: session_encode() [function.session-encode]: Cannot encode non-existent session. Array ( [0] => . [1] => .. [2] => sess_d7d6bd4d39d96a8bbbe9b8f2f3530534 ) Array ( [0] => . [1] => .. [2] => sess_d7d6bd4d39d96a8bbbe9b8f2f3530534 ) Array ( [0] => . [1] => .. ) session_start()の後1232494639 test|i:1232494639; session_destroy();の後1232494639
セッションがないと、session_encode()はエラーが出ます。
session_destroy();の後で、セッションファイルは消えています。
session_destroy();としたとしても、セッションのデータは取得できています。
さらにテキストリンクをクリックすると次のようになります。
Warning: session_encode() [function.session-encode]: Cannot encode non-existent session. Array ( [0] => . [1] => .. ) Array ( [0] => . [1] => .. [2] => sess_d7d6bd4d39d96a8bbbe9b8f2f3530534 ) Array ( [0] => . [1] => .. )
セッションIDは変わらないようです。
ヘッダー情報を確認すると、ブラウザからPHPSESSID=d7d6bd4d39d96a8bbbe9b8f2f3530534のクッキーを送ってます。
また少しファイルを変えてみます。
<? session_save_path("/tmp"); ini_set('session.gc_maxlifetime', 1000); ini_set('session.gc_probability', 1); ini_set('session.gc_divisor', 1); $test=""; $dir1 = scandir(session_save_path()); session_start(); $dir2 = scandir(session_save_path()); session_destroy(); setcookie(session_name(), '', time() - 3600); echo "<pre>"; print_r($dir1); print_r($dir2); echo "</pre>"; ?> <a href="session.php?<?=SID?>">リロード</a>
これを2回読み込むと次のようになりました。
Array ( [0] => . [1] => .. ) Array ( [0] => . [1] => .. [2] => sess_d7d6bd4d39d96a8bbbe9b8f2f3530534 )
まだセッションIDは変わらないようです。
ヘッダー情報を確認すると、ブラウザからPHPSESSID=d7d6bd4d39d96a8bbbe9b8f2f3530534のクッキーを送ってます。
サーバーからはSet-Cookie: PHPSESSID=deleted; expires=Tue, 22-Jan-2008 01:25:16 GMTと、
セッションを消すような情報はちゃんと送ってます。
また少しファイルを変えてみます。
<? session_save_path("/tmp"); ini_set('session.gc_maxlifetime', 1000); ini_set('session.gc_probability', 1); ini_set('session.gc_divisor', 1); $dir1 = scandir(session_save_path()); session_start(); $dir2 = scandir(session_save_path()); session_destroy(); setcookie(session_name(), '', time() - 3600, "/"); echo "<pre>"; print_r($dir1); print_r($dir2); echo "</pre>"; ?> <a href="session.php?<?=SID?>">リロード</a>
これを2回読み込むと次のようになりました。
Array ( [0] => . [1] => .. ) Array ( [0] => . [1] => .. [2] => sess_50d75d5dc45913ab63d9bd5120959fce )
無事、セッションが変わりました。
セッションクッキーを削除するときには、パスまで指定しないと消えないということです。
クッキーについての実験
ちなみに/tmpに手動で『 sess_ 』というファイルを置くと、ガベージコレクトのタイミングで削除されます。
『 sess 』というファイルは削除されません。
http://www.example.php?PHPSESSID=test
と適当なセッションIDをGETクエリで付けてアクセスすると、セッションファイルが無くても『 sess_test 』というセッションファイルが作成され、
このセッションIDは有効になります。
http://www.example.php?PHPSESSID=test
と適当なセッションIDをGETクエリで付けて、さらにクッキーでPHPSESSIDを『 test2 』としてアクセスすると、
クッキーのほうが優先されて『 sess_test2 』というセッションファイルが作成されます。
http://www.example.php?PHPSESSID=あいうえお
としてみると、
Warning: session_start() [function.session-start]: The session id contains illegal characters, valid characters are a-z, A-Z, 0-9 and '-,'
セッションIDに使用できるのは、『 aからz、AからZ、0から9、および「-(ハイフン)」』で構成されたものじゃないと駄目です、と怒られます。
http://www.example.php?PHPSESSID=----
としてみると、
『 sess_---- 』というセッションファイルが作成されます。
クッキーがない状態で、
http://www.example.com/test.php
とセッションを発行するページにアクセスすると、クッキーを書く命令がサーバーからは返されます。
また<?=SID>の部分には『 PHPSESSID=【セッションID】 』と出力されます。
クッキーがない状態で、
http://www.example.com/test.php?PHPSESSID=test
と適当なセッションIDをGETクエリで付けてアクセスすると、クッキーを書き換える命令はサーバーからは返されません。
また<?=SID>の部分には『 PHPSESSID=test 』と出力されます。
これはセッション固定攻撃(session fixation)の対象となります。
あるサイトに対して、http://example.com?PHPSESSID=testのようなリンクを張ってしまい、セッションハイジャックを行う攻撃です。
session_regenerate_id();が書かれたページに、
クッキーがない状態で、
http://www.example.com/test.php?PHPSESSID=test
と適当なセッションIDをGETクエリで付けてアクセスすると、新しいセッションIDにクッキーを書き換える命令がサーバーからは返されます。
セッションIDがクッキーにある状態でアクセスすると、クッキーを書く命令はサーバーからは返されません。
また<?=SID>の部分には何も出力されません。
つまり
http://www.example.com/test.php?<?=SID>&a=test
とすると
http://www.example.com/test.php?&a=test
となってしまうため、<?=SID>はGETクエリの最後に書かないといけません。
session_regenerate_id();が書かれたページに、
クッキーがない状態で、
http://www.example.com/test.php?PHPSESSID=test
と適当なセッションIDをGETクエリで付けてアクセスすると、新しいセッションIDにクッキーを書き換える命令がサーバーからは返されます。
ini_set("session.cookie_path","/test/");と書かれたページに、
クッキーがない状態でアクセスすると、『 /test/ 』ではなくて『 /test 』のパスでクッキーを書く命令がサーバーからは返されます。
session_name("hoge&<test>あ");
とすると、
<?=SID>の部分には『 hoge&<test>あ=【セッションID】 』とHTMLエスケープはされず出力されます。
変数名『 hoge&<test>あ 』とクッキーを書く命令がサーバーからは返されます。
session_nameには命名規則はないみたいですね。
print_r($_COOKIE);
として確認すると次のアクセスでInternet ExplorerもFire Foxも、変数名『 hoge&<test>あ 』というクッキーを送っています。
cookie、POST、GETにセッションIDを付けないでセッションを使用する
セッションID以外にユーザーの一意なIDがとれるなら、GETなどにセッションIDを付与する必要はありません。
例えば一意なIDを$uidとするとき、session_start()の前にsession_id($uid)とすることで、内部的にセッションが使用できます。
ただしセッションIDには『 aからz、AからZ、0から9、および「-(ハイフン)」』しか使えません。
一意なIDが推測可能なものであれば偽装されないように気をつけましょう。
携帯電話のモバイルサイトで個体識別情報が取得できるとき
アクセスの多いサイトでセッションを使う場合
ユニークユーザーの多いサイトでは、それだけセッションファイルが多くなる。このときガベージコレクトにかかる時間はディスクI/Oに依存し、
たまたまガベージコレクトに出くわしたユーザーは、ページが表示されるまでの時間が長くなる。
このようなときには、ガベージコレクトを使わず(session.gc_probability = 0にする)、cronでセッションファイルを削除すると良い。
以下は10分おきに1時間より古いセッションファイルを削除するクーロンの例
*/10 * * * * daemon nice -n 18 find /tmp -type f -name "sess_*" -mmin +60 -exec rm
セッションのデフォルトの設定
session.save_handler = files
セッションをファイルに保存する。
session.save_path = /tmp
保存するファイルの場所は『/tmp』とする。
session.use_cookies = 1
クッキーが使えるなら使う。
session.name = PHPSESSID
セッションの変数名は『PHPSESSID』とする。
session.auto_start = 0
セッションを自動的に開始しない。
session.cookie_lifetime = 0
クッキーを使用する場合、有効期間はブラウザを閉じるまでとする。
session.cookie_path = /
クッキーを使用する場合、有効なURIは『/』(全ての階層)とする。
session.cookie_domain =
クッキーを使用する場合、ドメインは限定しない。(別々のドメインで持ち回りができるということではない)
session.cookie_secure =
クッキーを使用する場合、SSL接続のみとしない。
session.gc_probability = 1
ガベージコレクトの確率の分子は『1』とする。
session.gc_divisor = 100
ガベージコレクトの確率の分母は『100』とする。
つまりは1/100=1%の確率でガベージコレクトを行う。
session.gc_maxlifetime = 1440
ガベージコレクトにより破棄されるファイルの古さ(セッションが有効な時間)は1440秒=24分とする。
関連記事
- 1ファイルにclassを記述して実行する方法
- PHP Startup: Unable to load dynamic libraryのエラーの解決方法
- CakePHP1系(CakePHP1.3)をPHP7・PHP8以降に対応させる方法
- Composerコマンドでウクライナへのメッセージが表示されたことがあります
- Composerをインストールする方法と使い方
- PHPのPEARは2019年に改ざんされたことがあります
- PostgreSQLでSCRAM authentication requires libpq version 10 or aboveと出るとき
- Apacheで所有権や書き込み権限があるにも関わらずPermissions deniedが出る場合
- PCやスマホがネットワーク内にあるかどうかを調べる(在宅かどうかの判断)
- プログラムでもっとも正確に日本の祝日を求める方法(内閣府公表CSVの過去3度の改訂履歴)
- EC-CUBE2系で商品を大量にカートに入れると注文情報が抜けたりカートが消えたりする
- Smarty2をPHP7に対応させる方法(The /e modifier is no longer supported Smarty_Compiler.class.php, line 270)
- CakePHPのバージョンごとのシステム要件
- yumのius(iuscommunity.org)でエラーが出る場合
- iusリポジトリで公開されているパッケージの一覧
- phpMyAdminでログイン画面を出さずにデータベースに接続する方法
- さくらサーバ(さくらのレンタルサーバ)でcronを使ってPHPを定時実行する
- php.ini が見つからない時
- PHPでMySQLなどにPDO接続をすると、could not find driverのエラーが出る場合
- PHP Strict Standards: Non-static method と出る場合の対処法
- mb_send_mail、mb_encode_mimeheaderの文字化けのまとめ(半角カタカナなど)
- Twitter APIでのエラーの一覧
- CakePHPでカラムを比較してSELECTする方法
- ImageMagick更新で『PHP Startup: Unable to load dynamic library '/usr/lib/php/modules/imagick.so'』エラーが出る場合
- コマンドやphpMyAdminで複数のデータベースに接続できるユーザーを作成する方法
- phpMyAdminで『information_schema』などを非表示にする方法
- ディレクトリが存在するにもかかわらず、『No such file or directory』エラーが出る
- PDO_MYSQLをインストールする方法
- PEAR・PECLをインストールする方法
- file_get_contentsで$http_response_headerを使用するときの注意点
- サイトの更新情報をPINGサーバに送信する方法
- インクルードパスを設定する方法
- HEADリクエストを排除してサーバ負荷を軽減させる
- cron実行時の標準出力のメールを飛ばさない方法(cron実行時に毎回メールを飛ばさない)
- cron実行時のPATHなどの環境変数を確認する方法
- cronのメール送信先を指定する方法(cronごとに送信先のメールアドレスを指定する方法)
- cron実行時に『/bin/sh: 〜〜: command not found』と出てcronが実行されない場合
- 『crontab -r』でcronの設定を間違って消してしまった場合の対処法
- 日本語名のフォルダを作成する場合の注意点
- rename()を実行すると『Operation not permitted』とエラーが表示される
- cronを実行すると『TERM environment variable not set.』というエラーメールが飛ぶ
- 「ID」や「ID_xxxx」という文字列があるCSVファイルをExcelで開くとSYLKエラーが出る
- Excelの日付が数字になるときの対処法
- PHPでfacebook投稿時に公開範囲を指定する方法
- PHPで複数の画像をfacebookに投稿する方法
- PHPでfacebookのフィード(ウォール)に投稿する方法
- PHPでのfacebookアプリの認証処理(APIを使うユーザー認証)
- facebook APIを使用する時にfacebook Appsでアプリを登録するまでの流れ
- SELECTタグで色を選択する場合のサンプル
- POSTでアップロードできるファイルサイズの制限を変更する方法
- Zend Optimizerのインストール
- Zend Serverとは
- Live Commerceとは
- SSL(HTTPS)でファイルのダウンロードができない場合
- ファイルダウンロード時のファイル名が文字化けする対処法
- simplexml_load_file()、simplexml_load_string()でparser error : Input is not proper UTF-8, indicate encoding !
- Deprecatedエラーを消す方法 (php.iniや.htaccess)
- Cactiのインストール RRDToolを利用したサーバ監視ツール
- JISコードでstrlenの文字数が合わない(目視の文字数とstrlenの文字数が異なる)
- echoしても文字は表示されないのに、emptyがtrueにならない
- [暗号化]ブロック暗号とは(AES/DES/Blowfish PKCS5Padding ECB/CBC IV)
- == と === の違い(比較演算子)
- Firefox、Chromeなどで文字化けを防ぐ方法 ヘッダー情報に文字コードを指定
- CakePHP、Symfony、Zend Frameworkの比較
- ブラウザの中止ボタンを押した後も処理を実行させる方法 タイムアウト以外の停止
- HTMLファイルのエンコードを『内容から判別する』にしない方法
- SQL Buddy ブラウザベースのMySQL管理ツール
- Twitter APIを使用する (Twitterアプリケーション登録)
- Mantisのインストール
- Mantisのユーザー管理テーブル(mantis_user_table)
- create_functionでメソッドを使用する方法
- strtotimeでmonthを使用するときの注意点
- コマンドラインからpearを実行するとエラーが出る 環境変数PHP_PEAR_PHP_BINの設定
- PEARを更新する方法
- zend_mm_heap corrupted とは
- switch文とif文の違い
- fgetcsv関数を文字化け対応 setlocaleの文字コード指定
- Deprecatedの修正例(POSIX)
- Fatal error: Call to undefined function imagecreatefromjpeg() の対処法
- PHPをyumでインストールする
- php_network_getaddresses: getaddrinfo failed: Temporary failure in name resolutionの対応
- fsockopenでSSLサーバに接続する
- PHPでPDFファイルを作成する FPDF FPDI TCPDF
- 『このインターネットのサイトを開くことができません。』と出て、ファイルをダウンロードできない
- 複雑なExcelファイルをプログラムで作成する方法
- Excelで保存したときのCSVファイルの仕様
- フォーム要素の属性名の『ドット( . )』は『アンダーバー( _ )』に変わります
- サブドメインにアンダーバーがあるとクッキーは使えない
- アンダーバーのあるドメインではセッションクッキーは使用できません
- NetBeans6のインストール(JavaだけでなくRuby、PHP、C/C++に対応した統合開発環境)
- memcachedを使用する(memcacheライブラリ)
- date.timezoneを設定するとPHPが早くなる
- PHPフレームワークの一覧
- mbstringエミュレータ
- Fatal error: Maximum execution time of 30 seconds exceededの対処法
- PHPのインストール
- 例外処理(Exception)
- Windows版PHPにPEAR・PECLをインストールする
- PHPをコマンドラインから使用する方法
- 画像の保存やメール転送を制限する方法
- PHPの閉じタグは書いてはいけない
- $_SERVER['PHP_SELF']は危険?
- Net_UserAgent_Mobile 携帯判別PEARパッケージの使い方と注意点
- stdClassクラスとは
- ユーザーエージェントからのキャリア、世代判別
- クラスとオブジェクト
- str関数、preg関数、ereg関数の速度比較
- 配列値格納の構文と組み込み関数による速度比較
- 正規表現のパターン文字列に日本語文字を使うときの注意
- ダブルクオート/シングルクオート/ヒアドキュメント、echo/printの速度比較
- forとforeachの速度比較
- SJISじゃなくてSJIS-win、EUC-JPじゃなくてeucJP-winを使おう
- 文字列の一部を得る関数mb_substrとmb_strcutの違い
- mb_strlenやmb_strimwidthの注意点
- failed: No space left on device
- VGA端末用に出力画像を拡大縮小する方法
- VGA端末の画像表示対応
- SSL通信かどうか
- docomo端末でCSSを使うには
- yumで、より新しいパッケージをインストールする方法(CentOS)
- 住所や駅名などから緯度経度を取得する
- empty関数について
- $_REQUESTに入る値と、その優先順位
- mail関数やmb_send_mail関数でReturn-Pathを設定する方法
- 携帯サイトのmailtoを端末ごとに書き換える関数
- MySQLのソケットエラー
- EclipseでPHPプロジェクトにする方法
- Softbankの携帯で文字の色を白にするときは注意
- mailtoの使い方
- 携帯サイトでのmailtoの使い方
- mailto本文での改行 ドコモのN、Pで送信に失敗します
- 数字(0〜9)のみかどうかを調べる正しい方法
- PCからデコメールを送るときの仕様
- PHPのバージョン表記の隠蔽
- quoted-printable文字列の変換
- Mantisのメール文字化け
- Issue-Tracker [バグ追跡システム]
- phpBugTracker [バグ追跡システム]
- eGroupWare [バグ追跡システム]
- OpenTask [バグ追跡システム]
- <docomo>タグ、<au>タグ、<softbank>タグの使用例
- 動的ページを静的ページに偽装する方法
- 『サイトが移動しました』を出さない方法
- セッション固定攻撃(session fixation)
- Softbankで絵文字を表示させる
- 位置情報・GPS情報の取得方法
- サイトを公開するときの設定
- クッキー(cookie)について
- 携帯電話端末の判別ライブラリ Net_UserAgent_Mobile
- 個体識別情報・UIDの取得方法
- OpenPNEのツッコミどころ
- magic_quotes_gpc = On の対策
- Windows版PHPのインストール
- Mantis(マンティス) バグ管理システム
- CakePHP
- Symfony(シンフォニー)
- EC-CUBE
- Zen Cart(ゼン・カート)
- OsCommerce
- OpenPNE
- PukiWiki
- MediaWiki
- Wordpress
- Nucleus
- Movable Type
- NetCommons(ネットコモンズ)
- Joomla(ジュームラ)
- Drupal(ドルーパル)
- XOOPS Cube
- Geeklog(ギークログ)
- UTF-8からSJISで文字化け
- ファイル操作
- Smarty
- 正規表現
- ちいたん
- Symfony
- サンプルコード
- EC-CUBE
- Zend Framework
- Ethna
- OpenPNE
- CakePHP
- WordPress
- XOOPS Cube
- Drupal(ドルーパル)
- FPDF 1.52 リファレンス
- Doctrine
- 講座
- Yii
- Live Commerce
- SOAP拡張モジュール
- PEAR
- Composer
スポンサーリンク