MW211 EXIT

devlog
PHP/ZIPファイルに圧縮してダウンロード
2011年10月03日
「PEAR」の「Archive_Zip」が実装されていることが前提条件。
┌──────────────────────────────────────┐
│C:\xampp\php>pear list                                                      │
│INSTALLED PACKAGES, CHANNEL PEAR.PHP.NET:                                   │
│=========================================                                   │
│Archive_Zip                0.1.1       beta                                 │
└──────────────────────────────────────┘
「Archive_Zip」クラスの「create()」メソッドを使えば、
ZIPファイルが圧縮生成される。
┌──────────────────────────────────────┐
│// ZIPファイル生成                                                          │
│require_once('Archive/Zip.php');                                            │
│$zip_file = 'xxxx/xxxx.zip';                                                │
│$newArchiveZip = new Archive_Zip($zip_file);                                │
│$newArchiveZip->create('oooo/ooo1.txt','oooo/ooo2.txt',…);                 │
│// ダウンロード                                                             │
│header('Content-Disposition: attachment; filename="ダウンロードファイル名"'); 
│header('Content-Type: application/octet-stream');                           │
│header('Content-Length: '.filesize($zip_file));                             │
│readfile($zip_file);                                                        │
└──────────────────────────────────────┘
生成されるZIPファイルは「xxxx/xxxx.zip」、
圧縮されるファイルたちは「oooo/ooo1.txt」など(複数指定できる)
なお、「Content-Length:」はダウンロード時の進捗表示のために
全体サイズを指定している。
分類:PHP、PEAR
PHP/一意な一時ファイル名
2011年10月02日
一時的なワークファイルとかに名称をつけたい場合、
以下のような方法があります。
┌───────┬──────────────────────────────┐
│date('YmdHis')│秒単位(「u」をつければマイクロ秒もありだが…)               │
├───────┼──────────────────────────────┤
│time()        │UNIX秒単位                                                  │
└───────┴──────────────────────────────┘

っておい、以下のような便利な関数があるじゃないか。
┌──────────────────────────────────────┐
│tempnam(パス,接頭辞)                                                        │
└──────────────────────────────────────┘
ちなみに接頭辞はWindowsの場合、3文字(3バイト)までらしい。
分類:PHP
HTML/ファイルを名称変更してダウンロード
2011年09月30日
ファイル(csvファイルとか)をそのままダウンロードする方法は以下の通り。
┌──────────────────────────────────────┐
│<input type="button" value="入手" onclick="location.href='xxxx.xxx'"/>      │
└──────────────────────────────────────┘

これだと実際にあるファイルをそのままひっぱってくる感じだ。
さて、ここでファイル名を任意の名称に変更したい場合はどうすればよいか?
例えば内部管理用のファイル名と外見えのファイル名が違う場合とかだ。

簡単な方法がみつからない。
とりあえず、以下なら実現できる(ちとめんどくさい)。

まずはformで囲い、POSTメソッドで飛ばす。(たいていは自分に戻ってくるようにする)
ただし、その前にひと手間必要なので、JavaScript関数をはさむ。
┌──────────────────────────────────────┐
│<form method="post" action="">                                              │
│<input type="button" value="入手" onclick="dload(this.form,'xxxx.xxx')"/>   │
│</form>                                                                     │
└──────────────────────────────────────┘

JavaScript関数にて、「$_POST['download']」に変更前のファイル名を入れてsubmit。
┌──────────────────────────────────────┐
│<script type="text/javascript"><!--                                         │
│function dload(inForm, inValue){                                            │
│  var new_element = document.createElement('input');                        │
│  new_element.type  = "hidden";                                             │
│  new_element.name  = "download";                                           │
│  new_element.value = inValue;                                              │
│  inForm.appendChild(new_element);                                          │
│  inForm.submit();                                                          │
│}                                                                           │
│--></script>                                                                │
└──────────────────────────────────────┘
本当はsubmit(のvalueに)にファイル名をぶちこんであげれば楽なのだが
submitボタン名に表示されてしまうので、hidden属性を使う。
ボタン名に表示されても構わないのであればJavaScript不要で以下だけで可。
┌──────────────────────────────────────┐
│<form method="post" action="">                                              │
│<input type="submit" name="download" value="xxxx.xxx"/>                     │
│</form>                                                                     │
└──────────────────────────────────────┘

