Archive for the ‘php’ Category

    はてなブックマーク - PHPmatsuriに行ってきました!!(二人目?)
    このエントリーをはてなブックマークに追加

    こんにちはFusicの新入社員 伊藤です。

    PHPmatsuriのブログは二人目です。この後にまだ6人も残っています。
    参加者多いですねー。

    PHP Matsuriに参加させていただきました!
    今回が初参加です。他社のプログラマーの方々に囲まれて、緊張しました。

    CakePHPのコアディベロッパーの方のワークショップに参加したのですが、
    コアディベロッパーの方のキーボードを叩く運指がとてもキレイで、印象に残っています。
    (無駄な動きが少ない!!すごい!!)

    他にもいくつかの講演を聞いたのですが、
    大半の時間はコンテストに向けた開発にあてました。

    開発テーマ

    今回の開発のテーマは「PHPであーる」です。
    間違えました、「PHPでR」です。

    R」とは統計計算とグラフィックスのための言語・環境です。
    昨年までの大学院の研究でこの「R」を用いていたので、テーマに採用しました。
    「R」は元々クライアント側で動かすものですが、
    ブラウザでも使ってみたいと思った事がアイデアの発端です。

    「R」は難しい統計計算を詳しく知らない人でも統計計算をカジュアルに扱う事ができるツールです。
    今回は「R」を知らない人でも「R」の機能をカジュアルに扱う事ができるツールを目指しました。

    今回やったこと

    ①ブラウザで値を入力すると下に表示された3Dグラフが連動するツールを作りました。
    「R」のperspという関数を扱えます。
    persp

    ②Maunga Whau山の標高データを用いて山の三次元モデリングを行いました。
    ブラウザから山のグラフのタイプを選択することができます。
    やまだー

    ③他にも色々な「R」の関数をブラウザから扱えるようにしました。

    仕組みとしてはまず入力値をAjaxを用いて取り込みます。
    次にPHPを用いて「R」を動かす為の「Rスクリプト」をつくります。
    「R」に「Rスクリプト」を渡してグラフを作成します。
    作られた画像をそのまま表示します。
    (連動と言っても、画像を差し替えているだけです…。)
    本当に「R」をサーバサイドで動かせられるのか心配でしたが問題無く動きました。

    結果なんとか賞を頂くことができ、「CakePHP2実践入門」をGETしました。
    (やったー!!欲しかった本です!!)

    感想

    業務に関係の無いコーディングだったので、とても楽しめました。
    純粋にプログラムを組む事を楽しめたと思います。

    闇PHP祭りでダメコードが発表され、会場はとても盛り上がっていたのですが、
    自分は若干笑えない部分もあり、ちゃんとしたコードを書こうと強く思いました。

    開発者の方々と色々とお話をさせて頂きましたが、自分の知識不足を痛感致しました…。
    来年には話の内容を全て理解できるようになりたいです。

    とても楽しい二日間でした。
    来年はもっともっと実力をつけて、もっと面白いものを作るぞー!!

      はてなブックマーク - PHPmatsuriにいって来ました!(一人目?)
      このエントリーをはてなブックマークに追加

      多分久しぶりな登場の気がする萩原です。

      昨年に引き続きPHP Matsuriに参加させていただきました!
      (今回は福岡!)
      弊社からは何と8人も参加させて頂きました。
      全員LTで発表しましたので発表の最後の方にはまたFusicかとつぶやかれるくらいでした。

      一人目って書きましたが別に二人目とかタイトルが続くことは多分ないんじゃないかと思います。

      今回のPHP Matsuri

      今回は、本当にネタが思いつかずやることが決まったのは当日14時くらいでした。
      大して役に立たないものおもしろそうなものを作ろうということは何となく事前に決めていましたが。

      何とかネタは思いついたものの、時間内に出来るんだろうかとか思いながらバタバタ作っていたらなんだかんだで日付が変わったころには大体できてしまっていました。
      残り時間は書いたのもを見直したり、前でファミコンやってるのを眺めてたりホークスと横浜のトレードに衝撃を受けていたり(しかも今日公式に発表されたトレード、メンツが変わってたし)してました。

      今回やったこと

      今回はお絵かきのアプリを作りました。
      ただお絵かきするだけじゃつまらないので、
      お絵描きの履歴を取っておいて速度まで再現するものを
      CakePHPとJavasciptで作成しました。

      具体的に何をしたかというと
      ・canvasを利用して絵を描きつつ、mousemove中のマウスの座標や色、線の太さ、時刻を取得。
      ・絵を描き終わったタイミングでAjaxでデータを送信して保存。
      ・保存したデータを利用して、SetTimeoutを使ってcanvasで描写。

      なんてことをやってました。

      え?PHPがどこにあるのかって?
      saveとかfindとか使ったってば!
      PHPmatsuriの間一つもPHPに関してググらなかったけど!

      因みにmousemoveでとれる座標はすべて取得しているので1分くらい描き続けると保存のAjaxが30秒くらいかかります・・・。
      (まぁVM使って動かしてたんで実際にやればもっと速くなるとは思いますが・・・。)

      ちなみにちょっと公開する場所とかないのでお見せできないのが残念です。

      ついでに言うと発表はダダすべりしました・・・。

      感想

      ネタは2週間くらい前から考えてたんですが、思いついたのは当日。
      当日になって「エイヤ」でやっても意外となんとかなるものだなと思ってしまいました。

      発表は失敗しましたが(一説にはマイクが入ってなかったとかなんとか・・・)、
      作ったものを評価してくれたみたいで本とシャツをいただけました!
      ありがとうございます!

      前回は結構セッションをたくさん聞いたので、今回はコーディングをメインに参加しました。
      やっぱりあの雰囲気でコードを書くのはとても楽しかったです!

      何か次回は北海道とかいう宣言が何かなされていたので次回は北海道なのでしょう(笑)

      次回も楽しみにしておきます!
      後結局のところ私はFusicの変態枠なのでしょうか・・・

        はてなブックマーク - CakePHP2.0で現状の問題点などまとめました。
        このエントリーをはてなブックマークに追加

        そろそろ誕生日の萩原です。誕生日プレゼントください。去年も似たようなことを言ったような気がするのは気のせいです。

        最近、CakePHP2を色々触ってまして、色々困ったことがあったので、まとめておこうかなと思います。(CakePHP2.0.4現在)
        (下でCakePHP2.xなんか知りませんと言われてますが・・・)

        AppControllerをapp/Controller以外に置く場合の注意

        CakePHP2からは皆さんご存知の通り、AppController及び、AppModelが、app直下に設置が出来なくなりました。

        CakePHP2ではAppControllerはapp/Controller以下に設置をすること、と言うことになっています。

        しかし、個人的には出来れば、直接アクセスするコントローラとはAppControllerは分けたいところです。

        そこで、AppControllerをapp/Libに設置をしようと考えまして設置を行っていました。

        app/Lib以下にAppControllerを設置後は、AppControllerを継承するコントローラにはApp::usesの記述が必要になります。

        <?php
         
        App::uses(&#039;AppController&#039;, &#039;Lib&#039;);
        
        class PostsController extends AppController {
         
        }

        しかし、作業をしていく内に、たまにAppController内のアクションが読めないというエラーが出ることがありました。(debug2でも)

        元凶はapp/tmp/cache/persistent/cake_core_file_mapのキャッシュ(こいつがなかなかの曲者です・・・)だと言うことはすぐにわかったのですが、どうにも再現性も取れず、対策がなかなかつかめない状態でした。(1ヶ月くらい悩んでいました・・・)

        結局のところ現象としては

        (1)404ページ(missing controllerなど)にアクセス
        (2)CakeErrorControllerを見に行く
        (3)CakeErrorControllerがapp/Controller以下にセットしていない場合は、CakeコアのCakeErrorControllerを見に行く
        (4)当然、コアのコントローラにApp::usesの記述があるはずもなく、継承するAppControllerの場所としてApp/Controller以下を見に行く
        (5)ないので、CakeコアのAppControllerにアクセスしに行く
        (6)さらに、キャッシュにAppControllerの位置はCakeコアにある、と記述
        (7)その後、通常のシステムのページにアクセスしても、AppControllerとして、CakeコアのAppControllerを見に行く
        (8)App/Lib以下に設置したAppConttroller内のアクションが呼ばれない

        ということが起こっていました。

        解決策としては

        ①AppControllerを素直にApp/Controller内に設置する
        ②CakeErrorControllerをApp/Controller内にコピーしてApp::usesをセットする

        ①はまずまず問題ないく動作をするはずです。

        ②についてはCakeコアでAppControllerを継承しているものが、他には通常あまり使わないであろう、PagesControllerくらいだったので、こちらでもおそらく問題なく動作すると思います。

        (2011/12/15追記)

        LibにAppControllerを置くと言う件について、Libの中にControllerのディレクトリを作ってその中に置けばいいという指摘を頂きました。
        試してみると、app/Lib/Controller/AppController.phpという形で設置をしたら、確かに問題なくusesなしでもapp/Lib/Controller/AppController.phpを見に行ってくれました。
        これならCakeErrorを書き換える必要もなくなるので、これが一番良い解決法かもしれません。

        app以下のクラス名とPlugin以下のクラス名が同名だと誤動作する

        これは具体例を挙げた方が早いと思います。

        app/Controller/PostsController.php(①)と、app/Plugin/Post/Controller/PostsController.php(②)の二つの同名のコントローラがあるとします。

        初めに①にアクセスした後、②にアクセスをしようとすると、①にアクセスをしてしまうというものです。(逆もしかり)

        これが起きてしまう原因はapp/tmp/cache/persistent/cake_core_file_mapのキャッシュがプラグインを考慮していないためです。(またお前か・・・)

        実のところ、AdminPluginを作成してそこに管理画面を実装しようとしていたところでしたので、これはかなり致命的でした。

        解消方法自体はコアを触れば出来なくもないのですが、コアのアップデートなど一切できなくなるのでお勧めはしません。

        どうしても動作させたいのであれば、lib/Cake/Core/App.phpをプラグインを考慮するように直接編集すると、動作はします。

        まぁ、ただ当分はapp以下とPlugin以下で同名のクラスが入るような実装は避けた方が良いでしょう。

        (2011/12/16追記)

        CakePHPチームにチケットを投げてみましたが、同名のクラスは現在使えない、Cake3で計画中と言われました。

        PaginatorのorderにSQLが記述できない

        CakePHP2からPaginatorがコンポーネントに分離されたことは皆さんご存知かとは思いますが、CakePHP2では現在のところPaginatorでorderにSQLがそのまま記述が出来ません。

        例えば

        $this->Paginator->settings = 
            array(&#039;order&#039; => array(&#039;`hoge` is null ASC&#039;)):

        のようなソートを行いたい時に上記のorderが無視されます。(実際に必要な場面がありました・・・)

        これは、コアのPaginatorComponentを見ればわかるのですが、352行目~の記述で

        if ($object->hasField($field)) {
        	$order[$alias . &#039;.&#039; . $field] = $value;
        } elseif ($object->hasField($key, true)) {
        	$order[$field] = $value;
        } elseif (isset($object->{$alias}) && $object->{$alias}->hasField($field, true)) {
        	$order[$alias . &#039;.&#039; . $field] = $value;
        }

        とありまして、例外が全く、無視される形になっています。

        この記述自体は1.3にもあるのですが、1.3では最後にarray_mergeをしているので、SQLも取り込んでくれていたのですが、2.0では無視された状態です。

        どうしても特殊なorderをかけたい場合は現状では素書きのSQLやDBのviewなどで対応しておいた方が良いかもしれません。

        (今回私の場合は、元々orderをかけたかったテーブルがviewだったのでviewにソート用のカラムを泣く泣く追加しました・・・)

        (2011/12/16追記)

        CakePHPチームにチケットを投げてみたところ、orderを文字列で指定したら動くじゃん!って言われたので現在配列で指定したんだけど・・・と返しているところです。

        SSLページでのCookieのセキュア属性を外す方法

        SSLページがあるページとないページが混同する場合、Cookieのセキュア属性が付いていると、セッションを共有できないため、セキュア属性を外してあげる必要があります。

        1.3の場合は以下の対応が必要になります。

        app/config/core.php

        //	Configure::write(&#039;Session.save&#039;, &#039;php&#039;);
        	Configure::write(&#039;Session.save&#039;, &#039;session_custom&#039;);

        app/config/session_custom.php

        <?php
         
        if (empty($_SESSION)) {
            ini_set(&#039;session.use_trans_sid&#039;, 0);
            ini_set(&#039;session.name&#039;, Configure::read(&#039;Session.cookie&#039;));
            ini_set(&#039;session.cookie_lifetime&#039;, $this->cookieLifeTime);
            ini_set(&#039;session.cookie_path&#039;, $this->path);
        }
        ini_set(&#039;session.cookie_secure&#039;, 0);

        これは、コアのcake_session.phpの設定を強引に上書きをしています。

        CakePHP2ではcore.phpに以下の記述をすれば、対応できます。

        Configure::write(&#039;Session&#039;, array(
            &#039;defaults&#039; => &#039;php&#039;,
            &#039;ini&#039; => array(
                &#039;session.cookie_secure&#039; => 0
            )
        ));

        特に新しいファイルを作成する必要はなく、手軽です。

        CakePHP2.0ではセッションを共有するしないにかかわらず、SSLがあるページとないページが混同するサイトでは、セキュア属性は外した方が良い。

        これは、まずSSLのあるページ(①)でログインをした後、SSLのないページ(②)にアクセスし、その後、①のページにアクセスをすると、ログアウトしてしまうと言う現象のためです。(これは1.3では発生しません)

        詳しい原因についてはまだ追い切れていないのですが、①にアクセスした後、②にアクセスすると①と異なるセッションキーが振られます。(これは当然の話)

        その後①のページにアクセスすると、②で発行されたセッションキーに上書きされてしまうため、ログアウトをしてしまいます。

        以上の理由から、今のところ、SSLがあるページとないページが混同するサイトでは、セキュア属性は外して置いた方が良いと思います。

        (2011/12/16追記)

        CakePHPチームにチケットを投げてみたところ、上記の書き方でセキュア外せばいいじゃん!って言われました。

        最後に

        まだCakePHP2は駆け出しで、問題が色々と出てますが、触っている感じとしては1.3とそう大差なく使えています。そして早いです。

        きっとこれからどんどん良くなっていくと思うので皆さんどんどんさわりましょう!

        後、本当にfile_mapのキャッシュには要注意です!
        ああ・・・app.phpの750行目を消してfile_mapのキャッシュをなかったことにしたい・・・w