いまさら1000speakers@仙台のネタ
1000speakers@仙台#1の感想とか書こうと思いつつ、いつのまにか時が流れ……。
相当いまさら感はあるものの、id:sato165さんが発表していたLPOのネタを何となく。
<?php /** * 検索キーワードをハイライト */ class HighlightKeywords { /** * 終了タグ */ const PREFIX_TAG = '<span class="keyword">'; /** * 終了タグ */ const SUFFIX_TAG = '</span>'; /** * HTTP_REFERERのQUERY_STRINGをマッチする正規表現 */ const REGEXP_HTTP_REFERER = '^http(?:s)?:\/\/(?:.+?)(?:\?)(.+)$'; /** * 検索エンジンのクエリ情報 * * @var array */ static private $searchEngines = array( 'google_cojp' => array( 'pre_url' => 'http://www.google.co.jp/', 'query' => 'q', 'encode' => 'UTF-8', ), 'google_com' => array( 'pre_url' => 'http://www.google.com/', 'query' => 'q', 'encode' => 'UTF-8', ), 'yahoo_cojp' => array( 'pre_url' => 'http://search.yahoo.co.jp/', 'query' => 'p', 'encode' => 'UTF-8', ), 'msn_cojp' => array( 'pre_url' => 'http://search.msn.co.jp/', 'query' => 'q', 'encode' => 'UTF-8', ), 'goo' => array( 'pre_url' => 'http://search.goo.ne.jp/', 'query' => 'MT', 'encode' => 'EUC-JP', ), 'infoseek' => array( 'pre_url' => 'http://search.www.infoseek.co.jp/', 'query' => 'qt', 'encode' => 'UTF-8', ), 'livedoor' => array( 'pre_url' => 'http://search.livedoor.com/', 'query' => 'q', 'encode' => 'UTF-8', ), ); /** * 検索キーワード * * @var array */ private $keywords = array(); /** * コンストラクタ */ public function __construct() { $encode = mb_internal_encoding(); $regex_encoding = mb_regex_encoding(); mb_regex_encoding($encode); if (($referer = self::getEnv('HTTP_REFERER')) !== null) { foreach (self::$searchEngines as $s) { if (strpos($referer, $s['pre_url']) === 0) { if (($query = self::getRefererQuery($s['query'])) !== null) { $query = rawurldecode($query); $query = mb_convert_encoding($query, $encode, $s['encode']); $query = mb_convert_kana($query, 's', $encode); foreach (mb_split('\s', $query) as $k) { $this->keywords[] = htmlspecialchars($k, ENT_QUOTES); } } } } } mb_regex_encoding($regex_encoding); } /** * 検索キーワードをハイライト表示 * * @param string $buffer * @return string */ public function highlight($buffer) { $replace = array(); foreach ($this->keywords as $k) { $replace[] = self::PREFIX_TAG.$k.self::SUFFIX_TAG; } return str_replace($this->keywords, $replace, $buffer); } /** * このキーワードで検索されているかをチェック * * @param string $keyword * @return boolean */ public function isRequested($keyword) { return in_array($keyword, $this->keywords, true); } /** * HTTP_REFERERのQUERY_STRINGを返却 * * @param string $varkey * @return string */ private static function getRefererQuery($varkey) { $varvalue = null; if (($referer = self::getEnv('HTTP_REFERER')) !== null) { $raw = ''; if (preg_match('/'.self::REGEXP_HTTP_REFERER.'/', $referer, $matches)) { $raw = $matches[1]; } foreach (explode('&', $raw) as $row) { $query = split('=', $row); if (isset($query[0], $query[1]) && ($query[0] === $varkey)) { $varvalue = $query[1]; } } } return $varvalue; } /** * 環境変数の値を返却 * * @param string $varkey * @return string */ private static function getEnv($varkey) { $varvalue = null; if (isset($_SERVER[$varkey])) { $varvalue = str_replace( array("\x00","\x01","\x02","\x03","\x04","\x05", "\x06","\x07","\x08","\x0B","\x0C","\x0E", "\x0F","\x10","\x11","\x12","\x13","\x14", "\x15","\x16","\x17","\x18","\x19","\x1A", "\x1B","\x1C","\x1D","\x1E","\x1F","\x7F"), '', $_SERVER[$varkey]); } return $varvalue; } }
といいつつも検索キーワードをハイライトするだけだから、ちょっと趣旨が違ってる。
↓みたいに使ってHTML出力のキーワードをハイライト用のタグで囲むような。
<?php ..... $highlight = new HighlightKeywords; ob_start(array($highlight, 'highlight')); ?> <html> ..... </html>
↓みたいなことをすれば、一応は本来の目的としても使えるかも。
<?php ..... $highlight = new HighlightKeywords; ob_start(array($highlight, 'highlight')); ?> <html> ..... <?php if ($highlight->isRequested('ぐらころ')) : ?> ぐらころなら! <?php endif ?> ..... </html>