PHPからMecabを利用する拡張モジュール

PHPからMecabを使いたかったので、Page2さんで公開されているPHP拡張モジュールを試してみた。試したのは、PHP5とMecab 0.95という組み合わせ。

  1. ソースのダウンロード
    $ wget http://page2.xrea.jp/pub/php_mecab-0.2.0.tgz
    $ tar zxvf php_mecab-0.2.0.tgz
  2. コンパイルとインストール
    $ cd php_mecab-0.2.0
    $ /usr/bin/phpize
    $ ./configure --with-php-config=/usr/bin/php-config \
    --with-mecab=/usr/bin/mecab-config
    $ make
    $ sudo make install
  3. 動作確認
    <?php
    dl('mecab.so');
    
    $t = new MeCab_Tagger();
    $str = 'すもももももももものうち';
    
    echo $t->parse($str);

    実行結果1

    す      接頭辞,名詞接頭辞,*,*,す,す,*
    もも    名詞,普通名詞,*,*,もも,もも,代表表記:股
    も      助詞,副助詞,*,*,も,も,*
    もも    名詞,普通名詞,*,*,もも,もも,代表表記:股
    も      助詞,副助詞,*,*,も,も,*
    もも    名詞,普通名詞,*,*,もも,もも,代表表記:股
    の      助詞,接続助詞,*,*,の,の,*
    うち    名詞,副詞的名詞,*,*,うち,うち,*
    EOS

    問題なく動作しているようだけど、「すもも」が一つの名詞として認識されてなくて、「す」+「もも」という変な組み合わせになっている。次に辞書をJumanからipadicに変更してみる。

    <?php
    dl('mecab.so');
    $options = array('-d', '/var/lib/mecab/dic/ipadic');
    
    $t = new MeCab_Tagger($options);
    $str = 'すもももももももものうち';
    
    print $t->parse($str);

    実行結果2

    すもも  名詞,一般,*,*,*,*,すもも,スモモ,スモモ
    も      助詞,係助詞,*,*,*,*,も,モ,モ
    もも    名詞,一般,*,*,*,*,もも,モモ,モモ
    も      助詞,係助詞,*,*,*,*,も,モ,モ
    もも    名詞,一般,*,*,*,*,もも,モモ,モモ
    の      助詞,連体化,*,*,*,*,の,ノ,ノ
    うち    名詞,非自立,副詞可能,*,*,*,うち,ウチ,ウチ
    EOS

    今度はちゃんと認識してくれた。素晴らしい!

PRhagger@第20回PHP勉強会

KLab株式会社@六本木ヒルズで行われているPHP勉強会に来ています。

内容は、PHP Extensionの作り方と Rhaco で作られたアプリケーションの紹介が2つ。Rhacoというのは、DjangoのGeneric Viewやテンプレート継承の仕組みを取り入れたPHP向けのフレームワークです。で、このRhacoを使って作ったPHP版Plaggerが話題になり、勉強会の申し込み開始から数時間で定員がいっぱいになってしまったとのことでした。そういえば、いつものPHP勉強会とは違って、Perl界隈の人が多いような…


PHP Extensionを作ろう

  • PHP4とPHP5
  • 会社のサーバ落ちたので聞けなかった(残念)

Prhagger

  • haltさんの自己紹介

    幼稚園の時にスーパーマリオをワープなしでクリア
  • 某サイトの話とか

  • Subscriptionプラグイン FeedIn,bloglines,CustomFeddMixi

  • Filter FilterLou

  • Publish

  • Rhacoフレームワーク 名前はアオガエルから

  • 次回はエロPRha

    Publish_Photozouでエロ動画10000ファイル保存w
    iTunesで見たり
    YouTubeは帯域制限がかかっているので1日中動かしている
  • Perl版があるのにそのモチベーションはどこから?

    PerlよりPHPが得意だから
    Plaggerは敷居が高い
    アップロードしただけで動くようにしたい
    やりたいからやっている

WorkStyle

  • GTDツール

  • PHP版の他にJava版もある, Python版も作成予定

  • rhacoの特徴

    Easy setup
    Library independent
    URL mapping
    O/R Mapping
    Generic View
    Admin

