« 2012年1月 | トップページ | 2012年3月 »

2012年2月の29件の記事

2012.02.29

[javascript] 和暦変換サービス

和暦ってたまに必要になって、やっつけで変換処理を書くことが多い。日本全国津々浦々、いろんなところで別々に書かれているんじゃないかな。でも結果が変わるはずは無いのだから、世界に唯一そういうプログラムがあればよいってことで、ワンネンドンリーな和暦変換のWEBサービスでも書いておこうかとやってみた。JSONPをやってみるとか、そういう目的もあったのだけど。

とりあえず、xmlを返すAPIもあるのだけど、javascriptでお手軽に使えるバージョンを。内部的にはJSONP使っているので、クロスドメインOKです。

上のコード

<script type='text/javascript'
  src='http://bicycle.life.coocan.jp/takamints/js/takamints.js'>
  </script>
<button
  onclick="toWareki();"
  >2012-02-29は和暦では?</button>
<script type='text/javascript'>
function toWareki() {
  takamints.toWareki(
    '2012-02-29',
    function(wdt) {
      alert(wdt); 
    }
  );
}
</script>

今のところ、フォーマットはひとつだけだけど、いろいろバリエーションが作れますね。逆変換とかも、必要かもね。ちゅうか、このサービス自体にホントに需要があるのかどうかは疑問だけど。ま、とりあえず、こんなことも出来るということで勉強にはなった。

「今までコールバックがグローバル領域の関数しか呼べねーんじゃJSONPなんて使えねー」という人だったのですが、専用のコールバック関数を提供すればなんてこたーないんだなと気がついて。動的に生成したSCRIPTを後で削除するためにIDを生成していたんだけど、これをキーにしてユーザー定義のコールバックを登録しておけば、後で呼び出せるわけですよ。

2012.02.28

[php] PHPExcelで幅と高さを指定して画像を貼り付ける

帳票出力にPHPExcelを使っているのですが、本日、画像の縮尺変更で少しはまったのでメモしておきます。

画像の幅と高さをsetWidth()とsetHeight()で自由に変更して(アスペクト比を無視して)シートに貼るときは、先にsetResizeProportional(false)で、縦横比を保持しないように設定しましょう。ってことなんです。ソース読んでわかりました。

↓の例。たとえば images/hoge.png が640x480pxの画像だとして、これを 50x50 に縮小してエクセルに貼り付けたい場合、単純に以下のようにやってもうまくいきません。画像オブジェクトがデフォルトで元画像の縦横比を保持するようになっているため、あとから呼び出しているsetHeightで幅も設定されてしまうためです。

$d = new PHPExcel_Worksheet_Drawing();
$d->setPath('images/hoge.png');
$d->setWidth(50);
$d->setHeight(50);
$d->setWorksheet(
    $excel->getActiveSheet());

望み通りの結果を得るには、以下のように先に setResizeProportional(false) と呼び出して縦横比を保持しないように設定する必要があるんですね。

$d = new PHPExcel_Worksheet_Drawing();
$d->setPath('images/hoge.png');
//↓これが必要
$d->setResizeProportional(false);
//↑これが必要
$d->setWidth(50);
$d->setHeight(50);
$d->setWorksheet(
    $excel->getActiveSheet());

ちなみに、PHPExcel_Worksheet_Drawing(正確には基本クラスのPHPExcel_Worksheet_BaseDrawing)には、 setWidthAndHeight というメソッドがありますけど、これは縦横比を保持する設定でしか動作しません。指定した幅と高さにうまく収まるような大きさに縦横比を保持したまま収めるためのメソッドのようですな。縦横比を保持しないようにしていると、見事に何にもしないで帰ってきますw

PHPExcelはソースを読むと妙な面白さがあって不思議と腹が立たない。とても良いことですね。

2012.02.27

これからどうなる

土曜日は暖かかったのに、日曜からガンガン寒くなって今日なんて雪。明日なんて氷点下?東京マラソン観戦で疲れたのか(笑)時を同じくして、一時的に良くなっていた風邪もぶり返す。というか引きなおした感じ。声がとっても痛いのよ。もう2週間になるがいつ治るかもう分からん。

長年、家近く、駅近くにあったコンビニが、数百メートル西の、おそらく極端に人通りの少ない場所へ移転するため本日最終日(29日開店)。「どう考えても客が減る」と地元では全員首をひねって歩いている(ウソ)。自動車は入りやすくなるみたいだが歩行者の場合は少し危険を感じるくらいの場所ですねん。ホントに不可思議な移転だが、とにかく不便になるのがなんともね。

AIJにはもとより悪意があったのだろうか?エルピーダの巨大破綻はなにかのハジマリなのか?自称占い師の洗脳からナカジマさんが逃れるには?近くのコンビニの行く末は?

いろいろ気になる年頃である(一部除外)。経営ってとってもムツカシイのでしょうね(一部除外)。

いやしかし、コンビニ跡地(駅前一等地)がなんになるのか?それが一番気になるな。

2012.02.26

東京マラソンでアドレナリン

たまたまテレビつけていたら東京マラソンやっていて、先頭が20キロ過ぎだった。ちょうど面白い展開が始まったところのようで、結局最後まで目が離せなかった。

駆け引きとか各選手の思惑や状況や努力の結晶とか背負っている期待とか意地とかも含めて、なんとおもしろきスポーツよ(←意味なく清盛風味)と興奮。

従来マラソンや駅伝のテレビ中継は退屈な気がして見なかったのですが、自分でちょっと走るようになってからは、あのスピードの「凄み」ってやつを感じるようになったかもしれん。自分の倍のスピードだもんな。全力疾走でもあのスピードは出ないもん。それで2時間て。しかもゴールしてすぐに笑顔でしょ。あーこわ。

見終わって少し走りたくなった(影響されやすいw)が、昨日の軽いジョグで太ももの表側に軽く筋肉痛が出ていたので、やめといた。

そろそろ朝ラン再開したいが、まー、ゆっくり行こう。

↑この「非常識シリーズ」(?)最近よく見かけます。

2012.02.25

雨の日ウォーク&ラン

今日は月一度の眼科の検診。眼圧が高いので毎月チェックに行っております。

いつもは自転車でピッと行って帰ってくるのだが、今朝はあいにくの雨。自宅から眼科までは3.5kmなんだけど、電車を使うと2キロ以上歩くことになり、電車待ちで余計に時間がかかるので、歩いてみることにした。

ユニクロジーンズ、アディダスのランニングシューズ、ウィンドブレーカーはパールイズミというわけのわからん恰好(笑)で、だいたい1キロを9分から10分のペースで歩く(けっこう早歩きですな)。

たいして降っていないが地面はしっかり濡れていた。風景的にもなんだか面白い気がして、なんてこたーない街路樹とかとってみたり。

