macでPHP開発環境の構築

久しぶりの更新になってしまいましたが、備忘録なので仕方ないということで。

MacBook Proを購入しまして。
各種アプリ開発環境はサクッとインストールしたのですが、
PHP開発環境はeclipseを入れたくらいのものでした。

Mac自体がapache、mysql、postgresql、その他もろもろ入れられるので
自鯖で開発できるようにしたかったんです。

HomebrewでPHPのバージョン切り替えも簡単にできる感じで
(できればmysqlとかapacheもバージョン変えられるといいなと思ってる所ですが)
開発できれば色々と楽になるかな、と。

ということで、いろいろ調べつつ実行。

【とりあえずHomebrewの基本的なことを調べる】
Homebrewってのは、linuxで言うyumみたいなパッケージ管理システムのひとつ。
yumとの違いは、yumが既にビルドされているパッケージをインストールするのに対して
HomebrewはinstallコマンドでDL後にビルドしてインストールするらしい。
macではHomebrewとかMacPortsというパッケージ管理システムが多用されるみたい。

MacPortsはデフォルトでMac内に入っているアプリを依存関係として使用してくれない
らしく、既にインストールされているapacheも別の場所に再度入れて…みたいな事を
してしまうらしい。
ので、今回はHomebrewで。

前提として(?)Xcodeだけではなくてcommand line tools for Xcodeが必要なので、
app storeやらmacのサイトやらで入手する必要がある。
command line tools for Xcodeは、以前はXcode内に同梱されていたようなのだが
今は別梱らしいので、それも探して入れないといけなくなったらしい。
こういう細かい事は、Homebrewのインストール後に英語で注意書きが出るから
それを読めば大丈夫。

Homebrewのインストール自体は非常に簡単で、ターミナルから

ruby -e “$(curl -fsSkL raw.github.com/mxcl/homebrew/go)”

と入力するだけ。
その後

brew doctor

は走らせておく必要があるみたい。

ちなみに、Homebrewを使っていろいろインストールした際のキャッシュとかDLしたものは、
/Library/Caches/Homebrew/内に入るみたい。
で、その後はbrewコマンドでHomebrewを使ってパッケージを入れることになる。
例えば、

brew install wget

とか

brew uninstall wget

みたいな。

【apacheやらmysqlやらpostgresqlやら】
apacheはとりあえずmacに最初から入っているものを使用。
(面倒なので。)
必要に迫られることがあれば何か考えることにする。

sudo apachectl start

とかで起動して、http://localhostとかで動いたかどうか確認。
configは、/private/etc/apache2/httpd.confにある。

mysqlはHomebrewでインストール。
ターミナルを起動して、

brew install mysql

と打つだけ。
その後はどうするか(英語で)表示されるので、その通りに

unset TMPDIR
mysql_install_db --verbose --user=`whoami` --basedir="$(brew --prefix mysql)" --datadir=/usr/local/var/mysql --tmpdir=/tmp

とかでデータベースの構築。
(/usr/local/varディレクトリがないとmysql_install_dbでエラーが起きるかも?)

mysql.server start

でmysql起動。

postgresqlもHomebrewでインストール。
mysqlとほぼ同様なので、詳細は割愛。

brew install postgresql
initdb /usr/local/var/postgres -E utf8
pg_ctl -D /usr/local/var/postgres -l logfile start

という感じ。

PHPは後日で。5.1系のインストールができないかどうか悩んでいるところなので。
5.2系〜5,4系までは問題なくインストールできたんだけどね。

CSVファイルの扱い

CSVって、基本的に

・改行コードCRLF
・文字エンコードShift-JIS

であることが多いんだけども、
macintoshで作られたCSVを拝見したらCRだった。

さすがマック。…というべきか?

とりあえず、fopenしてfgetcsvで…とか思ったが、CRだとfgetcsvが上手く動いてくれない
(全てのデータが1行目にあると思われてしまう)
ので、改行コードを先に始末しないといけない。

ついでにUTF-8で書かれているPHPでも文字が読み込めるように
追加でひと手間加えてやる。

// SJISで記載されたCSVはUTF-8環境下では正常に読み込めないので、ここで対応
$buf = mb_convert_encoding(file_get_contents(CSVファイルのパス), “utf-8”, “sjis”);
// 改行コードCRLF、CRをLFに変換
$buf = preg_replace(“(\r\n|\r)”, “\n”, $buf);
// テンポラリファイルとして保存
$fp = tmpfile();
fwrite($fp, $buf);
rewind($fp);