ここのところのPHP勉強会は、話題がてんこ盛りで面白いですね。懇親会でDo you PHP?の人といっぱい話ができたのも収穫でした。次回の勉強会も出たいです。

PHP勉強会に参加してDjangoで掲示板を作りました

第17回PHP勉強会に参加してきました。会場となったECナビさんのオフィスは、とても綺麗でステキでした。

内容は時間内に各自で掲示板を作ろうというもので、皆さん、EthnaとかSymfonyとかお気に入りのフレームワークで作っていました。僕はというと、後ろのほうで隠れてDjangoで作りました。PHP勉強会なのにごめんなさい、ごめんなさい。

メインロジックはあっという間にできてしまって、HTMLとかスタイルシートが一番時間がかかった気がします(といってもadmin画面のパクリだけど)。実際にコードを書いたのは50行くらいです。本当にシンプルで面白くもなんともないのですが、せっかく作ったので公開することにします。これからDjangoを始めようという方向け。


勉強会の後の懇親会にも参加させてもらいましたが、PHPな方々と交流できて楽しかったです。

LLRing直前オフに行ってきた

PHPとPythonな人達が合同でLLRing直前オフをやるというので、参加してきました。
Software Design編集部やインプレスの人もいて、かなり盛り上がったよ。
  • 柴田さんが 『みんなのPython』 にサインを書きまくっていた。自分も持って行けばよかった。
  • Djangoの露木さんにいろいろ聞く。Djangoの勉強会を開催しようということに(決定ですよね?)
  • uemuraさんと初めて話した。Macのことをもっと聞きたかった。
  • tokuhiromさんがいいこと言ってた。「Rails含め他のWebフレームワークは横並び、Djangoはひと味違う」
  • Ura5hanの人がスーツ姿で登場して、「今日はJavaのコスプレしてますが」と言っててウケた。

  • PythonよりPHPのほうが若い人が多い気がする。
  • PHPのフレームワークは、関東と関西で人気のものが違うらしい。
  • Zend Frameworkはまだまだらしい。
  • むむむさん、面白かった。

CFUSION_ENCRYPT関数をPHPで書いてみる

思いっきりチラシの裏。中身は文字列とキーの排他論理和をとって16進化してるだけ。

function cfusion_encrypt($text, $key) {
    $keylen = strlen($key);
    $j = 0;
    $newval = "";

    for ($i=0; $i<strlen($text); $i++) {
        if ($i >= $keylen) $j++;
        $wd = (ord(substr($key, $i - $keylen * $j, 1)) ^ ord(substr($text, $i, 1)));
        $newval = $newval . sprintf("%02X", $wd);
    }
    return $newval;
}

PEAR::HTML_TreeMenuとDB_NestedSet

今日は、HTML_TreeMenuDB_NestedSetではまってました。
どちらもPEARというPHP用のライブラリです。規模は違うけど、PerlのCPANみたいなものですね。
HTML_TreeMenuがツリー構造のメニューを配列から生成するもので、DB_NestedSetがその配列をデータベースに保存するためのものです。ノードの追加や移動などのメソッドが用意されてるんで簡単にツリー形式のメニューが作れます。ただ、ドキュメントが少なくてここに辿り着くまでにかなり苦労しました。

最初、PEAR::Treeを試したんですけど、HTML_TreeMenuとの連携という点ではDB_NestedSetのほうが簡単です。DB_NestedSetのメソッドとして実装されているので、HTML_TreeMenuは意識する必要がありません。
ただ、1.3以降のベータバージョンでないと、tree_toHTML()というメソッドが使えないので、出力を変数に格納することができません。CMS等で使う場合は、最新版にしましょう。
本当はここにサンプルを載せたいけど、風邪をひいたらしく体調悪いのでまた次回。

もう、XOOPsやめます

/.クローンとしてしばらく使ってきましたが、自分が求めてる機能とのずれを感じてきたのでxoopsやめます。
・纏まったドキュメントを管理したい
・モジュール(ポートレット?)を簡単に追加できる
・RSS提供サイトが増えてきたのでうまく組み込む
・ローカルなコミュニティを複数作りたい
見た目は、plone.orgみたいな感じでTrackBackに対応したやつを自分で作ろうかなぁ。
PHPで作ったポータルフレームワークを発展させるか、JAVAの勉強を兼ねてJetspeedでやるか。

