やってた人はすでにやってたことだと思います(実際やってます)が、
いつの頃からか、これが「ランディングページ最適化(LPO)」という
なんともかっこいい名前で呼ばれるようになってました。
ランディングページとは、ユーザがはじめに訪れるページのこと。
そのページからユーザが求めているページ(情報やサービス)へ
スムーズに誘導するよう最適化するというのが定義らしいです。
このひとつの方法として、
検索キーワードに応じて動的にコンテンツ変えることが考えられます。
ユーザが直前に見ていたページのURLは、
$_SERVER['HTTP_REFERER']を見るとわかります。
(必ずわかるとは限りませんが)
Yahooの検索結果などから来ると検索キーワードも
これに含まれているので、キーワード(=ユーザの要求)に応じた
コンテンツを動的に配置できます。
1.$_SERVER['HTTP_REFERER']からキーワードを抽出する。
2.キーワードに合ったコンテンツを配置する。
これだけなら簡単に出来るのでやらないと損です。
てなわけでクラスにまとめてみました。
《特徴》
キーワードを抽出来る検索結果ページは、
Yahoo(yst)、Google、MSN(Live search)の3つだけです。
$targets に追加すればもっと増やせます。
あいまいなキーワードが少しでも一致するよう
引数に与えた文字列は全て以下のように変換し書式を統一しています。
・文字コード ⇒ 内部エンコード
・半角カナ ⇒ 全角カナ
・英数字 ⇒ 半角&小文字
・長音(ー,―,-,‐) ⇒ マイナス(-)
・スペース(全角スペース・改行・タブ) ⇒ 半角スペース
mb_string extension 必須です。
lpoKeyword.php
<?php
/**
* lpoKeyword class
*
* use mb_string extension
*/
class lpoKeyword
{
// keyword
var $keyword = null;
// Target site params
var $targets = array (
// Yahoo
'yst' => array (
'regx' => '/^http:\\/\\/(?:[a-z-]+\\.)+yahoo\\.(?:co\\.jp|com)\\//',
'word' => 'p',
'encode' => 'ei',
),
// Google
'google' => array (
'regx' => '/^http:\\/\\/(?:[a-z]+\\.)+google\\.(?:co\\.jp|com)\\//',
'word' => 'q',
'encode' => 'ie',
),
// MSN (Live search)
'msn' => array (
'regx' => '/^http:\\/\\/(?:[a-z]+\\.)+(?:msn\\.co\\.jp|live\\.com)\\//',
'word' => 'q',
'encode' => null,
),
);
/**
* lpoKeyword ( [ $url ] ) constructer
*
* @var string $url default: null
*/
function lpoKeyword ( $url = null )
{
// init $url
if (null === $url) {
$url = $_SERVER['HTTP_REFERER'];
}
if (!strlen($url)) {
return;
}
// get keyword
if (preg_match('/^http:\\/\\//', $url)) {
$keyword = $this->getKeyword($url);
} else {
$keyword = $this->encode($url);
$keyword = $this->format($keyword);
}
if (!strlen($keyword)) {
return;
}
$this->keyword = $keyword;
}
/**
* inKeyword ( $keyword )
*
* @var string $keyword ex. "pen Order"
* @return bool
*/
function inKeyword ( $keyword )
{
if (!$this->keyword || !strlen($keyword)) {
return null;
}
$keyword = $this->encode($keyword);
$keyword = $this->format($keyword);
if (false !== strpos($keyword, ' ')) {
$keyword = explode(' ', $keyword);
} else {
$keyword = array($keyword);
}
foreach ($keyword as $word) {
if (false !== strpos($this->keyword, $word)) {
return true;
}
}
return false;
}
/**
* getKeyword ( $url )
*
* @var string $url
* @return string
*/
function getKeyword ( $url )
{
// get target site
$Target = null;
foreach ($this->targets as $site) {
if (preg_match($site['regx'], $url)) {
$Target = $site;
break;
}
}
if (!$Target) {
return null;
}
// get keyword
$regx = '/[&\\?]'. $Target['word']. '=([^&]*)/';
preg_match($regx, $url, $match);
if ($match[1]) {
// (raw)urldecode
if (false !== strpos($url, '+')) {
$Keyword = urldecode($match[1]);
} else {
$Keyword = rawurldecode($match[1]);
}
} else {
return '';
}
// encoding
$inEncode = mb_internal_encoding();
$keyEncode = 'auto';
if ($Target['encode']) {
$regx = '/[&\\?]'. $Target['encode']. '=([^&]*)/';
preg_match($regx, $url, $match);
if ($match[1]) {
switch (strtoupper($match[1])) {
case $inEncode:
$keyEncode = $inEncode; break;
case 'UTF-8':
$keyEncode = 'UTF-8'; break;
case 'EUC-JP':
case 'EUC':
$keyEncode = 'EUC-JP'; break;
}
}
}
$Keyword = $this->encode($Keyword, $keyEncode);
// format
$Keyword = $this->format($Keyword);
return $Keyword;
}
/**
* format ( $text )
*
* @var string $text
* @return string
*/
function format ( $text )
{
$text = mb_convert_kana($text, 'KVas');
$text = str_replace(array('ー','―','-','‐'), '-', $text);
$text = preg_replace('/\\s+/m', ' ', $text);
$text = strtolower($text);
$text = trim($text);
return $text;
}
/**
* encode ( $text [, $encode ] )
*
* @var string $text
* @var string $encode
* @return string
*/
function encode ( $text, $encode = null )
{
if (null === $encode) {
$encode = mb_detect_encoding($text);
}
$inEncode = mb_internal_encoding();
if ($inEncode != $encode) {
$text = mb_convert_encoding($text, $inEncode, $encode);
}
return $text;
}
}
?>
function lpoKeyword ([ $url ])
コンストラクタは、URLからキーワードを抽出します。
$url を指定した時は$url から、
何も指定しなければ $_SERVER['HTTP_REFERER'] から
キーワードを抽出して $this->keyword に格納します。
$url には、”http://” で始まるURL以外に、文字列を指定することが出来ます。
URL以外の文字が指定された場合は、その文字で$this->keywordを初期化します。
function inKeyword ( $keyword )
URLから抽出したキーワードに、指定の単語が含まれているか判定します。
$keyword には、判定したい単語をスペースで区切って指定します。
$this->keyword の一部でも単語が含まれていれば、true を、
一つも無い場合は、false を返します。
function getKeyword ( $url )
$url から抽出したキーワード文字列を返します。
通常使う必要はありませんが、インスタンス生成後に
特定のURLを指定したい時などに用います。
《サンプル》
検索キーワードに応じて、ピックアップに表示するメニューを切り替えています。
インスタンス生成後は、
$lpo->inKeyword('キーワード1 キーワード2 ・・・')
の判定結果を、if文で切り替えています。
<?php // クラスファイルのロードrequire_once 'lpoKeyword.php';// インスタンス生成 // 引数省略時は $_SERVER['HTTP_REFERER']で初期化$lpo = new lpoKeyword();?> <h3>ピックアップ</h3> <?php // 'mysql'が含まれていた場合のコンテンツ if ($lpo->inKeyword('mysql')): ?> <h4>MySQLの導入</h4> <p> <a href="./mysql01.php">どのバージョンを選ぶ?</a> |<a href="./mysql03.php">インストール編</a> </p> <?php // 'session' または 'セッション' が含まれていた場合のコンテンツ elseif ($lpo->inKeyword('session セッション')): ?> <h4>sessionでつまづきました</h4> <p> <a href="./session02.php">セッション変数が消えた</a> |<a href="./session03.php">クッキーとセッションさてどっち?</a> </p> <?php // その他のコンテンツ else: ?> <h4>PHP実験室</h4> <p> <a href="./test01.php">文字列連結どれが早い</a> |<a href="./test02.php">forとwhileどっちが早い?</a> </p> <?php endif; ?>
《これからの課題》
$_SERVER['HTTP_REFERER']から抽出したキーワードは
文字コードが判別できない場合があり、mb_string の自動変換に不安がある。
ターゲットサイト(検索エンジン)のウェブAPIドキュメントなんかを調べれば、
自動変換しなくて済む方法がみつかるかも。
このようなコンテンツの切り替えよりも、実際LPOで時間の
かかるところは、どのページが、どんなキーワードで訪問され、
どんなコンテンツを配置すれば効果的か、を調べたり検証したりする部分です。
これに向くアクセスログ解析が必要です。
Google Analytics も役立つでしょう。
リファラからの検索キーワードをいろいろ調べてて、たどり着きました。
自分のところでも試しに実装してみたのですが、うまくできました!ありがとうございます。
あとってendifによる制御も知らなくて、勉強になりました!