いつもは人であふれかえっている眼科も、この雨のせいで人がまばら。いつもなら1時間待ちとかあるのに、今日はすぐに呼ばれてちゃっちゃと終了。

眼圧は両目とも17mmHgで完全標準範囲ど真ん中。いつもは範囲の上限ギリギリだったり、超えていたり(目薬を差していてコレなので問題なのね)するので、コレを快挙と云わずして何と言おうかオドロイタ。歩いたのが良かったのかもしれない。バチット決めて自転車だと、なーんとなく頭に血が上っている感じで眼圧も高くなっているような気がするしなー(あ、医学的根拠は無いですイメージですよ)。

帰りも歩いていたんだけど、雨がほとんど降っていなかったので、しんぼうたまらずビニ傘閉じて抱えてちょっとジョグ♪。久しぶりの有酸素運動にカラダが喜んでいる感じだった。

明日晴れたら久しぶりに本気走りしたいなー。雨でも合羽着て走るのはアリですね♪

2012.02.24

[php] 日付演算 DateTime/DateIntervalのうるう年対応

仕事で関わっているシステムで、日付の演算(一日あととか一ヶ月前など)でDateTimeクラスとDateIntervalクラスを使っていたのですけど、うるう年に対応していなくて声を上げて驚いた。

2012年3月1日の前日を取得するコード。

$d = new DateTime();
$d->setDate(2012,3,1);
$d->sub(new DateInterval('P1D'));
$t = $d->getTimestamp();
echo date('Y-m-d', $t);

出力結果はまさかの2012-02-28。これはいろいろな局面でまずいでしょ。見間違いかと何度かやってみたがダメ。

仕方が無いので別なやり方。以下のような記述が出来ることを発見して事なきを得た。この「演算内容を文字列として書く」というところがイヤなんだけど、まー仕方がない。このほうが短くなるし。

$t = strtotime("2012-03-01 -1 days");
echo date('Y-m-d', $t);
//出力結果  2012-02-29

しかし、こんな単純なバグがあるもんか?と自宅でやってみたら正しい結果。バージョン違いかな。ちなみにホスティングしているサーバーでは、DateTimeが使えなかった(笑)。

いろいろ勘案すると、DateTime/DateIntervalは使わないほうがよいのかな。ちょっとイカレタ仕様だし(笑) ― 特にDateIntervalのコンストラクタとか目を疑うしw

2012.02.23

減量と引き換え

先週からの風邪は大してひどくもならず、ちょっと長いけど順調に治りかけ?と感じていたところ、7日間処方されていた薬が切れたとたんにノドが痛くてゴホゴホ・・・

ジブンの場合、風邪をひくと満腹中枢がやられてしまうのか大いにバカ食いするようになって、「食べる⇒太る⇒治る(風邪が)」というすばらしくシアワセなプロセスをたどります。

しかし、今回はかなり本気の減量中ということもあって、食事量について十分に制御していたら、長引く&ぶり返し。あかんがな。

体重は年明けから2.5キロほど減っていてかなり順調なので、「これならランも自転車も楽やろな♪」と週末、久しぶりに運動したいと思っていたが、、、無理かな。残念xxx

2012.02.22

家庭内グルメが二度おいしい

今週は長男さんの高校(調理関連)で作品展やらなんやら催し物があるため、お休みだったり昼までだったり。

ということで、これ幸いと、家内が長男さんに晩御飯をお任せしていて、昨日も今日も晩御飯を作ってくれているのだが、なんというのかそれぞれ丁寧な逸品でね。親が言うのもなんだけど非常に旨い。

昨日はかぼちゃの肉詰めが優しくて圧巻。今夜はポテトとチーズの肉巻きというのかな。これもやわらかくて優しくって素晴らしい。

時間があるから、一般的な家庭料理より時間をかけているようだ。味わいながら、次はここをこういうふうにすればまた違ったおいしさになるかもねなんて、決してグルメな家庭じゃないが、いろいろ話が広がるもんで、ありがたい話だ。

次の日のお弁当にもこれらを入れてくれるので、親父は二度おいしくて「嗚呼!シアワセ」である。

2012.02.21

MySQLのDISTINCTとCONCATで日本語文字列が変になる。

mysql(5.1)で、以下のSQLで末尾の「年」が表示されなくて困ってた。

何が悪いんだかわけわからん。

SELECT DISTINCT
  CONCAT(
    YEAR(date_begin),
    '年') as y
FROM table

いろいろ複雑な事情があるのでしょう。DISTINCTしなかったり、YEARを使わなかったり、'年'を'NEN'に変えてみるとおかしくならない。ちなみにYEARじゃなくってMONTHでもダメ。場合によっては「SYNTAX ERROR」が出たり。

しばらく困っていたけど、解決法は単純。なんてことはない、明示的にCASTするだけ(↓)

SELECT DISTINCT
  CONCAT(
    CAST(YEAR(date_begin) AS CHAR),
    '年') as y
FROM table

暗黙のキャストが行われるとうまく行かないってことかもしれんが、DISTINCTとの関係は不明なまま・・・。なにより、このバグっぽい挙動に困ってた人が、自分だけっぽくて孤独・・・

2012.02.20

HTML要素のイベントハンドラを自動登録

リッチクライアントなWebアプリを作るときなど、1ページでたくさんのイベントハンドラ(onclickなど)を扱う場合、いちいちひとつずつ設定するのは大変ですし楽しくない。

こんな機械的な作業は自動的にやりましょう(jQuery必要です)。

mypage.html:とりあえずボタン置きます。

<script
  type='text/javascript'
  src='page.js'>
</script>
<script
  type='text/javascript'
  src='mypage.js'>
</script>
<!-- ボタン要素 -->
<button id='btnSample'>
自動登録されたボタン
</button>

page.js:ページロード時にボタンエレメントを探して、idが付けられていて「id+イベント名」的なメソッドがあるなら、bindします。

//Webページ基本クラス
Page = function () {}
Page.prototype.init = function () {
  var THIS = this;
  $('button').each(function() {
    var elm = this;
    if(elm.id) {
      $.each(['click'],
        function(i,evt) {
          var fxn = THIS[elm.id+'_'+evt];
          if(fxn) {
            $(elm).bind(evt,function() {
              return fxn.call(THIS, elm);
            });
          }
        });
    }
  });
}

mypage.js:具象的なイベント処理は派生クラス側に記述。

//Pageを継承したMyPageを定義する
MyPage = function() {}
MyPage.prototype = new Page();

//'btnSample'のクリック処理
//thisはMyPageのインスタンス
MyPage.prototype.btnSample_click =
function(element)
{
  alert(element.id + ' clicked');
}

$(function(){
  //Webページのインスタンス生成
  var page = new MyPage();
  //ページの初期化
  page.init();
});

