PyhaLokkaにMLを作りました。

Lokka-ja | Google グループ

僕一人ではすごく悲しい雰囲気になってしまうのでサクラでいいので入ってください・・・。

PyhaLokkaの開発について

ブログってフレームワークのHello world的な扱いで出てくるぐらいなので誰でも作れます。逆に言うと技術的なチャレンジは少なく、どれだけ手を動かせるか的なところがあってプログラマー的には面倒です。だからあまりエッジな人は作りませんよね。あるとすればミニマリストのための超シンプルツールで、これは作ってて楽しい。僕も以前、普通に作り始めたらそうなってしまって、一般ユーザーやデザイナーがWordPressに求めてるようなものは出来ませんでした。

PHP以外で一般ユーザーやデザイナーにも普及するWebアプリなんて無理なんだと諦めていましたが、RedmineはWeb制作会社にいるデザイナーに何人か聞いたら結構な割合で知ってました。なんだ、Rubyでも行けるんじゃん。

「なんで僕らは仕事で、自分のブログで、WordPressを使ってるんだ?Rubyでそういうのが無いのはおかしい!」

そんなよく分からない義務感?が開発の原動力になっていて、元々そういうツールがあればそれを使いたいし、その開発に参加すれば良いと思っています。しかし上記の様な事情があってあまり作りたがる人はいません・・・。

※Radiant CMSは僕的に設計やコードは素晴らしくて若干うっとりしたぐらいです。しかしデザイナーに聞くと、本当に欲しいのは純粋なCMSではなく、ブログツールベースのCMSであるようなのです。

PyhaLokkaはSinatraベースのまだまだ未熟なブログツールなので、Rubyがわかれば誰でもコーディングの余地がいくらでもあります。(例えば投稿した後にflushで「投稿しました」とか出すべきなのを出してないとか、helperその他はpadrinoのモジュールに置き換えたいとか、テストが無いとか・・・)

貧相なプロジェクトの割にWordPress打倒!という分り易くも無茶な目標を掲げてやっていくのは面白いかもなあと最近思いはじめました。

「みんな、オラに力(コード)を分けてくれ!」

irc.freenode.netに#lokkaと#lokka-jaというチャンネルを作りました。(#lokka-jaの方は日本語で話す)

pyha (irc.freenode.net)

  • インストールしてみた
  • インストールできない
  • 改造してみた
  • ここバグってる
  • lokka.orgのドキュメント(日本語 or 英語)を書いてくれる方

などいらっしゃったらJoinしていただけると嬉しいです。

  • WordPressのPHPプラグインを書くのにウンザリしていたRubyistの方
  • 「the_post()ってなんだよ!」と思ったことがある方
  • HerokuかわいいよHerokuという方
  • 無駄にスケールするCMSが欲しい方

におすすめです。

ihara.jpg

何でCMS作りたいかというと、WordPressが凄い便利だなーと思うからです。

デザイナー(@machidaさん)とプログラマー(俺)で会社をやってますが、デザインがメインの会社なので当然デザインの案件が多いです。そうすると、WordPressがあればプログラマーは何もしなくていいという案件がとても多いんです。

@machidaさんがWordPressを使い込んでるということもあるんですが、プログラマー無しでまともなWebサイトが作れるとかWordPress凄いなー。嫌だなー 怖いなー 怖いなー って思ってたんです。(褒め言葉)

でもまあ、時々はそのサイト向けに特化した機能や動きが必要になって、既存のプラグインでは対応出来ない時、プログラマー(俺)がプラグインをPHPで書くんですが、これが辛い・・・。

また、既存のプラグインで対応できるかの調査でそのプラグインのコードを全部読んだりするんですが、これもシンドイ・・・。(プラグインの作者がヘボイとかそういうわけでは全然無く、PHPとWordPressのルールと流儀をしっかり守ると逆にシンドイコードになるのです・・・)

それは我慢しろって話ですが、PaaS環境(GAE, Heroku)で動かないのがかなりダルイ。

