Posts Tagged ‘php’

Windows+Eclipseで(ゴテゴテした)快適なCake開発環境を作る(CakePHP Advent Calendar 2011 11日目)

日曜日, 12月 11th, 2011

@mon_satさんからバトンを受け取ってのAdvent Calendar2011 11日目担当EG(@EGMC)です。
初参加で地味ネタですが、開発環境の話ってあまり聞かないのでとりあえず自分なりに育てた開発環境の話をしてみます。

※注 この前置きは長いのでさっさと本題に入りたい方は「開発環境構築編(ここから本編)」へどうぞ

ネタはWindows+EclipsePDT+その他tools。
昨今、勉強会に行くと皆MacBook Airなどを片手に、華麗にターミナルを開いてVimやEmacsで優雅にコーディングしている光景を目に致します。
そんな光景を横目に見つつ、しかしThinkpadでWindowsを起動してEclipseでもっさり開発している人たちも一定数いるはずだ!と信じてこのエントリーを書く次第です。いるかなあ。いるといいなあ。
前提として環境は

・開発サーバー(物理でもVPSでも)を外部(VMとかではなく)立てていて、DBは同サーバー(または同一ネットワーク内)にある
・ローカル環境はWindows+EclipsePDTで構築しており、プロジェクトは作成済み
・ソース編集はローカルで行うが、DBの操作やデバッグ(ログのtailとか)はリモートで行う
・ローカルのWindows環境にもphpがインストールされてる(bake用)

とします。
それ以前の情報は検索すればすぐ当たると思うので他に譲ります。
なお、cake1.3系で書きますが2.0系でも基本的に同じような事が出来ます。
環境設定上examle.netとかにしている部分は適宜ご自分の環境に置き換えてくださいませ。

なぜWindowsなのか?

・プラットフォームに依存したエディタとか、使い慣れたツールがたくさんあるからです。例えば私はHTMLエディタにCrecsent EVEを使ってます。

なぜEclipseなのか?

・元々自分がJava開発をメインでやってたのでその流れて使い始め、慣れていたというのが大きい
・起動の重さとかは色々あるものの、強力な補完機能(コード、Docコメント)、コードへのジャンプ、バージョン管理連携、プラグイン拡張など現実的な機能が多い
・最悪外部エディタが起動出来たり結構なんとかなる
・他の環境(Andoroid開発環境とか)と同居出来る
・起動の遅さについてはRAMDISKなどを使ってある程度は改善出来る

なぜ外にサーバーを立てるのか?

・自分の場合、会社と家で使うPCが違ったりするのでローカルに環境作ると何かと面倒くさい
・外部から叩かれる(例えばFacebookのプラグイン入れたりとか)ような機能を追加したりする
・他の人と環境を共有したりする
・↑みたいなことが無ければ全然VMでいいかなーと思ってます

使うツール群

Eclipse PDT(IDE)
WinSCP(ファイル転送)
PortFowarder(ポート転送)

開発環境構築編(ここから本編)

1)ファイルの自動転送

今回の構成では開発環境はリモートにあるのですが、ソースの反映は書き換えたらリアルタイムで行いたいですよね。
というわけで変更を即座に反映するよう自動転送します。
WinSCPの同期機能を使います。

ローカルはEclipseのプロジェクトフォルダを指定してパスを合わせます。
これで監視下のフォルダで変更があると即座にリモートへ転送してくれます。
無視したいファイル(.svnなど)はこんな感じで除外リストに入れておきましょう。

この状態でセッション保存しておけば、起動→接続→CTRL+Uですぐ同期をスタート出来ます。

2)Eclipseの自動補完を効かせる

なぜEclipseなのか?の所で補完機能を使いたいからだよ!と書きましたが、フレームワーク故にというかCakeはあまりモデルそのものをnewしたりしないので、そのままではほとんど補完が効きません(モデル、コンポーネント、etc・・)。
というわけで補完を効かせるようにコードをいじります。
正直、IDEの補完機能のために不要なコードを足すのはどうなの?という思いもありますが開発効率や動作速度を天秤にかけてこの方法を採用しています。

app_controller.phpに

/**
* Userモデル
*
* @var User
*/
var $User;

/**
* セッションコンポーネント
*
* @var SessionComponent
*/
var $Session;