後はPOST先で、ファイル名を生成してダウンロード実行。
┌──────────────────────────────────────┐
│if (isset($_POST['download'])) {                                            │
│  header('Content-Disposition: attachment; filename="'
                                             . ダウンロードファイル名 . '"'); │
│  header('Content-Type: application/octet-stream');                         │
│  readfile(htmlspecialchars($_POST['download'], ENT_QUOTES));               │
│  exit();                                                                   │
│}                                                                           │
└──────────────────────────────────────┘
分類:HTML
JavaScript/POSTメソッドとGETメソッドをネストする方法
2011年09月28日
ということで前回(JavaScript/POSTメソッドとGETメソッドを切り替える方法)からの
続き(「怪獣殿下」を彷彿とさせる初の二話構成です)。

今度は、POSTメソッドの中にGETメソッドを入れる方法(をより真剣に検討)。
┌──────────────────────────────────────┐
│<form method="post" action="xxxx.php">                                      │
│  <input type="button" value="GET実行" onclick="submit2()"/>                │
│  <input type="submit" value="POST実行"/>                                   │
│</form>                                                                     │
└──────────────────────────────────────┘
までは(ほぼ)一緒です
#あ、実はsubmit2()の引数が(使わないから)こっそりなくなってる。

さて、JavaScriptの中ですが、こんな感じでどうでしょうか。
┌──────────────────────────────────────┐
│<script type="text/javascript">                                             │
│function submit2() {                                                        │
│  // 念のためこれから作るformを削除しておく(ある時だけ)                     │
│  var oldForm = document.getElementById("newForm");                         │
│  if (oldForm) {                                                            │
│    oldForm.parentNode.removeChild(oldForm);                                │
│  }                                                                         │
│  // 新規formの設定                                                         │
│  var newForm = document.createElement("form");                             │
│  newForm.setAttribute("method", "get");                                    │
│  newForm.setAttribute("action", "oooo.php");                               │
│  newForm.setAttribute("id"    , "newForm");                                │
│  newForm.style.display="none";                                             │
│  // 新規属性の設定  ※いくつでも設定可能(このブロックを繰り返す)           │
│  var newInput = document.createElement("input");                           │
│  newInput.setAttribute("name" ,name属性名);                                │
│  newInput.setAttribute("value",値);                                        │
│  newForm.appendChild(newInput);                                            │
│  // 新規formの作成とsubmit                                                 │
│  document.getElementsByTagName("body")[0].appendChild(newForm);            │
│  newForm.submit();                                                         │
│}                                                                           │
│</script>                                                                   │
└──────────────────────────────────────┘
ま、JavaScriptの中でformの世界を創ってあげる(でsubmitする)感じですね。
これなら、submitボタン(にあたるもの)がどこにあっても文句をいわれません。
ただし、formの中に定義している各属性は(そのままでは)連れてこれないので
ひとつひとつ「setAttribute()」と「appendChild()」で
(ひっぱってきては)作り直してあげる感じでしょうか。
ひっぱってくる部分は、「getElementById(ID).value」とかでできます。

GETメソッドだったら、URIを作ってしまった方がはやいという話もありますね。
ま、これだとPOSTメソッドへの流用も可能です。
分類:JavaScript
JavaScript/POSTメソッドとGETメソッドを切り替える方法
2011年09月27日
formタグはネストすることができない。
┌──────────────────────────────────────┐
│<form method="post" action="xxxx.php">                                      │
│  <form method="get" action="oooo.php">                                     │
│    <input type="submit" value="GET実行"/>                                  │
│  </form>                                                                   │
│  <input type="submit" value="POST実行"/>                                   │
│</form>                                                                     │
└──────────────────────────────────────┘
だから、上記みたいにPOSTしたい範囲の中にGETしたい範囲があるなんてのは無理。
さて、どうしよう。
ということで、まずはgetのsubmitボタンをJavaScript化して
POSTメソッドのformなのに、GETメソッドとしてsubmitさせるという方法。

