クッキーの有効期限


これはそのままではクッキーの有効期限を指定する文字列には使えない。
これは以下のような形にする必要がある。

重要
Wdy, DD-Mon-YYYY HH:MM:SS GMT

日付の区切りにはダッシュ「-」を使わなければならない。
たとえば、「Tue, 15-Jan-2030 00:00:00 GMT」という文字列になる。

GMT形式(グリニッジ標準時)での曜日は次のようにすれば求められる。

こう指定しても、日本では2030年1月15日の0時0分0秒ではなく、2030年1月15日の9時0分0秒まで有効だということになる。
- 2021/01/21 -


クッキーの動作不全

CGIスクリプトのパソコン・スマホの共用化の過程で出くわしたトラブルである。
スマホではクッキーの読み書きが想定通りになっているが、パソコンではそうなっていない。
  1. スマホでは投稿者の名前が「***」のとき、クッキーにも「***」が設定され、読み出されている。
    この点ではクッキーの操作は正常に動作している。

  2. このプログラムをパソコンで使うと、投稿者の名前が「###」のとき、クッキーは「+++」が設定され、読み出されている。
    「+++」は以前このパソコンの他のCGIスクリプトで設定していたものである。
    今ここで「###」にしてもクッキーに「###」が設定されることがなかった。
これは今修正しているCGIスクリプトに誤動作の原因がある(要するにバグ)ということである。
ただし、これはこのスクリプトを一つだけしか使わない場合には今のままでも問題は生じない。一つのマシンで多くのスクリプトを使い、それがクッキーの読み書きをしているような場合に、クッキーデータ(値)の混同というトラブルが発生するということである。
スマホではこのスクリプト1つしか使っていない。パソコンでは同じようなスクリプトを多数使っている。これが誤動作の原因である。


クッキーの読み込み

クッキーの読み込みはプログラム起動時にする。今のパターンは以下のようになっている。

タコの殿堂 # 起動時のクッキー読み込み if($bCookie == 1) { &GetCookie(); # クッキーのキーと値を連想配列$COOKIEに取得する。 $strCookieName = $COOKIE{'cookieName'}; # この$strCookieNameという変数名はまぎらわしくて不適当である。 # この'cookieName'というキー名が固定的だから誤動作の原因になる。 } else { $strCookieName = ""; }

問題点
このソースの問題点は次の2点である。
  1. 誤動作の原因
    クッキーの「キー名=値」のペアを設定(書き込み)するときに、どのソースでもその「キー名」をすべて「cookieName」にしていたことが原因である。
    したがって読み込みも当然「cookieName」というキー名を使うことになる。
    パソコンではいろいろなCGIプログラムを使っているが、どれも同じ方法だった。したがって、混同されて想定通りにならなかった。それが誤動作の原因だった。
    スマホ用ではこのCGIプログラムしか作っていないから混同されなかった。
    したがって、ここは使うプログラム名に合わせたものを使う必要がある。

  2. 変数名が不適切な点
    $strCookieNameという変数名はクッキーに保存されている投稿者の名前という意味のつもりだったが、クッキー用の連想配列のキー(名前)とバリュー(値)のペアの「名前」と混同しやすい。
    ここは$strUserNameなど「Cookie」を使わないものに変更するのがいいだろう。


クッキーの書き込み

クッキーの設定(書き込み)はファイルの書き込み時にする。今のパターンは以下のようになっている。

タコの殿堂 if($bCookie==1) { &SetCookie("cookieName", $strName); # フォームに入力された名前($strName)をクッキーに書き込む。 }

問題点
ここでも「キー名」を「cookieName」にしていることが誤動作の原因になる。別のものに変更する必要がある。もちろん、読み込み時に使ったものと同じものにするのは当然である。


修正後の状態

上の「問題点」をふまえて修正したクッキー関連部分の修正後の状態である。

プログラミング # ■起動時に実行する $constCookieKey = "scriptKeyName"; # これは各プログラムごとに異なる名前のキー名(文字列)を指定する。 $strCookieValue = ""; # $constCookieKeyで読み出した値を保持する。 if($bCookie == 1) { &GetCookie(); # クッキーを連想配列に取得。 $strCookieValue = $COOKIE{$constCookieKey}; # クッキーに保存されている投稿者名を取り出す。 } else { $strCookieValue = ""; } $strName = $strCookieValue; # $strNameはフォームに入力されている投稿者名を保持。 # ■ファイル書き込み時に実行する if($bCookie==1) { &SetCookie($constCookieKey, $strName); # 現在フォームに表示されている投稿者名をクッキーに書き込む。 }

実行例
スマホではクッキーの投稿者名が「スマホ」になっている(Fig.1)
Fig.1

上と同じプログラムでもパソコンではクッキーの投稿者名が今設定した「パソコン」になっている(Fig.2)
修正前のものではここが「ドラゴン」など別の名前になっていたのである。
Fig.2

- 2021/01/21 -


ローカルプログラム

ローカルで使うプログラム(ユーティリティ)も少しは整理する必要がある。
*.cgi,*.phpとして単独で使う場合は*.htmlファイルのUTF-8化の影響は受けないから、今のままのEUC-JPでよい。

Fig.1


Fig.2


しかし、JavaScriptなどでの出力結果を*.htmlファイルに埋め込む場合は、*.jsファイルもUTF-8にする必要がある。
従来のようにShift_JISの*.jsを使うとUTF-8化によって次のような文字化けを起こす(Fig.3)

Fig.3

解決
この現象を修正するには*.jsファイルをUTF-8の文字コードで保存すればよい。
Shift_JISファイルが多く、UTF-8ファイルとの混在状態が続く間は、*.jsのファイル名には区別のために、末尾に_u8を付加する。
たとえば、date.jsはShift_JIS、date_u8はUTF-8というようにしておく。
- 2020/12/05 -


杜撰サンプル

Microsoftのリファレンスに大昔から出でいるサンプルに次のようなものがある。

資料
#include <stdio.h>

void main( void )
{
   FILE *stream;
   char tempstring[] = "String to be written";
   int  i;

   /* Create temporary files. */
   for( i = 1; i <= 3; i++ )
   {
      if( (stream = tmpfile()) == NULL )
         perror( "Could not open new temporary file\n" );
      else
         printf( "Temporary file %d was created\n", i );
   }

   /* Remove temporary files. */
   printf( "%d temporary files deleted\n", _rmtmp() );
}

問題点
  1. tempstringはどこにも使われていない。
    これが出ているのはどういうわけか。推測するに、作成したtemporary fileに書き込むための文字列のようであるが、その部分は書かれていない。

  2. temporary fileが作成できなかった場合(最悪の場合全部)。
    そこでこのプログラムが終るわけではない。perror関数は単にメッセージやエラー情報を出すだけである。
    その後、存在しないtemporary fileを_rmtmp関数で削除することになるが、その点の配慮は何もされていない。

tmpnam関数

これとよく似たものに、tmpnam関数を使ってテンポラリファイル名を生成する方法がある。これは「ファイル」ではなく「ファイル名」を作成するだけである。こちらの方が使いやすい。
  1. tmpfile関数で作成されるファイルは「"w+b"」のファイルであるのに対して、tmpnam関数の場合はそういう限定がない。その分使いやすいということである。
  2. tmpfileでは作成したファイルは終了時に自動的に削除されるが、tmpnamの場合は自動的には削除されない。
SOURCE
tmpnamを使う方法で行の削除(ccp_0387)


ファイル検索
検索ウインドウ表示/非表示(IE)





非検索