/**
* authコンポーネント
*
* @var AuthComponent
*/
var $Auth;

/**
* セキュリティコンポーネント
*
* @var AuthComponent
*/
var $Security;

のように書いてどのクラスかを教えてあげます。

これで補完が効くようになります。

3)ローカルからbakeを使う

cakeといえばbakeですよね。
モデルやコントローラの生成が楽に行えますが、リモートで生成したファイルをいちいち持ってくるのは面倒です。
ローカルで(かつIDE内で)作ります。

bakeは当然phpが必要なのでローカルのWindowsマシンにphpを入れます。
bake.batはphpにパスが通ってる前提なのでパスを通します。

さて、これでbakeは実行出来るのですが、モデルの情報を取得するのにDBに接続しなければなりません。
ローカルにDB作るという方法もありますが、いちいち二重化させるのは面倒なのでリモートのDBに繋ぎたいです。
ポート転送を使いましょう。
Teratermのポート転送機能などもありますが、今回はPortForwarderを使います。

config.txtはこんな感じで

Host dev.example.net
HostName dev.example.net
# hostname or IP address

User hoge
# username on server. NEEDED

LocalForward 13306 localhost:3306
# localforward info1

Compression yes
# if you need compression

IdentityFile dev.example.net-key.rsa

13306ポートをリモートサーバーの3306に転送してます。
これでPortForwarderを立ち上げてDBの接続先を13306にすれば繋がります。
開発環境と、ローカルで接続情報が異なる場合は実行パスの判定などを行って接続先を切り替えます。

core.phpで切り替える場合は例えばこんな感じで

if (__FILE__ === 'C:\path_to_workspace\project\app\core.php') {
// ローカルでbakeするための設定
    define( '_DB_HOST' , '127.0.0.1:13306' );
    define( '_DB_NAME' , 'projectname' );
    define( '_DB_USER' , 'user' );
    define( '_DB_PASS' , 'pass' );
} else {
    // サーバーで動かすための設定
    define( '_DB_HOST' , '127.0.0.1:3306' );
    define( '_DB_NAME' , 'projectname' );
    define( '_DB_USER' , 'user' );
    define( '_DB_PASS' , 'pass' );
}

※ちなみにCake2.x系の場合はPORTは別指定になりますね

bake用の実行構成を実行→外部ツールから作成します。

これでIDEからbakeが実行出来ます。

ファイルの生成を行った後、F5でファイルのリフレッシュを行うと反映されますね。

ここまでやると晴れて快適に補完も効き、bakeも使え、ソースも同期される開発環境が構築出来ます。

ちなみにここまでの設定をすべて行って必要な諸々を起動すると画面はこんな感じになります。

・・・・まあ非常にWindowsらしい感じですね、うんうん。
立ち上げているものも多く、そもそもサーバー側で作業すれば楽なことも多々ありますが、まあこれはこれで慣れればいいものですよー。
Windowsで開発をされている方のお役に立てれば幸いです。
あと、こんな面倒なことしなくてもこんなんありまっせ!みたいな情報もあれば是非twitterなどで突っ込んで頂ければと思います。

そんなこんなで初参加のCakePHP Advent Calendar 2011でした。明日は@slumbers99さんです!


CakePHP2.0.2で意地でもTwigを使ってみる

火曜日, 11月 15th, 2011

CakePHPの2.0系が最近安定版リリースされましたね。
まだまだ情報は少ないですが、折角なので新規の開発は1.3系ではなく2系でやりたい!と思うこの頃です。

さて、CakeといえばテンプレートエンジンはSmartyを使う人が多い印象ですが私は圧倒的にTwigが好きです。然り、Twigが好きなわけです。

CakeでTwigを利用するプラグインはこんな感じでKjell Bublitz氏が作成されているわけですが、早くも2系に実験的ながら対応しました的なことが書いてあるのでこれは!ということで導入してみました。
2系の仕様がよくわかってなかったりドキュメントがまだアレだったりと色々ありましたがとりあえず動かせてます。

環境:
CakePHP2.0.2
Twig1.3.0(stable)
cakephp-twig-view(commit a5fc2e6291)

導入:
1)基本的にInstallationに書いてある通りのフォルダ階層で突っ込みます。

こんな感じで、Plugin直下にtwig_viewを配置。
Twig本体はvendorsの下に配置。