WordPress用にさくらインターネットの500円の共有レンタルサーバーを借りるのがお決まりのコースなんですが、WordPress以外は全部Herokuに置くようになってから、@machidaさんが、

「何でWordPress、Herokuで動かないんですかねえ」

と、キレそうになっているのでHerokuで動くWordPress的な物が欲しいのでCMSを作ります。

最近仕事でWordPressのテーマやプラグインのコードに触れています。

WordPressには「結果を標準出力に出力する」か「返り値(文字列)として返す」かというフラグを引数に持つ関数がとても多い。

下記のコードは同じ動きをする。(実際にthe_titleの上記フラグは第三引数ですが分かりやすくするために簡略化しています。)

// エントリのタイトルを出力する
<?php the_title(); ?>
komagata [p0t]

<?php echo the_title(false); ?>
komagata [p0t]

本体にこういう関数が多いため、プラグインでも暗黙的にその動作を求められる。

何で後者がデフォルトじゃないのか。そもそも、

// エントリのタイトルを出力する
<?= the_title() ?>
komagata [p0t]

こうじゃ駄目なのか?

これはショートタグがマナー違反とされているため、<?php echoと書くのが面倒でこうなっているんではないでしょうか。

そもそも何故ショートタグが色々なコーディング規約で非推奨になっているのかも理解出来ない。XML宣言と同じ事はそれ程問題なんだろうか。何かセキュリティーホールがあるのかな?

テーマの中で<?php echo とわざわざ書かなければいけないせいで、テンプレートがウリのPHPの良さが損なわれている気がしてならない。

WordPressではthe_xxx()という名前だからといって必ず上記の機能を持っているわけではない。そもそも返り値を返さない関数も多い。

リファレンスを見ると、最近のバージョンになるにつれてthe_xxx()は関数内で出力、get_the_xxx()は文字列として返り値を返すというルールが出来つつあるっぽいが統一されそうな気配は無い。

この手の瑕があちこちに見られます。大勢に使われることで成長してきたソフトウェアだから仕方のない事だと思います。しかし、もう大きく舵を切らないとマズいところに来ていると感じました。

特に安価なレンタルサーバーで動くことが大きな長所であるWordPressは無料からあるクラウド環境に対応出来ないと今後生きていけないと思う。

それにはデータベースの抽象化がほぼ必須だ。このまま生SQL CREATE文を抱えた大量のプラグインと一緒に沈没していく危険性が高い。

僕の考えたWordPress生き残り戦略

  1. 今のAPIは期限付きDeprecatedで残しつつ、クリーンでデータベース非依存のAPIを作る。(本家がやらなくても、プラグイン制作者用ライブラリを作るでも良い)
  2. PHP4の排除運動に便乗して一緒に旧API依存プラグイン/テーマを推奨しない運動を広める。(新APIへ対応するプラグイン/テーマ開発者・ユーザーをAutomattic社とか作者のMattとかが賞賛しまくる。)
  3. プラグイン・テーマのバージョンを見て、管理画面で嫌な警告を出す。
  4. 1〜2年後ぐらいに旧APIを削除(ドーン!)
  5. ユーザーはいつの間にかクラウドに対応してる。

地味で当たり前で退屈な方法だけど今はじめないと手遅れになると思いました。

Ruby on Rails携帯サイト開発技法

事実上、Railsでの携帯開発本は他に無いので携わる人は必携であります。

個人的に感じたのは俺の様に「Rails使ってるけど携帯開発から逃げ回っている人」に特にオススメです。携帯案件やることになったら買うしか無いです。

  • 携帯の絵文字をPCでも表示する。(jpmobileの機能には無い)
  • 位置情報の利用
  • ActionMailerで絵文字やデコメ
  • リファラーからセッションIDが漏れることに対する対策
  • Flash Lite
  • jpmobileを使わない一からの実装

どうよコレ。俺の様な携帯弱者のRails厨が震え上がる内容ばっかりでしょう。頭痛いわー、俺・・・・。(大抵の携帯サイトの仕様には全部含まれてそうだし・・・)