// 1行ずつ処理していく
while($data = fgetcsv($fp))
{
// 各種処理
}

こんな感じで。
まさかCRの改行コードで苦しめられるとは…これっぽっちも考えていなかった。

一旦、clamdを停止する

VPSにqmail & vpopmail & clamd & spamassassinでメール環境を作っていたのだが
重い!メモリを大量に食う!
ので、他に何もできなくなる!

…ということで、一旦止めた。

 /home/vpopmail/etc/tcp.smtp
:allow,QMAILQUEUE=”/var/qmail/bin/qmail-scanner-queue.pl”

:allow,QMAILQUEUE=”/var/qmail/bin/qmail-scanner-queue.pl”

多分これでcdbを作成し直して、qmail再起動。
動いてるっぽいし、大丈夫っぽい?

プロジェクトを別視点から見直す的な。

今日は新規開発を一旦やめて、ソースコードレビュー。
とは言っても、開発者本人が別人になったつもりでプロジェクトを眺め返しただけの話だが…

しかし、成果はかなり大きかったかも。
ファイル構成やらファイル名やら関数名から定義名まで大量に手を入れたが、
おかげでパッと見で構成からどれが何をしているかまで格段に見やすくなった。

しっかり基本設計していても、結局開発中に様々な都合で仕様変更になって
その時に成り行きでやってしまう部分は、後で見返すと統一性に欠けていたり
システム全体から使う際の利便性に欠けていたりするようで。

そのあたりを時間をかけてじっくり調整することができました。
以後の拡張性についても検討したつもりだし。
うん、大満足。

勢いでガッツリ作ってしまうのも良いのですが、
こうやってたまに見返すのも良いもんですね。

…まぁ、そんなの土日くらいしかできないんですけどね。

kohanaでマニュアルに記載されていない小技

・Modelもディレクトリに入れられる件
controllerに関しては、Routeさえ設定すれば
application/classes/controller/directory/filename.php
と設置できるよ、と書いてあるんだけど、
modelに関してはこういう記載がなかったんだけど…

普通に
application/classes/model/directory/filename.php
で問題なし。
で、ロードする際に

new Model_Directory_Filename();

としてやればよい。

・その際にORMモジュールで使用するモデルについて
例えば、application/classes/model/table/table.phpを
ORMで使用する、とかいう場合は、
orm.phpの_initializeと、factory の2つのfunctionに手を入れればOK。

initialize()
// $this->_object_name = strtolower(substr(get_class($this), 6));
$this->_object_name = strtolower(substr(get_class($this), 12));

factory()
//$model = ‘Model_’.ucfirst($model);
$model = ‘Model_Table_’.ucfirst($model);

こんな感じ。
おかげで非常にディレクトリ構成がすっきりさせられた。
うん、どうせMVCモデルにするならここまでやりたかったんだ。
大満足。

kohanaとPEARの件

色々やってみたのだが、結局kohanaのRequestクラスでは
ユーザーエージェントを変えたり、レスポンスコードを受け取ったりすることが
できないので、PEARのクラス名などを書き換えることで対応。

class HTTP_Request → class PEAR_HTTP_Request
function HTTP_Request → function __construct

同じく、HTTP_Responseに対しても同様の処理をして。

require_once Kohana::find_file(‘pear’, ‘HTTP/Request’);
error_reporting(E_ALL & ~E_NOTICE & ~E_DEPRECATED & ~E_STRICT);
$req = new PEAR_HTTP_Request($url);

って感じにしたら、無事に動いた。

まさかPEARとkohanaでクラス名の衝突があるとは。
それでこんなくだらない時間を割くことになるとは。。。。。

kohanaとPEARでハマる

なんかもう、こういう事もあるのかと…

PEARのHTTP/Requestを使用して作ったプログラムをベースに
kohanaに実装し直そうと思い…

require_once “HTTP/Request.php”;
の代わりに、
require_once Kohana::find_file(‘pear’, ‘HTTP/Request’);
にして。

kohanaがシステムでerror_reportingを自動で書き換えてるので、
error_reporting(E_ALL & ~E_NOTICE & ~E_DEPRECATED & ~E_STRICT);
と入れてDEPRECATEDではじかれるのも対応して、

$req = new HTTP_Request($url);
でうるさく言われたから
$req &= new HTTP_Request($url);
にしても、別のエラー出てきやがって、

なんじゃこりゃー!?
と思ったら、kohanaの中に既にあるのね、HTTP_Requestっていうクラスが。

とりあえず、ここでPEARを使用するのを断念。
面倒だけど、全部