2)初期設定諸々

app/Config/bootstrap.phpあたりに下記コードを追加してプラグイン有効化

CakePlugin::load('TwigView');

app/Controller/AppController.phpにてviewClassの変更
(2系は$viewではないっぽい)

class AppController extends Controller {

    public $viewClass = "TwigView.Twig";
}

3)app/Plugin/views/twig.phpの編集
そのままだと動かなかったのでパスまわりの修正をする。
・Twigオートローダーの読み込み

// Load Twig Lib and start auto loader
App::import('Vendor', 'TwigView.TwigAutoloader', array(
'file' => 'Twig'.DS.'lib'.DS.'Twig'.DS.'Autoloader.php'
));
include_once __DIR__ . '/../vendors/' . 'Twig'.DS.'lib'.DS.'Twig'.DS.'Autoloader.php';

・・App::importがなぜかうまく読み込めてなかったので無理矢理include・・App::importの仕様がようわからんです。

・2系用にパス周りの修正とautoescape
まとめてこんな感じに書き換えちゃいました。
autoescapeは後述しますがちょっと問題があるのでお好みで。私はonにしました。

    function __construct(&$controller, $register = true) {

        parent::__construct($controller, $register);

        if($this->isCake2()) {

            // just collecting for str_replace
            $this->templatePaths = array(
                APP.'View',
                ROOT.DS.'cake'.DS.'Lib'.DS.'View'
            );
            $loader = new Twig_Loader_Filesystem(APP.'View');
        } else {
            $this->templatePaths = array(
                APP.'views',
                ROOT.DS.'cake'.DS.'libs'.DS.'view'
            );

            // we always look in APP, this includes error templates.
            $loader = new Twig_Loader_Filesystem(APP.'views');
        }
        // setup twig and go.
        $this->Twig = new Twig_Environment($loader, array(
            'cache' => TWIG_VIEW_CACHE,
            'charset' => strtolower(Configure::read('App.encoding')),
            'auto_reload' => (bool) Configure::read('debug'),
            //'autoescape' => false
            'autoescape' => true
        ));;

        // overwrite some stuff
        $this->Twig->addExtension(new CoreExtension);

        // activate |trans filter
        $this->Twig->addExtension(new Twig_Extension_I18n);

        // activate |ago filter
        $this->Twig->addExtension(new Twig_Extension_TimeAgo);

        // activate basic filter
        $this->Twig->addExtension(new Twig_Extension_Basic);

        // activate number filters
        $this->Twig->addExtension(new Twig_Extension_Number);

        if (isset($controller->theme))
            $this->theme =& $controller->theme;

        $this->ext = '.tpl';
    }

}

$this->isCake2()を使ってざっくりパスの切替をしています。
$this->isCake2は親で設定されるプロパティを使って判定しているので、親のコンストラクタの後に諸々の処理を移動しています。

4)使ってみる

コントローラーでこんな値を設定してみて


public function index() {

    $array_vars = array("foo" => "<bar>","hoge" => "<hogehoge>" );

    $this->set("hello", "<hello! It's a beautiful Twig World!!>");
    $this->set("array_vars", $array_vars);

}

出力してみます。ビューファイルの拡張子は.tplで(変更可能)

<div>
変数:
     {{hello}}
</div>
<div>
連想配列:
<ul id="sortable_list">
{% for k,v in array_vars %}
    <li> {{ k }} , {{ v }}</li>
{% endfor %}
</ul>
</div>
<div>
ヘルパー:
    {{form.create()|raw}}
    {{form.input('input')|raw}}
    {{
    form.input('email', {
        'label': 'Your E-Mail Address'| trans
        })
    |raw}}
    {{form.end()|raw}}
</div>

こんな感じに出力されます

<や’もエスケープされてますね。
オートエスケープをオンにするとヘルパーで生成したコードもエスケープされてしまうので|rawで出力しています。
ここらへんを考慮してデフォルトオフにしているんでしょうが、出来ればヘルパーで生成した場合は自動で生出力とかにしたい・・。

ざっくりまとめ

2.0対応の部分についてはまだドキュメントなども追いついてない部分がありますがとりあえず動かすことは出来ました。
ソースはすべてgithubで公開されているので自分もフィードバック送ったりしたいところですがgitの使い方がようわからん・・。使わないとなあ。

