lunarpagesを解約した

2年間お世話になった、海外のサーバー、lunarpagesを解約した。

転送量・容量無制限、言語はPHP、Ruby、PEAR、PYTHONに対応、MySQLデータベース数無制限で、ひと月たったの$4.95と、数字だけを見ると日本では考えられない太っ腹さですが、数字では見えない問題もあり、3年目の更新はしませんでした。

一番の問題はサポート。
海外のホスティング会社なので当然、日本語でのサポートは受けられない。

で、英文を書くのは面倒なので、ネットで調べてみたりするのですが、日本語の情報は少なく、結局英語を読まないといけない。

しかも仕様変更が割と頻繁に起こったりして、仕様変更を知らせるニュースレターをほったらかしにしてると完全に浦島太郎になってしまいます。(最近まで容量が無制限になっていたことを知らなかった。)

そして、速度。
もっさり感はどうしようもない。

慣れれば気にならないのですが、訪問者は慣れてないですからね…。
下りももっさりしてますが、上りはもっとつらい。
FTPでアップロードしてると、途中で切断されてしまうことが頻繁に起こります。

最後に、CPU使用率の制限がきびしい。これは盲点。
1万PVを超えるようなサイトで、動的に処理していたりすると、リソースの使いすぎだと、お叱りのメールがきます。

転送量が無制限だからと、アクセス数の多いサイトを置いたりすると痛い目をみます。ちなみにメールを無視すると追い出されます。返金もなし。

ということで、解約しました。

いろいろと書きましたが、これらの問題を割り切れる方にとっては、ホントに、ものすごくお得なサービスだと思います。

余談。
解約メールをすると、1年間で半額の$50にまけるけど、どう?と言われました。ちょっと心が動きましたが、丁寧にお断りしました。拙い英語で。