HTML要素にID付けて、そのIDを利用した名前のメソッドを定義すれば勝手にbindされるわけで、同じ名前を何度も正確に書く手間から開放されます。

上の例ではbuttonのclickだけですが、他のHTML要素の他のイベントにも使えます。onsubmitとかonchangeとか。

2012.02.19

クッキーでちょっと困った件

先日TwitterAPIとOAuth認証の調査目的で作ってみたツイッターのアプリですけど、いちいちブラウザを立ち上げて認証を通すのがアレなのでアクセストークンとアクセストークンシークレットをクッキーに混ぜてクライアント側に保存しようとしたら、いろいろ本題と外れたところでつまずいて、まー困ったというか、勉強になったというか・・・。

まず、クッキーのパスの問題。IE9の場合、ここで書いたような(実ファイルのスクリプト以降にも架空のパス要素がつながるような)URLをsetcookieの第四引数(path - クッキーを有効としたいパス)に与えたら、受け取ってはくれるけど、返してくれないようだった。

↓IE9は受け取っても返してくれない?…(動いているスクリプトはindex.php)

//クッキーをあげる
setcookie(
  "cookiename", 
  "$acc_tok,$acc_tok_secret",
   time() + 60*60*24*14,
  '/app/index.php/module/action/',
  $_SERVER["SERVER_NAME"])

当初、なにが問題なのかわからなかったのですが、ためしに'/'を与えてみたら、すんなりOK。Ffirefoxでは問題なかったんだけど、どっちが正しい動きなんだろう。

もういっちょ、上の問題解決過程でわかったクッキーの管理上の問題(大きな問題ではないけれど)。Firefoxでしか確認していないのだけど、同じドメインの同じ名前のクッキーでも、上で書いた有効パスが違っていると、別物として保存されているようだった。先に詳細な(下位の)パスを指定して食わせておいて、あとからパスを(より上位の)'/'に変えてサーバーからのsetcookieによって削除しても、最初のクッキーは削除されず、毎回古いクッキーが送られてきていた。結局ブラウザ側から個別にクッキーを削除して解決したけど、同じドメインで同じ名前のクッキーなら上書きしてくれたらいいのにね。これは仕様なのだろうか。

サーバー側のプログラムでもクロスブラウザに関して気を使わなくてはならないのですな。

2012.02.16

S・N・S

FB覗いてびっくりした。

1月9日に中学校の同級生からメッセージが来ていたのに、1ヶ月以上放置していた。すまん。

強烈にかしこまった文面が笑えるけれど、最近の実名SNSで同姓同名を見つけたときのことを思えば理解できる。自分もそういうの何回か送ったことあるし。みんな思うところはおんなじか。

自分にビートルズを教えてくれた本人で、たしか姫路に住んでいる。なかなか近くなのに会うことも無く20年以上か。おもろいもんやなーと。

いいね!SNS。

2012.02.15

Twitterアプリを試作してみた

今日は風邪ひいて仕事を休んだ。昨日の朝から感じていた喉周辺の痛みが悪化。昨夜は酒を控えてみたが効果が無かったようである。飲めばよかったね。

喉は痛いが熱は出ず、寝込むわけでも無い。夕方くらいから頭脳明晰(でもないか)で少々退屈。なのでPC立ち上げてなにしよう・・・と考え、「あ、せやせや長い間放置していたTwitterアプリに手をつけてみよう!」ということになった。1年ほど前かな?「OAuth認証ってなんじゃらほい?」とコチョコチョしていたものなんだけど、当時は結局、認証を通せず「わけわからんわー」と放置していたもの。でも今日は軽く認証を通せて、タイムラインも見えて、つぶやけた。めでたい。

アプリケーションとしてはまったく形にはなっていませんし何をするにも不便この上ないブツなので公開はしませんが、自作のなんちゃってPHPフレームワークのなんちゃってアクションクラスの中身だけここに貼っておきましょう。いろいろ創造をたくましくしてくださいな。

<?php
/**
 * インクルードパスを追加
 */
function add_include_path($path) {
	ini_set(
		'include_path',
		ini_get('include_path') .
		PATH_SEPARATOR .
		$path);
}
add_include_path('sys/ext/Net_URL2-2.0.0');
add_include_path('sys/ext/HTTP_Request2-2.0.0');
add_include_path('sys/ext/HTTP_OAuth-0.2.3');
add_include_path('sys/ext/Services_Twitter-0.6.3');

require_once('HTTP/OAuth.php');
require_once('HTTP/OAuth/Consumer.php');
require_once('Services/Twitter.php');
require_once('conf/twitter.conf');

class Actions {
	public $is_oauth = false;
	
	/**
	 * コンストラクタ
	 */
	public function Actions() {
		$this->is_oauth = $this->isOAuth();
		if($this->is_oauth) {
			$this->access_token =
				$_SESSION['access_token'];
			$this->access_token_secret =
				$_SESSION['access_token_secret'];
		}
	}
	
	/**
	 * トップページのアクション。
	 * アプリ認証のURLを表示する
	 */
	public function execute_index($request) {
		$consumer = $this->getConsumer();
		$consumer->getRequestToken(
			'http://twitter.com/oauth/request_token',
			CALLBACK_URL);
		$_SESSION['request_token'] =
			$consumer->getToken();
		$_SESSION['request_token_secret'] =
			$consumer->getTokenSecret();
		$this->auth_url =
			$consumer->getAuthorizeUrl(
				'http://twitter.com/oauth/authorize');
	}
	
	/**
	 * 認証完了後にリダイレクトされるコールバックアクション。
	 * verifierでアクセストークンを取得してセッションに保持。
	 * 表示内容はパブリックタイムラインやホームのタイムラインを
	 * 表示するアクション(下にある)へのリンクを表示。 
	 */
	function execute_callback($request) {
		$this->verifier = $_GET['oauth_verifier'];
		$consumer = $this->getConsumer();
		$consumer->setToken(
			$_SESSION['request_token']);
		$consumer->setTokenSecret(
			$_SESSION['request_token_secret']);
		$consumer->getAccessToken(
			'http://twitter.com/oauth/access_token',
			$this->verifier);
		$_SESSION['access_token'] =
			$consumer->getToken();
		$_SESSION['access_token_secret'] =
			$consumer->getTokenSecret();
	}
	
	/**
	 * つぶやく。
	 */
	function execute_tweet($request) {
		$this->status = $request['tweet'];
 		$twitter = $this->getTwitter();
		$this->response =
			$twitter->statuses->update(
				$this->status);
	}
	
	/**
	 * 自分(認証を受けた人)のタイムラインを表示する。
	 */
	function execute_showHomeTimeline($request) {
		$twitter = $this->getTwitter();
		$this->timeline =
			$twitter->statuses->home_timeline();
	}
	