まずはformのネストを潔くあきらめて、submitボタンをただのボタンにして
JavaScriptに後を託す。
┌──────────────────────────────────────┐
│<form method="post" action="xxxx.php">                                      │
│  <input type="button" value="GET実行" onclick="submit2(this.form)"/>       │
│  <input type="submit" value="POST実行"/>                                   │
│</form>                                                                     │
└──────────────────────────────────────┘
で、JavaScriptの中でこんな感じで内容を書き換えてsubmitさせてしまうのだ。
┌──────────────────────────────────────┐
│<script type="text/javascript">                                             │
│function submit2(inForm){                                                   │
│  inForm.setAttribute("method","get");                                      │
│  inForm.setAttribute("action","oooo.php");                                 │
│  inForm.submit();                                                          │
│}                                                                           │
│</script>                                                                   │
└──────────────────────────────────────┘

これは、POSTとGETが(立場が)逆の場合も可。
というか、そっちの方がおすすめ。
なぜなら大抵、POSTする内容は量が多いので、GET化(URI化)すると
URIがものすごい長文になってしまい、あまり実用的ではない。
#IE7だと「res://ieframe.dll/dnserror.htm」エラーとかになる。

ということで、明日につづく。
分類:JavaScript
PostgreSQL/数値文字変換
2011年09月26日
本来数値である項目を事情があって文字型項目として保持してたりして
これを本来の数値型に変換して取得したい場合には、「TO_NUMBER()」を使う。
┌──────────────────────────────────────┐
│TO_NUMBER(列,'S999D0')                                                      │
└──────────────────────────────────────┘
こんな感じになる。
第二引数として、書式を指定してやるのがちょっとめんどくさいかも。

一方その反対に数値を文字型に変換するのは「TO_CHAR()」だ。
┌──────────────────────────────────────┐
│TO_CHAR(列,'S999D0')                                                        │
└──────────────────────────────────────┘
こんな感じ(TO_NUMBER()と同じ)。
日付型なんかは以下のような感じで変換できて便利。
┌──────────────────────────────────────┐
│TO_CHAR(列,'YYYY-MM-DD HH24:MI:SS')                                         │
└──────────────────────────────────────┘
さて、話は戻って「TO_NUMBER()」。
こいつが意外と厄介で、入力値(つまり参照する列)に文字列が混じっていると
エラーとなってしまうのである(NULLならOK、''はNG)。

そこで、ISNUMERIC的なことをして条件分岐させたいところだが、見当たらない。
ならばということで、正規表現で数値を抜き出す方法を代案として考えた。
┌──────────────────────────────────────┐
│SUBSTRING(列 FROM E'^\-*[0-9]+\.?[0-9]*$')                                  │
└──────────────────────────────────────┘
これならエラーを回避できる。
┌──────────────────────────────────────┐
│TO_NUMBER(SUBSTRING(列 FROM E'^\-*[0-9]+\.?[0-9]*$'),'S999D0')              │
└──────────────────────────────────────┘
文字列が混じっている場合は、NULLになる。
分類:PostgreSQL
定数の値
2011年09月25日
定数の値はたいてい「1,2,3…」とかだ。
┌─┬─┐
│ 1│男│
├─┼─┤
│ 2│女│
└─┴─┘
みたいな感じ。

ふと、数値じゃなくてもいいんじゃね?とか思い、「male、female」の頭文字をとって
┌─┬─┐
│m │男│
├─┼─┤
│f │女│
└─┴─┘
な~んて定義してみる。

同じじゃん。こっちの方が直感的でわかりやすいし。オレって天才。
なんて思っていると実は落とし穴に嵌っていることに後から気づく。

そう、ソート順のキーに指定した場合「女→男」の順なってしまうのだ。

定数の値は、並び順の番号と心得るべし。

#順番については男尊女卑ではありませんのであしからず
分類:SQL、注意、設計
SQL/INSERT文に一意制約をつける
2011年09月24日
一意属性(UNIQUE)をつけたいのにつけられない項目があるとする。
例えば、削除区分とかを使って削除レコードを履歴として残している場合の
実質的なキー項目とかの場合だ。
#削除レコードを除いて中では一意になる項目とかのこと