また、2系の仕様がイマイチよくわかってないのでTwigの読み込みがApp::importになってたりアヤシイ感じなのでここはこうじゃないだろ!というツッコミお待ちしております。


第57回PHP勉強会@東京で濃ゆい話を聞いてきた

土曜日, 11月 12th, 2011

初心者向け負荷軽減のはなし(taka0024/60分/php中級者~Webプロデューサーを目指す人へ)

@taka0024さん

・初心者向け負荷低減
・負荷軽減はお金になるよ!

最初にアンケート
1)立場は?
→プログラマーが多数

2)何やってる?
→自社サービスが多数

3)負荷軽減やってる?
→結構やってるが多数

ある日突然負荷軽減して欲しいといわれたら?
携帯SNS→プログラム作り直せば?→いやそりゃ無理っしょ→で、実際に負荷低減した話。
初心者向け、と銘打ってましたがDBの水平、垂直分割が出てきたり結構色々。

tips)
materはブラックホールエンジンを使ってレプリケーションさせる
クエリアナライザを使う
普通のクエリログもみる
MySQLのバージョンは新しいのを使おう。

気になったけど聞きそびれた点・・・)
具体的にどの程度の効果があったのか、ざっくりの数値かグラフレベルでみたいなあ。
インフラのコスト面での話。

触れてはいけないほうの闇の話(sasezaki/10分/PHP初級者)ykll

@sasezakiさん

・コードは書いたとおりに動く
・個々一番氏へのお礼がありました

どこまで書いていいかわからないが
・メンテナは大変・・・
・テストコードがis_array

雑感)
・なにそれこわい
・テストコードのパッチ・・は・・面倒・・なのかな?

PHP がいっぱい(@yuya_takeyama/10分/PHP のバイナリを日常的にビルドする人向け)

@yuya_takeyamaさん

node.js / Socket.io → リアルタイムwebapp
→node楽しいよnode

phpenv →バージョンの切替、pearとかも
php-build→こっちはビルドツール

php-build
・ビルドらくちん
・依存パッケージは自分でいれる
・依存関係でこけてる場合はtmpの中にログがはかれるのでみてね

phpenv globalでバージョン切替
phpenv-v each で各バージョンで実行出来る

php-buildのconfigureオプションは?
→定義ファイルでいじればいいよ。マルチバイトとかね。

pure PHPでのバイナリ処理(yoya/20分/PHPでのWebプログラミングに飽きてきた人)

@yoyaさん
スライド

・purephp→標準関数を使う
・2進数大好き

jpg、png、gifなど、仕様を知っていれば画像サイズとかはさくっと取れる

openpear/IO_Bit
・byte/bit処理するのに便利
・応用例→IO_SWF

PHP用回帰テストツール-PROVE(@yohgaki/10分~30分)

@yohgakiさん

・realip
→プロキシとか挟んだ場合にリモートアドレス取るの面倒だよね
→まあmod_rpafとか色々あるけど、ロジック側でさくっと何かするには便利かも

PROVE
・個人利用は無償
・PROVEは内部動作を場合によってはオーバーライドすることで環境に依存しないテストを実行

これ

perl Regexp::Assemble を php に移植する話(rti/25分/他の言語も気になる人)

@super_rtiさん
スライド

・多分今回一番盛り上がったスライド。懇親会の中だったのでツッコミ多数。
・perlの正規表現自動生成エンジン(って言い方あってるかな・・)perl Regexp::Assemble をPHPに移植する話
・一行ごとにPHPコードに置き換え。言語仕様の壁を結構無茶な方法で乗り越え・・。
・実行速度は(perl5.8.8とのPHP5.4の比較では)高速。十分実用ですね。
・メンテナ募集、githubにあります。
テストサイト。落ちるとくじらが飛ぶそうです。皆さん頑張ってくじらを出しましょう!

・・・この後の家電の話も相当面白かったんですが力尽きたので割愛。

総じて(事前にアジェンダみてわかってはいましたが)濃ゆい発表で非常に面白かったです!
あとハイパーのエンジニアとしてお声がけくださった皆様ありがとうございました。cakeの愚痴ばっかですいません。

最後に、会場提供してくださったVOYAGE GROUPさんありがとうございました。
第57回PHP勉強会@東京