$request = Request::factory('http://example.com/post_api')->method(Request::POST)->post(array('foo' => 'bar', 'bar' => 'baz'));
とか
$request = Request::factory('http://example.com/put_api')->method(Request::PUT)->body(json_encode('the body'))->headers('Content-Type', 'application/json');
とか書き直さないといけないわけね。
あー、もう。
悲しい限りだ。。。。。

kohanaで開発を始めてみたのだが…

しっくりくる部分と、しっくりこない部分が。。。。。

・しっくりくる部分
SQL関係は書くの楽ですね。
ORMモジュールを使っていても、

$datas  = ORM::factory(‘table’)
->where(‘hoge’,’!=’,’abc’)
->order_by(‘id’,’ASC’)
->find_all()
;

とかやってやれば、

SELECT tables.* FROM tables AS table WHERE hoge != ‘abc’ ORDER BY id ASC;

ってなってくれますので。
SQLの組み立てが直感的に楽ですね。

というか、結構便利なモジュールが揃っていて助かります。
Auth、ORM、paginationは即使用可能でした。
cacheはちょっと実感沸かないのでスルーです。

Authも実装まで少し時間かかりましたが、まぁかかったと言っても2~3時間ですか。
「実際に認証させる部分」のSQLさえ書ければ、あとはロジックを組むだけですので。

いやぁ、これ結構便利ですわ。

kohana初期設定とFuelPHP

くっだらないトコロに気を取られて結構時間を食ってしまった。

・タイムゾーンの設定とか
application/bootstrap.php内を編集。

date_default_timezone_set(‘Asia/Tokyo’);
setlocale(LC_ALL, ‘ja_JP.UTF-8’);
I18n::lang(‘ja’);

としてみた。
…まぁ、I18nに関してはja.phpが存在しないので意味がないというか、
そもそもI18nができたところで、普及に必要なのはL10nだったりM17nだったり
するのだろうけれども。

…普及というか、今の自分に必要、というか。w

とりあえずタイムゾーンの設定してやるだけで、ログの表示時間がしっかりするので
開発する気になるというもんです。

・mod_rewrite
とりあえず、デフォルトで置いてあるsample.htaccessをそのままリネームして
.htaccessとして使用。
これでURIの中にindex.phpが入ってしまう不格好から開放される。

さて、開発はじめましょうか。

・FuelPHPについて
なんか書籍も出ていて相当流行っているみたいですね?
CI後継というかCI開発者が携わっているらしく、 使い勝手も近いみたいですね。
インストールもコマンドラインが使える&sudo権があるなら楽勝みたいですし
結構興味はあります。
なんといっても日本語で情報が山ほど出てきますし。
kohanaでやってみる予定の案件が終了したら手を出すかも?出さないかも?
といったところです。

私的には、○○出版社さんから書籍を出されている方のお名前を拝見して
ビビりましたが。
だってCI徹底入門書いてる方なんですもん。。。。。

kohana インストール編

テンプレートエンジンはBlitzにしようかとも思ったんだけれど、
PECLを使わないといけない手前、レンタルサーバでは使えないので
何か適当なテンプレートエンジンを使おうかと思ってます。

それはさておき、kohanaのインストールについて。
手順はいたって簡単で、公式からzipをダウンロードしてきて
解凍して中身を公開ディレクトリにアップする。

で、そのまま公開ディレクトリ内のindex.phpにアクセスすれば
Environment Tests(環境試験)が始まる。

例えば、Cache Directoryのテストに対して
The /home/xxxxx/public_html/application/cache/ directory is not writable.
みたいにエラーが出てくれる。
当該ディレクトリに書き込み権限をあげないといけないわけだ。

Your environment passed all requirements.
Remove or rename the install.php file now.
という表記が出ればテスト的にはOK。
install.phpを削除かリネームすれば、kohanaがちゃんと稼動してくれる。

あとはOptional Testsについて。
PECL、cURL、mcrypt、GD、MySQL、PDOは追加機能で使うから
これも使用可能かどうかチェックしてくれる。
暗号化やら画像処理やら必要であれば、それぞれ確認しておくと良いかと。

導入時のサーバ側のテストとしてはかなり優秀ですね。

まぁ後は基本的なMVCモデルの通りに組んでいけばOKです。
modelはapplication/classes/modelに、
viewはapplication/viewsに、
controllerはapplication/classes/controllerに、
それぞれphpファイルを設置していきます。

超基本的な部分としては、こんな感じですか。
さて、modelにtraitを使ってどんな楽しい事ができるのか…
楽しみです。