ま、とにかく事情があって一意属性はつけられないが
一意であって欲しい場合、INSERT時に制約をかけるとするなら
一旦SELECTで読み込んで存在を確認した上で
存在していない場合のみINSERTするとかいう処理になると思う。

これを一回のSQL文で実現させることができないものかと考えていたのだが
「相関副問い合わせ」ってやつを使えばできてしまうのだ。
┌──────────────────────────────────────┐
│INSERT INTO 出力表 (出力列)                                                 │
│    SELECT 入力列                                                           │
│        FROM 入力表                                                         │
│        WHERE 条件                                                          │
│          AND NOT EXISTS (SELECT *                                          │
│                              FROM 出力表                                   │
│                              WHERE 出力.出力列 = 入力表.入力列);           │
└──────────────────────────────────────┘

「副問い合わせ」までで挫折して「相関副問い合わせ」なんかとは縁がなかったが
こうやって使ってみると便利なものだ。(ってこの使い方が正しいのかはやや不安)

★この方法には問題があることがわかりました、後日加筆修正します
分類:SQL
SQL/呉越同舟?Ⅱ
2011年09月23日
以前、まったく違う列を結合したかのように取得する方法を取り上げた。
┌──────────────────────────────────────┐
│SELECT 表1.列11,                                                            │
│       表2.列21                                                             │
│  FROM 表1,                                                                 │
│       表2                                                                  │
│  WHERE 表1.列11 = '値'                                                     │
│    AND 表2.列21 = '値';                                                    │
└──────────────────────────────────────┘
上記のようにすれば、あたかも以下の結果を横に並べたようになるのである。
#但し、双方ともに一件ずつ該当し、結果が一件になるような場合が望ましい
┌──────────────────────────────────────┐
│SELECT 表1.列11                                                             │
│  FROM 表1                                                                  │
│  WHERE 表1.列11 = '値';                                                    │
└──────────────────────────────────────┘
┌──────────────────────────────────────┐
│SELECT 表2.列21                                                             │
│  FROM 表2                                                                  │
│  WHERE 表2.列21 = '値';                                                    │
└──────────────────────────────────────┘

これに集合関数が絡んでくるとひと工夫必要なことがわかったので追記する。
┌──────────────────────────────────────┐
│SELECT 表1.列11                                                             │
│       MAX(表2.列21)                                                        │
│    FROM 表1,                                                               │
│         表2                                                                │
│    WHERE 表1.列11 = '値'                                                   │
│      AND 表2.列22 = '値'                                                   │
│    GROUP BY 表1.列11;                                                      │
└──────────────────────────────────────┘
当然ながら、結果一件なのだが「GROUP BY」がないと建て前として
集合関数との整合性がとれないので、これは(必須な場合は)必須みたいだ。
分類:SQL
HTML/テーブルタグのセンタリング
2011年09月22日
昔はCENTERタグってものがあって、以下のように囲えばOKだった。
┌──────────────────────────────────────┐
│<CENTER><TABLE>…</TABLE></CENTER>                                          │
└──────────────────────────────────────┘

でも、CENTERタグなんか使うなってことになって、以下のような感じになった。
#実はこの辺があやふや(なにせCENTERタグをバリバリ使ってしまっていたから)
┌──────────────────────────────────────┐
│<TABLE align="center">…</TABLE>                                            │
└──────────────────────────────────────┘

そんでもって、CSSってのになって以下のような形で現在に至っています。
#style属性じゃなくてstyleタグにまとめればなおいいけど、説明の便宜上こちらに
┌──────────────────────────────────────┐
│<table style="margin:auto;">…</table>                                      │
└──────────────────────────────────────┘

…ところが、IEがこれに対応していない。
ってことで、妥協案としてこんな感じになります。(ああ、ややこしい)
┌──────────────────────────────────────┐
│<div style="text-align:center;">                                            │
│<table style="margin:auto; text-align:left;">…</table>                     │
│</div>                                                                      │
└──────────────────────────────────────┘
分類:CSS、HTML
前へ 1 … 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 次へ