	/**
	 * パブリックタイムラインを表示する。
	 */
	function execute_showPublicTimeline($request) {
		$twitter = $this->getTwitter();
		$this->timeline =
			$twitter->statuses->public_timeline();
	}
	
	/**
	 * Services_Twitterのインスタンスを返す。
	 */
	private function getTwitter() {
		$oauth = $this->getOAuthConsumer();
		$twitter = new Services_Twitter();
		$twitter->setOAuth($oauth);
		return $twitter;
	}
	
	/**
	 * 認証されているかどうかを返す。
	 * セッションでチェックしているに過ぎない。
	 */
	private function isOAuth() {
		return (
			array_key_exists(
				'access_token',
				$_SESSION)
			&& array_key_exists(
				'access_token_secret',
				$_SESSION)
		); 
	}
	
	/**
	 * 認証されたOAuthコンシューマーを返す。
	 */
	private function getOAuthConsumer() {
		$oauth = $this->getConsumer();
		$oauth->setToken(
			$this->access_token);
		$oauth->setTokenSecret(
			$this->access_token_secret);
		return $oauth;
	}
	
	/**
	 * 認証されていないOAuthコンシューマーを返す。
	 * CONSUMER_KEYとCONSUMER_SECRETは、
	 * twitter.confで定義している。
	 */
	private function getConsumer() {
		return
			new HTTP_OAuth_Consumer(
				CONSUMER_KEY,
				CONSUMER_SECRET);
	}
}

いろいろ突っ込みどころが満載のソースだと思いますが、今後徐々に手を入れて行きたいなと。フレームワーク側もイロイロ機能増強が必要だし。

以前の失敗要因は、勘違いとバージョン違いでした。OAuth認証通すためにはServices_Twitter意外にイロイロ必要で、しかもServices_Twitterのバージョンが古かったという不始末。あら恥ずかしいですね(笑)。しかし、今でも「Services_Twitter」でググったら、古い0.4.0の情報が出てくるので無理も無い。最新はPEARから取ってこなアカンのですね。勉強になりました。

それから以前はフレームワーク的なアプローチをしていなかったので、ごちゃごちゃになってしまったというのも大きな要因。

フレームワーク万歳

2012.02.14

前向いて歩けば楽しいものだ


photo credit: Maxwell GS via photopin cc

「うちの子、自閉症?」と思ったときは、暗闇に一人で放り出されたような気分だった。どこへどう進んでよいかわからないし、周りはまったく見えないし。明かりをつければ、もしかしたら隣に何か見えるのかもしれないが、もしかすると、何にも無い暗闇が広がっていたりして・・・などとビビッて何にも出来ない状況ね。

重度の障害だとそういうことは無いのかもしれないけど、軽度発達障害の場合は、そういう状況に陥っちゃう人が多いんじゃないかな(勝手な想像ですが)

まーとにかく不安と確信が徐々に高まりながら、家族にも誰にも相談しないで、2歳9ヶ月から4歳5ヶ月の1年半くらい、そんな状態だったのね。

でも、この悶々とした期間が自分にとってまったく無駄だったかと言うと、そうでもないと思うのね。最初は「自閉症だったらどうしよう~」なんて、ちょっと軽めにウロウロしているだけ。でも、最終段階ではぐぐっと深みに落ち込んだあと、「自閉症でもそうでなくても別に自分は親として『どうもしない』よな。なんにも変わらん」と思うようになっていた。

この心境に至るプロセスってのが、実はむしろ重要なんじゃないかと思うのだがどうだろう。自分はこの期間内、それ以降よりも多く、自閉症や発達障害について「冷静で幅広い客観的な知識」を欲していました。そのおかげで抜け出せたとも思う。

もし、似た状況の人がいるなら何かの足しにしてもらえればと書きました(伝わってないかもしれないけどw)。先日も同じようなことを書いているけど、もうちょっと的を絞って書いておきたかったのね。

で、ここまで書いて、自分で何が言いたいのかわかってきた気がするので書いておく(頭悪い感じw)。
社会や生活の楽しさや厳しさ、幸不幸の差なんて言うのは、家に障害児がいるかどうかには関係ないからね。得てして不幸のヒーロー/ヒロインになってしまいがちだけど、そこを間違わないようにしたいやねー。
と、そういうこと(笑)

2012.02.13

ここが踊り場正念場


photo credit: MarcelGermain via photopin cc

最近、寒がり&冷え性になった気がする。単純に気温が低いのもあるだろうけど、先週末から体重を一気に減らした影響もあるのかな。

それと日中にだるさを感じる。奥のほうに蓄積しているエネルギーをうまく出せていないような。。。

ダイエット的には「あー来た来た♪これこれ!」と熱烈歓迎。踊り場状態なので、カラダさんがリバウンドをあきらめる瀬戸際という所かと。燃料消費しろ>カラダ

以前の記憶では、数日で慣れると思うんだけどね。

2012.02.12

粉もん担当

土曜の晩ご飯はたこ焼きだった。

たこ焼きは、粉の説明に書かれているよりも、シャバシャバにした方が良いと思うのだが、うちのホットプレート付属の少し大きめの穴ぼこでは、時間がかかる。

夕方5時から焼き始め、飲まず食わずで(日本酒は一合呑んだが)フッラフラになりながら最終的にご家族様ご一同が、晩ご飯として満足される分量を焼き終えたのは、なんと8時半だった。焼きあがれば皆さん次から次へと食べられるので、作業終了時点で残っているのは、自分の分だけ。

ほっとして手元がぐらつき青海苔さんが一年分・・・

タコを食べるのはジブンとムスメだけ。代わりにチーズを入れたりしているけど、今回マグロをサイコロに切って入れてみた。ちょっと前にテレビでやってた。普通に旨かったらしい(私は喰っていない)。が、やはりたこ焼きはタコだな。

日曜日には危うくピザを打たされそうになったが、あれは半日仕事なのでやばい。今回は必死の抵抗で難を逃れた。また今度。うどんも打ちたいな(←年中言ってる)

2012.02.11

小1次男の参観日


photo credit: BLW Photography via photopin cc

次男君の小学校の「授業参観」に行ってきました。送り迎え(特別支援学級へ行っておりますので)を含めて小学校へ三往復(笑)。一年のうちで一番寒い時期だと思うが、目を疑うような服装の児童を見たりしてこっちがブルブル。小学生のあの元気は発電に使えないのか?

学校に着くなり次男の名前を呼んで駆け寄ってくれる子がいたりしてニッコリ。呼ばれた本人はそちらを見ながらも、知らぬ存ぜずで下駄箱へ行っちゃってこっちがあせる。ゴメンネ、予定外の突発イベントは理解できないような構造になっております。ご理解くださいな。

