伊藤清徳の垂直落下式ムーンサルトプレス

PerlとかPHPとかMySQLとか...がんばっても8割だ。

Category: 未分類 (page 2 of 4)

YiiでInter-Mediatorを使ってみる

INTER-MediatorというPHPアプリケーションフレームワークがあります。
HTMLからのDBカラム指定でデータが呼び出せたり、
Javascriptの制御でDB操作ができたりなど、なかなか重宝するフレームワークです。

が、必ずしも万能というわけではないのかなというところがあり、
私はSymfonyなどに代表されるMVCフレームワークにINTER-MEdiator(以下、IMと略す)を統合して、
利用しています。

以前はCodeigniterにIMを統合するという記事を書きましたが、今回はYiiに統合をしてみます。


Yii?

PHPのフレームワークといえば?というところで最初にあがってくるようなフレームワークではないですが、柔軟で高速で、かつ、スカッフォールディングなどベースの生成が頭がいいので、気に入って利用しています。他方CakePHPほどの「なんでも感」はないので、PHPerとしての「地力」が試されるフレームワークであると思っています。


早速やってみましょう

これよりさきはMySQLへの接続を前提としてお話をすすめます。

IMのファイルは、yiiのアプリケーションディレクトリ(通常であればprotected)に配置します。

/protected/Inter-Mediator/...

のような感じですね。
特に何かコマンドを打つ必要はありません。


設定ファイルの書き換え

データベースへの接続設定をIMでも使いまわせるようにするために、
初期値ではメイン設定に閉じ込められているデータベース設定を、
別ファイルに移します。

/protected/config/main.phpの

'db'=> array(
			'connectionString' => 'mysql:host=localhost;dbname=dbname',
			'emulatePrepare' => true,
			'username' => 'user',
			'password' => 'pass',
			'charset' => 'utf8',
		), 

の値の部分をカットして、

'db'=> require dirname(__FILE__) . '/database.php'

とします。新規に/protected/config/database.phpを作成して、その中を

<??php
return array(
			'connectionString' => 'mysql:host=localhost;dbname=dbname',
			'emulatePrepare' => true,
			'username' => 'user',
			'password' => 'password',
			'charset' => 'utf8',
		);

とします。
さらに、main.phpのほうには、Yiiのセッション機能を使えるようにするために、加筆をします。
(IMの設定情報をセッションで保持することで柔軟に利用できるようにします)

//DBを外に
		'db'=> require dirname(__FILE__) . '/database.php',
		
		
		//セッションを追加
		'session'=>array(//追加
				'class'=>'CDbHttpSession',//追加
				'sessionTableName'=>'sessions',//追加
				'connectionID'=>'db',//追加
		),

先ほどのDBの設定の部分の下に、セッションを利用可能にしておきます。
そして、下記に説明するヘルパを自動読み込みさせるために、サードパーティーライブラリのフォルダを自動ロードするように設定します。

	'import'=>array(
		'application.models.*',
		'application.components.*',
	),

とします。

	'import'=>array(
		'application.models.*',
		'application.components.*',
		'application.vendor.*',
	),

に書き換えます。
設定ファイルの書き換えは以上。


ヘルパファイルの作成

続いて、IMの設定をラクにするヘルパファイルを作ります。
/protected/vendor/ImHelper.php
を作成し、

<??php
YiiBase::import('application.Inter-Mediator.*');
class ImHelper
{
	//デバッグ
	private static $debug = FALSE;
	
	// ----------------------------------------------------
	
	/**
	 * IMコードのセット
	 */
	public static function setImCode( $im1, $im2 = array(), $im3 = array() )
	{
		//データベース設定をロードしてIMの引数に設定
		$database = require YiiBase::getPathOfAlias('application.config') . '/database.php';
		$im3['db-class'] = 'PDO';
		$im3['dsn'] = $database['connectionString'];
		$im3['user'] = $database['username'];
		$im3['password'] = $database['password'];
		
		
		//一時コードの発行
		$code = sha1( uniqid( '', true ) );
		$data = array(
			'im1' => $im1,
			'im2' => $im2,
			'im3' => $im3,
			'debug' => self::$debug
		);
		Yii::app()->session['im_temporary_code_' . $code] = $data;
		
		return $code;
	}
	
	// ----------------------------------------------------
	
	/**
	 * IMコードの取得
	 * @param type $im 
	 */
	
	public static function getImCode( $code )
	{
		global $callURL;
		$callURL = Yii::app()->createAbsoluteUrl( 'im/get', array('code'=>$code) );
		require_once 'INTER-Mediator.php';
		$params = Yii::app()->session['im_temporary_code_' . $code];
		//echo 'var test = ' . json_encode($params) . ';';
		IM_Entry( $params['im1'], $params['im2'],  $params['im3'], $params['debug'] );
	}
	
	// ----------------------------------------------------
	
	/**
	 * URL作成
	 */
	public static function getUrl( $im1, $im2 = array(), $im3 = array() )
	{
		$code = self::setImCode($im1, $im2, $im3);
		return Yii::app()->createAbsoluteUrl( 'im/get', array('code'=>$code) );
	}
	
	// ----------------------------------------------------
}

と書いて起きます。

YiiBase::import('application.Inter-Mediator.*');

で、IMのフォルダ内をオートロードの対象にしておきます。


IM自体の改造

IM自体の改造が必要です。

まず、INTER-Mediator.phpを改造します。