そういう方にはとてもいいんじゃないでしょうか。基本、携帯はPHPの本ばっかりなので。

取り敢えず3冊買った・・・。

Ruby on Rails携帯サイト開発技法

1冊は俺用なので欲しい方は@komagataまで住所をDM頂ければ郵送しますー。ブログにでも本の感想を書いていただけると本が沢山売れるかもしれません!

稀有なプログラマー

著者のひとり、@yoshukiさんは非常に珍しいプログラマー兼業農家(米農家)です。

ちょっとした畑とかじゃなくてガチの水田。晴耕雨読を地で行ってる方です。

過去2年も三上米収穫祭と称してお米食べる会が模様されており、今年も楽しみです。

ネタとかじゃなくてマジで

OKOME

「お米食べろ!」

@yoshukiさんといえば電気屋(兼農家)の息子だけあってか、道具にこだわりがある印象が強いです。学生時代はTSUKUMOの店員としてアキバネイティブの自作野郎でCANOPUS信者(ビデオカード)。ノートはThinkPad。キーボードはRealforce以外認めない!そんでRubyに詳しいっつーんだから面白い。

@yoshukiさん支援で無断でプロモーション活動をしています・・・。

Rails検証報告書: プログラマの思索

Railsで特徴的なのは、CookieでHTTP セッションを管理できることだろう。

ここの仕組みが非常に分かりやすい。

Railsの後から付いた機能で一番素敵だと思うのがこの機能です。

「Cookieなんて仕様上は4KBしか保存出来ないんだから寧ろ弱体化してね?」

とか認識されることが多い気がしてならない。

コレ、導入時にも度肝を抜かれて、以降常に、

「ハンパねー、マジCookieセッションハンパねー!」

と脳内のアフロの人が言ってるんですが、大した利点に感じる人は少ないのか、他の言語やWAFで全面採用している例を見たことが無い。

Cookieセッション

そもそもセッションという言葉自体が複数の処理をまとめた単位という広義の意味とWebアプリケーションで複数リクエストにまたがってサーバー側に保存されるデータという狭義の意味が混在して使われているという事情があってWeb上でのテキストコミュニケーションを阻害している。

RailsのCookieセッションと言った場合は広義のセッションだが、狭義のセッションは存在しないと断言すると分り易い気がする。

RailsはHTTP(RESTアーキテクチャスタイル)の原則に従う形で何も共有しないという設計上のポリシーを持っている。

そもそもCookieと言う仕様はステートレスなHTTPプロトコルに広義のセッションを構築する上でNetscapeが考え出した上手い抜け穴だ。

CookieのデータはHTTPヘッダーに記載されて全データが送受信される訳だからHTTPリクエストの内容だけで全ての情報を表現するという原則からはみ出していない。

狭義のセッションに関しては言語仕様やアプリケーションサーバーの実装に委ねられていて、例えばPHP(言語仕様に狭義のセッションが含まれている)とJavaのTomcatとでは全然違う。

殆の実装でそうなっているんだけど、Cookie内の一意のIDをキーにしてサーバー上に(メモリであれ、ファイルであれ)狭義のセッションデータを持っている。

単体のHTTPリクエストやレスポンスで全ての情報を表現できなくてはHTTPの原則であるステートレスとは言えない。(Cookie内のIDがサーバー上のセッションデータを対応しているとしてもそれは単体のHTTPリクエストやレスポンスだけで判断出来ない、/tmp/sess_IDファイルの中にシリアライズされてるとかいった暗黙のルールが含まれている。)

RailsのCookieセッションは広義のセッションの維持はCookieによってのみ維持され、クライアントPCに保存され、それを元にしてステートレスなHTTPリクエストとして送出される。

認証

Rails2.x以降、Cookieセッションに移行すると同時に、認証は「restful_authenticationプラグインを使ってね!」という風にあっさりと変わった。

これは使う側やユーザーにとっては大した違いに見えないが、内部的には認証方式がBASIC認証に変わっている!

