サクサク読めて、アプリ限定の機能も多数!
トップへ戻る
災害への備え
www.programming-magic.com
ループの中にループがあるような多重ループを抜ける場合には、C言語ならgotoを使ったり、PHPなら数値指定付きのbreakを使ったり(『多重ループを抜ける[PHP]』参照。)と特殊な方法を使うことがある。 JavaScriptでは、goto文もbreak文で数値を指定することもできないが、Javaと同じようにラベル指定付きのbreak文を使うことができる。 例えば、以下のように変数を使って2回breakしているコードがあるとする。 var break_flag = false; //多重ループから抜けるためのフラグ for(var i=0; i<5; i++){ for(var j=0; j<5; j++){ document.writeln("("+i+", "+j+")"); if(i == 2 && j == 4){ break_flag = true; break; } } if(
PHPでエラーが発生したとき、どのファイルの何行目でエラーが発生したかなどは表示されるためにすぐにわかることだが、そのエラーが自作関数の中で発生した場合、その関数がどこから呼ばれたのかを知りたいことは多い。 開発環境によっては、なんらかのソフトウェア(Zend Studioなど)の機能でそれを調べることができることもあるが、できないこともある。 実は、バックトレース(呼び出し履歴)はPHP標準の関数で表示させることができる。 表示させるだけならdebug_print_backtrace関数、配列データで取得したいならdebug_backtrace関数を使う。 <?php function test1($number){ test2($number * 3, 'これは引数です。'); } function test2($string){ print "エラーが発生しました。\n"; prin
「「@」でエラー抑制すると PHP が遅くなるという噂について : a++ My RSS 管理人ブログ」で、@がある場合とない場合で速度比較をして以下のような結果が出た。 ・・・遅い・・・遅すぎる・・・ここまでパフォーマンス悪くなるとは・・・ 細かい処理とはいえ、最大10倍違うわけですから・・・ すいません、完全なる私の敗北です。これからはちゃんと isset() とか死ぬほど使います (_o_) これに各所で反応があった。 PHPの@によるエラー抑制機能の遅さ - Blog::koyhoge 大切なのは数秒のスピードアップ?それとも? - Web屋のネタ帳 F's Garage:ソースコードは一期一会の精神で書くべし。 PHPの配列の参照とデフォルト値とE_NOTICE-なんかばんざい 眠る開発屋blog » @のエラー抑制とか 私もいくつか書きたいことがあるので、書いておくことにする。
PHPの標準関数はエラーが発生したときに文字列を表示してそれを知らせるものがあるが、詳しいエラー内容をユーザに見られてしまうと、そこから内部仕様がばれて攻撃を受ける恐れがある。 そこで、表示するエラーレベルの設定を変えることで、簡単に表示・非表示を変えることができる。 表示するエラーレベルの設定を変えるには、php.iniや.htaccessなどでerror_reporting の値を変える方法と、error_reporting関数を使う方法などがある。このとき、httpd.confや.htaccessなどのPHP外部でerror_reportingの値を設定する場合には、E_ERRORなどの定義済み定数は使えないことに注意する必要がある。 # エラー表示をOnにする php_value display_errors 1 #「E_ALL & ~E_NOTICE」を設定 php_value
「hoge○○hoge○○○○hoge○○hoge○」という文字列があり、PHP+正規表現で行頭以外にあるhogeを全てHOGEに置換して、「hoge○○HOGE○○○○HOGE○○HOGE○」としたかったのだが、やり方がよくわからなかった。 行頭にある「hoge」マッチする正規表現であれば以下のように簡単に書けるが、行頭以外にあるhogeにマッチする正規表現がわからなかったのでいろいろと試してみた。 preg_replace('/^hoge/', 'HOGE', $text); まず浮かんだのは、戻り読み言明を否定する方法だったが、どうも戻り読み言明のなかで行頭を意味する「^」は使えないらしい。 preg_replace('/(?<!^)hoge/', 'HOGE', $text);
MySQLでは以下のようなクエリーでカラムを削除する。 ALTER TABLE <テーブル名> DROP <カラム名>; ALTER TABLE test DROP flag; ALTER TABLE test DROP number; ALTER TABLE sample DROP address; 以下のようなクエリーで同時に複数のカラムを削除することもできる。 ALTER TABLE <テーブル名> DROP <カラム名>, DROP <カラム名>, ....; ALTER TABLE test DROP login_name, DROP comment; ALTER TABLE sample DROP regist_time, DROP status_id;
JavaScriptとPHPではそれぞれURLエンコード、デコードする関数を持っているが、それぞれ微妙に動作が違う。 URLエンコードする関数は、PHPには、rawurlencode関数、urlencode関数の2つがあり、JavaScriptには、escape関数、encodeURI関数、encodeURIComponent関数の3つがある。 それぞれのエンコード関数とデコード関数の組み合わせでどうなるのかを調べてみた。 JavaScriptとPHPのURLエンコード動作検証(ソース表示) 注目すべき点は以下の4つ。 urlencode関数が半角スペースを「+」に置換する escape関数だけが2バイト文字を他と違う文字に置換する encodeURI関数は置換する文字が少ない escape関数+(decodeURI関数 or decodeURIComponent関数)で2バイト文字はエラ
ある変数AとBの値を交換するとき、普通は一時変数を使って値を交換する。 例えば、C言語で整数変数のSwap関数を書くと以下のようになる。 void swap(int *a, int *b){ int tmp; tmp = *a; *a = *b; *b = tmp; } 実はこのとき一時変数(tmp)を使わずに値を交換する方法もある。 一時変数を使わずに値を交換するにはXOR(排他的論理和)を使う。 void swap(int *a, int *b){ *a = *a ^ *b; //① *b = *a ^ *b; //② *a = *a ^ *b; //③ } これは "A XOR B XOR A = B" という性質を利用したものだ。 交換する変数をAとB、その値をa,bとすると以下の表のようになる。 変数Aの値変数Bの値 初期状態
通常、ループを途中で抜ける場合breakを使うが、ループの中にループがあるような多重ループを抜けるには、C言語ならgotoを使ったり、Javaならラベル指定付きbreakを使ったりと特殊な方法を使うこともある。 PHPでは、goto文もラベル指定付きbreak文もサポートされていないので、変数を用意して2回breakしなければならいと思っている人も意外といるが、PHPではbreak 2;というように値を指定して多重ループを抜けることができる。 (※PHP6からはgoto文がサポートされるらしい。) 例えば、以下のように変数を使って2回breakしているコードがあるとする。 <?php $break_flag = false; //多重ループから抜けるためのフラグ for($i = 0; $i<5; $i++){ for($j=0; $j<5; $j++){ echo "({$i}, {$j
formからデータを送る方法にはGETとPOSTの2種類がある。 基本的にはその2種類のどちらかしか使わないが、formのaction属性に指定するURLを書き換えることで、GETとPOSTの両方を同時に送ることもできる。 <form action = "?test=1234&name=Fermat" method = "POST"> <table> <caption>GETとPOSTを同時送信</caption> <tbody> <tr><th>年齢[age]</th><td><input type = "text" name = "age" value = "45"></td></tr> <tr><th>名前[name]</th><td><input type = "text" name = "name" value = "Gauss"></td></tr> </tbody> </ta
SQLで以下のようにテーブルを結合すると、どちらか一方にNULLを含んだデータや一方にデータが存在しないものは結果として出てこない。 SELECT * FROM a,b WHERE a.id = b.id SELECT * FROM a JOIN b ON (a.id = b.id) この結合を内部結合(INNER JOIN)という。 例えば、以下のようなデータがあったとする。 > SELECT * FROM user; +----+-----------+ | id | name | +----+-----------+ | 1 | トム | | 2 | 太郎 | | 3 | エイダ | | 4 | 鈴木 | +----+-----------+ > SELECT * FROM access_log; +----+---------+---------------------+ | id
※比較の結果としてtrueが返されるところに○、falseが返されるところに空白( )を出力している。 ※JavaScriptでマウスがある行、列に色を付けて表示している。 緩やか比較(= =) true false 1 1.0 "1" "1.0" 0 0.0 "0" "0.0" -1 -1.0 "-1" "-1.0" null array() array(1) array(0) array(null) "" "php" "true" "false" "null" NAN INF true
標準入力に何かを入力させて処理をするプログラムをデバッグする場合、何度も同じ入力を繰り返すことがよくある。そんなときには入力データをファイルとして用意して、パイプとリダイレクションを使ってファイルに入出力をすると便利だが、それ以外にもfreopen関数を使う方法もある。Windows上でVisual Studioのような統合開発環境を使って開発をしている場合には、こちらの方が便利かもしれない。 例えば、以下のように、標準入力から数値を読み込んで計算結果を出力するプログラムがあったとする。 #include <stdio.h> int main(){ int n; while(scanf("%d", &n)){ printf("%d * %d = %d\n", n, n, n*n); } return 0; } このプログラムは以下のようにfreopen関数を使うことで、data.txtから
LinuxなどのOSで、新しくファイルやディレクトリを作った場合、特に指定しなければ決まったパーミッションが設定される。 ファイルであれば0644、ディレクトリであれば0755が設定されることが多い。 これは、umaskによって設定されていて、「umask」とコマンドを入力すると設定されている値が表示される。 例えば、0022が指定されていた場合、新しくディレクトリを作ると~0022 & 0777 = 0755により、0755が設定される。 PHPでは、mkdir関数の第2引数でパーミッションを指定できるが、このときumaskが0022になっているとこのディレクトリのパーミッションは0755になる。 mkdir($name, 0777); そんなときは、mkdirのあとにchmod関数を呼んでやるとパーミッションが0777に変更される。 chmod($name, 0777); または、u
右クリックされたときにJavascriptで独自メニューを表示したい場合や左クリックされたときにのみ特殊な処理をしたい場合など、稀にマウスのどのボタンでクリックされたのかを知りたいことがある。どのボタンでクリックされたかというのは、event.buttonやevent.whichで知ることができるのだが、呼ばれたイベントによって値が違ったり、ブラウザによって値が違ったりするので、主なブラウザでそれぞれのイベントについて値を調べて表にしてみた。 クリックされたときに発生するイベントには、onClick、onMouseDown、onContextMenu、onMouseUp、onDblClickがある。それぞれのイベントでのevent.buttonとevent.whichの値を、左クリック、中クリック、右クリックで調べてみた。aタグとそれ以外では挙動が違うことがあるので、aタグとspanタグで
labelタグは、inputタグと文字や画像の関連付けをして、その文字や画像をクリックしてもinputタグをクリックしたのと同じように動作させるものだが、この動作はブラウザによって違いが出ることがある。 そこでlabelタグの動作を統一する方法を考えてみる。 以下のように、inputタグをlabelタグの子要素とするとid属性、for属性を省略することができるが、IE6はこれに対応してない。 (※IE7では対応している。) <input type = "checkbox" id = "checkbox1"> <label for = "checkbox1"> ここをクリックするとチェックが付く。 </label>
mysqlコマンドでも調べることができる。 >mysql --version mysql Ver 14.12 Distrib 5.0.32, for pc-linux-gnu (i486) using readline 5.2 さらに、「mysql -u -p 」で接続すると表示される。 >mysql -u user -p test Enter password: Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 11 Server version: 5.0.32-Debian_7etch1-log Debian etch distribution Type 'help;' or '\h' for help. Type '\c' to clear the buffer.
PostgreSQLにはランダムな数値を取り出すRANDOM関数があり、これを使うことにより、テーブルからランダムにデータを取り出すことができる。 RANDOM関数は以下のように0以上1未満の値をランダムで返す。 > SELECT RANDOM(); random ------------------- 0.322386509888985 (1 row) > SELECT RANDOM(); random ------------------- 0.677151894977853 (1 row) これを使ってランダムにデータを取り出す。 例えば、以下のデータがあるとする。 > SELECT * FROM book; id | title ----+---------------------- 1 | 赤ずきん 2 | ブレーメンの音楽隊 3 | 白雪姫 4 | シンデレラ 5 | ヘンゼル
AUTO_INCREMENTの値をリセットするには以下のようにALTER TABLEでできる。 ALTER TABLE <テーブル名> AUTO_INCREMENT = 1; ALTER TABLE test AUTO_INCREMENT = 1; ALTER TABLE sample AUTO_INCREMENT = 1; このとき、AUTO_INCREMENTの付いたカラムに1以上の値を持ったレコードが存在すると、その値以下には設定できない。 例えば、以下のようなデータがあると5以下には設定できないが、6以上には設定できる。 > select * from newspaper; +----+--------+ | id | name | +----+--------+ | 1 | 毎日 | | 2 | 読売 | | 3 | 毎日 | | 5 | 日経 | +----+--------+
PHPは、プログラムをHTMLの中に埋め込むように書くことができるというのが利点の一つである。 単純にHTMLに文字を出力するコードを埋め込む場合、以下のように書く。 <?php echo 'xxxx'; ?> これは、short_open_tagの設定がonになっていると、以下のように書くこともできる。 <?= 'xxxx'; ?> さらに、最後の「;」を省略して以下のように書くこともできる。 <?= 'xxxx'?> ただし、以下のように書くことはできない。 <?php= 'xxxx'; ?> この省略記法は便利ではあるが、short_open_tagをonにすることで、 <?xml version="1.0"'; ?> などがphpコードと認識されてしまうため、わざわざ以下のように書かなければならなくなる。 <? echo '<?xml version="1.0"?>'; ?> また
「PHP 省略できる参照渡しの引数 - JE no hitori chat」によるとPHP4.4.2では、参照渡しの引数にデフォルト引数を設定して、引数を省略することはできなかったらしい。こんなこと試したことがなかったので、PHP4.4.4とPHP5.2.0で試してみた。 以下のように、参照渡しの引数にデフォルト引数を付けた関数をテストしてみる。 <?php //参照を引数に取る関数 (省略可) function test(&$arg = null){ echo '<div>function: test($arg)</div>'; if($arg == null){ echo '<div>引数は省略されました。</div>'; } else{ echo "<div>\$arg: $arg</div>"; $arg = "「{$arg}」は変更されました。"; } } //初期状態 $str
会員制の掲示板のように、ユーザが登録し利用するWebサービスを提供する場合、認証のためにユーザのパスワードを保存・管理することが多い。 このとき、パスワードを平文で保存(暗号化などをせずにそのまま保存)していると、管理者や開発者などにはパスワードを見ることができてしまう。 管理者や開発者に悪用する気がなかったとしても、パスワードの漏洩などにより誰かに悪用されてしまう危険性がある。 その対策として、パスワードを暗号化するという手もあるが、復号されてしまう危険性もある。 そこで、パスワードをmd5やsha1のような不可逆な変換(変換したものから元に戻せない変換)をして保存する。 認証のときには、「md5(sha1)で変換して保存したパスワード」と「入力されたパスワードをmd5(sha1)で変換したもの」を比較して一致するか調べる。 これで仮に変換して保存したパスワードが漏れたとしても、不可逆
ユーザのブラウザの種類を判別する情報として、以下のようなユーザエージェント名が取得できるが、これを見ても知らなければ詳しい情報がわからない。 Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1) Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727) Sleipnir/2.6.1 Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727) Mozilla/5.0 (Macintosh; U; Intel Mac OS X; ja-jp) AppleWebKit/523.12.2 (KHTML, like Gecko) V
JavaScriptを使えばテーブルのセルをドラッグで選択するようなインターフェースを作ることもできる。 Google カレンダーでは、それをうまく利用し、ユーザに簡単な操作でわかりやすく特定の期間(2日の3時~9時など。)を選択させている。 テーブルのセルをドラッグで選択するサンプル テーブルのセルをドラッグで選択するには、ドラッグを開始した位置にあるセルと現在の位置にあるセルを取得し、マウスの動きに合わせてセルの色を変更すればいい。 まず、セルの選択をさせるtableのonMouseDownイベントで以下のような関数を呼び、ドラッグを開始したセルを保存する。 var startCell = null; // マウスダウンのイベント処理 function mouseDown(table, e){ if (!e) var e = window.event; startCell = e.sr
PHPでは2つの配列を合わせるのに、「+」演算子で行う方法とarray_merge関数で行う方法がある。 2つの方法は全く同じ動作をするわけではなく、いくつかの違いがある。 例えば、以下のような2つの配列があるとする。 $array[0] = array( 1 => '伊藤博文' 2 => '黒田清隆' 3 => '山縣有朋' '?' => '小渕恵三(1)' ) $array[1] = array( '?' => '小渕恵三(2)', 85 => '森喜朗', 87 => '小泉純一郎', 90 => '安倍晋三', ) このデータを+演算子で加算をすると以下のような結果が得られる。 print_r($array[0] + $array[1]); Array ( [1] => 伊藤博文 [2] => 黒田清隆 [3] => 山縣有朋 [?] => 小渕恵三(1) [85] => 森喜朗
PHPは、echo,printやprintf関数など様々な方法で文字列を出力して、その結果をブラウザに表示させることができる。 このとき出力される結果が、あまり変化することがない場合、あらかじめその出力結果をHTMLファイルに出力しておいて、それを表示させる方が処理が減って効率が良くなることがある。 例えば、ブログでは投稿回数に対して、閲覧回数の方が明らかに多い。投稿などがされない限り、出力結果に変化はない。 さすがに、全てのページを生成しないにしても、閲覧回数の多いトップだけでもHTMLファイルにしてユーザに見せれば、サーバへの負荷は減るはずである。 ページの更新は、投稿があるたびにPHPでHTMLファイルを出力させればいい。 こういった処理をさせるために、PHPファイルを書き換えるとなると、echoやprintをfwrite関数などに全て書き換えなければならないと思うかもしれない。 し
doctestモジュールは、テストコードとその結果をコメントとして書くことで自動的にテストを行ってくれるものだ。テスト用のコードは一度確認した後は、保存することすらしなかったり、しばらくして消してしまったりすることもあるが、doctestのようにコメントにテストコードを書けば、それは実行例としてコメントに残るし、コードを変更した場合にはそれを使ってテストができる。 例えば、与えた引数xを2倍にして返す関数では以下のようになる。 #!-*- coding:utf-8 -*- def double(x): """ 与えられた数の2倍を返す関数。 >>> double(3) 6 >>> double(10) 20 >>> double(8) 16 """ return x * 2 if __name__ == "__main__": import doctest doctest.testmod(
次のページ
このページを最初にブックマークしてみませんか?
『Programming Magic is under construction』の新着エントリーを見る
j次のブックマーク
k前のブックマーク
lあとで読む
eコメント一覧を開く
oページを開く