if (!class_exists('Crypt_RSA')) {
    require_once($currentDir . 'phpseclib' . DIRECTORY_SEPARATOR . 'Crypt' . DIRECTORY_SEPARATOR . 'RSA.php');
}
if (!class_exists('Crypt_Hash')) {
    require_once($currentDir . 'phpseclib' . DIRECTORY_SEPARATOR . 'Crypt' . DIRECTORY_SEPARATOR . 'Hash.php');
}
if (!class_exists('Math_BigInteger')) {
    require_once($currentDir . 'phpseclib' . DIRECTORY_SEPARATOR . 'Math' . DIRECTORY_SEPARATOR . 'BigInteger.php');
}

//Yiiのオートローダーを一旦解除
spl_autoload_unregister(array('YiiBase', 'autoload'));


if (!class_exists('Crypt_RSA')) {
    require_once($currentDir . 'phpseclib' . DIRECTORY_SEPARATOR . 'Crypt' . DIRECTORY_SEPARATOR . 'RSA.php');
}
if (!class_exists('Crypt_Hash')) {
    require_once($currentDir . 'phpseclib' . DIRECTORY_SEPARATOR . 'Crypt' . DIRECTORY_SEPARATOR . 'Hash.php');
}
if (!class_exists('Math_BigInteger')) {
    require_once($currentDir . 'phpseclib' . DIRECTORY_SEPARATOR . 'Math' . DIRECTORY_SEPARATOR . 'BigInteger.php');
}

//Yiiの再登録
spl_autoload_register(array('YiiBase', 'autoload'));

とします。これは、先のImHerlper.phpでIMのディレクトリ内をオートロードの対象にしたわけですが、PHP拡張である「Crypt_RSA」などのクラスの存在拡張をチェックすると、自動的にファイルを探しに知ってしまうのを回避しています。

続いて、GenerateJSCode.phpを改造します。

