忍者ブログ

カウンター

プロモーション

カレンダー

12 2025/01 02
S M T W T F S
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31

AntinomyMy の実験室

   私のWEBアプリ実験室です!

ブログ内検索

楽天でお買い物

twitter

最新トラックバック

最新コメント

忍者アナライズ

ウェザーニュース

バーコード

本を買う

アクセス解析

Google+

[PR]

[PR]

×

[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。


No Image

PHPの挙動が環境で変化する問題(ZipArchive編)

PHP の調べ物

メモでーす^^;

PHPでZIPファイルを作る処理、
これでZIPファイル名がおかしかったので、これを取り上げる。

具体的には、img_xxx.zip.何らかの文字列
みたいになるので、何が原因か?

それを調べようと思い、テストソースを書いてみた。

思っていた事とは違ったが、Linuxのサーバーと
Windows のサーバーで挙動が違うので載せることにした(メモだけど)。

勿論、PHPのバージョンにも大きく関係しているが、
どのバージョンでもできるだけ共通に書ける事が望ましいので、
バージョンどうこうというよりも、こうなるとこうなった!という内容だけを記述してみる。

<?php
 
$openFile = 'img_001.zip';
 
$fp_debug = fopen($openFile, 'a+'); //指定のパスのファイルネームがあれば追記モードで開き、無ければ作成
$zip = new ZipArchive();
$zip2 = new ZipArchive();
$rs = $zip->open($openFile, ZIPARCHIVE::CREATE); //
$rs2 = $zip2->open($openFile, ZIPARCHIVE::CREATE); // | ZIPARCHIVE::OVERWRITE
if($rs === TRUE){
echo 'ZIPオープン';
    $zip->addFromString('test.txt', 'ここにファイルの内容を書きます');
$zip->close();
}else{
echo 'ZIPエラーミス';
}
if($rs2 === TRUE){
echo 'ZIP2オープン';
    $zip2->addFromString('test2.txt', 'ここにファイルの内容を書きます2');
$zip2->close();
}else{
echo 'ZIP2エラーミス';
}
 
echo "<br>\r\nZIPの中身<br>\r\n";
$zip3 = new ZipArchive();
if ($zip3->open($openFile) == TRUE) {
for ($i = 0; $i < $zip3->numFiles; $i++) {
echo "No$i:". $zip3->getNameIndex($i)."<br>\r\n";
}
}
 
fclose($fp_debug);
 
?>

これをLinux、Windows の環境で実行すると、img_001.zipファイルは両方とも出来るのは確認できる、
しかしWindows環境で、1回目の実行でファイルを作ったPCのディレクトリを見れば確認できるが、
zip3のオブジェクトで中身を表示するルーチンの部分(ブラウザ閲覧)ではすぐに確認が取れない。

結局Windows では、ブラウザをリロードした2度目の実行でzip3のオブジェクトでの確認ができる・・・
Linux は1度目からリロードせずに確認できる、これもかなり変な感じだが、
それは適当にロックが?!?!?!?!?と予想して、後回しにして(なぜ?とか言わないでネ!゜w゜; 眠いのですw)、
そして先にこれ以前に大きな違いが作られたファイルに見られた。

Windows環境の方では、「test.txt」のみが作られ
Linux環境では、「test2.txt」のみが作られたのを確認した。

とりあえず、ファイルをロックして、使っている状態でfopenでロックしたつもりであったが、
そんなのお構いなしで、ZIPファイルの作成処理に入ってしまっている。

結局私が知りたかった、
img_003.zipのファイルを追加したり消したりしていると、
img_003.zip.7Cnqxd というファイルネームが出来る原因が掴めなかった(追伸:--- 追伸の追伸 ---、ブログ後半以降で解決?)。

元々自分が作ったプログラムを修正しているのではないので、
毎回何が悪いんだろう;w;?と思いながら、あれこれやってみて、
おかしな挙動に気がついたりする。


今回、なんとなくわかった事は、ZIPファイルのロックや、重複オープンで、仕方なしに別名でZIPファイルを作成した為に、
 名前が変わっているのでは無さそうだ・・・・)


個人的なメモでした<_ _> お粗末!