最初は普通学級での授業。児童全員が「こんなことができるようになりました」と発表。次男君は計算カードで計算をしていました。もじもじしながらもしっかりと発表。実はコチラがドキドキしていましたが、お友達に問題を出すようなシーンでは元気よく手を上げていましたし、とても発達障害児には見えませんでした。

ただ、他の子は「ボクは1学期のときは○○が出来なかったけど、3学期になってできるようになりました。見てください」なんてパターンで発表しているんだけど、次男君は「ボクは数字が好きなので計算します」という程度(笑)。次男君、いつから足し算や引き算が出来るようになったかを覚えていないだろうから(幼稚園の年少では既にやってた気がする)、そう言うしかなかったのだろうね。とりあえず周りに合わせて、うまく取り繕うことが出来ないという感じ。別に問題があったわけじゃないけど、そういうところに自閉症の特性(特徴?)を見た気がした。「あーなるほどねー」って感じ。

なにより落ち着いて誰にも迷惑をかけず普通学級で授業を受けられているのを目にして、先生方やお友達と、よい信頼関係が結べているのだろうと感じました。大きくなるに従ってその辺がどうなっていくのかは少し心配なのですが。

次は特別支援学級での発表会。一年生から三年生の全員で、詩の音読やハンドベルの演奏(キラキラ星で「ラ」担当)。コチラは親との距離が近くて変に意識していたのかソワソワしていた(普段からそうなのかもしれないけど)。ハンドベルの後半、どこかに意識がいっちゃってたのか、重要なところで2音抜きw。そこ鳴らさないとあんまり出番は無いのだがwww。でも自分が間違えたところをよく理解していたようで、ならちゃんとやりなよーと思いましたが、まーよく頑張った。演奏のあとはみんなで「おおあらし」という椅子取りゲームみたいなのをやって終了。

親のほうが緊張した感じの参観日だった。

2012.02.10

PHPで「なんちゃって静的URL」

ジブン用にsymfonyライクで軽量なフレームワーク的なる物をササッと作ろうとしているんだが、契約しているホスティングサーバーではURLの書き換えが出来ず、本質的な問題ではないけど、それでもモジュールやアクションを

http://host/app/index.php?m=module&a=action

などと指定するのは、どう考えてもイケてない。。。と思っていたところ。。。

http://host/app/index.phpに対して、

http://host/app/index.php/module/actionというリクエストをしても、ちゃんとindex.phpが動いて、且つ、要求どおりの(後者の)URLを参照でき、さらに普通のパラメータもちゃんと受け取れる。。。と、昨日はじめて知りました。

「百歩譲ってコレは使える」と書いてみた↓

//URLからモジュールとアクションを抽出
$sma = $_SERVER['PHP_SELF'];
$sma = preg_replace(
  '(^.*/index\.php)', '',
  $sma);
$ma = explode('/', $sma);
while(count($ma) < 3) {
  $ma[] = '';
}
if($ma[1] != '') {
  $module = $ma[1];
}
if($ma[2] != '') {
  $action = $ma[2];
}

//HTMLのbaseディレクトリを決定する
$n = substr_count($sma,'/');
$base_dir='';
for($i = 0; $i < $n; $i++) {
  if($base_dir != '') {
    $base_dir .= '/';
  }
  $base_dir .= '..';
}
$base_dir .= '/';
$base_dir .= $module;
$base_dir .= '/';
$base_dir .= $action;

ベースディレクトリの指定はオプション的なものなんだけど、たとえばモジュールとアクション以降にも静的アドレス的なURLをパラメータ的に続ける仕様にしたとき、強制的にモジュールとアクションの位置にHTMLのベースアドレスを持ってくるために必要。

あんまりやりすぎるとフレームワークが軽量じゃなくなってきそう(笑)

2012.02.09

設置数制限のある広告をココログベーシックの記事下に自動配置


photo credit: Darwin Bell via photopin cc

script要素で提供されている広告をブログの各記事の下などに貼りたい。しかし1ページ内の設置数の上限が設けられていて、記事に直接書いてしまうと、複数並ぶトップページで上限を超えちゃう可能性がある。

このブログはココログベーシック。レイアウトを自由に編集できないみたいなので「ページが表示された時、javascriptでブログレイアウトの特定要素(コンテンツのヘッダーやフッター部分)にscriptを生成すればよいのだな♪」と簡単に思った。が、なかなかこれがうまくいかんかった。スクリプトが書かれても中身が実行されないとか、クロスブラウザ的問題とか、deferってなにそれおいしいの?とか

頭の片隅ではモヤモヤしながら結局、そのまま一ヶ月近く放置してましたが、昨日、まさにあきらめかけていたその時、「パッと光明」頭が光る。

「div要素の中にscriptを直接書いてdivを丸ごと移動させればいいじゃんイイジャンそれイイジャン♪」と、、、、まー気づいたというか、「それ先に考えるだろフツー」と落ち込んだというか(笑)

以下のスクリプトをブログのレイアウトの中にしのばせる(ワタシはトップバナーのところ)。jQuery必要です。上から二つのコンテンツそれぞれの最後に広告表示。コンテンツがひとつしかない場合は2つ目をページの最後に表示してます。html要素のidやclassは使っているレイアウトに依存すると思うので、他のレイアウトでやるならfirebugなんかで調べてからヨロシク。

<div style="display:none;">
    <div id="ad1" style="display:none;">
        <script type="text/javascript">
        //広告1
        </script>
    </div>
    <div id="ad2" style="display:none;">
        <script type="text/javascript">
        //広告2
        </script>
    </div>
</div>
jQuery(function(){
    var ad1 = $("#ad1");
    var ad2 = $("#ad2");
    var e=$(".entry-body");
    var e1 = e.get(0);
    var e2 = e.get(1);
    var bsel = '.content-bottom:last';
    var b = $(bsel).get(0);
    if(e1) {
        $(e1).append(ad1);
        if(e2) {
            $(e2).append(ad2);
        } else {
            if(b) {
                $(b).append(ad2);
            } else {
                $(e1).append(ad2);
            }
        }
        ad1.show();
        ad2.show();
    } else {
        if(b) {
            $(b).append(ad1);
            $(b).append(ad2);
            ad1.show();
            ad1.show();
        }
    }
});

なんてこたーない、もーまんたい。まったく問題なく動作してるので、なんともいやはや(笑)

2012.02.08

再ダイエットなう

Medium_4222533261

思えば2年前の体重は56キロ近辺の標準体重ジャストミートだったのに、自転車通勤しなくなったこの一年で急激に肥えて、1月の中旬には63キロの大台を記録。不摂生極まりない生活をしていた頃の体重に迫る勢い。今は以前と違ってある程度の運動をしているので、筋肉量などのカラダの組成は違うだろうが、さすがに看過できないレベル。