public function generateInitialJSCode($datasource, $options, $dbspecification, $debug)
{
	$q = '"';

public function generateInitialJSCode($datasource, $options, $dbspecification, $debug)
{
	global $callURL;
	$q = '"';

としておきます。IMのコードを見ると、$callURLがセットされていれば、このURLを優先して利用する仕組みになっているようですので、globalにして、先のImHelper.php内でコールするURLを指定できるように改造しています。

もしかすると、

if (isset($callURL)) {

if ( $callURL != '' ){

にしておいたほうが賢明かもしれません。


IM処理用コントローラーの設置

次にIMの処理を担うコントローラーファイルを設置します。
/protected/controllers/ImController.php
を作成し

<??php
class ImController extends CController
{
	
	// ----------------------------------------------------
	
	/**
	 * アクセスルール
	 */
	public function accessRules()
	{
		return array(
				'actions'=>array(  ),
				'users'=>array('@'),
			),
		);
	}
	
	// ----------------------------------------------------
	
	/**
	 * IM用コード出力
	 */
	public function actionGet( $code )
	{
		echo ImHelper::getImCode($code);
	}
	
	// ----------------------------------------------------
}

と保存しておきます。アクセス状況によってはアクセスルールを適切に設定したほうがよいでしょう。


準備完了

準備ができました。
あとは任意のコントローラーアクション内で、

$ds = array(
			array(
				'name' => 'categories',
				'records' => 20,
				'paging' => true,
			),
		);
		$def = array();
		$ds2 = array();
		
		$url = ImHelper::getUrl(
				$ds,
				$def,
				$ds2
		);

とすれば、$urlにIMの設定を呼び出すための一時URLが発行されるため、
viewの中で表示するなり、clientScriptクラスに登録するなりすればOK

ImHelper::getUrl()の引数は
IM_Entry()の引数に引き当てられます。
DBへの接続設定はImHelperで自動的に割り当てられるので、不要です。


これで、開発高速化!

現場からは以上です。

Yahoo!ショッピングのカートフォームに無茶をさせる

以前、楽天のカートフォームに無茶をさせるというと記事を書きましたが、
(もう2年も前なのか!?)
今回はYahoo!ショッピングのカートフォームに無茶をさせてみましょう。
 


フォームのソース

まずは、ヤフーショッピングが出力しているコードを見てみましょう。

<form name="form2" method="post" action="https://order.shopping.yahoo.co.jp/cgi-bin/cart-form;_ylc=[セッションコード?]?[ショップID]+[セッションコード?]&ccode=Nat">
<input name="vwitem" type="hidden" value="[商品ID]">
<input name="vwcatalog" type="hidden" value="[ショップID]">
<input name="vwquantity" type="text" value="1" class="ptPrice">
<input type="image" src="http://i.yimg.jp/images/store/shp/bt/bt_003.png" alt="カートに入れる" width="142" height="36" border="0" onClick="YAHOO.JP.sc.addCart(YAHOO.JP.sc.products, YAHOO.JP.sc.prop22);">
</form>

 
こんな感じです。
[セッションコード?]はセッション用の一時コードか何かのようです。
ちょっとこの辺りは追うことができず…
[ショップID]は、Yahoo!ショッピング開店時に申請したショップのIDです。
これはショップURLからも判断出来ます。
[商品ID]は商品を登録した際に、任意で商品につけるコードです。
 


外してもOKなコードがある

上記の用なフォームを作成することで、
ヤフーショッピング用のカートフォームが
作成できることがわかりました。
 
が、そもそも、この通りに作る必要があるのか検証したところ、
どうやらその必要は無さそうです。
セッションコードと思しきコードは省略しても、
ちゃんとカートに商品が追加できることがわかりました。
 

<form name="form2" method="post" action="https://order.shopping.yahoo.co.jp/cgi-bin/cart-form?[ショップID]&ccode=Nat">
<input name="vwitem" type="hidden" value="[商品ID]">
<input name="vwcatalog" type="hidden" value="[ショップID]">
<input name="vwquantity" type="text" value="1" class="ptPrice">
<input type="image" src="http://i.yimg.jp/images/store/shp/bt/bt_003.png" alt="カートに入れる" width="142" height="36" border="0" onClick="YAHOO.JP.sc.addCart(YAHOO.JP.sc.products, YAHOO.JP.sc.prop22);">
</form>

 
フォームタグのaction属性に付けられた難解なURLは、
ここまで単純化してもちゃんとカートに入ってくれます。


オプション的な要素は?

オプション的な要素は任意のオプションを追加することができます。

<form name="form2" method="post" action="https://order.shopping.yahoo.co.jp/cgi-bin/cart-form?[ショップID]&ccode=Nat">
<input type="text" name="色" value="赤" />
<input type="text" name="サイズ" value="M" />
<input name="vwitem" type="hidden" value="[商品ID]">
<input name="vwcatalog" type="hidden" value="[ショップID]">
<input name="vwquantity" type="text" value="1" class="ptPrice">
<input type="image" src="http://i.yimg.jp/images/store/shp/bt/bt_003.png" alt="カートに入れる" width="142" height="36" border="0" onClick="YAHOO.JP.sc.addCart(YAHOO.JP.sc.products, YAHOO.JP.sc.prop22);">
</form>

このようにするとカゴの中に
色:赤
サイズ:M
として商品が追加されます。
 
このオプション値を変更することで、
カートは同じ商品でも、別の明細としてカート内に追加をする仕組みになっているようです。
逆に、カート内に以前に同じ商品IDとオプション値を持つ商品が以前に追加されている場合は、
個数が合算されて追加される仕組みになっています。
 
この法則を使うと、裏技的な使い方として、
オプション値にタイムスタンプなどを埋め込んでおけば、
能動的に明細行をカゴボタンを押すごとに分けることが可能です。
 


楽天より仕組みが簡単

楽天では、楽天側が自動発行するデータベースIDを利用して
カートに商品を入れる仕組みになっているため、
カスタマイズがわかりにくいですが、
Yahoo!ショッピングでは、ショップ側がつけたIDのみを利用するため、
カスタマイズが非常にわかりやすいです。
 
たとえば、
自分のブログに、
前述の仕組みを利用してヤフーショッピングのカートフォームを埋め込んで、
ランディングページを作ったりすることができ、
モール内に閉じがちな、プロモーション手段を少しだけ広げることができます。
 
また、ヤフーショッピングは楽天と違い、
CSVでの商品登録などはオプションではないので、
CSVを通して簡易DBを作ることが可能ですから、
無料のCSV検索CGIなどを利用して、
自社サイトにカートシステムを実現するなんてこともできなくはないです。
 


モールの特性は知っておくべき

フォームなどの特性を知っておけば、
モールの規約の範囲内で、モールの枠を少しだけ超えたプロモーションをすることができます。
私は楽天やらカラーミーショップなど、結構な数を「魔改造」していますが、
フォームを使って実験をしてみた賜物です。
(がゆえに、無茶な仕事がたまに落ちてきたりしますがw)
 
知っていることはとても重要なことです!

線はできているか。

あるクライアントの話をする。
そのクライアントさん読んでいたらごめんなさい(笑)
読んでいても、それ相応の信頼関係ができていると思っているので、流してください。


今年にはいってからそのクライアントさんには、
店頭イベントの総合的な広報について任せていただいています。

店頭イベントの一発目が先日終わり、
コストかかってない割にはそれなりの売り上げ的成果があげられ
結果としてはまずまずでした。
 
私の指導があったものの、
この成果自体は、クライアントさんの取り組みの結果だと思います。
 


が、そもそもこんな短期間のイベントを繰り返し、
そしてひとつのイベントの成果を
「良かったね」「悪かったね」
と評価して終わるのが果たしていいのかっていう問題に
クライアントさんは、まだ気付いていないようです。
 


今回のイベントの内容は、
あるブランド商品に関して県下最大級の品揃えをするトランクショーで、
そこにこのクライアントさんの長年の経験を加えて、
即売会や相談会をするものです。
 
イベントとしては正直言うと「よくある」ものです。
 
「よくある」もので、ある程度の成果を上げられたことは喜ばしいことですが、
それで終わっていていいのかということです。


イベント時ご来店いただいたものの、
その時はご購入いただいたけなかったお客様がいらっしゃるとします。 
1回のイベント「だけ」を評価していると、
ご購入いただけなかったこのお客様というのは、
自店にとって「貢献のなかったお客様」ということになります。
 
そう。数字の上では。
 


しかし、今回のイベントの内容をもう一度振り返ると

  • 都道府県下で最大級の品揃えを見せる
  • 長年その商品を扱ってきた知識を価値とする

ということですが、後者をお客様に認識していただけたとすれば、
適切な期間に、適切な内容のニュースレターやEメールが、
その後も届けられたとしたら、
いつか、もう一度ご来店いただけるのでは?


 
1回のイベントや広報ごとに評価をして
「あーよかったねー」「だめだったねー」って言っていては、
「線」でなく「点」です。
点をつなげて線にしていかなくてはいけません。
 
一度ご来店いただいたお客様をフォローして、
しっかりと自店のリピーターになっていただけるようにしなければならない。
(反復購買という意味ではなく、何度も足を運んでいただけるように)


そんな話わかってるよ。
そんな話知ってるよ。
 
なんておっしゃる方いっぱいいらっしゃると思います。
確かにそうですね。
いろんな経営コンサルタントが散々言っていることですから。
 
そこで問いたいのが
ニュースレターやEメールを送るとして
「適切な時期」や「適切な内容」というのを知っていますか?
ということです。
 


 
何社かのコンサルティングをさせていただいた、
私の経験からすると、
扱っている商材、店主の人間性などなど様々な要因で
「適正」は定まらないです。
このお店の場合は1ヶ月ごとに送るのがいいとか、
はたまたこっちのお店は4ヶ月ごとに送るのがいいとか、
本当に様々です。
 
こればかりは、お客様と店の人という関係性の中でうまれる
「肌感」で蓄積していかなくてはいけない「知識」です。
(もちろん数字としては解析などに出てくるとは思いますが)
 


一つのイベントや広報を「点」として、
それぞれを結びつけたことが「線」とは言い切れないところがあります。
 
前述のとおり
自店なりの「こうしたら→こうなる」という方程式を知っていく。
これが「線」だと思うのです。
 
つまり、PDCAでしょ?って言われるかもしれません。
おっしゃるとおり。
でもね。おそらくもっと手前の問題だと思うのです。
PDCAを回すだけの
「もてなし」と「しつらえ」を準備していかなくてはいけませんね。

プロレスと私とマーケティングと


一年ぶりにDDTプロレスを見てきた。
名古屋は半年に一回くらい、栄のテレピアホールで行われる。
エンターテイメント性を重視したプロレス展開で
メジャーでない団体だが日本武道館で大会を行うなど勢いのある団体だ。
写真は名古屋出身の注目レスラーの彰人選手。


プロレスはあまり人気がなくなっている興行ではあるけれど、
誰かを連れてプロレスを見に行くと「面白い」といってくれるし、
友達と友達が繋がって、友達になる。
 
今日もそんなことがあった。
私を通して友達と友達が友達になった。
  
まぁプロレスにかぎらず遊びというのはそういう側面があるけれど、
レスラーが演じるドラマを通じて、感性を共有できるところがいい。
と私は思っている。
 


僕は感性価値を重視してマーケティングコンサルの仕事をしている。
感性価値の基礎はこんな感じだ。
 
例えば5億円というお札の束があるとする。
それに価値を与えるのは、人間だ。
そして、5億「円」という価値が地球規模ではどういう価値を持つかは、
各地域の人々の主観で決められる。
円相場とかは、人の感性で決められている側面があるわけだ。
 
だから「価値を伝えること」より「価値が伝わること」をベースに
広報戦略を打つことを考える。
これは似ているようで違う。


私が敬愛するマーケティング研究家である
小阪裕司先生、藤村正宏先生
は普段から「自己開示をすべき」とおっしゃっている。
 
いずれの先生においても
相手を選び、自分を知ってもらう努力をしなければ、
相手も自分を選び、そして自分を知ってくれることなどない。
知ってもらえないのに、価値が生まれる?
ということを繰り返し啓蒙されており、
そのためには「自己開示が必要」と説いている。
 


私は数年前までWEB業界の人に全く知られていなかった。
だが、現在は、私のTwitterは、WEB業界関連の方々1200名くらいの方に
フォロー頂いている。
まったくありがたい話だ。
 
徐々に私のことを知ってもらえるようになったのが、
何を隠そうこのブログだ。
このブログのタイトル「垂直落下式ムーンサルトプレス」は
プロレス関連の言葉。

「あー!読んでますよ!ブログ!なんだっけパワーボムだっけ?」
みたいな声を沢山かけていただけるのです。
プロレス好きな人なら更に深い方向へツッコミを入れてくれる方も沢山いる。
そして好感をもってもらう。
(ちなみに私は「プロレスヲタク」ではなく「プロレス技ヲタク」ですw)
 
好感を持ってもらうと、いろんなことが伝わりやすい。

  • 価値が伝わりやすい
  • 言いたいことが伝わりやすい
  • やってほしいことが伝わりやすい

これは感性価値マーケティングではすべてのスタートだ。
 


趣味というのは仲のいい誰かに勧められて始めることが多くないだろうか?
格闘やプロレスに否定的だった私の奥さんを
プロレスに連れて行ったら、突然のようにハマった。
上の写真は、DDTプロレスのHARASHIMA選手。
奥さんが好きな選手だ。
 
一度好感を持ってもらった相手が、
「これいいのよ」と薦めてくれたものというのは、
案外「じゃ買ってみようかしら」とか「はじめてみようかしら」という気になる。
 
私はECコンサル会社に在籍していた会社員時代
いろいろな仕組みをPHPで作ってはクライアントに提供してきた。
が、あまり使ってくれなかった。
手前味噌だが、そのモノ自体は非常に有用なものだったという自信がある。
でも使ってくれなかった。
 
今考えてみると、当たり前だ。
そのクライアントにとっては、
私に十分な好感や信頼を与えてもらっていなかった。
そんな人に聞く耳を持つというのは、
自分に置き換えてみると、あまりないことだと思う。
たとえ、事細かな説明を付け加えたとしても。
 
商売において「こだわり」はとても重要な要素だ。
こだわりのない商売は商売になり得ない。
他方「こだわり」はコモディティになってしまう要素もある。
なぜなら、競合もこだわっているから。
何にどのようにこだわっているのか伝える方法を知らなければいけない。
 
私以外の人が誘ったところで、
奥さんはプロレスを見に行くことはなかったと思う。
このことはマーケティングにおいても重要な視点だと思う。
クチコミとかがまさにそれだろう。


価値は人の感性が決めるのだから、
人の感性にどれだけ近づけるかはとても重要な考えの一つだ。
 
自己を開示する方法を、さらに磨いていきたい。
と、プロレスと私とマーケティングを無理やりつなげて話してみた。

HTML5をKARUTAで学んだ話。


先日、2013年1月6日にHTML5KARUTA @ 名古屋・伏見MYCAFEを開催しました。

まず、MYCAFEのスタッフの皆さんご協力ありがとうございます。


ことの発端は2012年末、普段より交流のある、優さんより、
全国的にHTML5KARUTAなるものをやるから名古屋でもどう?
というお誘いをいただき、せっかくなので快諾させていただきました。
HTML5では名古屋において爆心地でいらしゃっり、
名実ともにフロントエンドテロリスト対策のスペシャリストとして活躍していらっしゃる、
じゃっくばうあー氏に主催をお願いしました。


そもそもHTML5KARUTAとはなんぞやってはなしですが、
HTML5KARUTAとはこういったものです→http://roadstohtml5.com/html5karuta/

要するにHTML5の勧告候補に定義されたHTMLタグの機能を聞いて、
それを示すタグをKARUTAでとりましょうというものです。

全部で108のタグがあります。


私は正直言って「勉強」なんかだいっきらいです。
座学が実践のなんになるんだと平気で言い放つくらい勉強がだいっきらいです。
 
なのでHTML5も普通に使われるまではと思い、
ほとんど勉強してませんでした。
 
子供の頃の遠い記憶で、僕はリトミックに通っていました。
ユーリズミックなどとも呼ばれますが、
これは、物心が付く前に楽器などを使って、
音楽やリズム、国語や英語を体に染み付ける教育手法です。
この経験は今でも僕の中に息づいています。

HTML5KARUTAも同様で、
楽しんで覚える、、、というより感じて覚えるという点は、
体に染み付くだろうなと思いました。
 
HTML5のことを体動かしながら、
笑いながら話すなんてことありますか?
多分これくらいしかないじゃないですか。

とてもいい経験だと思いました。


今回はじゃっくばうあー氏に読み手も頼んだことで、
KARUTAとりの後により詳しい説明もしてもらえたことも大きいですね。

ばうあー氏も知らないことを感じつつ、
楽しんだ後に深めるというのは、非常にいいことです。
 
改善点としては、何かTipsも披露できれば、
より深まったのかなという気がします。


つぎはCSS3KARUTAができるとかできないとか。

保護中: だから春を体験!沖縄●●ホテル

このコンテンツはパスワードで保護されています。閲覧するには以下にパスワードを入力してください。

FX.phpよりも簡単 FM-and-PHP

FileMakerでは、FileMakerServerを導入すれば、
HTTPリクエストとXMLによって、
基本的な挿入・編集・削除・検索ができる他、
スクリプトの実行なども行えるようになっています。
この仕組を利用して、PHPでもFileMakerデータを扱えるようにしたもので、
有名なものには「FX.php」があります。


FX.phpは、

  • リクエストURL作成
  • リクエスト実行
  • レスポンス取得

などを、自動で行なってくれるクラスライブラリで、
PurePHPとして動作します。
ソケットで外部接続できるサーバーと、
XMLによるカスタムWEB公開されたFileMakerServerのDBがあれば、
FileMakerをWEB用のデータソースとして、
PHPから扱えるようになる仕組みです。
 


FX.phpは、やりとりをXMLで行うという性質から、
通常のデータベースソフトウェアとはかなり異なる操作を求められ、
正直申し上げて、あまり抽象化されておらず、
慣れにはかなりの時間を有します。

レスポンスの取得結果も、XMLをパースしたものそのものに近いので、
エラーチェックも、結果取得のループも、
レスポンスで返される配列から判断しなければならなかったりします。


そんなとき出会ったのが「FM-and-PHP」というライブラリです。開発自体は2009年に止まってしまっているようですが、FileMakerのXML公開エンジンの仕様はその頃から、それほど大きな変更がないため、そのまま利用できます。また、このライブラリ自体はBSDライセンスが採用されているようで、OSSですので、改変なども問題ありませんので、何か問題があれば自分で書換えて使えます。

サイトを読んでみると、この作者も、FX.phpがちょっとなんだかなと思っていて作り始めたという経緯があるようです。


簡単なコードを書くと

require_once 'fmandphp.php';
$fm = new FM_AND_PHP();


//////接続設定

//ホスト情報
//FileMaker5系も対応その場合は、第三引数を「5/6」と書く。
$fm->setFileMakerHost( 'サーバーID/host', 'ポート', '7');

//データベースファイル名(拡張子を除いたもの)
$fm->setDatabaseName( 'データベース名' );

//認証
$fm->setDatabaseUserPassword( 'ユーザー名', 'パスワード');


//////クエリ実行

//データ取得したいデータが表示されているレイアウト名
$fm->setDatabaseLayout( 'レイアウト名' );

//条件指定
//「==」なら完全一致
$fm->addSearchField( 'フィールド名', '値', '==' );

//今から何をするかを指定
//findは検索 newとすると新規レコード追加
$fm->setCommand("find");

//クエリ実行
$fm->doQuery();


//////エラーチェック
if( $fm->getErrorNumber() != 0 )
{
//エラー表示
echo $fm->getErrorDescription();
return;
}


//////データ取得
while( $fm->getNextRecord() )
{
echo $fm->getField( '取得したいフィールド名' );
}

こんな感じ。
MySQLなどの通常よく使われるデータベースエンジンに比べると、
煩雑な気はしますが、
SQLの扱いに慣れていない場合などは、
クエリ手続きがひとつひとつメソッドになっている分、
扱いがしやすいかもしれません。


これと同じ事をFX.phpでやる場合は、
クエリの作成まではほぼ同様のことをやりますが、
エラーチェックは、クエリの返り値から、特定のキーを指定してチェック、
レコードの取得は、クエリの返り値から、itemsのキーをループさせます。
また、itemsの中も二次元配列になるため、
非常にレスポンスの扱いが煩雑になります。

また、FileMakerのXML操作では、
レコードのアップデートや削除は、
一旦データを検索し、各レコードに与えられている「編集ID」を取得し、
その編集IDに対して、アップデート、削除の指示を出さなくてはなりません。

FX.phpの場合、このIDもレスポンスの中から取得しなければならず、
アップデート編集時は、特にコードが冗長になりますが、
FM-and-PHPでは、このIDも取得できるメソッドが揃えられています。


ちなみにこのFM-and-PHPライブラリ開発元がドイツの会社であるため、
ライブラリ自体はドイツ語を扱うのにラクなように作られています。
日本語を扱うのに問題のないように改造するには、
fmandphp.phpの1455行目付近の「doFm7Encoding」というメソッドを

function doFm7Encoding(&$value) {
return;
}

と何もしないメソッドに変更してしまえばOKです。
(ただし、PHPアプリケーションが「UTF-8」で動作していることが前提です)


このように扱いやすいFM-and-PHPですが、FX.phpに比べて劣る点もあります。

  • オブジェクトフィールドの中身を取得するプロキシを持っていない
  • EUC-JPなどのUTF-8以外の文字コードに対応していない

などです。全体的にFX.phpに比べできることが少ない。という認識でOKです。
この点は、目指すアプリケーションの内容しだいでどちらを選ぶかということを示しています。

FX.phpはCake用の拡張ライブラリがあったりしますので、
至れり尽くせり感はすごくありますが、
ちょっとしたアプリケーションを書く場合や、
自分で拡張して、自分のためのライブラリにしたい場合などは、
FM-and-PHPを優先したいところです。

セール・キャンペーンは誰向けにやる?

現在あるお店のCRM開発に携わっています。
別のコンサルタントさんが入っていて、そこで学んだことをちょっとだけブログに。


RFM分析ってご存知でしょうか。
マーケティングに置いては基礎中の基礎なので、ご存知の方も多いと思います。
Recency/Frequency/Monetaryで、
これまでの購買顧客を、時系列を考えながら利益貢献度で分析、ランク付しようという分析手法です。


で、そのランク付で何をするか。
上位ランクほど、お金をおとしてくれる人なわけですから、
その人を手放さないための施策を打っていこうということですね。

経営は、利益で得た経営資源の再分配が一生終わらないものと捉えることができます。
サラリーマン給与のように入ってきたお金は自分のものというわけではないです。
入ってきたお金を経営資源に回して、
それを使って次の利益をどう得るかということが繰り返されるのが、経営なわけですよね。
実に単純な話しです。

ランク付をすれば、上の方の人には多めに還元してもOK、
下のランクの人にはあんまり還元してもなぁ。
ということです。これを実現するためのランク付けをするわけです。


航空会社はマイレージ会員という形で、それを実現しています。
マイレージ獲得数は、搭乗回数や距離で発行されます。
したがって、獲得数によって利益貢献度が簡単に測れますね。
しかも、マイレージには有効期限が付いているのでRFM分析において重要な、
「最近の」利益貢献度が高い顧客が、
マイレージ獲得数によって、
顧客側にとっても、航空会社側にとってもわかりやすい示準となっています。

さらに、航空会社の場合は、マイレージ会員をランク付して、
利益貢献度の高い顧客には、割引という形で利益還元したり、
他のランクにはないサービスを提供することで、
顧客が離れない手法をとっているわけです。


WEBとかECやってると、広く新規顧客を集めるために、
セールというのを打っているケースが多いです。
手法的には否定しません。
新規顧客は重要ですので、セールして集めるというのは
良い手法でしょう。

が、新規顧客を集めるばっかじゃ、なかなか利益が上がりません。
仕方ないですよね、利益率下げて、
一見さんをひたすらに集めている状態ですから、
やり方によっては「売上はあがるけど利益があがらない」ということになりかねません。


日本国内の市場に目を向ければ、この先しばらくは人口は縮小していきます。
要するに、モノやサービスを購買してくれる顧客が減少します。
その中で、利益率を下げて、一見さんを集めるばかりの商売をしていたら、
いつかは商売自体が疲弊してしまいます。

やはりリピーター重要。

航空券のマイレージは単価の高いサービス・商品になるので、
すべての商売が同じ考え方が当てはまるかといえば、
たしかに疑問ではありますが、
しかし、利益の再分配という意味では、最も進んだモデルで、
参考しない手はないでしょう。


消費経済が全体的に冷え込んでいて、
小売などでは、資産となっている不良在庫/不動在庫のみが、
帳簿上利益になってしまっているというのはよくある話で、
それを手っ取り早く現金化したり、
スケールメリットで安くモノを仕入れて、
小規模な利益を数で大きくしたりしながら、
新規顧客を獲得するためのセールというのは、
容易に打ち出しやすい施策ですが、
継続性という意味では非常に苦しい施策でもあります。

全員に広く同じセールをするというのは、
なかなか厳しいとしか言い用がありません。
すでに買ってくれた顧客を育てるほうが幾分ラクであるのは、
目に見えています。
 


 
ECやWEBに置いてもPDCAサイクルという言葉を聞くようになりました。
Plan(計画)→ Do(実行)→ Check(評価)→ Act(改善)
を繰り返して、業務を継続させて行ったり、業務を円滑にしようという施策です。

新規顧客のためのセールを繰り返すと、
CheckのところやActのところで、
金銭的コストで行き詰まりを見せるケースが多々あるように感じます。
Checkの所で、得た利益を経営資源として考えて、
それをどう再分配するかを、
リピータのためのセール(というか施策)に当てるという視点は、
市場が縮小していく日本国内のECにおいては、
とても重要なのではないでしょうか。

※そのために具体的にどうするのかという話は、
手の内を明かす事になってしまうので、
書けません。ごめんなさい。

RadPHP XE2を導入しました。

世界で唯一のPHPのRAD開発環境である、エンカバデロテクノロジーズ社の
RadPHP XE2」を業務に導入しました。


もともと、RadPHPは、Delphi for PHPという製品名で販売が開始された商品で、
その名の通り、Delphiの開発手法をPHPに使える開発ツールです。

RadPHPの操作画面

写真の通り、かつて、Window用アプリケーションのRAD開発環境において、
VisualBasicと双璧をなしていた、 Delphiの見た目そのままに近いです。
というか、おおよそ、WEBアプリケーションの開発画面には見えません。
この画面の通り、右側のツールから部品を選んで、真ん中のフォームに配置すると、
それでもうPHPアプリケーションの出来上がり!おそろしい。。。

Delphiで使われていた「VCL」というツールキットをPHP用に置き換えたことで実現できたそうで。。。
すげぇ。


5年ほど前までクライアントの業務管理アプリケーション開発などにDelphiを使っていたのですが、
開発の柔軟性が非常に高いFileMaker7系統に移行しました。
しかし、サーバーとクライアントの間でのシームレスなやり取りが必要になってきた昨今では、
FileMakerの利用では、スピード面や堅牢性に問題があったり、
これをクリアするためには高額な上位版が必要だったりと、
どちらかというと小さな個人商店を相手にしている、
私の業務では悩みが増えてきて、FileMakerを置き換えるプロダクトをここ1年ほど探していました。

幾つかの候補があり、

などがそれです。

Delphi for PHP(RadPHP)が比較的安価(3万円程だったので、購入はしたものの、
いかんせん、情報が少なく、多忙なのものあって勉強せずに放置となりました。
だめですね。。。orz


しかし、色々な業務に追われるようになり、
さすがにFileMakerじゃ苦しいよということも増えて来まして、
重い腰をあげて、何かに乗り換えるつもりで、調べていたところ出会ったのがこの動画。

RadPHP and Database Development

めちゃ簡単にDBのジェネレーター開発できるやん!!
そりゃもう衝撃だったので、眠らせておいたDelphi for PHPを使ってみたところ、
なるほど、こりゃええわ!ということで、後継バージョンのRadPHP XE2を導入しました。


PHPの書き方としては、MVCフレームワークなどとは大きく異なり、
各種クラスの命名規則や、メソッドのコール方法は、Delphiを触っている感覚に近いです。
幸い私はもともとDelphiを使っていたのものあって、それほど苦ではないですが、
普段通常のPHP開発を行なっている人にとっては、
戸惑う点の多い開発ツールかもしれません。

また、日本においては、使っている方が非常に少ないようで、
情報も少なく、書籍も1冊しか出ていません。
見た目に騙されて開発初級レベルの人が手を出すと痛い目にあうツールとも言えるでしょう。
(まぁ。私のレベルも低いですけどね)


現行のRadPHP XE2では、iOSアプリケーション開発などもできるようですし、
Facebookアプリケーションも作れるようです。
(まだ触ってません)

なんかワクワクですねー。

とりあえず、私の業務において、FileMakerを置き換えるに十分すぎるツールが、
3万円そこそこで導入できたので良かったです。


なお、本家のDelphiは、Professional版を買えば、
Windows用アプリケーションだけでなく、
MacOSX用やiOS用のアプリケーションまで開発できるようになってましたΣ( ̄□ ̄;
すげぇ。

ただ、かつてOSSが盛り上がったときに、
Linux版のDelphiである「Kylix」という商品が出たのですが、
中途半端に終わらせた過去もあるので、
現時点では手放しでは喜べないですが…。

本家DelphiのPro版ではRadPHPも同梱されているようです。
えぇっ。。。そっちにすればよかった。。。
大体10万円そこそこで買えます。


まぁ兎にも角にも良いツールが見つかりました。
しばらくはこのツールを勉強していきます。

スカイマークを使って沖縄に行って来た。

私のことをご存知ならば、私がよく沖縄にいくこともご存知だとおもうので、わざわざそれを日記にはしませんが、今回はじめてスカイマークエアラインズを使って旅をしたので、そのレポです。
すみません写真とかはないです。


まず、スカイマークエアラインズについて。
最近よく聞くLCC(ローコストキャリア)というタイプの航空会社です。名前の通り「格安路線」ですね。
 
2011年はJAL・ANAといった従来の航空会社も別会社でLCC参入をしたりして、日本におけるLCC元年と言える年です。
従来路線も、JALの子会社で沖縄の離島間路線を担当するJTAがLCCに匹敵する格安プランを発表したり、ANAでは待ちに待ったB-787の就航でLCCとの差別化を図るなど、航空業界としても激動の一年だったのではと思います。
 


さて、そのスカイマークの航空券の値段ですが、今回使った名古屋(中部)-沖縄那覇便は、定価が15,800円。もうこの時点で、激安ですが、平日の場合最安が5,800円で、先着順に全部で7段階の価格設定です。
今回僕は片道9,800円で利用しました。
これでもJALの早割の半分以下です。


使用機材についてですが、スカイマークはすべての路線を保有機材であるB737-800で運行しています。
意外にも、B737の機体としては最新鋭のハイテク機で運行しています。
 
同じ路線である、JALの名古屋(中部)ー那覇路線は、かつては、B777-200/B777-300/B747-400Dなどの大型機で運行していて、B777では、全席液晶モニタ付きなどで運行していた時期もありましたが、現在は、すべてB737-400で運行していて、使用機材としては、LCCであるスカイマークのが上という状況です。
 
しかしながら、スカイマークでは、内装などは簡素化されていて、テレビモニタでのニュース放映や、音楽番組提供などはありません。
iPodを持ち込んだり、新聞雑誌を買って行ったりというのは、必須かもしれませんね。
 
また、席は若干狭めです。
 


機内サービスも、新聞の貸出などもありませんし、飲み物は販売のみです。ブランケットは貸してもらえます。
FAさんのスタイルも、JALやANAのような綺麗できちっと感じではなく、ちょっと小綺麗な作業着といったイメージです。とは言え、対応は極めて丁寧です。日本のLCCだからかもしれませんが。
 


地上の受付やGHさんの対応はどうか。
対応としては、ごく一般的な丁寧さです。
 
チェックインと航空券発行が簡略化されていて、
ネットでの予約の場合、
支払いはクレジットカードかコンビニ支払い限定なのですが、
この支払手段を確認方法として、
カウンターに設置の受付機を使って航空券を発行します。

カード払いの場合は、支払いに使ったカードを受付機にいれることで、確認がとられて、航空券が発行されます。
コンビニ払いの場合は、申込時の電話番号と、コンビニでの支払番号が確認手段になります。
 
JAL・ANAとは違い、受付窓口が非常に少なくなっており、かなり早めに行って搭乗手続きを済まさないと乗り遅れの可能性があります。今回は出発時刻の45分くらい早めに行ったのですが、それでもギリギリでした。最低でも1時間は早く行っておく必要がありそうです。
(ちなみに航空機における出発時刻は、機体のドアが閉められて、航空機が動き出す時刻のことを言いますので、実際はもう少し早めに搭乗最終手続きが終わると思ってください。)
 
また、那覇空港では、通常受付カウンターは、3階にあるのですが、名古屋便の受付だけ1階の隅っこという扱いで、泣きそうになりますw


予約なのですが、基本的に2ヶ月前の午前9:30に予約受付開始です。
JALなどと違い、復路も2ヶ月前の午前9:30に予約することになるので、ちょっと面倒です。
 


で、なかなか困ったのが、運行時刻です。
スカイマーク全路線がというわけではなく、名古屋(中部)ー那覇路線に限った話ですが。
 
午前に中部を出る便は、7:40出発時刻になっています。
とにかく早い時間です。名古屋市内からのアクセスがギリギリで、
愛知県内でも、三河地方から来る人などは間に合わない可能性もあります。
 
また、帰りの那覇を午後に出る便は20:30発という時刻になっています。通常通り、運行しても、中部着が22:30頃で、預けた荷物など受け取りの時間を考えると、順当に行っても到着ロビーに出られるのが23時頃。
空港アクセスの唯一の手段である名鉄の最終電車が23:31発なので、40分遅延が発生すると、もう帰る手段がタクシーしかなくなります。
 
旅行の中身で見れば、JAL・ANAの便を使うより、行き帰りあわせて1日くらい余計に遊べるというおまけ感覚はありますが、空港までの行き帰りについては一考が必要です。
 


ざっとこんな感じです。個人的には、到着時刻以外は特に不満に思うようなこともありませんでした。国内で2・3時間の便だったらこれでいいと思います。
逆にJALなどを使う場合は、Jクラスなど申し込んで、違いを楽しむといいかなと思います。


 
【追記のレンタカー情報】
沖縄のレンタカーについてのお得情報。
 
沖縄のレンタカーはもともと安いです。
ヴィッツクラスが保険と免責補償料を含めると、
大体24時間で4,500円程度です。
 
スカイレンタカーという、
レンタカー会社をいつも使っているのですが、
会員になるだけで、数百円の割引がつきます。
で、ナンバー登録から4年以上経過した車を指定するプランだと、
保険と免責補償料を含めてもヴィッツクラスが
24時間で3,150円で借りることができます。
 


ついでに書いておくと、個人的には、沖縄では、日産やトヨタなどの、ディーラー系では借りないほうがいいと思っています。
 
というのは、安いという理由だけでなく、スカイレンタカーなどのほうが保証を広くすることができるからです。
 
通常レンタカーでは、事故(当て逃げや傷をつけてしまった場合など含めて)があった場合、免責として3万円、休業補償として3万円程度のお金を請求されます。
沖縄は道が滑りやすく、事故を起こしやすいのと、当て逃げも結構多いです。自分で事故ったならいいですけど、当て逃げでこのお金を払うのは非常にむかつく話です。
 
スカイレンタカーなどは、こういった免責などを免除する保険が1日315円で入れます。何があるかわからないので、315円で入れる保険ならつけておいたほうがいいというわけです。
 
ちなみに、私の働いてるオフィスの社長は、昔沖縄の道路でタイヤをすべらせて、VOLVOを横転させたことがあるそうですw


沖縄に行く際にご参考になれば^^

Older posts Newer posts