これまたファイルやDBに保存するステートフルな認証からステートレスな認証に思い切り変わっている。こんなもん土台をそっくりすり替えちゃう程の大変更だと思うんだけど、上位レイヤーに住んでる人には殆気付かれずに行った。

AtomPP策定のIETFの話し合い内でもあった、「APIと認証関係ねーだろう。認証はHTTPプロトコルの仕事」という身も蓋もない結論をあっさり採用する。そこに痺れる、あこがれる!

HTTPの原則を守る利点

ここまで過激にHTTPの原則を守る最大の利点は、Railsの設計方針としても上げられている「何も共有しない」からもわかるように非常にスケールアウトし易いところだ。そもそも、HTTP(の元のRESTアーキテクチャースタイル)はWebのような大きな分散環境を想定して作られたものである。

シンプルかつスケーラビリティの高いシステムを作るにはREST原則に従うのは理にかなっている。

何故ドラスティックな変更が可能なのか

Ruby界隈では標準仕様を決めてから実装するのではなく、「勝手に実装して、良いものだったら標準にしようか」というノリというか文化がある用に思う。

言語や周辺ツール・ライブラリの整備によって使い物になる実装が出来るまでの時間が恐ろしく短いため、整った仕様よりも、動くコードや自動テストが重視される傾向があるため、時間のかかる抽象的な議論が少なめになるせいではないだろうか。

例としては、最近各言語でxSGIと呼ばれてる仕様も通常、仕様とリファレンス実装を明確に分けるところをRubyではRackが実装を持って標準仕様を決めてしまった。そして実際にRack::RequestとRack::Responseはデファクトとしてあっという間に広まった。

不満

何が俺にこんな長文を書かせるかというと、

「Cookieセッション、BASIC認証を他の言語・環境でも使いたいんだよ!面倒臭くて仕方がない!」

というストレスが爆発したからである・・・。

localにphp5.3.1とwordpress2.8.6をインストールしてみるが、DBに繋がらないとのエラー。詳細が知りたいのでphp.iniのerror_logを設定してエラーログを見てみるが何も出力されてない。

<?php trigger_error('error raising!'); ?>

上記の様なスクリプトを実行してみると確かにエラーログに残るのだが・・・。