ということで、炭水化物抜いてみたり、酒の量を減らしてみたり、色々やってみたけど、一番効果を発揮したのは脂抜き。といって、厳格にやってるわけでもないけど。脂っこそうなものは量を控える程度で、野菜と水分は大量に。そして炭水化物は摂り過ぎないように気をつけている。

こう書いてみると、王道をいく基本的なダイエットといえそう。

それと、1月の終わりからお弁当を持っていくようになって、絶対的な分量が減ったというのも効果があったかも。2月に入ってから徐々に体重が落ち始めて、今週の初めに60キロを切った。今もいい感じで減量が進行中。まだまだいけそうな雰囲気ですが、ここからが正念場。何度かの踊り場状態を経験するだろうね。

実際、炭水化物をゼロにすれば体重的な変化が急。でもカラダに対する影響が大き過ぎて続かなかった。そして、強烈なリバウンドに遭って退散。

photo credit: alancleaver_2000 via photopin cc

2012.02.07

PHPの文字列連結、ダブルコーテーションとシングルコーテーションの速度比較

perlと同じくPHPでも、文字列をダブルコーテーションで括ると変数の展開が行われる。

処理スピードが遅くなるので「できればシングルコーテーションを使いなさい」とインターネットに書かれていた。

「さもありなんだがホンマかな?」と思ったので、イヤラシイけど確認してみた。

とりあえず変数の展開が行われない場合。。。

ほとんど差が無い。