---追伸---
なんか、ZIPファイルを作る時と、消すときのファイルネームの取得の仕方が違い、
なんか怪しいプログラムだったので(私が作ったのではない・・・)、
ZIPのファイルを->open($openFile) する時には、そのオープンするファイルが存在するか?
のルーチンを付け足したら、なぜか変なZIPファイル名のimg_003.zip.7Cnqxd が出来なくなった・・・
うーん・・・・・ よく分からない情報元からループしてファイル名を取得しているので、
その大本も怪しい

とりあえず、何を付加えたか?

if(file_exists($z_name)){ //ファイルが無いのに開こうとうすると、作られてしまうのを防ぎたい

というのを->open($openFile) が使われる前に行い、
一連のZIPファイルの内容をその判断(file_exists関数でファイルがあるかどうか)の中にいれたら
なぜか解決しました?!

実は違うファイル名で、無いファイルでも開こうとすると、新たしいZIPのファイルが出来てしまうので、
これが原因?だったのかな?と思っています・・

本当にスパゲティープログラム(変数名を何度も再利用して、途中で初期化とかする、関数化しないプログラム、
何度も同じルーチンが出現するけれど、全く同一かどうか、確認しないといけないプログラム、などなど)を
見て欲しいとか、どんだけ時間かかると思っているんだ!とか言いたくなるんですorz

同じ注文でも、中身によっては全く違うって事を同じ世の人に知ってもらいたかったりするw

長文のやった事、忘れない為のメモでした^^;ノシ

--- 追伸の追伸 ---

本当のバグがわかった!
複数の要求で、->open が書かれたファイルを同時に走らせて、
しかもinclude しているファイルの中にも->open 関数があった!

それで、よく見ると->closeが->open をした時の成功、不成功の判断で
->close をしていなくて、何の条件もなしに->close をしていた。

つまり、->open しなくともclose しているので、それで何かを閉じしまう可能性が、
何らかのバグなのであるかもしれないと思った。

どちらにしても、そこでエラーにもなるだろうから、
とりあえず、->open している時のみ、->close する様に、->open の戻り値で開いた場合のみ、
->close する様に修正した。

あと、サーバーやローカルサーバーの処理が多くなると、
zipの一時ファイルがほんの一瞬でも目に止まるまで、作成や削除のスピードが遅れ、
目に付く様になる気がした(Windows 7環境)。
どちらにしてもバグを持っているのは、Linux 環境※のみ※であるという、
不可解な状況なのだけれど、
opendir でZIPファイルを探して、そのファイルを処理などするときに、
zipの一時ファイルがあると、これに追加(削除も?)処理をしてしまい、
処理を施してしまうと、自動で一時ファイルが消えない様だ。

なので、名前を確認する必要がある(あった)。

img_数値.zip なのだが、これが・・・・
実例:
img_005.zip.lCyKob
img_005.zip.mdCkcu
img_005.zip.hj9NcF
img_005.zip.xcNUYx
img_005.zip.MK7cZG
img_006.zip.CSbPq9
img_006.zip.iWWGZc
img_006.zip.G3soMF
img_006.zip.T9tntU
img_006.zip.B2divg
などと、一時ファイルが出来てしまうのを確認している。

ここでちょっと公式のマニュアルにない仕様が、やはり明らかにある事を感じた。
それは、ZIPファイルの一時処理用のファイルが作成され、それは元の名前+αという仕様である。
公式マニュアルに載せておいてほしい・・・・ これでどれだけの時間を潰したやら・・・・

なので、しっかり対象のimg_数値.zip を探る様に
正規表現を使って、余計な文字があったかどうかを確かめる必要がある。

例えば
if('' != preg_replace("/^img_\d+\.zip/",'',$zf))
で、img_数値.zip を取り除いた後に、空白でなかったら・・・・ このファイルが違うので、他の処理をするなどです。

初めは空白出なかった時に、この一時ファイルを強制的にunlink を使って消そうとしていたけれど、
もしかして、これは放置していれば、そしてしっかりclose などがされていれば、消えるんじゃないだろうか?
と思い、unlink 関数をせずに放置をしていた所、やはり自動でうまく消えてくれる様であった。

私が作ったソースでない為・・・close が->open の戻り値で判断されていないのに無いのに気がつくのに時間がかかった;x;

多分、もう消す処理はしないので
!= でなく == にして
if('' == preg_replace("/^img_\d+\.zip/",'',$zf))
と書いて、{}内に正常な時として処理を加えれば通常は問題ない

ただ、デバッグのトラップとして、そのおかしな一時ファイルの名前を知りたい時は
== でなくて != にしておけばそこでそのファイル名を知ることが出来る。


あぁー なんでこんな得たいのしれないスパゲティーのソースを解析しないといけないんだろうと思いつつ、
眠くて仕方ないので、寝る事にする@x@;

もうなんか、眠くて何を言っているのか分からなくなっているので、後で見直すかも(かもですw)、
付加えとか、付加えとか、付加えとか、きっと多分あったりなかったりします(謎)


長文で失礼! お粗末でした<_ _>

拍手[0回]

PR

No Image

Windows とLinux で明らかに挙動が違う関数や書式

PHP の調べ物

Windows でPHPのプログラムを書き、
Webサーバー上のLinux で動かそうと思うと
案外挙動が違って動かない事が当たり前の様に起こる。

array_key_exists関数 も同様である。

Windows のPHP5.3.5 でこの関数を使えば、配列のキーでも値でも両方検索してくれる
しかし
Linux のPHP5.3.18 でこの関数を使うと、なんと配列の値でしか判定してくていない

つまり挙動が違うのである。


こういった事柄が多すぎる。

確かLinux で画像ファイルを生成しようとしたときにも
変数の型キャストをしないとWindows で動いた計算書式でも
動かない事があった、どんな事柄であったかメモをし忘れたが。

きっとWindows とLinux の両方で開発をおこなっている者は、
こういったことを沢山感じていると思う。

なぜ同じ環境でコンパイルしないのだろうかと、とても不思議に思える。

同じコンパイラが使えないのだろうかと思うが、PHPが便利であるからこそ本当に勘弁して欲しい。

今後も思い出したり再びこういった挙動の違いに遭遇したら、
再びメモをブログに取ろうと思う。


以上、今日は短め・x・

拍手[0回]


No Image

eval 関数と file_get_contents 関数で作る簡単データ読み込み

PHP の調べ物

久しぶりにメモ。

今回のメモは、PHPのeval 関数を用いて、
eval関数で読み込む内容にスクリプト自体を書き、
PHPで処理させる事が書かれている。
勿論eval関数は、
引数にスクリプトを与えると処理するという代物であるので、
何の変哲も無い、当たり前の事だと感じると思う。

しかし、引数に与える内容を、外部に書かれたファイル
丸々を読み込んで自身に取り込み処理させることが出来るのです。

これは普通に皆が使っている使い方なのだろうか?
基本的に危険を感じて使わないのか、思いついてはいないのではないか?と
思った。

また、その上記な様な使い方をするなら、
include系の関数を使えば良い気がするが、
それらと違い何時でも好きな時に好きなスクリプトを
読み込み、実行した状況を作り出せる。

今回私がなぜこの関数を使おうと思ったか?
それはPHPのスクリプトソースが書かれたファイルにも
エンコードがあり、それを解釈するにもエンコードがある。

Webブラウザで表示するコードにPHPのスクリプトソースも合わせたとしても
データベースから吐き出させるスクリプトコードをどう処理するかなど、
考えなければいけないことと・・・・・①

もしファイルを作りバイナリなどのデータを保存したとしても、
それを今度読み込むときに変数に読み込む処理を書かなければいけない・・・・・・②

レンタルサーバなどの休めのサーバはデータベースを複数持てないので
クラッシュした場合に困ったり、複数ないと使い勝手やパフォーマンスに困る気がする・・・・・・③

これらの理由が大きく、よく考えてみた所、
PHPのソースごとデータとして保存することを思いついた。

つまり、arrayなどや、いろいろな型をそのまま変数にPHPスクリプトを書いて保存して、
それをeval 関数で読み込めば、保存したソース内で指定した変数に値が保存される。

つまり元のソースに存在したかの如く、変数にデータが代入される。


以下2つのソースがサンプルです。
片方は、私が勝手に付けた拡張子です。podという拡張子なのは
PHP of DATA のつもりで付けました、そんな勝手に付けた拡張子なので
後から好きに変えてもらって問題ないです。
同じディレクトリに2つのファイルを置いて下さい。
同じ文字コードで書かれていて、同じ文字コードで解釈される様に設定しておいでください。

尚、PHP of DATA(仮称)側の文字列を作成するスクリプトは
特に載せてないですが、PHPスクリプトを書く要領で記述し、エスケープするPHPスクリプトを
考えて書いて、中の変数部分に好きなデータが埋め込める様にするだけだと思います。

注意点は、元のソースには何処からこの変数は記述があるのか?
と思ってしまうと思うので、その当りを気をつければ良いと思います。

適当なソースですが、参考にどうぞ。


 

ファイル名:<array_string.dop> 以下中身
 


$filedata=array('a'=>777,'b'=>567);
$filedata2=array('a'=>333,'b'=>789);

 

 

ファイル名:<php_of_data.php> 以下中身
 

 


 

<?php

 

$stringVal=<<<'hereDocument'
$arrayString=array('a'=>123,'b'=>555);
hereDocument;

 


eval($stringVal);
echo 'test';
var_dump($arrayString);
echo $arraystring;
echo $stringVal;

 

echo '<br/>file data php read<br/>';

 

$dop=file_get_contents('array_string.dop');

 

eval($dop);
echo $dop;
var_dump($filedata);
var_dump($filedata2);
?>


 






結果

 


test

 

array
  'a' => int 123
  'b' => int 555

$arrayString=array('a'=>123,'b'=>555);
file data php read
$filedata=array('a'=>777,'b'=>567); $filedata2=array('a'=>333,'b'=>789);

array
  'a' => int 777
  'b' => int 567
array
  'a' => int 333
  'b' => int 789

最後に追加の注意点ですが、evalで読み込ませる内容の元であるファイルは、データが内臓されたPHPスクリプトを作成のソース(私が言うpod拡張子)で一定の場所以外は書き込めない様なプロテクト対策が必要だと思います。つまり得体の知れない他のWebに吐き出したり、ユーザーが見ているブラウザに情報を吐き出す可能性があるスクリプトは危険です。 また、内部のデータも同様に、得体の知れないアドレスなどを保管するのは危険です。つまりWeb上の外部のアドレス先は、何時コンテンツが変更になるかわからないので、それらも理解した上で、Web上の外部のアドレスなどを保管するべきです。何にそのアドレスを使うのか、発想が変わった時には危険ですから。 また、データが内臓されたPHPスクリプトを作成のソース(私が言うpod拡張子)は Linux上などであればアクセス制限を施すべきです。ファイルが毎回新たな予測不可能なファイルネームで新規に作成される場合などは、しっかりchmod などでアクセス権限を変更するべきです。 そしてまた、大事な情報であれば、apacheのhtdocs直下などでWebページからアクセス出来る様なそんな場所で使うべきではありません。 こんな感じです。今回は短いメモでした<_ _>


追伸:
include とかでもファイルは読み込めるのと、
phpのserialize 関数もあるので、
特定のPHPソースとして残したい用途以外は
こんな使い方をしなくても良いかもです。

PHPのソースを吐き出すPHPのプログラムを作るのならば話は別ですが^ー^

拍手[0回]


No Image

PHP isset() とempty() の、もやもやメモ

PHP の調べ物

今更ではあるが、毎回ふと疑問に思うことがある。
何がしたいか判っているはずなのに、度々つまずく、毎回考える、
果たしてこのisset() とempty() は何をしたい時に使うのか?
何を表しているのか?

やりたい事から知りたい事を割り出してみた。

変数の入れ物があり、型や内容が明確か?
これが知りたいのだろう、ケースはいくつかある。


したいこと 知りたい型 知りたい値
- 不明 不明
Falseと0を別扱いしたい 不明 判る
型が作られたら値0だと判断させたくない 判る 不明
- 判る 判る

結局色を変えた2種類の事柄が知りたいが為に
isset() とempty() の関数を使うのだと思う。

ぶっちゃけ、ネットで色々調べるが、
最終的に解決できるであろう場所はココにある
公式マニュアルのPHP 型の比較表だ。

そして何よりもNULL とは何なのか?
これも公式マニュアルのNULLにも
その事柄が書いてある。

確かにその通りなのであるが、
しかし、これだけでは実感できない。
特に私の場合には配列の中身の扱いが不安である。

なので少し実験してみた。

以下ソース
---------------------------------------------------------------
<?php
header('Content-type: text/html; charset=UTF-8');


echo 'いきなりx</br>isset:'. (isset($x)?'何かある':'空') . '  empty:'. (!empty($x)?'何かある':'空') . '</br></br>';
var_dump($x);

echo '配列として見る</br>issetx[0]:'. (isset($x[0])?'何かある':'空') . '  empty:'. (!empty($x[0])?'何かある':'空') . '</br></br>';
var_dump($x);

$x[10]=0;
echo 'いきなりx[10]に0を代入</br>isset[10]:'. (isset($x[10])?'何かある':'空') . '  empty:'. (!empty($x[10])?'何かある':'空') . '</br></br>';
var_dump($x);

$x=0;
echo 'xに0を代入</br>isset:'. (isset($x)?'何かある':'空') . '  empty:'. (!empty($x)?'何かある':'空') . '</br></br>';
var_dump($x);

$x=array();
echo 'xを配列宣言</br>isset:' . (isset($x)?'何かある':'空') . '  empty:'. (!empty($x)?'何かある':'空') . '</br></br>';
var_dump($x);

$x[0]=0;
echo '配列xの[0]に0を代入</br>isset:' . (isset($x)?'何かある':'空') . '  empty:'. (!empty($x)?'何かある':'空') . '</br></br>';
var_dump($x);

$x[0]=1;
echo '配列xの[0]に1を代入</br>isset:' . (isset($x)?'何かある':'空') . '  empty:'. (!empty($x)?'何かある':'空') . '</br></br>';
var_dump($x);

$x[1]=1;
echo '配列xの[1]に1もを代入</br>isset:' . (isset($x)?'何かある':'空') . '  empty:'. (!empty($x)?'何かある':'空') . '</br></br>';
var_dump($x);

unset($x[0]);
echo '配列xの[0]だけunset</br>isset:' . (isset($x)?'何かある':'空') . '  empty:'. (!empty($x)?'何かある':'空') . '</br></br>';
var_dump($x);

unset($x);
echo 'x全てをunset</br>isset:'. (isset($x)?'何かある':'空') . '  empty:'. (!empty($x)?'何かある':'空') . '</br></br>';
var_dump($x);

echo ($x?'true':'false');

?>
---------------------------------------------------------------
以下結果:
---------------------------------------------------------------

いきなりx
isset:空 empty:空

null

配列として見る
issetx[0]:空 empty:空

null

いきなりx[10]に0を代入
isset[10]:何かある empty:空

array 10 => int 0

xに0を代入

isset:何かある empty:空

int 0

xを配列宣言
isset:何かある empty:空

array empty

配列xの[0]に0を代入
isset:何かある empty:何かある

array 0 => int 0

配列xの[0]に1を代入
isset:何かある empty:何かある

array
0 => int 1

配列xの[1]に1もを代入
isset:何かある empty:何かある

array 0 => int 1 1 => int 1

配列xの[0]だけunset
isset:何かある empty:何かある

array 1 => int 1

x全てをunset
isset:空 empty:空

null

false

---------------------------------------------------------------

結果

まず関係の無いことかもしれないが、
PHP では
型宣言されていないなんらかの変数を
配列として中身を初めて見ても、
その後から配列として型宣言された扱いとなったりはしない。
当たり前と言えば当たり前なのだが、
案外インスタンス関係はややこしく仕様が介入するので、
もしや?!なんて思ってしまうことがあるので、
これは収穫だったと思えた。

次に型の有無、これは型があり、値が使われていなければ
Emptyになると配列では証明された。

配列のEmptyは全く持って0 やFalse と変わらない、
その為型宣言後なのかだけを調べることはisset 関数でもempty 関数でも出来ない。
Emptyでは0やfalse 以外かどうかしかわらない、名前は空(empty)とと言う名称なので
型判断に思えてしまうので、毎回考えてしまうが、値が0やfalse以外かどうかしか確認できない。

つまり、結局値では0が代入されたりfalse だったりすればempty 関数ではTlue を返す。
empty関数が空であるtlue を返すのは型が宣言されていない時、0やfalse、empty の時。

※分かりにくいので ! をつけた !emptyとして使ったほうが理解しやすい場合もある、私の例題ではそうしている。

そしてisset関数が空であるFalse を返すのは
型が設定されていない時以外は結果的に全て返す。
また、0であってもfalseであっても型があればTlue を返す。
(isset関数で複数を同時に検査した場合、一つでもfalse判定であると、isset関数はfalseを返すので
 それには注意が必要。)
 

値(x)   !empty(x)   isset(x)

(例ではarray)
0,false,empty false true
0,false,empty以外 true true
無(NULL) NULL(値として比較すると0,false,emptyに相当) false false



一応参考のソースと結果を載せておく。
<?php

header('Content-type: text/html; charset=UTF-8');

echo (NULL==false?'NULL==false 同じ':'NULL==false 違う') . '</br>';

echo (NULL==0?'0==false 同じ':'0==false 違う') . '</br>';

echo (NULL===false?'NULL===false 同じ':'NULL===false 違う') . '</br>';

echo (NULL===0?'0===false 同じ':'0===false 違う') . '</br>';

?>
------ 結果 -------
NULL==false 同じ
0==false 同じ
NULL===false 違う
0===false 違う

当たり前であるが、NULLと型が一致するのはNULLしかない。


結論:
型チェックと数値チェックを混同しがちなisset関数と
!をつけた方が理解しやすい!empty関数、
これらを使い数値のチェックをするのは良いが、
型が存在するかなどは、配列に使えば話が変わる様に、
配列であるかなどのチェックが必要な場合がある。

型をチェックするのであれば、
is_array関数を用いるべきであり、
他の型をチェックするのには
is_から始まる 変数操作関数を使うべきである。

isset関数はNULL型かどうかの比較機能もつけた!empty関数だと
思えば良いのかもしれないが、実際はNULL型(値)との比較をするか、
is_null を使った方が良い場合もある。

特に細かく型を判定した方が良い場合などは
isset関数を使ってしまうよりは良いかもしれない。

そもそも紛らわしいのは、empty関数が空である場合をTrueとしていることである。
なので! をつけて !emptyとして使わなければいけないので、
これとisset関数の使い勝手を比較するのはとてもややこしく思えるのでした。

また、isset関数は、多くの引数を使い、多くの引数の中で1つでもisset関数で
falseな場合には1つでもTrueがあったとしても関数はfalseを返すので、
多数の変数全体の判断に使うのだと思います。

以上、長ぁーーーいメモでした<_ _>     (かなり前回の編集が適当だった為、書き直してあります。) 

拍手[0回]


No Image

$_SERVER['SCRIPT_FILENAME']は実行されたスクリプトの位置を返すのではない!

PHP の調べ物

ふと$_SERVER['SCRIPT_FILENAME']はPHP の説明によると
「現在実行されているスクリプトの絶対パス」と書いてあるので
読み込んでいるスクリプト内で使われているなら、
読込先のフルパスが帰ってくるのか?
疑問に思ったのでやってみた。

include()
include_once()
require()
require_once()

などで呼び出している中で$_SERVER['SCRIPT_FILENAME']を使ってみた。

以下、
--------------------------(読み込むスクリプト)--------------------------
script_name.php
------------------------------------------------------------------------------
<?php
function scriptArea(){
 return $_SERVER['SCRIPT_FILENAME'];
}
?>


--------------------------(直接始めに実行するスクリプト)--------------------------
script_area_test.php
------------------------------------------------------------------------------
<?php
include_once "script_name.php";

echo "includeエリア:" . scriptArea() . "</br>";

echo "そのままエリア:" . $_SERVER['SCRIPT_FILENAME'];

?>
 

--------------------------実行結果--------------------------
includeエリア:C:/hogehoge/script_test_area.php
そのままエリア:C:/hogehoge/script_test_area.php


--------------------------結論--------------------------
実行しているスクリプトの名前であって、
読込先のスクリプト内を表示することは出来ない。
あくまでサーバが最初に処理し始めたスクリプトの
名前を返す様だ。


セキュリティーからすれば外部からの見通しがきかなくなる点では安全かもしれないが、
読み込みスクリプトのパスを欲している場合に、この方法で取得出来ないということみたいだ。

それもそのはず、結果からみた予想ではあるが、処理開始始めに決定される変数が
$_SERVERなんだろうと思う。たかがそれだけの事だが、されどそれだけの事だった。

一応メモ書きであぁ~るっ。

拍手[0回]


[PR]