% grep -r @mysql .
./wp-includes/wp-db.php: $this->dbh = @mysql_connect($dbhost, $dbuser, $dbpassword, true);
./wp-includes/wp-db.php: if (!@mysql_select_db($db, $this->dbh)) {
./wp-includes/wp-db.php: $this->result = @mysql_query($query, $this->dbh);
./wp-includes/wp-db.php: while ($i < @mysql_num_fields($this->result)) {
./wp-includes/wp-db.php: $this->col_info[$i] = @mysql_fetch_field($this->result);
./wp-includes/wp-db.php: while ( $row = @mysql_fetch_object($this->result) ) {
./wp-includes/wp-db.php: @mysql_free_result($this->result);

なるほど・・・。

これだと原因究明が難しいのでmysql_connectの@を取って実行してみた。

% diff wp-includes/wp-db.php{,.org}
341c341
< $this->dbh = mysql_connect($dbhost, $dbuser, $dbpassword, true); # FIXED by komagata
---
> $this->dbh = @mysql_connect($dbhost, $dbuser, $dbpassword, true);

php_errors.log:

[14-Dec-2009 02:49:02] PHP Warning:  mysql_connect() [<a href='function.mysql-connect'>function.mysql-connect</a>]: [2002] No such file or directory (trying to connect via unix:///tmp/mysql.sock) in /users/komagata/Sites/wordpress/wp-includes/wp-db.php on line 341
[14-Dec-2009 02:49:02] PHP Warning: mysql_connect() [<a href='function.mysql-connect'>function.mysql-connect</a>]: No such file or directory in /users/komagata/Sites/wordpress/wp-includes/wp-db.php on line 341

なるほど、/tmp/mysql.sockにソケットファイルがあると思っているために接続できないらしい。

PHP: 実行時設定 - Manual

mysql.default_socket string

他にソケット名が指定されない場合、ローカルなデータベースサーバに 接続する時のデフォルトのソケット名。

php.iniにデフォルトのMySQLのsocketの場所を設定できる項目があることがわかった。ちなみに接続時のhostにもlocalhost:/path_to/mysql.sockといった指定が可能らしい。

PHPのマニュアルは非常に詳細な内容も記載されていて、日本語訳も充実しているので巷で問題になってたりすることの殆は公式マニュアルで解決することが多い。

macportsで入れた場合のmysqlのデフォルトのsocketの場所である/opt/local/var/run/mysql5/mysqld.sockを指定したら動いた。

問題解決のためにはコード内でエラー抑制はせず、各個人の環境でdisplay_errorsやerror_logを設定すべきだと思うが、php.iniが弄れない共有レンタルサーバーで使われることが多い事や、エラーがズラズラでてもパニックに陥るだけといった理由でこういう作りになっているのかなと思った。

本番環境ではすべきでないが、大抵の共有レンタルサーバーと同じ様にdisplay_errosOnにした場合、エラー抑制子を外すと、データベースに接続できない場合はこんな感じになる。

データベースエラー

たしかにちょっと怖い感じがするかも。初めてのインストールでこれが出たら諦めちゃう人も多いかも。

Macにインストール

% sudo port install php5 +apache2 +pear
% sudo port install php5-mysql php5-mbstring
% cd /opt/local/etc/php5
% sudo cp php.ini-development php.ini
% sudo /opt/local/apache2/bin/apxs -a -e -n "php5" libphp5.so
[activating module `php5' in /opt/local/apache2/conf/httpd.conf]
% sudo vi /opt/local/apache2/conf/httpd.conf
# mode_php5
Include conf/extras-conf/mod_php.conf

Timezoneを設定

/opt/local/etc/php5/php.ini

[Date]
date.timezone = Asia/Tokyo

MySQL設定

/opt/local/etc/php5/php.ini

[MySQL]
mysql.default_socket = /opt/local/var/run/mysql5/mysqld.sock

portsで入れたphpとmysqlそれぞれの見に行くsockの場所のdefaultが違う。

kawaduに言われてNAS上に固めてあったplnet.jpのソースを引っ張り出してきてgithubにアップした。

昔のソースは恥ずかしいけど、当時の俺のPHP4愛が注がれたコードを読んでみた。

何か、コードのテンションが全然違くて、兎に角書く!という感じ。

最近の俺は、ちょうどいいライブラリが無いだの、良い設計が思い浮かばないから実装しないだの、日和ってるなと。

「ライブラリが無いなら書けばいいじゃない。パンが無いなら(略」

「書くの?書かないの?書かないとしたら何時書くの?」

と当時の自分に劇詰めされてる気分になった。コーディング瞬発力が落ちてる。

元々俺は、ある種のトラウマから独自実装を病的に嫌う傾向があるんですが、それと怠惰が合わさり最強に見える。暗黒が持つと頭がおかしくなって死ぬ。

もっとガリガリガリガリ書くようにしよう!

参照:

WordPressにはContact Form 7というお問い合わせフォームが簡単に出来るプラグインがあるそうです。

しかし、さくらインターネットのスタンダードプランの様な共有SSLを使っている場合はformのactionが別のURLを指す必要があるので動きません。PHPでベタにお問い合わせフォームの作成を依頼されたんですが、面倒なのでContact Form 7を修正してWordPress本体とは別のURLで動くようにしました。

% diff wp-content/plugins/contact-form-7/settings.php{,.org}
115c115
<       return (string) 'https://secure1111.sakura.ne.jp/example.com'.$wpcf7_request_uri;
---
>       return (string) $wpcf7_request_uri;

多分、WebサーバーがURLを書き換えているので環境変数から現在のREQUEST_URIが取れない。仕方なくベタにURLを書きました。javascriptでfromのactionを書き換えれば汎用的になりそうですがそれはキモイのでこれでいいや。

参照:Contact Form 7: WordPress のお問い合わせフォームプラグイン。シンプル、でも柔軟。