ありゃ、表とグラフで時間単位が違っているわ(汗; 表のほうの単位がマイクロ秒ですねプログラム見たらグラフの縦軸単位がミリ秒じゃなくて秒ですわ。

回数が多くなると差は1%未満。ダブルコーテーションのほうが速い場合もあるようで少し驚き。回数が少ないほど差が大きいのは、メモリの確保などのオーバーヘッドが影響しているのかもしれない。

実行したスクリプトはこれ。$nに上のグラフの横軸の数値が入る。

<?php
function dqAdd($n) {
	$s = "";
	for($i = 0; $i < $n; $i++) {
		$s .= "0 123456789";
		$s .= "01 23456789";
		$s .= "012 3456789";
		$s .= "0123 456789";
		$s .= "01234 56789";
		$s .= "012345 6789";
		$s .= "0123456 789";
		$s .= "01234567 89";
		$s .= "012345678 9";
		$s .= "0123456789 ";
	}
}
function sqAdd($n) {
	$s = '';
	for($i = 0; $i < $n; $i++) {
		$s .= '0 123456789';
		$s .= '01 23456789';
		$s .= '012 3456789';
		$s .= '0123 456789';
		$s .= '01234 56789';
		$s .= '012345 6789';
		$s .= '0123456 789';
		$s .= '01234567 89';
		$s .= '012345678 9';
		$s .= '0123456789 ';
	}
}
?>

じゃあ変数展開するのと変数を連結するのではどうなるか?とやってみた。

わずかに連結するほうが速い。

わずかといってもだいたい3%くらいの差があるね。回数が少ないほうが差が開くのは上と同じ。

比較したのは以下の処理です。

<?php
function dqAdd($n) {
	$s = "";
	for($i = 0; $i < $n; $i++) {
		$s .= "0$i 123456789";
		$s .= "01$i 23456789";
		$s .= "012$i 3456789";
		$s .= "0123$i 456789";
		$s .= "01234$i 56789";
		$s .= "012345$i 6789";
		$s .= "0123456$i 789";
		$s .= "01234567$i 89";
		$s .= "012345678$i 9";
		$s .= "0123456789$i ";
	}
}
function sqAdd($n) {
	$s = '';
	for($i = 0; $i < $n; $i++) {
		$s .= '0'.$i.' 123456789';
		$s .= '01'.$i.' 23456789';
		$s .= '012'.$i.' 3456789';
		$s .= '0123'.$i.' 456789';
		$s .= '01234'.$i.' 56789';
		$s .= '012345'.$i.' 6789';
		$s .= '0123456'.$i.' 789';
		$s .= '01234567'.$i.' 89';
		$s .= '012345678'.$i.' 9';
		$s .= '0123456789'.$i.' ';
	}
}
?>

これは自宅PCでの結果なんだけど、実は仕事で使っているPCではシングルコーテーションで変数を連結するほうが遅かった。

自宅PCも仕事PCもWindows7。どちらも指数的に処理速度が伸びているように見えたが、ためしにホスティングしているUNIXサーバーでやってみると、自宅PCと同じくシングルコーテーションのほうが速い。でも、どうみてもリニアな処理時間が得られました。メモリの搭載量やプロセッサの数によってこういう差が出るのかも。

通常のプログラムでこれほど一時に大量にループしながら文字を連結することは無いと思うから、もしかしたら回数の少ないほうの速度差が大きいという結果を採用すべきかも。しかし、変数を連結する場合は、マシンによって結果が逆転する場合があるので、一概にどっちが速いといえるものでもないのだろう。

そして、速度差はミリ秒マイクロ秒の世界だけど、検証プログラム全体の処理時間は20秒近くかかっているから、無視できるレベルの差だと思う。総合的に考えて、コーディング時に細かく気にする必要は無いってことだ。気にする分だけ時間の無駄かも。

2012.02.06

div.onloadの実現

通常、div.onloadは効かないので、どうにかできんかとやってみた。一応使えそうなのでご紹介。ここではソースが見にくいので「これで使える!DIV.ONLOAD|たかみんつ」に同等の処理を紹介しています。

<html>
<head>
<script type="text/javascript"
  src="../js/jquery-1.6.2.min.js"
  ></script>
<script type="text/javascript">

//body以外のonloadも使えるようにする。
$(function() {
  //onload属性を持つ要素全て
  $('[onload]').each(function(){
    //標準でonloadに対応しているエレメントは
    //処理する必要なし。
    if(!isHandleOnload(this.tagName)) {
      var f = this.onload;
      //onloadの型別に処理を呼び出す。
      if(typeof(f) == 'function') {
        f.call(this);
      } else {
        (function() {
          eval(f);
        }).call(this);
      }
    }
  });
});
//標準でonloadを処理するタグの配列とハッシュ生成
var STD_ONLOAD_TAGS = [
  'BODY', 'APPLET', 'EMBED', 'FRAMESET',
  'IMG', 'LINK', 'SCRIPT', 'STYLE'];
var STD_ONLOAD_TAG_HASH = {};
for(var i = 0; i < STD_ONLOAD_TAGS.length; i++) {
  STD_ONLOAD_TAG_HASH[STD_ONLOAD_TAGS[i]] = true;
}
//標準でonloadを処理するかどうかを判定
function isHandleOnload(tagName) {
  return STD_ONLOAD_TAG_HASH[tagName];
}
</script>
</head>
<body>
  <div onload="alert(this.innerHTML);">
    コンテンツ1</div>
  <div onload="alert(this.innerHTML);">
    コンテンツ2</div>
  <div onload="">コンテンツ3</div>
</body>
</html>

「本来onloadが動作する要素」を判定する部分がいけてないけど、DIVだけに限定すればもっと簡単になる。

呼び出しのタイミングは厳格ではないけれど必要十分かな?。FirefoxとIE9で確認したら、ベタなbody.onloadよりも先に呼ばれていた(←これはjQueryの範疇だけど、下のnon-jQuery版も同じだった)。

ページロード時だけ要素を特定して処理するとか、そういった要素にIDをつけなくてもよくなるので、それなりにすっきりする。

上のはjQueryを使う前提で書いたけど、「jQueryが無くてもかまわないだろう」と軽い気持ちでやってみたが・・・

//document.bodyが出来上がるまで待って、
//callOnLoadを呼び出す。
(function() {
  var tid = setInterval(function() {
    if(document && document.body) {
      clearInterval(tid);
      callOnLoad();
    }
  }, 1);
})();
//いわゆる配列に対するforeach
function foreach(arr, f) {
  for(var i = 0; i < arr.length; i++) {
    if(f.call(arr[i]) == false) {
      break;
    }
  }
}
//HTML要素を判定して配列を返す
function getElements(parent, judge, list) {
  list = list || [];
  var nds = parent.childNodes;
  foreach(nds, function(){
    if(judge.call(this)) {
      list.push(this);
    }
    getElements(this, judge, list);
  });
  return list;
}
//標準以外のonloadをすべて呼び出す。
function callOnLoad() {
  var onloadElements = getElements(
    document.body,
    function() {
      return !!this.onload;
    });
  foreach(
    onloadElements,
    function(){
      if(!isHandleOnload(this.tagName)) {
        var f = this.onload;
        if(typeof(f) == 'function') {
          f.call(this);
        } else {
          (function() {
            eval(f);
          }).call(this);
        }
      }
    });
};

かなり大変(当たり前か)。jQueryはありがたいね♪あるものは使わないと(^^;

ハマショー!

2012.02.05

タイムリミット3時間

朝ママチャリでお買い物に行ったら、ええ天気で風も弱く、気持ちよかったから、久しぶりに自転車に乗りたくなった。

最近(というか昨年末)からミトロ方面ばかりだったので、久しぶりに姫路方面へ。できれば相生まで行きたいけれど、時間的に無理っぽいので、1時間半でどこまでいけるか試してみた。

250号線を西へ走り、曽根で2号線へ入るルート。加古川を越えたところと、曽根の交差点でかなり時間ロスをしているけど、その後は心地よく。

LSD(SSD?)のつもりだったけど、気持ちよくてちょっと踏み込んでしまい。左ふくらはぎにちょっとした違和感を感じたので、つま先下げてケイデンスも70くらいに抑えて、大事に大事に。

西今宿のローソンでカレーパン食って引き返す。

63キロ、2時間45分。2時半に帰着。帰りはそれなりの向かい風でフラッフラ。時間的には追加で10キロランニングにいけそうだったけど、遊びまくるのもどうかと思い(足のためにも)自重した。

西へ行くのは、曽根まで行かず、加古川から2号線に入るほうが効率よさそう。

2012.02.04

エア大工

先週に引き続き、二段ベッドの解体作業って先週はこれ書いていなかったか。二段ベッドの下段だけを長女が使用していましたが、それなりに傷みが出てきたので、使用中止とすることに。解体作業は、先週ほとんど終えていたのですが、底の合板などは「さらにばらせるじゃないか」と自己ツッコミ(小さくしないとゴミの日に出せないからね)。ということで、今週もバリバリっと。

かなりデカイ音が出て気を使う。

そして、

ベランダが材木問屋・・・

作業を終えてみると、まだ使える木があるので、なんか作れないかと思案。

今使っているPCの机とイスの高さがあっていないから、それが第一候補か。でも、自転車ラックの後ろ側のデッドスペースに棚があるとうれしいな♪とか、作る前からなんだか楽しい。

実際、いつから作り始めるか。予定は未定。

2012.02.03

まず「子の発達障害」を、受け入れることから始まる

当ブログには「自閉症」、「発達障害」などで検索して来ていただく方がそれなりにいらっしゃるようです。

うちは次男(7歳)が発達障害(療育手帳B2判定)と診断され、2011年の春から小学校の特別支援学級へ通っています。彼が幼稚園を卒園するまではその様子を(記録と愚痴みたいなのが大半ですがw)書いていましたが、最近はずいぶんかけ離れたことを書いておりますね。

彼の障害を疑った当初は、本当にインターネットにかじりついて、いろんな情報を漁りました。学術的な情報からオカルト的なものまですべて。一年くらいは続いたと思いますが、そのうち自分なりに、冷静に情報を取捨選択できるようになり、同時に、気持ち的にも安定し、客観的に「今、自分は子供のために何をすれば良いのか」がわかるようになりました。いや、わかったというより「こうしてみようかな!?」と思えるようになりました。前向きになれたってことですね。それまでは障害から逃げていました。認めた瞬間から、「かかってこんかい!」と、マジでそんな気分でした。

当ブログへ検索エンジンからいらっしゃる方も当時のワタシと同じような状況だとするならば、ほんの少しだけ先行しているワタシの経験や少しの知識も、なにかの「力」になれるかもしれないと思います。これから、徐々にでも、うまくまとまらないかもしれませんが、書いていきたいと思っています。

といっても、とんでもない情報量です。とりあえず今は、重要だと思うことを箇条書きにして、書き加えていくつもりです。なにしろ、うちも現在進行形ですし、医者でも脳科学者でもないのですから、明日何があるかはわからないです。でもこれって健常者でも同じことなんです。

とにかく同じ悩みや戸惑いをお持ちの親御さんに、今、強く伝えておきたいのは「大丈夫!」ということ。わけがわからなくてもとにかく大丈夫なんです。楽観しましょうということではありませんが、悲観していても前には進みません。真正面からお子様とその障害に対峙することで、必ず何らかの変化が生まれます。お子様も成長します。そして親も成長するんです。

ということで、少しアツくなりましたけど、以下箇条書きです。これらのことについて徐々に書いていくつもりです。

障害を受け入れる迄の期間

「障害かもしれない」と思い悩み、堂々巡りにならない。そして「そうではない証拠」を探さない。

少なくとも家族の中ではオープンに話をしたい。ご兄弟が年少の場合は少し気をつけるべきですが、近しい親戚、おじいちゃん、おばあちゃんには、正しい知識を啓蒙し、理解してもらう必要があると思います。

役所関係

早い段階で公的機関に相談する。

特別児童扶養手当は必ず申請しましょう。この制度を知らない人が多い。うちも長年知らなかった。

関わり方

簡単な言葉で短く指示。

冷静に対処。怒鳴らない。怒りをあらわにしない。

パニックへの対処。あわてない、言い合いにならない。その場で即座に解決しようとしない。強制的に排除しない。無視(放棄ではありません。無言で見守りながら落ち着くまで待ってあげてください)。子の前で親は常に冷静でいてあげてください。

一緒に喜ぶ。褒める。

子供の言葉をちゃんと聞く。いい加減な対応をしない。

正しい事を教える。将来社会に出ることを前提に考え、「まーいいか」と放置しない。親が家族が正しい生活習慣を実践する。

CSVのインポートにStringTokenizerは使えない

本日やらかしていたのでメモ。StringTokenizerは、区切り文字で区切られた文字の断片を返してくれるわけだけど、空文字は無かったことにしてくれるので、CSVファイルからデータをインポートするような処理には使えない(カラムがずれちゃうからね)

StringTokenizer t =
    new StringTokenizer(line, ",");
String[] c = new String[13];
int i = 0;
while (t.hasMoreTokens() && i < 13)
{
  c[i++] = t.nextToken();
}

↑これだけ書いて客先からクレーム受けるわけ。対処法は↓

String[] c = line.split(",", 13);

古い人はStringTokenizerをそのクラス名から使っちゃうケースがあると思う(だってストリングトークナイザーだもの)が、いろいろ不条理だよな。この動きでは使えるケースが見当たらん。

IE9のshowModalDialogで表示するドキュメント中でElementが未定儀

IE9で、showModalDialogで表示したドキュメント中でElementが未定義でエラーになる。Elementのプロトタイプをイロイロいじっているんだが、これは困った。回避方法が見つからん。

2012.02.02

SQLで月初めの日付を生成(1年分)

月毎の集計表で12か月分の各月の日付が必要で、以下のようなSQLを書いてみた(MySQL用です)。よく知ってる人からすれば当たり前の処理かもしれないけど、自分はすっと出てこないほうで、じっくり考えたから、とりあえずメモ。こういうのは「慣れ」なのかな。

過去に、安易にループしたりして、ソースコード的にも速度的にもえらい事になってるシステムを何度か見たことがある。

/*
 * 当月から過去12か月分の各月1日の
 * 日付を選択(当月含む)
 */
SELECT B.d - INTERVAL N.n MONTH AS d
FROM (
  SELECT DATE(CONCAT(
    YEAR(current_date),'-',
    MONTH(current_date),'-',
    1)) as d) AS B
  JOIN (
    SELECT 0 AS n UNION SELECT 1
    UNION SELECT 2 UNION SELECT 3
    UNION SELECT 4 UNION SELECT 5
    UNION SELECT 6 UNION SELECT 7
    UNION SELECT 8 UNION SELECT 9
    UNION SELECT 10 UNION SELECT 11
  ) AS N
ORDER BY d

0から11までの数列を作る部分はもうちょっとスマートに出来るのかもしれないけれど、ぱっと見てわかりやすいのはこれかなーと。

それから、一旦文字列化して日付に直しているところもスッキリしない。なんか良い手があるなら教えて欲しいです。

以下はこれをモディファイしたもので、年度内の各月を選択(年度が4月始まりの場合)。いつか使うケースがあるかもしれないので、これもメモ

/*
 * 当年度の各月1日の日付を選択
 * (4月始まりの場合)
 */
SELECT (B.d + INTERVAL N.n MONTH) AS d
FROM (
  SELECT DATE(CONCAT(
    YEAR(
      current_date - 
        INTERVAL (4-1) MONTH),'-',
        1,'-',1)) + 
        INTERVAL (4-1) MONTH as d) AS B
  JOIN (
    SELECT 0 AS n UNION SELECT 1
    UNION SELECT 2 UNION SELECT 3
    UNION SELECT 4 UNION SELECT 5
    UNION SELECT 6 UNION SELECT 7
    UNION SELECT 8 UNION SELECT 9
    UNION SELECT 10 UNION SELECT 11
  ) AS N
ORDER BY d

↑この本、面白そう。

2012.02.01

[symfony] HTMLタグを含む文字列をエスケープせずに出力する

symfonyでHTMLのタグを記述した文字列($this->str = '<p>文字列</p>'みたいなの)を出力すると、view.ymlでの設定にもよるらしいけど'<''>'が実体参照(それぞれ'&lt;''&gt;')に変換されて結局ブラウザにはHTMLコードがそのまま表示されてしまうんですよね(実は本日知りましたw)

赤い文字を表示したいと思って、以下のようにしてもダメなのね。

//アクション:actions.class.php

public function executeAction(
    sfWebRequest $request)
{
  $this->str =
    '<p style="color:red;">'.
      '文字列</p>';
}
//テンプレート actionSuccess.php
<?= $str ?>
<?php echo $str;?>

これを意図する通り表示させたいなら、テンプレート側で以下のようにすれば良いらしい。

//テンプレート actionSuccess.php
<?= $sf_data->get(
    'str', ESC_RAW) ?>
 

?。いやマジでなんのこっちゃと思いますけど、こうなのだから仕方がない。

通常、アクション側で$this->hogehogeとして使用された変数は、テンプレート側で単に $hogehoge と表記しますけど、果たしてその実体は?というと$sf_data->get('hogehoge')ということなんでしょうな(自信ないけどw)。そして、このgetメソッドは文字列をエスケープして返してくるけど、第二引数にESC_RAWという定数を与えるとエスケープしないってことなのだろうね。と推測した。

が、それだけでは説明が付かない事態。自作のクラスのgetterからHTMLを出力する場合もエスケープされてしまう。困った。

//HogeHogeは自作クラス
$obj = new HogeHoge();
echo $obj->getHtmlString();

これはどう対処するのかというと、、、
↓こうするんだって。

//HogeHogeは自作クラス
$obj = new HogeHoge();
echo $obj->getHtmlString(ESC_RAW);

驚いた。HogeHogeは自作クラスだから、getHtmlStringというメソッドも自作。引数は取らないように宣言しているのに、無理やり身に覚えのないESC_RAWを渡すと、エスケープ無しで返してくれる。つまりsymfonyさんが勝手にいろいろやってくれているんですね。

まさか使い始めて半年経ってこういうことを知る羽目になるとは、symfonyって深いなー。というか変態的だなw
こんなの知らなきゃわからないね。

アンジャッシュのネタが中国にぱくられるとかw。あのダブルミーニング的なネタは中国人でなくてもパクリたくなる気持ちはわかる。

« 2012年1月 | トップページ | 2012年3月 »

2017年5月
  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      
フォト

Google AdSense

銀の弾丸

無料ブログはココログ