Xoops 2.0.1とRSSヘッドライン

今日は風邪が悪化(変な肺炎かと心配するくらい)して咳が止まらないので、午後から仕事を放棄して帰ってきました。
病院に行ったはいいけど、保険証を置き忘れて家に電話がかかってくるなど散々でした。もう3日くらい禁煙してたり、情報処理の試験を欠席したりして治そうと努力してるのに一向に良くならない。こりゃ誰かに移すしか…

本題に入ると、ちょっと前にXoops 2.0.1にアップグレードしました。
アップグレード自体は上書きして、スクリプトを実行するだけととても簡単です。テーブルの更新も自動でやってくれます。よくできてます。
が、ヘッドラインモジュールが曲者でした。今は右側に/.とjapan.linux.comのヘッドラインが表示されてると思います。これが最初は正常に表示されるんだけど、2回目以降の更新がうまく動かないという不具合がありました。しかも、ページ全体を道連れにして何も表示されなくなってしまう。
さらに不運なことに、そのタイミングでGoogleのロボットがおいでになったために真っ白ページをインデクシングされてしまいました。

一応、次の対策で直ったと思うのだけれど、ちょっと自信なし…

modules/xoopsheadline/class/headline.php の123行目で常にtrueを戻すように変更しました。
 return false → return true

# 違うかなぁ。風邪引いて体調悪いので自信なし。

Xoops 2.0に移行しました

本日、Xoops 2.0RC3にアップグレードしました。 表面的にはあまり変わらないけど、管理側がとても使いやすくなっています。テンプレートを採用したことでViewのカスタマイズが簡単になりました。そして、モジュールの出力もプログラムをいじることなくカスタマイズできます。ソースを見ないとどんな変数が使えるか分からないので、お手軽とは言えないけど良いです。見習わなくちゃ。 気になったのは、キャッシュをして高速化を図っているみたいなんだけど、ファイルがあちこちに散らばっていて変更を反映させるのにどれを削除したらいいのか迷うところ。この辺は、アプリケーションレベルではなくてサーバレベルで一括して出来たらいいのに。

モデレーションをなくす方法

せっかくブロードバンド環境になったっていうのに、なかなか満喫する時間がありません。

モデレーションなしで投稿できるようにする方法です。 > 中川さん
通常は投稿されると、データはまずqueueテーブルに格納されます。そしてモデレータによって承認されると、storiesテーブルに移されて公開という手順です。
なので、投稿時に直接storiesテーブルに登録してしまえばモデレートなしになります。

こんな感じでしょうか。
本当は設定をみて、処理を切り替えなければいけないのだろうけど。
--- submit.php.orig     Thu Jan 24 09:03:45 2002
+++ submit.php  Tue Oct 16 23:14:30 2001
@@ -225,7 +238,18 @@
        $story = FixQuotes(filter_text($story));
        $storyext = FixQuotes(filter_text($storyext));
     }
-    $result = mysql_query("insert into $prefix"._queue." values (NULL, '$uid',
'$name', '$subject', '$story', '$storyext', now(), '$topic', '$alanguage')");
+// hide@yamashita.dyndns.org at 2001/07/29
+// No Moderation
+//    $result = mysql_query("insert into $prefix"._queue." values (NULL, '$uid'
, '$name', '$subject', '$story', '$storyext', now(), '$topic', '$alanguage')");
+    $aid = "hoge";
+    $hometext = "$story";
+    $bodytext = "$storyext";
+    $author = "$name";
+    $acomm = 0;
+    $haspoll = 0;
+    $id = 0;
+    $result = mysql_query("insert into $prefix"._stories." values (NULL, '$cati
d', '$aid', '$subject', now(), '$hometext', '$bodytext', '0', '0', '$topic','$au
thor', '$notes', '$ihome', '$alanguage', '$acomm', '$haspoll', '$id')");
+
     if(!$result) {
        echo mysql_errno(). ": ".mysql_error(). "
";
        exit();