php source code search with php
DESCRIPTION
@PHP勉強会#46 ソース検索をPHPでつくるTRANSCRIPT
柄沢聡太郎 (sotarok)
http://nequal.jp/
twitter.com/sotarok
PHP Source Code Search
with
PHP
Copyright © nequal, Creative Commons Attribution-Noncommercial 2.1 @ PHP Study #46.
始める前に
Copyright © nequal, Creative Commons Attribution-Noncommercial 2.1 @ PHP Study #46.
今⽇はPHP勉強会
Copyright © nequal, Creative Commons Attribution-Noncommercial 2.1 @ PHP Study #46.
なぜ 9/29 ではないのか
Copyright © nequal, Creative Commons Attribution-Noncommercial 2.1 @ PHP Study #46.
懇親会はピザだって?
Copyright © nequal, Creative Commons Attribution-Noncommercial 2.1 @ PHP Study #46.
⾁はどうしたんですか
Copyright © nequal, Creative Commons Attribution-Noncommercial 2.1 @ PHP Study #46.
本来のPHP勉強会
Copyright © nequal, Creative Commons Attribution-Noncommercial 2.1 @ PHP Study #46.
PHPerPHPerはは⾁の精神を忘れ⾁の精神を忘れてしまったかてしまったか
Copyright © nequal, Creative Commons Attribution-Noncommercial 2.1 @ PHP Study #46.
ごめんなさい冗談ですgusagiさん幹事おつかれさまです
じこしょうかい
Copyright © nequal, Creative Commons Attribution-Noncommercial 2.1 @ PHP Study #46.
sotarok
• そうたろう(けー)• プリン• プリン• プリン• pudding
• プリン• ⾁• ごはん• 自転⾞• 写真 – Sony α 300• Ethna
• nequal
Copyright © nequal, Creative Commons Attribution-Noncommercial 2.1 @ PHP Study #46.
宣伝• WikiHub
– http://wikihub.org/
– Gitで⽂書管理して,それをWiki 形式で整形して表⽰
– GitHub の Service Hook で簡単同期• 制限つきOpenBeta– 100⼈まで
Copyright © nequal, Creative Commons Attribution-Noncommercial 2.1 @ PHP Study #46.
宣伝2• プリンが好きです
なぜか誰も買ってこない
Copyright © nequal, Creative Commons Attribution-Noncommercial 2.1 @ PHP Study #46.
宣伝2• プリンが好きです
yuchimiriさんにRTまでされたのに
Copyright © nequal, Creative Commons Attribution-Noncommercial 2.1 @ PHP Study #46.
Preferred Infrastructure (PFI)
というところでインターンやってます
検索エンジンとかつくってるとこ!
だからか だからです
Copyright © nequal, Creative Commons Attribution-Noncommercial 2.1 @ PHP Study #46.
Agenda
• 検索エンジン• 転置インデックス• クロールとキーワード抽出• スコアリングと並び替え• デモ• 技術的な課題とか
Copyright © nequal, Creative Commons Attribution-Noncommercial 2.1 @ PHP Study #46.
検索エンジン• キーワードを⼊⼒– →そのキーワードが含まれる(そして探したいと思われる)⽂書が探せる
• ソースコード検索– grep
– gtags (GNU GLOBAL)
– trac + Hyper Estraier (BTS + Plugin)
– Google Code Search
Copyright © nequal, Creative Commons Attribution-Noncommercial 2.1 @ PHP Study #46.
grep
• 与えられたキーワードをファイルをたどり,⽂字列⼀致で探す
• 前処理が必要ない• どこにでも⼊ってる
• 大量の⽂書から探すのは時間がかかる– 同じキーワードで再検索するときもまた同じ処理
• ランキングづけができない
grepのデメリット
Copyright © nequal, Creative Commons Attribution-Noncommercial 2.1 @ PHP Study #46.
検索エンジンを作る• 既存のいろんなソフトウェアを使うのもいいけど• 「検索エンジン」– そんな難しくない– PHPでもできる– カンタンだよ!
• 今回の目標– ローカルのPHPソースファイルからメソッドや関数や変数を検索できるようにする– ディレクトリを指定して,再帰的にPHPファイルを検索– grep -rn 'substr' **/*.php
転置インデックス
Copyright © nequal, Creative Commons Attribution-Noncommercial 2.1 @ PHP Study #46.
転置インデックス• キーワードから⽂書を逆引きできるようにあらかじめつくっておくインデックス
• 焼⾁ =>
– ⽜角– Wikipedia – 焼⾁– YAKINIQUEST - ヤキニクエスト– ...
Copyright © nequal, Creative Commons Attribution-Noncommercial 2.1 @ PHP Study #46.
⽂書1I like Sushi, Yakiniku and pudding !
⽂書2PHPer like Yakiniku. Maybe not like Sushi.
⽂書3Dankogai is an enemy of PHPer.
※⽂書はフィクションです
Copyright © nequal, Creative Commons Attribution-Noncommercial 2.1 @ PHP Study #46.
⽂書1I like Sushi , Yakiniku and pudding !
⽂書2PHPer like Yakiniku. Maybe not like Sushi.
⽂書3Dankogai is an enemy of PHPer. He also like Yakiniku.
※⽂書はフィクションです
Copyright © nequal, Creative Commons Attribution-Noncommercial 2.1 @ PHP Study #46.
⽂書3Dankogai is an enemy of PHPer. He also like Yakiniku.
⽂書2PHPer like Yakiniku. Maybe not like Sushi.
⽂書1I like Sushi, Yakiniku and pudding !
1Sushi
Copyright © nequal, Creative Commons Attribution-Noncommercial 2.1 @ PHP Study #46.
⽂書3Dankogai is an enemy of PHPer. He also like Yakiniku.
⽂書2PHPer like Yakiniku. Maybe not like Sushi.
⽂書1I like Sushi, Yakiniku and pudding !
1Yakiniku
1Sushi
Copyright © nequal, Creative Commons Attribution-Noncommercial 2.1 @ PHP Study #46.
⽂書3Dankogai is an enemy of PHPer. He also like Yakiniku.
⽂書2PHPer like Yakiniku. Maybe not like Sushi.
⽂書1I like Sushi, Yakiniku and pudding !
1Yakiniku
1pudding
1Sushi
Copyright © nequal, Creative Commons Attribution-Noncommercial 2.1 @ PHP Study #46.
⽂書3Dankogai is an enemy of PHPer. He also like Yakiniku.
⽂書2PHPer like Yakiniku. Maybe not like Sushi.
⽂書1I like Sushi, Yakiniku and pudding !
21Yakiniku
1pudding
1Sushi
Copyright © nequal, Creative Commons Attribution-Noncommercial 2.1 @ PHP Study #46.
⽂書3Dankogai is an enemy of PHPer. He also like Yakiniku.
⽂書2PHPer like Yakiniku. Maybe not like Sushi.
⽂書1I like Sushi, Yakiniku and pudding !
21Yakiniku
2
1pudding
1Sushi
Copyright © nequal, Creative Commons Attribution-Noncommercial 2.1 @ PHP Study #46.
転置インデックスをPHPで• array でしょJK
$inverted_index = array(
'miyazaki' => array(1, 2, 6, 4 ...),
'aoi' => array(2, 6, 7, ...),
'sotarok' => array(...),
...
);
配列のキー:単語
配列の要素:⽂書IDのリスト
クロールとキーワード抽出
Copyright © nequal, Creative Commons Attribution-Noncommercial 2.1 @ PHP Study #46.
クロールとキーワード抽出• 対象の⽂書からキーワードを拾い集める• クローラー -> Google なら Google Botとか
• キーワード ->
– 空⽩区切りの⽂字列(英語圏のひと)– 形態素解析(明⽇ は あめ だ)– n-gram
• n⽂字区切りでキーワードにする• 2-gram(bi-gram)
• 明⽇ ⽇は はあ あめ めだ
Copyright © nequal, Creative Commons Attribution-Noncommercial 2.1 @ PHP Study #46.
クロールとキーワード抽出をPHPで(1)
•function crawl ($dirname)
• foreach(glob($dirname . "/*") as $file)
• if is_dir($file):
• $files += crawl ($file)
• else:
• if $file ~= /.+¥.php$/
• $files[] = $file
• return $files
Copyright © nequal, Creative Commons Attribution-Noncommercial 2.1 @ PHP Study #46.
クロールとキーワード抽出をPHPで(2)
• token_get_all ��������
• PHP �������������������������� ��� ��� ��� �
• ������������ tokenize ����������������������������
• http://php.net/tokenizer
• T_STRING
• T_VARIABLE
• キーワードの抽出– 関数名/メソッド名/クラス名/変数名– tokenizer を使う
スコアリングと並び替え
Copyright © nequal, Creative Commons Attribution-Noncommercial 2.1 @ PHP Study #46.
スコアリングと並び替え• なにかの基準で検索結果を並び替える• あてはまりの良い⽂書を上に出す
• 普通の検索なら– ページランク (Google のウェブ検索)– TF-IDF
• ⽂書中の単語の出現頻度• その単語の⽂書全体での珍しさ
– ...
Copyright © nequal, Creative Commons Attribution-Noncommercial 2.1 @ PHP Study #46.
スコアリングと並び替えをPHPで• スコアはソースコード中のそのキーワードの出現数
• 多い順に並び替え
uasort(
$scored,
create_function(
'$v1, $v2',
'return $v1[¥'count¥'] < $v2[¥'count¥'];'
)
);
PHP 5.3 ならfunction($v1, $v2)
でいける!
デモ
Hyper Pudding
http://gist.github.com/192879
Copyright © nequal, Creative Commons Attribution-Noncommercial 2.1 @ PHP Study #46.
技術的な課題• デモったやつは全部 on memory
– 大規模⽂書はイケない• symfonyで 140MB くらい⾷うかな
– ということで,転置インデックスを外部ファイル(Key-Value Store... まぁ,SQLiteとかでもいいけど) に保持するといい
• 並び替えの基準は出現頻度でいいの?– これはまあ難しいですね– 属性情報とかいろいろとればさらに
• And/Or 検索
Copyright © nequal, Creative Commons Attribution-Noncommercial 2.1 @ PHP Study #46.
まとめ• 簡単な検索エンジンはPHPでもつくれる– それもお⼿軽に
• インデックスをあらかじめつくっておけば検索は瞬時にできる
• 検索技術とか楽しい
ありがとうございました
Question?