[c#]複数のコントロールで共通のイベントハンドラを呼び出すには

よく使われるテクニックみたいなんですが、知らなかったのでメモ。

イベントハンドラは、1コントロール1イベントハンドラという決まりはないので、複数のコントロールで1つのイベントハンドラを呼び出すことができる。

たとえば、異なる2つのボタンがあり、ボタンのクリックイベントで、テキストボックスの値をクリックしたボタンのNameプロパティの値にする場合。

個別にイベントハンドラを用意した場合のコード:

private void button1_Click(object sender, EventArgs e)
{
    this.textBox1.Text = button1.Name;
}
private void button2_Click(object sender, EventArgs e)
{
    this.textBox1.Text = button2.Name;
}

で、これを1つにまとめる場合。

private void button1_Click(object sender, EventArgs e)
{
    Button btn = null;
    // senderとbutton1の型が同じ場合
    if (sender.GetType() == this.button1.GetType())
    {
        // senderをButton型として扱う
        btn = (Button)sender;
        // テキストボックスの値をsenderのNameプロパティにする
        this.textBox1.Text = btn.Name;
    }
}

あとは、button2のクリックイベントにbutton1のクリックイベントを指定するだけ。

コード量は多くなりましたが、同じような処理をする複数のコントロールがある場合は、1つにまとめた方がコード量が少なく済む。

CheeseCake:投票機能

今度作るシステムに投票機能が必要だったので調べてみた。確認したかったのは、どのように重複投票チェックをしているかの一点です。

投票履歴テーブル

CheeseCakeでは、投票の履歴を記録し、投票のたびに投票履歴がないかチェックしています。
投票履歴の記録に使われているテーブルはratinghistories。

mysql> show fields from cc2_ratinghistories;
+------------+-------------+------+-----+---------+----------------+
| Field      | Type        | Null | Key | Default | Extra          |
+------------+-------------+------+-----+---------+----------------+
| id         | int(11)     | NO   | PRI | NULL    | auto_increment |
| photo_id   | int(11)     | NO   | MUL | NULL    |                |
| visitor_id | varchar(32) | NO   |     | NULL    |                |
| created    | datetime    | NO   |     | NULL    |                |
| modified   | datetime    | NO   |     | NULL    |                |
+------------+-------------+------+-----+---------+----------------+

投票された写真のIdをphoto_idに、投票者のIdをvisitor_idに格納します。

visitorIdのゲット/セット

Cookieにvisitorキーの値が格納されている場合は$visitorIdにセットし、ratinghistoriesテーブルからレコードが存在するかチェックしています。Cookieに値が格納されていなかった場合は逆に値を格納。

if ($this->Cookie->read('visitor')){    $visitorId = $this->Cookie->read('visitor');    $hasVoted = $this->Ratinghistory->hasAny('Ratinghistory.photo_id = '.$photoId.' AND Ratinghistory.visitor_id = "'.$visitorId.'"');}else{   $hasVoted = false;   $visitorId = md5(uniqid(time()));   $this->Cookie->write('visitor', $visitorId, true, '1 month');}

Cookie->writeの4つ目のパラメータに’1 month’を指定し、visitorIdを1ヶ月保存しています。これで、一ヶ月間は重複して投票できなくなるわけか。なるほど。

はじめての投票の時のみ投票処理

あとは、投票チェックの結果にあわせて処理を変えればいいだけですね。

if ($hasVoted){
    $message = __('You can only vote once per photo.', true);
    $this->Session->setFlash($message, 'default', array(), 'error');
}else{
    $this->__updateRating($photoId, $visitorId);
    $message = __('Thanks, your vote has been counted.', true);
    $this->Session->setFlash($message, 'default', array(), 'success');
}

学んだこと/調べたこと

  • 重複チェックのパターン。投票以外にも使えそう。
  • 1.2で実装されたCookieコンポーネントの使い方。CookieコンポーネントのAPIもはじめて読んだ。

CheeseCake:タグ検索

本日のピンポイント・コードリーディングはCheeseCake2のタグ検索。

HABTMで関連付けられているモデルでのタグ検索(一方のテーブルのカラムをキーにしてもう一方のテーブルのレコードを抽出する)方法ではまったので、CheeseCakeではどのようにタグ検索を実現しているか調べてみた。

タグ検索の方法

PhotoモデルとTagモデルはhasAndBelongsToMany(HABTM)で関連付けられています。

タグ検索は、2つのモデル間を結びつけるphotos_tagsを介して行いますが、CakePHP hasAndBelongsToManyでページング(SQL LIMIT)とかを設定するにもあるとおり、hasMany関連での検索と同じ方法ではデータを抽出することができません。

× $data = $this->Photo->findAll('Tag.id'=>$id);

↑ PhotoはTagをLEFT JOINしていないので、Tag.idでの条件指定はできない

それでは、CheeseCakeではどのようにタグ検索を行っているのでしょうか。
CheeseCakeでは、以下のようにquery文を発行してデータを抽出しています。

return $this->query(  'SELECT '.     $fields.',     COUNT(DISTINCT t.tag) AS uniques   FROM '.    $prefix.'photos Photo,'.    $prefix.'photos_tags pt, '.    $prefix.'tags t   WHERE     Photo.id = pt.photo_id    AND t.id = pt.tag_id    AND t.tag IN ("'.implode('", "', $tags).'")'.$conditions.'   GROUP BY     pt.photo_id   HAVING      uniques = '.count($tags).   'ORDER BY     Photo.created DESC   LIMIT '.$offset.', '.$limit);

上記のコードがPhotoモデルのpaginateアクションに記述されています。queryを発行する以外にも方法はありますが、他の方法と比べて自由度は高い。

Cakeのメソッドに頼るよりも、自分でクエリを作成したほうが容易く処理を実装できることもある、ということは覚えておきたい。

EMチャージのおせっかいな自動切替システム

イー・モバイルは人を騙す

はっきり言って私は騙されました。
私はemobileのデータカードを使っていて、emチャージの30日定額プランを選択していたはずが、知らない間にスタンダードプランという、使った分だけ請求されるプランに切り替わっていて、トータルで78,750円もクレジットカードで支払っていました!!!

イー・モバイル EMチャージ導入メモでも書きましたが、私もEMチャージという、プリペイド方式のサービスを先月20日に契約しました。引用先ブログ主と同じく、10,000円分のチャージ付のデータカードを購入後、30日定額プランを設定。で、昨日、たった数時間で5,800円分のチャージを消化してしまいました。

当時から「EMチャージで自動チャージは危険」という声があり、とりあえず自動と名のつくものは無効にしておこうと思い、自動チャージと、自動プラン更新を無効にしておきました。

するとどうなったか。

  1. 30日定額プランが終了
  2. 31日目の24:00に従量型のスタンダードプランに自動で切り替わる
  3. 切り替わったことに気づかず、そのまま使用
  4. 突然EMチャージログイン画面が表示される(チャージが0になったときに表示される)
  5. 5,800円残っていたチャージが残り4円になっていた

自動はダメという先入観を持ち、説明も読まずに自動プラン更新を無効にしていたのは明らかに私に責任があるのですが、もし自動チャージを有効にしていたらと思うとぞっとします。

ちょっとした手違い、勘違いでパケ死してしまう今のシステムはやっぱり、問題があると思います。定額→スタンダードプランに自動で切り替わるシステムが問題なわけで、こういったトラブルをなくすためには、おせっかいなこの自動切換システムを廃止するべきではないでしょうか。

テストデータジェネレーター:個人情報テストデータ生成ツール

氏名、郵便番号、住所など、個人情報に関するテストデータを作成するときに便利なツール。
タブ、カンマ、スペース、SQL区切りで、氏名(カナ・半角カナ・かな・漢字)、住所、郵便番号、電話番号、西暦など、計36種類のデータを生成することができる。

区切方法別の、生成されるデータの拡張子は以下のとおり。
タブ :.txt
カンマ :.csv
スペース:.txt
SQL : .sql

さらにテンプレートを加工し、柔軟に出力データの体裁を変更できます。

個人情報テストデータ生成ツール

OpenOffice Calcでグリッド線を消す方法

OpenOffice Calcでグリッド線を消すのに手間取ったのでメモ。

メニューバーの「ツール(T)」からオプション(O)を選択 → OpenOffice.org Calcを展開してグリッドをクリック → グリッド線を表示する(I)のチェックを外す。

あー、でもこれって、Calcへの設定であって、ファイルに設定できるわけじゃないんですね。
ファイルに設定する方法ってあるのかな。

イー・モバイル EMチャージ導入メモ

引越し先のアパートにネット環境がなく、工事もさせてもらえないのでモバイル通信することにした。

EMチャージ|イー・モバイル

あらかじめチャージしておいた金額から料金を支払う前払い方式のサービスで、クレジットカードさえあればネットから契約し、データカードが送られてきた時点で利用できる。
もちろん工事の必要はなし。

1時間・1日・7日・30日定額があり、使いたいときに即日で利用できるのが利点。
導入までの流れをメモしておきます。

この投稿の続きを読む »

Mashupedia、3月31日にて閉鎖

Web APIと、それを利用したマッシュアップサービスの紹介を行っていたMashupediaが3月31日に閉鎖するそうです。

Mashupedia閉鎖のお知らせ

いつもMashupedia(マッシュペディア)をご利用いただきありがとうございます。
Mashupediaは平成20年3月31日をもって閉鎖することになりました。

この投稿の続きを読む »

サイドバーにピクセル広告を掲載するブログ

ピクセル広告で広告スペースを販売し、100万ドル、日本円にして1億もの広告費を稼いだサイト、The Million Dollar Homepageが日本でも有名になり同じようなピクセル広告ページが乱立した時期がありました。

あれから2年。最近はYou the Desigherのように、サイドバーにピクセル広告を貼りつけたサイトが増えているようです。

この投稿の続きを読む »