2008年12月25日木曜日

Googleみたいに?

PHPのサイトのロゴがクリスマスバージョン...!

2008年12月24日水曜日

RailsとMerbが統合するらしい

Railsよりお薦め!Rubyのフレームワーク Merb (Mongrel + Erb) をインストール」の記事がなぜか突然人気だなと思ったら、RailsとMerbが統合!するらしい。

DHHがMerbをコアにしてRails3を作るらしいけど、Merbのファサードを絞ったシンプルさが、DHH的な知らないと分からない隠れ規約に飲み込まれないかちょっと心配。

でもMerbもこのままマイナーなままよりはメジャーになった方が、Railsともどもお互い幸せなのかもね。

ついでにWeb Flavorも関係ないけどブレイクしないかな!

あ、Rails2のアプリはまた置き去りにされるのか...。

2008年12月22日月曜日

MySQLの timestampの自動更新ができない場合の修復方法

例えばcreated_atにはINSERT文でvalueにシステム時刻をセットし、updated_atは自動更新させることを想定している場合。

下記のように、間違えてtimestamp型の列を複数定義すると、2つ目以降のtimestampは初期値がオールゼロになり、自動更新もされない。

DROP TABLE IF EXISTS `test`.`members`;
CREATE TABLE `test`.`members` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`name` text NOT NULL,
`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

間違いに気づいて、Query Browserからテーブル定義を変更(created_atをdatetimeにして、updated_atのdefaultにCURRENT_TIMESTAMPをセット)しても、自動更新はされない。
なぜなら、Query Browserからテーブル定義を変更してtimestampにした場合、下記のようにON UPDATEの定義が無いから。
DROP TABLE IF EXISTS `test`.`members`;
CREATE TABLE `test`.`members` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`name` text NOT NULL,
`created_at` datetime NOT NULL,
`updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

Query Browserは、外部KEY以外のトリガーを作成できない。
なのでSQL文(DDL TDL)で列の定義を修正する。

ALTER TABLE members MODIFY updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP


修正できた。
DROP TABLE IF EXISTS `test`.`members`;
CREATE TABLE `test`.`members` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`name` text NOT NULL,
`created_at` datetime NOT NULL,
`updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

参考:MySQL :: MySQL 5.1 リファレンスマニュアル :: 12.1.2 ALTER TABLE 構文

MySQLで Database (Schema)を作成するDDL

よく忘れるのでメモメモ。
文字コードがデフォルトでよい場合は指定不要。

CREATE DATABASE データベース名 CHARACTER SET utf8;

2008年12月6日土曜日

mysql_conncet()で hostを localshotとする場合と127.0.0.1とする場合の違い

PHPのmysql関数の話。PDOを使えば関係ないかも。

mysql_connect()でhostにlocalhostを指定すると接続エラーになり、127.0.0.1を指定すると接続できること(環境)がある。

原因:
mysql_conncet()では、localhostの場合unixソケットを使い、127.0.0.1の場合はTCP/IP接続を使うため、らしい。
(Windowsの場合は実行ファイルの呼び出し???)
参考:codeなにがし::mysql_connect()のホスト名にlocalhostを指定するとソケット接続になる


こちらも参考:MAMP環境CakePHP1.2のbakeでSQL接続エラー - ElectronicBrain is eating BreakFast

PHPで SJIS-winを使う

メモ。

PHPで UTF-8←→SJIS の変換を行う場合の注意 : 地方で活動するweb制作者の日々を綴るblog

[php] mb_convert_encoding と UTF-8 の誤変換問題 ( しゃいん☆のブログ| 名古屋市 Webシステム開発 サーバ構築 ネットワーク構築 株式会社コネクティボ )

ke-tai.org > Blog Archive > PHPで絵文字を壊さずに文字コードや全角半角変換を行う方法

mobile、SJIS SJIS-win mb_convert_encodingとhtmlspecialchars - 。

Y's Blog | PHPでUTF-8からSJIS-winへの変換ではまる


sjisは使わずにSJIS-win使えば問題無い?

Googleの Sitemapにフィードを登録する場合の注意点






Google ウェブマスター ツールではSitemapとしてフィードを登録することができるが、いくつか注意点が。


1. 登録できるフィードはRSS2.0かAtom1.0のみ
 参考:
  雑記帳?一応Weblog - Atom 1.0キボン
  サイトマップの作成 - ウェブマスター向けヘルプ センター


2. Atom1.0を登録する場合、各エントリーにpublished(作成日)要素が必要
 publishedが無いとエラーになる。
 Atom1.0の仕様としてはupdatedは必須だが、publishedは必須ではないのだが。
 参考:
  Error in parsing sitemap for Atom Feed - Invalid XML tag - Sitemap Protocol | Google グループ
  RFC 4287 The Atom Syndication Format 日本語訳 - futomi's CGI Cafe (Atom1.0仕様書の和訳)

(2008/1/7 追記)
いつの間にか、Atom1.0でエントリーにpublishedが無くてもエラーにならなくなっていた。

RewriteCondで条件によって別のRewriteBaseを使う

できないみたい。

CakePHPで試してみたらできるようだ。

<IfModule mod_rewrite.c>
 RewriteEngine On

 RewriteCond %{REQUEST_FILENAME} !-d
 RewriteCond %{REQUEST_FILENAME} !-f
 RewriteRule ^(.*)$ index.php?url=$1 [QSA]

 RewriteCond %{REQUEST_URI} ^/foo
 RewriteBase /foo

 RewriteCond %{REQUEST_URI} ^/bar
 RewriteBase /bar
</IfModule>

CakePHPではWebのルート直下以外にCakeのホームディレクトリを作ろうとするとRewriteBaseの設定が必要になる。
上記の方法を使えば複数のディレクトリのように見せることができそう。



参考:mod_rewrite - Apache HTTP Server (和訳無し)


PHPのmb_send_mail()でのSMTPエラー(550 5.7.1)の解消方法

PHPのmb_send_mail()からIISの簡易SMTPサーバを使ってメールを送信しようとしたとき、下記のエラーが発生。

PHP Warning: mb_send_mail() [<a href='function.mb-send-mail'>function.mb-send-mail</a>]: SMTP server response: 550 5.7.1 Unable to relay for ...

原因はSMTPサーバがデフォルト設定で、中継を許可していなかったため。
中継を許可するIPアドレスに127.0.0.1を加えたらメールが送信できるようになった。

2008年11月25日火曜日

2008年11月24日月曜日

Googleカレンダーでスクロールホイールを使って月を移動

Googleカレンダーで月ごとのカレンダーを表示している時に、マウスのスクロールホイールを回すと表示中の月を次の月や前の月に移動できることにさっき気付いた。
地味だけどなかなか便利な機能かも。

2008年11月14日金曜日

PHPでサーバサイドでデータをPOSTする色々な方法











とても簡単にPHPからPOSTリクエストを送信する方法 [PHP, Tips] - Programming Magicがまとまっていて分かりやすい。

関連記事:floatingdays: PHPを使ってサーバサイドでXMLをPOST


2008/11/28 追記
POSTするときのContent-typeをオプションのheader(http header)として指定しないとNoticeが出る。その場合は"application/x-www-form-urlencoded"が適用される。
また、Content-typeに"text/html"などを指定すると受け側でエラーを起こすことがあるので注意。Railsとか。

PHPで簡単にURLのGETパラメータを作成する方法

標準関数のhttp_build_query()を使うと、URLのGETパラメータ(クエリーストリング)を簡単に作れる。
PHP5かららしい。


$query = array('foo' => 'ABC', 'bar' => 123, 'baz' => 'あああ');
echo http_build_query($query);
結果
foo=ABC&bar=123&baz=%82%A0%82%A0%82%A0

URLエンコードもしてくれるのが便利。


HTMLエスケープもしたいなら、第3引数を'&amp;'にする。(パフォーマンスを気にしないなら、URLをまるごとhtmlSpecialChars()した方が楽だが。)


echo http_build_query(array('foo' => 'ABC', 'bar' => 123), '', '&amp;');
結果
foo=ABC&amp;bar=123


参考:PHP: http_build_query - Manual

携帯サイト向けクローラのUser Agent一覧

手元の専用ログから、モバイルサイト向けの検索エンジン等のクローラ(Bot)のUser Agentを洗い出し。2008年6月~11月頃のもの。


Google(AdSense絡みも含む。ただしNokiaは集計していない)

  • DoCoMo/1.0/N505i/c20/TB/W20H10 (compatible; Googlebot-Mobile/2.1; +http://www.google.com/bot.html)
  • DoCoMo/2.0 N905i(c100;TB;W24H16) (compatible; Googlebot-Mobile/2.1; +http://www.google.com/bot.html)
  • DoCoMo/2.0 SH905i(c100;TB;W24H16) (compatible; Mediapartners-Google/2.1; +http://www.google.com/bot.html)
  • KDDI-CA34 UP.Browser/6.2.0.10.2.2 (GUI) MMP/2.0 (compatible; Mediapartners-Google/2.1; +http://www.google.com/bot.html)
  • SoftBank/1.0/911SH/SHJ001 Browser/NetFront/3.3 Profile/MIDP-2.0
    Configuration/CLDC-1.1 (compatible; Mediapartners-Google/2.1;
    +http://www.google.com/bot.html)


Yahoo!
  • DoCoMo/2.0 SH902i (compatible; Y!J-SRD/1.0; http://help.yahoo.co.jp/help/jp/search/indexing/indexing-27.html)
  • DoCoMo/2.0 N905i (compatible; Y!J-SRD/1.0; http://help.yahoo.co.jp/help/jp/search/indexing/indexing-27.html)
  • KDDI-CA23 UP.Browser/6.2.0.5 (compatible; Y!J-SRD/1.0; http://help.yahoo.co.jp/help/jp/search/indexing/indexing-27.html)
  • KDDI-CA33 UP.Browser/6.2.0.10.4 (compatible; Y!J-SRD/1.0; http://help.yahoo.co.jp/help/jp/search/indexing/indexing-27.html)
  • Vodafone/1.0/V705SH (compatible; Y!J-SRD/1.0; http://help.yahoo.co.jp/help/jp/search/indexing/indexing-27.html)
  • J-PHONE/2.0/J-SH03 (compatible; Y!J-SRD/1.0; http://help.yahoo.co.jp/help/jp/search/indexing/indexing-27.html)


goo
  • DoCoMo/2.0 P900i(c100;TB;W24H11)(compatible; ichiro/mobile goo; +http://help.goo.ne.jp/door/crawler.html)
  • DoCoMo/2.0 N905i(c100;TB;W24H16)(compatible; mobile goo; +http://emu.mobile.goo.ne.jp/)


livedoor
  • DoCoMo/2.0 SH905i(c100;TB;W24H16) (compatible;* livedoor-Yill/1.0; *+http://helpguide.livedoor.com/help/search/qa/grp627)


はてな
  • DoCoMo/2.0 D903i(c100;TB;W28H20) (compatible; Hatena-Mobile-Gateway/1.2; +http://mgw.hatena.ne.jp/help)


DeNA
  • DoCoMo/2.0 N902iS(c100;TB;W24H12)(compatible; moba-crawler; http://crawler.dena.jp/)



雑感:
  • docomoのみを偽装しているとこが多い
  • auはCASIO製が人気、それ以外はN905iとSHARP製が人気。なぜ?
  • docomoは902と905が多い
  • Yahoo!はJ-Phoneまでフォローしている一方、SoftBankがまだ無い?親子断絶?
  • Googlebot-Mobileはdocomoしか無い?
  • あれ?F☆Routeが来てない...



参考:
 Google Japan Blog: Google モバイル検索についてのウェブマスター向け情報
 Utilz: 携帯クローラ
 モバイル検索サイト クローラー一覧 - sin-news.com
 携帯サイトオーナーズClub 携帯クローラ user-agent 一覧
 携帯検索エンジンのクローラーのメモ ([黒]黒豚備忘録)
 User Agentリスト - Mozilla Firefox まとめサイト

Windows XP SPSP3にしたらスケジュールしたタスクが実行されなくなった

Windows UpdateでXP SP2からSP3にアップデートしたら、タスクスケジューラに登録していたタスクが全て実行されなくなった。
タスクのプロパティを開いて、パスワードを再入力したら実行可能になった。

SP3へのアップデートに一度失敗したことと関係があるのか?

2008年11月8日土曜日

PHP5のマジックメソッド

第2回設計勉強会に参加しました | Shin x blogを読んで初めてautoloadを知った。

ついでにマジックメソッドについてまとめてみる。


classのマジックメソッド



グローバル関数なマジックメソッド
  • __autoload()
    • 未定義のclassが参照された場合に呼ばれる
    • この関数の中でクラス名等に紐付いたファイルをインクルードさせれば、classを使う時にいちいちrequire/includeしなくてよくなる
    • newでのインスタンス生成や静的メソッドの呼び出しの他、extendsや型宣言などによるclassの参照でも呼ばれる
    • 参考:PHP: オブジェクトのオートローディング - Manual


今まで__construct, __destruct, __call, __get, __setくらいしか知らなかった。
__constructは別にすると、この中では__autoloadが特に便利。
また、__call, __get, __setはコーディングミス防止に役立つので生産性向上に寄与する。「重いので使うな」的なことが書かれていることが多いので、それなりに負荷のあるサイトでは使わないほうがよいのかも。(1ページ表示するのに__setを1000回使うサイトとか!)


参考:PHP: マジックメソッド - Manual

CakePHP 1.2のFormHelperのradio()で余分なhiddenを出力しない方法

CakePHP1.2のFormHelperでラジオボタンを出力すると、ラジオボタンの前に隠し項目が出力されることがある。


<input type="hidden" name="data[Foo][bar]" id="FooBar_" value="" />
<input type="radio" name="data[Foo][bar]" id="FooBarBaz" value="Baz" />
<label for="FooBarBaz">Baz</label>

このhiddenを出力させたくない場合、$form->radio()の第3引数の配列で、'value'に何か値をセットして渡す。
echo $form->radio('Foo.bar', array('Baz' => 'Baz'), array('value' => 'none'));
そうすると、
<input type="radio" name="data[Foo][bar]" id="FooBarBaz" value="Baz" />
<label for="FooBarBaz">Baz</label>

ラジオボタンの値に一致するvalueを渡すとそれが初期選択状態になるので、選択状態にしたくない場合は上記の例のように一致しない適当なvalueを渡す。


参考:API for CakePHP : The PHP Rapid Development Framework :: version 1.2.x.x

無料の携帯サイト向けアクセス解析サービス4つの比較

無料アクセス解析 with 位置情報 「なかのひと」

  • 携帯サイト向けは「うごくひと」
  • 画像埋め込み+オプションでPHP等のスクリプト埋め込み
  • 良い点
    • グラフを多用した大雑把なUIで見やすい
    • 機種の発売時期のグラフがある
    • 都道府県別のアクセス度合いが見られる。役には立たないが。(沖縄はいつも赤い)
    • スクリプト埋め込みを使うことにより、時系列に沿って検索キーワード(KDDIとSoftBankのみ)が見られる
  • 悪い点
    • スクリプト埋め込みを使えば、やろうと思えばリファラからリンク元の情報を取れるはずだが、それが無い
    • 表示ページや検索キーワードや機種の集計が無い


i2i無料『アクセス解析』携帯対応・訪問ルート分析の足あと機能
  • 画像埋め込みタイプ
  • 良い点
    • アクセスしてきた機種の細かい統計が見られる。表示できる文字数とか、iモードブラウザのバージョンとか。
  • 悪い点
    • 画像埋め込みなので、リファラが無いと引っ張れれない情報(リンク元と検索キーワード)が取れない


トップページ|myRTモバイル
  • 画像埋め込みタイプ
  • なぜかSoftBankしか集計されない...
  • 良い点
    • 対応している画像タイプの集計が見られる。でもSoftBankだけ...
  • 悪い点
    • SoftBankしか集計されない...
    • 画像埋め込みなので、リファラが無いと引っ張れれない情報(リンク元と検索キーワード)が取れない。しかもSoftBankしか集計されない...
    • 管理画面が重い。しかもSoftBankしか集計されない...


Google Analytics

CakePHPの標準機能でパンくずリスト(トピックパス)を生成する方法

CakePHPでパンくずリストを表示するサンプル YARETOKO「ヤレトコ」メインブログ


標準で使えるのが便利。
$html->addCrumb()の第2引数(URL)を省略すると、リンクでないただのテキストとして表示されるようだ。
なのでelementにするならURLを省略できるようにすると便利。

<?php
foreach ($crumbs as $crumb) {
 $crumb = am(array('url' => null, 'options' => null), $crumb);
 $html->addCrumb($crumb['title'], $crumb['url'], $crumb['options']);
}

echo '<div class="crumbs">';
echo $html->getCrumbs(' > ', 'トップ');
echo "</div>\n";


参考:API for CakePHP : The PHP Rapid Development Framework :: version 1.2.x.x

PHPで簡単にタグクラウドを生成するPEAR::HTML_TagCloudを試してみた

PEAR :: Manual :: HTML_TagCloud

これは簡単。とても簡単。便利。
タグを追加してbuildするだけ => PEAR :: Manual :: 導入


デフォルトだとタグの色がグレー等になるようなので、サイトに合わせて色を変えた方が良さそう。
普通のリンクの色(デフォルト 青、visited 紫、active 赤)にしたい場合はこんな感じ。
CSS

div.tagcloud a{
 /* 下線は消した方がタグクラウドっぽい */
 text-decoration: none;
}
PHP
<?php
$tags = array(.....); //ここにタグと件数が入っているとする

require_once('HTML/TagCloud.php');

$cloud = new HTML_TagCloud();
foreach ($tags as $tag => $count) {
 //経過時間をセットしない場合の例
 $cloud->addElement($tag, '/tag/' . urlencode($tag), $count);
}
echo $cloud->buildHTML(); //HTMLのみ出力する

携帯サイトをGoogle Analyticsでアクセス解析する方法






(2009/12/28追記:Google Analyticsで公式に携帯サイトをアクセス解析できるようになった → Google Analyticsで携帯からのアクセスを解析する方法 (公式Beta版)


Google Analyticsの利用規約上、問題ないのだろうか?


大元?:Linklove » Google Analytics without javascript!

HTTP Headerをいじった改良版:モバイルサイトで Google Analytics
(Webページのタイトルも送信する方法はコメント欄の下の方に書いてある。)

さらに微調整して関数化した改良版:モバイル(携帯サイト)でアクセス解析にGoogle Analyticsを使う方法 - Knowledge Database IT
(ただしSmarty用なので、Smartyを使わない場合は$var_refererには普通にリファラをセットする。)


Google Analyticsのコードには「UA-xxxxxx-x」形式でコードをセットする。
「ドメイン」にスキームは付ける?


求む体験談!

2008年10月30日木曜日

PHPのスクレイピングツールSnoopyにOSコマンドインジェクションの脆弱性

JVN#20502807: Snoopy における OS コマンドインジェクションの脆弱性

脆弱性を解消したバージョン1.2.4がリリースされている。

ver.1.2.3

$safer_URI = strtr( $URI, "\"", " " ); // strip quotes from the URI to avoid shell access
exec($this->curl_path." -D \"$headerfile\"".$cmdline_params." \"".$safer_URI."\"",$results,$return);

ver.1.2.4
exec($this->curl_path." -k -D \"$headerfile\"".$cmdline_params." \"".escapeshellcmd($URI)."\"",$results,$return);

影響があるのは、ユーザーが任意のURIを入力できる場合で、httpsスキームで始まり不正な文字を含むURIを入力された場合。(ダブルクォートのみは1.2.3でもエスケープされる。)
httpスキームの場合はこの関数(_httpsrequest())を通らないので影響無し。(httpの場合はcURLを使わずにsocketを開いてガリガリ書いている。)

ところでescapeshellcmd()でエスケープしているが、escapeshellarg()じゃなくていいんだろうか?

また、スクレイピングライブラリのhtmlSQLはSnoopyを内部的に使っているが、htmlSQLはhttpスキームのみを受け付けているので影響無し。(改造していない限りは。)

PCで携帯向けのWeb開発をするためのメモ






とりあえずメモ書き。整理できると良い。


モバイル検索結果をPCで見る

  • Googleモバイル検索
    • Googleモバイル検索
    • 携帯でも同じURL(www.google.co.jp/m OR google.jp/m)で使える
    • URL例: http://www.google.co.jp/m?q=[URLエンコードした検索文字列]
    • URLエンコーディングはたぶんUTF-8で
  • Yahoo!モバイル
    • Yahoo!モバイル検索の結果をキャリア別に表示
    • 検索結果から、そのまま携帯ブラウザのシミュレータでの閲覧ができる


シミュレーター(× シュミレーター)


PCサイトを携帯用に変換するサービス


その他


参考資料

Scala調査メモ

Javaから離れて久しいが、最近Scalaが気になる。



感想:
  • 文法が面白い。ループとか。
  • XMLを練り込めるのが面白い。
  • 特にレンタルサーバの場合など、PHPほど気軽に使えなさそう。
  • Apacheのモジュールで動けば気軽に使えるのだが...

2008年10月25日土曜日

Goolge Docsから Bloggerへの投稿でエントリーのタイトルが登録可能になった

中途半端な感じだったGoolge DocsからBloggerへの投稿がだいぶ改善された。

1. Docsで付けたタイトルがそのままエントリーのタイトルとして登録されるようになった。(今までは登録後にわざわざタイトルをコピーして更新していた。)

2. 改行等が反映されない不具合が解消された(気がする)。(今まではDocsからの登録後、Docs側で1回再登録していた。)

その代わり、なぜか本文の先頭に10行くらいの空行が入るようになった。
なぜ?

携帯電話関連の日本製Apacheモジュール

mod_ktai

携帯サイトの場合、キャリア・機種によって絵文字の出力、表示可能データ量、画面の大きさなどが異なる為、キャリア・機種判別、絵文字の出し分け等、携帯サイト向けの知識が不可欠です。
mod_ktaiを使用すると、それらの処理を簡単に行なうことが可能です。
参考:

 ke-tai.org > Blog Archive > ゆめみのmod_ktaiがとうとうリリース、しかも無償利用が可能

 オープンソース研究室: mod_ktaiを試してみました




mod_chxj

国内の主要携帯(3キャリア)向けコンテンツ変換ミドルウェアをApache2.x用のモジュールとして作成します。
CHTMLや通常のHTMLで作成したコンテンツを出力時にUserAgentを見てそれぞれの端末用に変換します(画像はJPG、GIF、PNGからJPG、GIF、PNG、BMPへ)。
QRコード生成機能付。
参考:ke-tai.org > Blog Archive > 携帯向け自動変換用Apacheモジュール「mod_chxj」が0.10系にバージョンアップ



mod_cidr_lookup

mod_cidr_lookupは、アクセスしてきたクライアントのIPアドレスが、起動時に読み込んでおいたCIDRブロック群のいずれかにマッチするかどうかを判別するためのモジュールです。
参考:DSAS開発者の部屋:ケータイやクローラの判別などに使えるmod_cidr_lookupを公開しました

Googleによる自然言語解析検索の実例に関する考察

動的URLへの検索エンジンの対応 『GoogleとYahooの違い』 : 実例 : リアルSEOで、検索されたキーワードの実例として「東京上野駅近く女性一人でも気軽も入れる店」って...。

もう少し精度が高まれば、PowersetのやりたいことはGoogleが実現しそうな勢いだ。

関係ないが、TechCrounchでもそうだが、サイト内にある検索機能より、Google検索の方が対象が広く、かつ表記の揺れに強くて使いやすい。

Googleモバイル検索に携帯サイトとして表示される方法

結果として、下記のようなサイトでGoogleモバイル検索に携帯サイトとしてインデックスされた。
ただし、これが最良の方法とは思えない。これ以外の方法もたくさんあるだろう。


文字コード
Shift_JISでOK。


マークアップ(HTML)
DOCTYPE無しのCHTMLでOK。
XHTMLは試してないが、DOCTYPEは気を付けた方が良さそう。
(GoogleはXHTML Basicを推奨しているが、他のフォーマットでも問題無し?
 参考:携帯サイトのDOCTYPEについてもう一度考えてみる。 携帯ホームページを作ろう! -ちょっと詳しいモバイルサイトの作り方-


MIME-Type
CHTMLなら text/htmlでOK。
XHTMLは試してないが、application/xhtml+xmlらしい。


URL振り分け
無し。PCと携帯で同じURLで、表示内容は別にしている。
ただしNokiaは対応(携帯向け表示)している場合も対応していない(PC向け表示)場合もあり。(両方ともインデックスされた。)
本来はPCと携帯は別のURLにすべき?


IP制限(携帯用IPのみ閲覧を許す)
していない。


半角カタカナ
英数字とカタカナはほとんど半角に変換して表示している。


絵文字
使っていない。


ページのファイルサイズ
携帯向けに小さくしてくる。


Sitemap
Googleにモバイルサイトマップを登録した場合も、登録しない場合(ただしPC用サイトマップは登録済み)も、両方インデックスされた。


Googleモバイル検索にインデックスされているかどうかは、携帯版Google検索で"site:example.com"で検索すれば分かる。
Yahoo!モバイル検索はYahoo!モバイルで同様に調べられる。

Yahoo!モバイル検索ではau向けは問題ないが、docomoとSoftBank向けで、インデックスされていたりされていなかったり...。


参考(今後改善するための参考として):
 携帯サイトのDOCTYPEについてもう一度考えてみる。 携帯ホームページを作ろう! -ちょっと詳しいモバイルサイトの作り方-
 モバイル検索エンジンのインデックス対策 - 携帯SEO・ケータイ検索エンジン最適化 - ププアブログ
 Googleモバイル(googlebot-mobile)にインデックスさせる - 携帯検索エンジンSEO - ププアブログ

2008年10月13日月曜日

郵便番号検索APIのまとめ

無償のもののみピックアップ。
住所からの検索ができるものが意外に少ない。



(2011/07/21 追記)
今ならGoogle日本語入力のAPI(Google CGI API for Japanese Input)を使うという手もある。
参考:floatingdays: Web form用入力ヘルパー JavaScriptライブラリいろいろ
サンプル:GAddress Finder 動作サンプル - ゼロと無限の間に

2008年10月3日金曜日

Windows用のフリーのバックアップツール × 3

個人的には、BunBackupが見た目が分かりやすくて使いやすい。

  • BunBackup
    • シンプルで分かりやすいGUI
    • パソコンに詳しくなくても使えそう
    • ミラーリングも可能(デフォルトでは非表示メニューになっている)
    • コマンドラインからの実行も可能 (参考:BunBackup FAQ
      "BunBackupへのパスBunBackup" /AUTO:"BunBackup設定ファイル(*.lbk)へのパス"
  • FastCopy
    • 「Windows系最速(?)のファイルコピー&削除ツール」
    • 一般の人には最初は少し分かり辛いかも
    • 右クリック時に表示されるメニューからFastCopyを呼び出せるのが便利そう
    • 常駐させて同期させるなら便利そう
    • コマンドラインオプションは豊富
  • Fire File Copy
    • 「ファイルのコピーや移動を「高速に、しかもガリガリという音を立てずに行おう」という、ちょっと珍しい(?)ツール」
    • 大容量のファイルコピーに向いている?
    • コマンドラインオプションは一番多そう(参考:コマンドラインオプション

Flickr services (Flickr API)で写真検索

写真検索のマニュアルはFlickr Services: Flickr API: flickr.photos.search

必須のパラメータは api_key。

キーワード的なものでの検索のパラメータは text。

sortは、

  • デフォルトは date-posted-desc
  • ただし radial geo query の場合は指定したポイントからの ascending distance
  • 指定可能な値
    • date-posted-asc
    • date-posted-desc
    • date-taken-asc
    • date-taken-desc
    • interestingness-desc = 人気の高い順
    • interestingness-asc

licenseで指定する値は、Flickr Services: Flickr API: flickr.photos.licenses.getInfoのExample Response欄を参照。


PHPなら、Serialized PHP Response Formatでの取得が一番手軽そう。

CakePHP初心者のための Tips (CakePHP 1.2)






自分用のメモ。



本家のマニュアル:The Cookbook :: 1.2 Collection :: マニュアル







URLでパラメータを受取る






AppControllerの記述例


<?php

class AppController extends Controller {

public $components = array('foo');

}




  • AppControllerは、CAKE_HOME/app/app_controller.php に置く。







DBを使わない場合の設定







Controllerでのset()を一度で済ます






ControllerからViewにデータを渡す方法




Pagesコントローラについて




レイアウト用のファイル






エレメント






FormHelperの使い方






特定のページでしか使わないCSSやJavaScript



  • layoutでこれらを出力する場所に「echo $scripts_for_layout;」する。


  • HTML部分を書いた後でもCSS等を指定できるのは便利。


  • CSSとJavaScriptを別の場所に出力はできなそう。


    //link to webroot/css/foo.css

    $this->addScript($html->css('foo'));

    //include webroot/js/bar.js

    $this->addScript($javascript->link('bar'));

    //write Code Block of JavaScript

    $this->addScript($javascript->codeBlock("alert('Hello! CakePHP.');"));







翻訳(GetTextの使い方)


2008年9月20日土曜日

CakePHP 1.2で WebService APIを利用する

Webで公開されているAPIからデータを取得したりデータを送信するBehaviorがBakeryで公開されている。

Webservice Behavior (Articles) | The Bakery, Everything CakePHP

HTTP GET、HTTP POST、XMLRPCが使えるようだ。


GETしたいだけならオーバースペックかも。
POSTもcURLを使わずに、PHPでPOSTリクエストを送信する - PHPプロ!ニュースの方がシンプルでいいかも?


参考:CakePHP1.2のBehaviorを使う - 院生エンジニアのにっき

2008年9月19日金曜日

RSS/Atomフィードを生成したりSitemapを作成するPHPライブラリ

P2_Feeder2

(Google独自の)携帯向けサイトマップであるモバイル・サイトマップに対応してるけど、まだBeta版。

Updateが止まっていてAtom1.0に対応していないFeedCreatorの代わりになるか?

2008年9月16日火曜日

CakePHP 1.2 のFormHelperで日付選択リストを作る

$form->datetime()を使うと、年月日(または年月日+時間)を選ぶselect要素が簡単に作れる。

echo $form->datetime('cal', 'MDY', 'NONE'); // => Septemper-1-2008

//第3引数をNONE以外すると、時間の選択リストも表示される。(デフォルトは"12")
echo $form->datetime('cal', 'MDY', 24);


オプションとしてarray('monthNames' => false)を渡すと、月の表示が数字になる
echo $form->datetime('cal', 'YMD', 'NONE', null, array('monthNames' => false)); // => 2008-01-1

「日」がゼロ埋めなしなのに「月」だけゼロ埋めされているのが嫌な場合は、あらかじめ$form->month or $form->dayにデータをセットしておく。(参考:CakePHP FormHelper#datetime()で年月日表示を変える | Shin x blog
array_combineを使ったのはoption要素のvalue属性を表示値と同じにするため。
$form->options['month'] = array_combine(range(1, 12), range(1, 12));
echo $form->datetime('cal', 'YMD', 'NONE'); // => 2008-1-1

デフォルトでは年が現在から前後20年ずつ、大きい順に表示されて煩わしい。
今年と来年を小さい順に表示するにはこんな感じ。
$years = range(date('Y'), date('Y') + 1);
$form->options['year'] = array_combine($years, $years);
echo $form->datetime('cal', 'YMD', 'NONE');



Flashでページをめくるライブラリで逆方向にめくる方法

Flashでページをめくるライブラリで、日本の縦書きの本のようにページを左から右へめくるようにする方法。


Page Flip by PiXELWiTの場合

  • Actionsレイヤー フレーム2の「gotoAndPlay(4)」を変更し、最初に表示したいページのフレームに行くようにする
    (全部で8ページの場合は「gotoAndPlay(13)」)
  • シンボルBound PagesのActionsレイヤー フレーム1の冒頭にある変数dir, flipPage, curPageの初期値を変更する
    • dirは-1にする
    • flipPageは表示しているページとその裏のページを足して2で割った値にする
      (全部で8ページの場合は7.5)
    • curPageは表示しているページとその右側のページを足して2で割った値にする

      (全部で8ページの場合は8.5)

Free PageFlip 2.25 by Iparigrafikaの場合
  • Actionsレイヤー フレーム5の50行目あたりでセットしている変数「directlink」の値を最初に表示したいページ番号にする
    または、
    directlinkに関する記述(51~53行目)を削除してしまい、直接変数「page」にページ番号をセットしてもOK
  • 要は、初期処理で変数「page」にセットされたページを最初に表示するようになっているようだ



2008年9月15日月曜日

検索エンジンによる自分のサイトのインデックス状況やSitemapを管理するまとめ

Google:Google ウェブマスター ツール - マイレポート

  • サイトマップはモバイル・動画・ニュースなどいろいろ受け付けている
  • iGoogleガジェットもここから取得できる

日本のYahoo!:サイトエクスプローラー(サイト管理者向けツール) - Yahoo!検索
  • モバイル向けのフィード・サイトマップは受け付けていない

世界のYahoo!:Yahoo! Site Explorer
  • モバイル向けのフィード・サイトマップも登録可能(xhtml or wml)
  • Yahoo! JapanではなくYahoo.comのアカウントが必要

CakePHP 1.2 で多国語対応(GetText)調査メモ

PHPでは _() または gettext() でgettextできるが、CakePHPではそれをラップして __() でgettextできる。

//PHPの例
echo _('We love PHP');
//CakePHPの例
__('You love CakePHP'); //第2引数でtrueを指定すればechoせずに戻り値を返すこともできる
CakePHPではCakeコンソールからi18nできて便利そう。
CakePHPでのgettextについては、CakePHP 1.2 の多言語対応メモ - miau's blog?が、参考サイトへのリンクも多く、よくまとまっていて参考になる。


あとはひっかかりそうなところについてのメモ。


複数形
英語など単数と複数でメッセージが変わる場合、__n() を使う。
//例
__n('cat', 'cats', $catCount);
echo __n('mouse', 'mice', $mouseCount, true); //第4引数は戻り値を返すかどうか
詳しくは、1.2系の多言語対応メモ(2) - Writing Some Codeを参照。
Rubyよりも使いやすいと思う。

(2008/09/17 追記)
__n()の第3引数は、シンプルな変数でないと機能しないようだ。sprintfとかの関係だろうか?
//NG

__n('cat', 'cats', $cat['count']);


//OK
$count = $cat['count'];
__n('cat', 'cats', $count);
(追記終わり)


言語によってメッセージ内のパラメータの順番が違う場合
翻訳メッセージの複数個所に穴埋めで項目名などを入れる場合で、言語によって順番が違う場合の対応方法。
1.2系の多言語対応メモ(3) - Writing Some Codeの後半を参照。

avast! 4 Home Editionの便利な使い方

「ご家庭 での 非営利使用 にのみ無料」なavast! 4 Home Editionを使うためのメモ。

本家:
 無料アンチウイルス - avast! 4 Home Edition ダウンロード


スクリーンセーバー起動時にバックグラウンドでウィルスチェックを行う方法:
 avast! 4 Home Edition - Online soft


定期的にウィルスチェックを行う方法:

  • 下記内容を書いたバッチファイルを、Windowsの「タスク」で定期的に実行する
    (ashQucik.exeへのパスは環境に合わせて変更する。下記は「C:Program FilesAlwil Software」ディレクトリにバッチファイルを置く場合。)
    @echo off
    rem メモリ内をチェックする場合
    Avast4ashQuick "*MEMORY"
    rem チェックしたいドライブを全て指定する
    Avast4ashQuick "C:" "D:"
  • 途中でウィルス等が見つかると止まっちゃうかも
  • 参考:おじいちゃんのメモ - おじいちゃんのメモ-特殊な検査方法


2008年9月6日土曜日

CakePHP1.2の layoutで使える Helperのまとめ

head要素内に記述する要素など、layoutに書く要素のうちHelperで作成できるもののまとめ。



  • ドキュメント宣言 (参考:HtmlHelper::docType
    //引数なしの場合はXHTML1.0 Strict
    echo $html->docType();
  • Content-Typeのmetaタグ (参考:HtmlHelper::charset)※2008/09/13 誤り修正
    //デフォルトはPHPのdefault_charset???
    echo $html->charset();
  • CSS (参考:HtmlHelper::css
    複数ある場合は配列で渡せる。
    //webroot/css/foo.cssを読み込む場合
    echo $html->css('foo');

    //webroot/css/foo.cssとwebroot/css/bar.cssの2つを読み込む場合

    echo $html->css(array('foo', 'bar'));
  • JavaScript (参考:JavascriptHelper::link
    これも配列で渡せる。
    //webroot/js/foo.jsを読み込む場合


    echo $javascript->link('foo');



    //webroot/js/foo.jsとwebroot/js/bar.jsの2つを読み込む場合


    echo $javascript->link(array('foo', 'bar'));


    JavascriptHelperを使う場合、ControllerでこのHelperを有効にしておく。(「s」が小文字なので注意!)
    var $helpers = array('Html', 'Javascript');
  • その他、$html->meta('xxx')で作成できるもの (参考:HtmlHelper::meta
    • RSS ('rss')

    • Atomフィード ('atom')
    • favicon ('icon')
      • デフォルトはwebroot/favicon.ico
    • metaタグのkeyword('keyword')
    • metaタグのdescription ('description')


YUI Girdsを使うならこんな感じになる。
<<?php ?>?xml version="1.0" encoding="<?php echo ini_get('default_charset'); ?>" ?>
<?php echo $html->docType(); ?>
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja" lang="ja">
<head>
<?php echo $html->charset(); ?>
<meta http-equiv="Content-Style-Type" content="text/css" />
<meta http-equiv="Content-Script-Type" content="text/javascript" />
<title><?php echo $title_for_layout; ?></title>
<?php
echo $html->meta('icon', '/favicon.ico'); //サイト全体で共通のfaviconを使う場合
echo $html->css(array('foo', 'bar'));
echo $javascript->link(array('foo', 'bar'));
echo $scripts_for_layout;
?>
</head>

<body>
<div id="doc2" class="yui-t7">

<div id="hd">
ここにヘッダーを書く
</div><!-- #hd -->

<div id="bd"><div class="yui-g"><?php echo $content_for_layout; ?></div></div>

<div id="ft">
ここにフッターを書く
</div><!-- #ft -->

</div><!-- #doc/[2-4]?/ -->

</body>
</html>

少しくらいCSSやJavaScriptを書くだけなら、わざわざHelperを使わずに直接書いた方がいいかも。
JavaScriptは</body>の直前に書きたいが、これでは無理か...?



CakePHPで特殊な用途に使われるテーブルのフィールド名



CakePHP 1.2で bakeするメモ

CakePHP1.2では、bakeはこんな感じで実行できる。

cake bake

cakeコマンドはCAKE_HOME/cake/consoleディレクトリにあるが、bakeはアプリケーションを作りたいディレクトリ上で実行する必要がある。WindowsではCakePHP のおいしい食べ方: [1.2]Easy Bake on Windowsを参考にすると楽。オプションとしてappのパスを指定できた。
cake -app /path/to/app bake


bakeでのModelの作成はDBのテーブルを元にするので、DBにテーブルが1つも無いと怒られる。
テーブルを作ってからbakeすること。
Welcome to CakePHP v1.2.0.7296 RC2 Console
---------------------------------------------------------------
App : app
Path: CAKE_HOME/app
---------------------------------------------------------------
Interactive Bake Shell
---------------------------------------------------------------
[D]atabase Configuration
[M]odel
[V]iew
[C]ontroller
[P]roject
[Q]uit
What would you like to Bake? (D/M/V/C/P/Q)
> M
---------------------------------------------------------------
Bake Model
Path: CAKE_HOME/app/models/
---------------------------------------------------------------
Error: Your database does not have any tables.

bakeでModelを作るとオプションでvalidationも付けられる。
が、maxLengthなど値を指定するルールをbakeでどうやって指定するかわからない。

CakePHP1.2インストールメモ

CakePHPアプリケーションへのアクセスを http://example.com/cake とする場合のインストール手順のメモ。
(参考:The Cookbook :: 1.2 Collection :: マニュアル :: CakePHPによる開発

  1. ダウンロード
    • CakePHPのサイトからアーカイブをダウンロード
    • アーカイブを適当な場所(以下CAKE_HOMEと呼ぶ)に解凍
  2. Apacheの設定
    • 今回のようにアプリケーションのルートURLをサブディレクトリにする場合、そのままでは404 Bad Requestになってしまうので注意。
      CAKE_HOME/app/webrootにある.htaccessにRewriteBaseを追加すればOK。(参考:siwa32.com » CakePHPをはじめる6 サブディレクトリ運用まとめ
      <IfModule mod_rewrite.c>
       RewriteEngine On
       RewriteBase /cake
       RewriteCond %{REQUEST_FILENAME} !-d
       RewriteCond %{REQUEST_FILENAME} !-f
       RewriteRule ^(.*)$ index.php?url=$1 [QSA,L]
      </IfModule>
  3. 動作確認
    • http://example.com/cake/ にアクセスして、CakePHPが動作することを確認
  4. DB接続の設定(参考:The Cookbook :: 1.2 Collection :: マニュアル :: CakePHPによる開発 :: 環境設定 :: データベースの設定
    (※これはbakeを使っても設定できる)
    • CAKE_PHP/app/configにあるdatabase.php.defaultをコピーしてdatabase.phpというファイルを作る
    • database.phpを編集
      var $default = array(
       'driver' => 'mysql',
       'persistent' => false,
       'host' => 'localhost',
       'login' => 'USER_NAME', //DBユーザー名
       'password' => 'PASSWORD', //DBのパスワード
       'database' => 'cake', //DB名
       'encoding' => 'utf8', //MySQLで日本語を扱うため
      );
    • 編集してから http://example.com/cake/ にアクセスすると、DB関連のメッセージのメッセージがGREENになる

楽天アフィリエイトのPC用 URLと 携帯用URLとの違い

楽天アフィリエイトのPC用URLと携帯用URLの関連性について。公式な資料が無いので推測を元に調査してみる。


楽天Webサービスでの説明を見ると、PC用と携帯用のアフィリエイトURLは別になっている。

http://hb.afl.rakuten.co.jp/hgc/[アフィリエイトID]/?pc=[商品URL(PC)]
もしくは、
http://hb.afl.rakuten.co.jp/hgc/[アフィリエイトID]/?m=[商品URL(モバイル)]
ちなみに、楽天Webサービスで商品URLを取得する場合にはRequestのパラメータとしてPC用か携帯用かどちらかを指定するため、両方の商品URLを1度に取得することはできない。


楽天のアフィリエイト作成ツールでは、PC・携帯共通URLを作成できる。

例(分かりやすいようにURLデコード&改行してある)
http://hb.afl.rakuten.co.jp/hgc/[アフィリエイトID]/?
pc=http://www.rakuten.co.jp/verjus/827100/665544/705842/#845704
&m=http://m.rakuten.co.jp/verjus/i/845704/

これを見るとPC用URLから携帯用URLを作成できそうだが、楽天の商品URLには下記の2種類のタイプがある。
A. http://item.rakuten.co.jp/monoshop/dul_ch06_k282/

B. http://www.rakuten.co.jp/t-plaza/710008/716540/#727421
Aが昔ながらのURL?
Bは携帯からも見られる商品用のURL?
いくつかデータを見てみると、Bの場合は色違いなどで複数の商品から選べるアイテムのようだ。この例の場合、"710008" "716540"の2種類。4種類くらいのアイテムもあり、その場合スラッシュ区切りで4つのコードが並ぶ。おそらく最後のシャープ付のIDで内部的には制御してるようだ。

さらに調べると、携帯版の楽天とPC向けの楽天では商品数がかなり違う。PCの方が数倍多い。
しかも、携帯版の楽天はドメインがwww.rakuten.co.jpのアイテムのみが対象になってる(ような気がする)。(数えるほどしか調べてないのでたまたまそういうデータを見ただけかもしれないが。)

ただし、wwwで始まる商品でも携帯版楽天で探してもヒットしないものもあるので、wwwで始まれば携帯からアクセスできるというわけではないようだ。
よく見たらwwwで始まりPCでしかヒットしない商品は全て品切れだった。たくさんのデータで検証したわけではないが、このサブドメインの違いで携帯からのアクセスが可能か判断できそう。


結論(ただし推測)
サブドメインがwwwの商品のみ、携帯版楽天からアクセスできる。その場合、下記のアフィリエイトURLによりPC・携帯で共通のアフィリエイトリンクになる。
(見やすくするために改行したが実際には改行しない。また、パラメータのURL部分はURLエンコードすること)
http://hb.afl.rakuten.co.jp/hgc/[アフィリエイトID]/?
pc=http://www.rakuten.co.jp/[ショップID]/.../.../.../#[商品ID的なもの]
&m=http://m.rakuten.co.jp/[ショップID]/i/[商品ID的なもの]/
モバイル用の"i"の部分とかは怪しいかも。

2008年9月3日水曜日

Google Chrome

Google Chrome触ってみた。速い速い。昔のOperaを思い出す。それ以上に速い。

JavaScriptコンソールやHTML解析っぽいのもデフォルトで付いてる。

アプリケーションショートカットもなかなか面白い。htaみたい。社内向けシステムとかで余計な上部メニューを消したい場合なんかにもいいかも。

これでExtensionとは言わないまでもGreaseMonkey(CreamMoneky?)くらいあれば乗り換えるかも...。せめてGoogle Customize相当のものがあればなあ。

2008年9月1日月曜日

Google Reader Filterで日本語のキーワードを扱う方法

Google Readerで指定したキーワードを含む記事をグレイアウトしたりハイライトしたりするGreaseMonkeyの「Google Reader Filter」。(そのまんまな名前だ。)

日本語が 使えないという指摘があるが、実際には使える。
ただし、キーワードの前後が半角スペースか先頭か末尾でないとヒットしない
これは日本語に限った話ではないが、単語単位で半角スペースが入る英語では問題が無いため、日本語の問題に見えたのだろう。


具体的なコードの該当箇所は下記のとおり。

_getRegExp:function (items) {
 return new RegExp("(^| )("+items.join("|")+")($| )","i");
}
JavaScriptと正規表現が読める人には察しが付くだろうが、キーワードをorで繋いで、前に「先頭or半角スペース」、後ろに「末尾or半角スペース」という条件でマッチさせている。

なので、日本語をキーワードに使うには、キーワード欄に
.*あああ.* (「あああ」を含むタイトルをマッチ)
いいい.* (「いいい」で始まるタイトルをマッチ)
.*ううう (「ううう」で終わるタイトルをマッチ)
というように書けばOK。

キーワードは正規表現として使われるので、他の正規表現を埋め込んじゃってもOK。
逆に正規表現で特別な意味を持つ記号はエスケープしないと正しく動かない。


上記のような書き方が面倒な人は、GreaseMonkeyのファイルを開いて該当箇所を下記のように変更すれば「.*」の記述が不要になる。
キーワードの使い方によっては幅広くヒットしすぎて使い辛そうだが。
_getRegExp:function (items) {
 return new RegExp("("+items.join("|")+")","i");
}

2008年8月28日木曜日

MySQLをオンラインでバックアップ

MySQL5.0以降の話。(MySQL 4.1 リファレンスマニュアルには記述が無いが、MySQL 5.0 Reference Manualには記述があるので。)

InnoDBではテーブルのロック("--lock-all-tables" 省略形は-x)をせずにmysqldumpでオンラインバックアップができるらしい。
参考:MySQL AB :: MySQL 5.1 リファレンスマニュアル :: 7.12 mysqldump — データベースバックアッププログラム(ページの一番下の方)


使用例

mysqldump -u USER_NAME -pPASSOWRD -A --single-transaction > /path/to/backup/dir/mysqldump.sql

"-p"とパスワードの間にはスペースを入れない。
"-A"は"--all-databases"の省略形。
"--single-transaction"はテーブルのREAD ONLYなロック?アプリケーションをブロックしないで済むようだ。 InnoDBのみ有効。
--single-transaction
このオプションはサーバからデータをダンプする前にBEGIN SQLステートメントを発行します。InnoDBといったトランザクションテーブルに対してのみ便利です。なぜなら、アプリケーションをブロックせずに、BEGINが発行された当時のデータベースの状態をダンプするからです。
このオプションを使用しているときは、一定の状態でダンプされるのはInnoDBテーブルのみだということを留意してください。例えば、このオプションを使用中にダンプされたMyISAMやMEMORYテーブルは状態が変化する可能性があります。

mysqldumpの出力はSQL。データベース・テーブル等のCREATE文やデータのINSERT文等が書いてある。
そのままSQLを実行すればリストアできる(はず)。

mysqldumpを使ったバックアップ・リストアは、データ量が多い場合には時間がかかるらしいので注意。

2008年8月15日金曜日

PHPで出力する文字列をまとめて変換する

ob_start()を使うと、出力する文字列をまとめてfunctionに渡すことができる。

bool ob_start ([ callback $output_callback [, int $chunk_size [, bool $erase ]]] )

この関数は出力のバッファリングをオンにします。出力のバッファリングを有効にすると、(ヘッダ以外の) スクリプトからの出力は実際には行われず、代わりに内部バッファに保存されます。

$output_callbackにはコールバックするfunction名を文字列として指定する。

ob_end_flush()等をしなければ、バッファにたまった文字列はPHPスクリプトの終了時にコールバックのfunctionに渡される。
なので、出力全体を変換したい場合は明示的にob_end_flush()する必要はない。

コールバックのfunctionにはバッファにたまった文字列が渡される。
コールバックのfunctionが戻り値として文字列を返すと、その文字列が出力される。

//例
ob_start('zenkaku2hankaku');

function zenkaku2hankaku($str) {
  return mb_convert_kana($str, 'ask');
}
なので、mb_output_handlerのように、文字列としてデータを受け取り戻り値も文字列の標準関数だと使いやすい。

また、ob_start()は重ねて実行できる。
出力バッファはスタッカブルであり、このため、他の ob_start() がアクティブの間に ob_start() をコールすることが可能です。この場合、ob_end_flush() を適切な回数コールするようにしてください。複数の出力コールバック関数がアクティブの場合、ネストした順番で逐次連続的に出力がフィルタ処理されます。

2回以上ob_start()を実行した場合、ob_start()を実行した順と逆の順番にコールバックのfunctionが呼ばれる。
<?php
ob_start('test2');
ob_start('test1');

echo '1st';

function test1($s) {
  return str_replace('1st', '2nd', $s);
}
function test2($s) {
  return str_replace('2nd', '3rd', $s);
}

// => "3rd"が出力される

YUI Grid.css用の XHTML 1.0 テンプレート

YUI: CSS Grid Builderで作ったHTMLの冒頭部分をXHTML 1.0 Strictにしたもの。

横幅は950pxでカラム分割無し、文字コードはUTF-8の場合。
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja" lang="ja">
<head>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8" />
<meta http-equiv="Content-Style-Type" content="text/css" />
<meta http-equiv="Content-Script-Type" content="text/javascript" />
<title>TITLE</title>
<!-- Keywordsはもう要らないと思う
<meta name="Keywords" content="FOO,BAR" />
-->
<meta name="Description" content="DESCRIPTION" />
<link rel="shortcut icon" type="image/x-icon" href="/favicon.ico" />
<link rel="stylesheet" type="text/css" href="some.css" />
<!-- フィードの記述は種類による -->
<link rel="alternate" type="application/rss+xml" title="FEED TITLE" href="http://www.example.com/feed.xml" />

<!-- スタイルシートは別ファイル化を推奨 -->
<style type="text/css"> /* ... */ </style> </head>
<body>
<!-- ここのidとclassは横幅等で変わる。YUI Grid Builderで調べるのが楽。 -->
<div id="doc2" class="yui-t7">
<div id="hd">
HEADER

</div><!-- #hd -->
<div id="bd">
<div class="yui-g">
MAIN
</div><!-- .yui-g -->
</div><!-- #bd -->
<div id="ft">
FOOTER
</div><!-- #ft -->
</div><!-- #doc/[2-4]?/ -->
<!-- charsetはhtml本体と同じなら不要 -->
<script type="text/javascript" src="some.js" charset="UTF-8"></script>
<!-- JavaScriptも別ファイル化を推奨 -->
<script type="text/javascript">
//<![CDATA[
...
//]>
</script>
</body>
</html>

2008/12/22 変更:JavaScriptのHTMLコメント化をCDATAに変更

htmlでボタンに表示する文字列を途中で改行する方法

htmlフォームのボタン系input要素はvalue属性の値をボタン上に表示するが、その表示する文字列を途中で改行する方法。 下記のように改行したい箇所に、改行コードの実体参照である「&#13;&#10;」を入れる。

<input type="button" value="この後で &#13;&#10; 改行してね" />
Windows版Safariでは、改行はするがボタンの高さが1行分なので半分見えなくなってしまった...。 もしかするとWindows以外では表示が崩れる?(改行コードも違うし。) 素直にbutton要素とか使った方がいいかも。
<button>この条件で<br />絞り込む</button>
ただしbutton要素だと、submitボタンとかresetボタンを作るにはJavaScriptで動きを付けないといけなくなるが。type属性でsubmitボタンにしたりresetボタンにしたりできるみたい。(2009/06/16 修正)

参考:
 改行コード(HTML, Java, URL & エスケープシーケンス)
 GAC なぜなにGAC->HTML

ホテル予約サイトの地図機能の比較

主に日本国内のホテル予約について。

  • るるぶトラベル
    • トップページのメイン部分にJavaScriptの日本地図。そこから詳細な地図にドリルダウンしていく
    • スクロール地図を選ぶと、真ん中にMapionの地図がある構成になる
      • 左側に絞込み条件、真ん中に地図、右側に地図範囲内のホテル一覧
      • Mapionの地図上のピンをクリックすると、地図の下に簡単なホテル情報を表示する
    • UIとしてよくできている
  • 楽天トラベル
    • 地図は独自の地図のドリルダウン
  • フォートラベル
    • 地図は独自地図のドリルダウン
  • 日本旅行
    • 国内宿泊予約では、ページ上部に地図・カレンダー・条件などの絞込みがあり、下側にホテル一覧がある
    • 地図は独自のJavaScript
    • 地図で地区を選ぶとリロードされ、メイン部分に範囲内のホテル一覧が表示される
  • まっぷるnet
  • 宿ぷらざ
    • 地図は独自地図のドリルダウン
  • yoyaQ.com
    • 価格.com系
    • 地図はGoogle Maps(都道府県の絞込みまではFlash)
  • J-reserve
    • 外国人向けの日本のホテルの予約サイト
    • 地図は独自のドリルダウン(全国/地方の2段階)
  • 東京ビジネスホテル予約.biz
    • 地図とホテル一覧をAjaxで表示
    • 地図はGoogle Maps
    • 予約まではできない

2008年8月14日木曜日

Delicious Bookmarksからデータが消えて PCがフリーズする問題の解決方法(追記:解決した!)

FirefoxのアドオンにDelicious Bookmarksというものがある。ショートカットからDeliciousへのPOSTができたりBookmarkをツールバーに表示したりと非常に便利なのだが、バージョンが2.0.95に上がったら壊れてしまった。(ローカルデータが認識できなくなりSyncを繰り返す。CPU負荷も高く、PCが固まる。)

しばらくこのアドオンを無効にしていたが、先ほどこの問題の解決策を見つけた。

It seems that 2.0.95 causes some trouble, but after I delete delicious.rdf file in my firefox profile directory, it seems works well. This is suggested at the forum in yahoo group described above. Worth to try, I guess, if you in trouble.
from Delicious Bookmarks のレビュー :: Firefox Add-ons
(※2008/8/13のXoraさんのレビュー)
Firefoxのプロファイルにあるファイル「delicious.rdf」を削除したら直るとのこと。
試しにやってみたら、確かに直った気がする。しばらく様子を見てみよう。(※追記あり!)

しかしXolaさんも書いているとおり、"And of course we still need a fix release."
Fixした時に今回の解決策(delicious.rdfを2.0.95に合った形にした)のせいでまたインストールし直しとかにならなければよいが。


追記:しばらくしてFirefoxを再起動したら、またSyncし始めちゃったよー

追追記(2008/08/21):
Delicious Bookmarks のレビュー :: Firefox Add-onsの"Work-around for 2.0.95 problems"をやったら解決した。
1) Log out of delicious.
2) Uninstall delicious addon 2.0.95.
3) Quit firefox
4a) Delete this file for XP: C:\Documents and Settings\\Application Data\Mozilla\Firefox\Profiles\.default\delicious.rdf
or
4b) Delete this file for vista: C:\Users\\AppData\Roaming\Mozilla\Firefox\Profiles\.default\delicious.rdf
5) Restart firefox and install delicious addon version 2.0.64

2.0.64は2つ前のバージョン。1つ前までは試してみたが、2つ前まで戻さなくちゃいけないとは。
今のところこれで以前のように動いている。
Deliciousからの新バージョンについての反応がまだ無いところを見ると、よほど深刻な問題なのか?!

追追追記(2008/08/22): 1つのPCでは解決したが、1つのPCではフリーズっぽくなる...HELP!

2008年8月12日火曜日

Google Msps ストリートビュー

我が家もばっちり映ってた。家の前に雪があるけど、何月頃に撮ったのかな?

2008年8月1日金曜日

del.icio.usが delicious.comに変わってた

普段、Firefoxのアドオン使ってるからdel.icio.usのサイトが変わってるのに気づかなかった。もうdel.icio.usではなく、deliciousなんだね。

機能的にはソートとかがちょっと増えたぐらい。レスポンスは早くなった気がしないでもない。
一番変わったのは見た目。とても見やすくなった。今まであまりにもテキスト表現に頼ってたのが良く分かる。やっぱり色とか線とかの表現力は大きい。

2008年7月30日水曜日

Amazon Web Serviceの Search Indexって

今はDVDってあるけど、将来はBlu Rayになるのかな?
それともDVDはDVDで残るのかな?
仕様変更による影響が大きそう…

2008年7月28日月曜日

Amazon Webサービスのパラメータ

一番よく使う商品の検索(ItemSearch Operation)の主なパラメータについてのメモ。

大元のリファレンスはAmazon Web Services: Amazon E-Commerce Service
フレームになっていてリンクし辛いので、説明ページへのリンクはフレーム内の個別ページへのリンクにした。

  • Operation
    • リクエストの種類。(必須項目)
    • 固定で「ItemSearch」
  • SearchIndex
  • Keywords
    • 任意のキーワード
    • タイトルや著者など多くのデータを対象に探してくれるので、アバウトな検索に便利。
  • ItemPage
    • 検索結果ページ数。ItemSearchでは1回のリクエストで最大10個のデータを返す。11個目以降が欲しければページ数を指定する。
    • 何も指定しなければ1ページ目が返される。つまりトップ10.
  • Sort
    • 並び順
    • 説明ページ:Sort Values for JP
    • SearchIndexがBlendedの場合は指定できない(エラーになる)
    • リリース順で取得したい場合に、DVD・CDと本ではパラメータが違うので注意
  • ResponseGroup
    • 取得データ内容
    • 説明ページ:Response Groups
    • 「Small,Images」あたりを基本に、必要に応じてTracksとかCustomerReviewsとかを追加すればたいてい間に合う

WWW SQL Designerの Save ・ Loadをスマートに改良

WWW SQL Designerの改良第2弾。(第1弾はWWW SQL Designerのインストール&設定。)
WWW SQL Designer(以下WSDと略す)でServer側にデータを保存する場合の操作を楽にする。

ちなみにWWW SQL Designerの現在の最新版は2.1.1。2.0.1からそれほど変更はなさそう。


初期表示時のデータのロード
これは改良ではなくもともと本体が持つ機能。
ドキュメントには書いてないが、WSDでは下記のようにURLに保存時の名前を付けてアクセスすると、保存されているデータを初期表示できる。

http://localhost/wsd/?keyword=foo


保存時の名前のセット
保存する時に名前を訊かれるが、デフォルトが空なのでいちいち入力するのが面倒。上記のようにURLにkeywordがある場合、それをデフォルトで表示すると便利。
js/wwwsqldesigner.jsの1197行目を下記のように変更する。
var name = prompt(_("serversaveprompt"),"");

var name = prompt(_("serversaveprompt"), location.href.split("=")[1]);


ロード時のURLのリセット
上記の保存時の名前のセットする改良を生かすには、ロード時にはロードする名前に合わせてURL中のkeywordが変わるようにしたい。
js/wwwsqldesigner.jsの1208行目(「SQL.IO.prototype.serverload = function(e, keyword)」の直下)に下記を追加する。
if (!keyword) {
 var name = prompt(_("serverloadprompt"),"");
 if (name) {
  location.href = "?keyword=" + encodeURIComponent(name);
 }
 return;
}

これでロード時にそのkeywordのURLに遷移するようになる。

レンタルサーバーでメール受信時にプログラム起動する方法


さくら

  • maildropというメール配信プログラムを使っているため、.forwardによるメール処理設定は使えない
  • maildropでは、メールアカウントごとにmailfilterを設定すればプログラムの起動など好きな処理が可能
  • catch all(※1)は無いので、virtualなアカウントで受信してプログラムを起動することはできない
  • Gmailのようにメールアカウントの後ろに"+"を付けてメールアカウントを擬似的に増やすことはできないようだ
  • 1つのメールアドレスで複数の処理やデータを振り分けるには、下記の方法が考えられる
    • サブドメインで振り分ける(@の左側が同じなら、異なるサブドメインでも同一アカウントとして扱われるらしい)
    • 件名にKEYを入れてそれで判断する(参考:mailto:について
  • メールの自動返信だけならmailfilterでmailbotを使えばできる


XREA


X Server


結論
特定のサブドメインに来るメールをプログラム側で宛先メールアドレスごとに処理をしたい場合、X Serverを使うのが良さそう。(試したわけでは無い。要確認。mailfilterを編集しなければいけない?件が気になる)
(例)123.shop@sub.example.com(123の所は任意の数字)に来たら、メールの振り分けで「宛先が.shop@sub.example.comのメールは/var/php/reply.phpに渡す」という設定をしておく


※1:「catch all」とは、存在しないメールアカウントへのメールを特定のメールアドレスに転送する機能のこと

CentOSで vsFTPdに 匿名(anonymous)でアクセス

自分しかアクセスしない(できない)FTPサーバ(vsFTPd on CentOS)にanomnymousでファイルを転送できるようにしたい。
(vsFTPdやファイアウォール等の他の設定は既にしてある。)


  1. vsFTPdで使うディレクトリの所有者設定(グループは関係ないかも)
    mkdir /var/ftp/my
    chown ftp:ftp /var/ftp/my
  2. vsFTPdの設定ファイルを編集する
    vi /etc/vsftpd/vsftpd.conf
  3. anonymousについての設定をする
    # Allow anonymous FTP? (Beware - allowed by default if you comment this out).
    anonymous_enable=YES

    # obviously need to create a directory writable by the FTP user.
    anon_upload_enable=YES
  4. vsFTPdを再起動
    /etc/init.d/vsftpd restart

Windowsのコマンドプロンプトから接続してみる
  1. 接続(-Aはanonymousにするオプション)
    C:>ftp -A 192.168.1.xxx
    Connected to 192.168.1.xxx.
    220 (vsFTPd 2.0.5)
    331 Please specify the password.
    230 Login successful.
    Anonymous login succeeded for xxx@xxx
  2. 最初いる場所は「/var/ftp」なので、所有者をftpにしたディレクトリに移動
    ftp> cd my
    250 Directory successfully changed.
  3. ファイルを転送
    ftp> put c:test.txt
    200 PORT command successful. Consider using PASV.
    150 Ok to send data.
    226 File receive OK.
    ftp: 24 bytes sent in 0.00Seconds 24000.00Kbytes/sec.
  4. これで/var/ftp/my/test.txtに転送された。このファイルのアクセス権限を見てみる
    -rw------- 1 ftp ftp
  5. vsftpd.confのlocal_umaskは"022"にしてあるが、これはanonymousには適用されないようだ


参考:
 floatingdays: Linuxコマンド備忘録
 How to build Internet Server with Linux: ftpのセキュリティ
 ファイルのパーミッション、アクセス権限について (Unix Linux)


XMailからバッチファイルを起動する方法

XMailで、カスタムドメイン処理コマンドエイリアスを使ってWindows上のバッチファイルを実行する方法。
基本的に使い方はコマンド実行機能 - xmailserver.jpに書いてあるが、一部このままでは動かないのでメモ。


バッチファイルを使う例
(パラメータ間のスペースは実際にはタブで書く)

"external" "1" "0" "C:test1.bat" ""
"external" "1" "0" "C:test2.bat" ""


ポイント
  • externalコマンドのパラメータが3つだと動かないので、空でも4つ目のパラメータを渡す必要がある
  • 優先度(上記例では1)を0にすると環境によっては(?)実行されないことがあるので1にした方が良さそう
  • メールのファイルを渡す場合、タイムアウト秒数(上記例では0)を余裕を持った数字(300とか)にする。そうしないと外部プログラムを実行する前に、XMailがファイルを削除してしまう可能性がある(参考:コマンド実行機能 - xmailserver.jp
  • バッチファイル実行時のディレクトリは下記になる。間違えてバッチファイルからの相対パスを書かないように注意
    C:WINDOWSsystem32
  • コマンドは複数行並べて書くことができる(参考:コマンド実行機能 - xmailserver.jp
  • コマンド実行機能 - xmailserver.jpにはコマンドとしてWindowsのコマンドやバッチファイルを指定できると書いてあるが、実際にはできないようだ。(あるいはやり方が特殊なのか?)
    "コマンド" には XMail の内部コマンド、OS の内部コマンドや外部コマンド、シェルスクリプト(UNIX)やバッチファイル(Windows)、標準入出力に対応した任意のプログラムなどを指定できます。

2008年7月21日月曜日

Amazonアソシエイト用のURL

3分LifeHacking:Amazonの長いURLを短縮表示する - ITmedia Biz.IDによると、下記のように短くできるらしい。
アフィリエイトの場合でも「構わない」と書いてある。

http://amazon.jp/dp/[asin]


しかし、hxxk.jp - Amazon の http://www.amazon.co.jp/dp/ASIN No. 形式ではアソシエイト ID が使えない !?によると、上記ではアソシエイトが有効にならないとのこと。
(※下の追記参照)
アソシエイトが有効になる短い形は下記らしい。
http://amazon.jp/o/ASIN/[asin]/[affid-22]/ref=nosim

上記のURLの最後の「ref=nosim」(noismじゃない!)は、商品の詳細ページに直接遷移させるために付けてある。
これにより以前はアソシエイトによる収入が増える可能性が高くなっていたが、現在は収益への直接の影響はないようだ。(参考:Amazonアソシエイトの紹介料率システム変更にともなう戦略の変化 [絵文録ことのは]2007/01/28

ただし上記の参考リンク先に書いてあるとおり、その商品の詳細にリンクを貼りたい場合(その商品の関連記事を書いた場合など)、ref=nosimを付けておいた方が親切になるケースが多いと思う。(下記の追記参照)


(2011/5/26 追記)
「http://amazon.jp/dp/[asin]」形式のURLの場合は「http://amazon.jp/dp/[asin]?tag=[affid-22]」というようにクエリーストリングとしてトラッキングID(アフィリエイトID)を付ければ有効みたい。(文字数は「http://amazon.jp/o/ASIN/[asin]/[affid-22]」形式と同じ。)
また、「http://amazon.jp/o/ASIN/[asin]/[affid-22]」形式の場合の「ASIN」は小文字でもいいみたい。
Amazon公式のリンクの動作確認ツールで確認すると便利。

それから、今はref=nosimを付けても付けなくても同じページになるようだ。


くまくまーさんのサイトを見やすくするuserContent.css

Rails関連の参考記事が充実している「ヽ( ・∀・)ノくまくまー(ノk|*‘-‘)<ノリマツ!愛だよ、愛!)」。
良いサイトなのだが、記事によっては記事部分の横幅が広すぎて横スクロールしないと読めないのが読み辛い。

FirefoxのuserContent.cssで何とかしよう。

@-moz-document url-prefix("http://wota.jp/ac/") {
 div.day {
  max-width: 950px;
 }
}

見やすくなった。



PHPで fgets()する時の改行コード

Macの場合、php.iniで「auto_detect_line_endings = on」を指定すれば、改行コードを意識しなくて良いらしい。
auto_detect_line_endingsはデフォルトではコメントアウトされている。

注意: マッキントッシュコンピュータ上で作成されたファイルを読み込む際に、 PHP が行末を認識できないという問題が発生した場合、 実行時の設定オプションauto_detect_line_endings を有効にする必要が生じるかもしれません。

php.iniにはこう書かれている。
; If your scripts have to deal with files from Macintosh systems,
; or you are running on a Mac and need to deal with files from
; unix or win32 systems, setting this flag will cause PHP to
; automatically detect the EOL character in those files so that
; fgets() and file() will work regardless of the source of the file.
(ここでいう「Mac」とは、OS Xになる前のバージョン9までの古いMacを指すと思われる。参考:改行コード - Wikipedia


これは逆に言うと、Macが関わらないLinux・Windowsだけの環境なら、auto_detect_line_endingsの設定も含めてfgets()での改行コードについて特に意識しなくてよいということだ。

試しにWindows上のPHPで改行コードが「CR+LF」の場合と「LF」の場合でfgets()結果に違いがあるか実験してみたところ、違いは無かった。
(auto_detect_line_endingsはコメントアウトのまま。)
しかし、改行コードが「CR」の場合、全て1行目として扱われてしまった...。

テストに使ったコードは下記の通り。
<?php
$fp = @fopen('test.php', 'r');
$i = 1;
if ($fp) {
 while (!feof($fp)) {
  echo "$i : " . fgets($fp);
  $i++;
 }
 fclose($fp);
}


あと、fgets()で取得した文字列の最後には改行コードが付いているので注意。不要な場合はrtrim()で取り除ける。

ブログ アーカイブ

tags