信頼はずっと、挑戦はもっと。

お問い合わせ
TEL:03-3496-3888

BLOG コアテックの社員ブログ (毎週月曜~金曜更新中)

LIST OF ARTICLES

記事一覧

  • テクログ

    プレビュー画面を作ったよ

    今、fuelphpというフレームワークを使ってブログ機能みたいなのを作っているのですが、独自で作っているからもう何がなにやら分かりません。 で、ブログをアップする前にプレビュー画面の表示をさせたいということで、Jqueryを使ってデータの受け渡しに挑戦! 参考にさせていただいたのはコチラ! ありがとうございます。 テキストや既存の画像は上のJqueryプラグインをちょちょいと修正すれば、さくっと表示できる。 実際作ったpreview.jsはこんな感じ。 (function($){ $.fn.previewButton = function(config){ var button = this; var defaults = { //プレビューのurl 'url' : null, //キーとタイプのハッシュ {key:type, …} 'post' : {} }; var config = $.extend(defaults, config); if (config.url){ button.live('click', function(){ var form = $(this).parents('form'); var newform = $(''); $('body').append(newform); $.each(config.post, function(i, val){ switch(val){ case 'title': var _val02 = $('#edit_news_title').val(); newform.append( form.find('input[name = ' + i + ']').clone().val(_val02)); break; case 'textarea': var _val = $('iframe:first').contents().find('.cke_editable').html(); newform.append( form.find('textarea[name = ' + i + ']').clone().val(_val)); break; case 'category': var _val03 = $('#edit_news_category').find(':selected').text() newform.append( form.find('[name = ' + i + ']').clone().val(_val03)); break; case 'new_category': var _val04 = $('#edit_news_newcategory').val(); newform.append( form.find('input[name = ' + i + ']').clone().val(_val04)); break; case 'tag': var _val05 = $('#edit_news_tag').val(); newform.append( form.find('input[name = ' + i + ']').clone().val(_val05)); break; case 'topimg_main': var _val06 = $('#edit_news_topimg').val(); newform.append( form.find('[name = ' + i + ']').clone().val(_val06)); break; case 'writer': var _val07 = $('#edit_news_writer').val(); if(_val07 ==""){ _val07 = $('#edit_news_topimg').find(':selected').text(); } newform.append( form.find('input[name = ' + i + ']').clone().val(_val07)); break; default : break; } }); window.open(this.href, "preview"); newform.attr("target", "preview"); newform.attr("action", config.url); newform.attr("method", "post"); newform.submit(); newform.remove(); return false; }); } }; })(jQuery); (function($){ if(1){     $('input#form_preview').previewButton({ 'url'  : 'preview', 'post' : { 'text'         : 'textarea', 'title'        : 'title', 'category'     : 'category', 'new_category' : 'new_category', 'tag'          : 'tag', 'topimg_main'  : 'topimg_main', 'writer'       : 'writer', }     }); } })(jQuery); ちゃんと表示されてるかなぁ? POSTを受け取るコントローラーはこんな感じ。 public function action_preview() { $data = ""; //POSTの値を変数に格納 if(!empty($_POST['title'])){ $data['title'] = $_POST['title']; }else{ $data['title'] = ""; } if(!empty($_POST['text'])){ $data['text'] = $_POST['text']; }else{ $data['text'] = ""; } if(!empty($_POST['category'])){ $data['category'] = $_POST['category']; }else{ $data['category'] = ""; } if(!empty($_POST['new_category'])){ $data['new_category'] = $_POST['new_category']; }else{ $data['new_category'] = ""; } if(!empty($_POST['topimg_main'])){ $data['topimg_main'] = $_POST['topimg_main']; }else{ $data['topimg_main'] = ""; } if(!empty($_POST['writer'])){ $data['writer'] = $_POST['writer']; }else{ $data['writer'] = ""; } if(!empty($_POST['tag'])){ $data['tag'] = $_POST['tag']; }else{ $data['tag'] = ""; } //セッション関数 Session::set_flash('pre_title', $data['title']); Session::set_flash('pre_text', stripcslashes($data['text'])); Session::set_flash('pre_category', $data['category']); Session::set_flash('pre_new_category', $data['new_category']); Session::set_flash('pre_topimg_main', $data['topimg_main']); Session::set_flash('pre_writer', $data['writer']); Session::set_flash('pre_tag', $data['tag']); return View::forge('ビューファイルの場所が入るよ!', false); } POSTで得た情報をセッションでviewに渡すだけの簡単な作りです。 で、困ったのが、 Jquery.upload.jsを使って、『画像を一時的にuploadしたものをプレビューに表示する』というもの。 そもそも、初心者の僕はいろんな処理が絡むような、また、ファイルの受け渡しが複雑になるような部分が根本的に苦手なようで、このふたつの処理をうまく理解することが出来なかった。 はじめに、上のプレビューのコードにfileを追加したら、アップロードしようとしている画像ファイル名は取得できたけれど、上記のようにプレビュー画面に反映することは勿論出来なかった。 それはアップロードが出来ていなかったからだ!(当たり前) そこで、まずはJquery.uploadのコードを見てみる。 $(function(){ $('#edit_news_uploadimg').change(function(){ $(this).upload('demo.php', function(res){ alert(res); },'html'); }); }); これ、合ってそうじゃない!?合ってそうだよね!? そして、アップロード先のurlであるdemo.phpを試しに作っておいてみる。(アップロードが出来れば僕らの勝利なのだから。) コードは色々と端折ってますがこちら。 // ※$_FILES["file"]["tmp_name"]がテンポラリにあるファイル名 // ※$_FILES["file"]["name"]がアップロード元のファイル名 //tmpからファイルをコピー $tmpimg_file = date('U').".jpg"; //※便宜上jpgにしているだけだよ! move_uploaded_file($_FILES["file"]["tmp_name"],$tmpimg_file); //セッションに格納 Session::set_flash('pre_file', $tmpimg_file); return '一時アップロードしました'; 合ってそう!合ってそうだよ!! でも、どうしても取れない。 ちゃんとそのdemo.phpを見ているかの確認もしたし、alert(res) の部分をalert('死んで俺に詫び続けろオルステッド') とかにするとちゃんと出てくるのに、resが取れないし、ファイルもアップロードされない。 僕らは、一言「一時アップロードしました」って言って欲しいだけなのに......。 で、この解決の鍵は『MVC構造、及びフレームワーク』に隠されていました。 「MVC構造、及びフレームワーク」の特徴として、必ず「コントローラー」を経由して「ビュー」に受け渡しするのは当たり前ですよね。 そう、その当たり前が抜けていた。 コントローラー.......? public function action_demo() 作ってない!!! そうさ、上記のdemo.phpをviewファイルに作ってもコントローラー作ってなきゃ受け渡しされるはずが無いのでした。 そうなると、別にアップロード先にviewなんて要らないから、コントローラーでアップロードの処理をしてしまえば良い。 おまけにここで画像ファイルかどうかの判定も入れてしまおうかと。 editer機能のコントローラーに以下を追加。 public function action_demo() { // ※$_FILES["file"]["tmp_name"]がテンポラリにあるファイル名 // ※$_FILES["file"]["name"]がアップロード元のファイル名 //拡張子取り出し $preview_extension = explode('.', $_FILES["file"]["name"]); //画像ファイル拡張子タイプを配列に $extension_type = Config::get('app.img_extension'); //画像ファイルかどうか判定 if(array_search($preview_extension[1],$extension_type) === false){ return '画像ファイルを選択してください'; } //tmpからファイルをコピー $tmpimg_file = "????????????????".date('U').".".$preview_extension[1]; move_uploaded_file($_FILES["file"]["tmp_name"],$tmpimg_file); //セッションに格納 Session::set_flash('pre_file', $tmpimg_file); return '一時アップロードしました'; } これで画像ファイル判別+リネーム+tmpファイルへのアップロードが完了。 上記コードの「Session::set_flash('pre_file', $tmpimg_file)」でセッションにSET。 ※これはfuelphpの便利なメソッドだよ! プレビュー画面のviewで、 「Session::get_flash('pre_file')」でファイル情報をGETして表示完了! ※セッションで表示させるのとか合ってるのかなぁ、正直謎だ........ ハハッ!ここで勘の良いお方はお気付きのはずだ! これ、jquery.uploadでアップロードした画像のみ、一番上のコードのpreviewのJquery使ってないんです..... preview.js も public function action_preview() も、どっちも全くコード弄っていない。 ここわかんねー!!! Js間で絡むと思ってましたよ。。いや、絡ませる方法もあるんだろうな。 いやはや、これでなんとかプレビュー画面完成です。 最後に、tmpファイルに溜まっていく画像データをcronで一定時間したら消す処理を忘れないように!パンパンになるよ!! 終わり
  • テクログ

    error_log

    こんにちは。みなさんはerror_logってどんな使い方してますか? 私はバッチプログラムや、ブラウザに出力したらまずい時(echoやprintが使えない)などによく使ってます。 error_log — 定義されたエラー処理ルーチンにエラーメッセージを送信する 書き方は error_log ( string $message [, int $message_type = 0 [, string $destination [, string $extra_headers ]]] ) 私はよく以下のようにしてます。 error_log(出力したいデータ,3,出力先ファイルのパス); あとはターミナルエミュレーターでサーバにログインして tail -f 出力先ファイルのパス みたくしてやると、リアルタイムで起動時の出力を確認できます。 詳しい説明はこちらhttp://php.net/manual/ja/function.error-log.php
  • テクログ

    レコードセット

    技術ブログ2回目の投稿です。 今回はデータベースへのアクセス操作を行うADOについて書きたいと思います。 ADOの使い方によって、処理速度が結構変わります。 で、そこでポイントなのがレコードをオープンするときのカーソルタイプ(CursorType)です。   ■カーソルタイプの種類と説明 ・adOpenForwardOnly:前方カーソル (デフォルト値)  レコード移動は前方方向への参照のみ・adOpenKeyset:キーセットカーソル  レコード移動は前後可能。ただし、他ユーザーが更新したレコードは参照できるが、追加削除したレコードは参照できない。。・adOpenDynamic:動的カーソル  レコード移動は前後可能。ただし、他ユーザーが追加・更新したレコードも参照できる。・adOpenStatic:静的カーソル  レコード移動は前後可能。ただし、他ユーザーが更新したレコードも参照できない。   総レコード数を取りたい場合、adOpenForwardOnly以外を指定するとRecordCountで取得することができたり、AddNewなどで容易にレコードの追加などが可能になるのですが、処理速度がかなり落ちてしまう原因になったりします。 データ参照だけを行う場合には、adOpenForwardOnlyのほうが早いです。 データ件数が多くなるほど、処理速度の差を実感できます。 このレコード操作はAccessやVBAでも使えるので、覚えておくと便利かも?
  • テクログ

    HTTPリクエストとリアルタイムWEB、最近つまずいたこと

    こんにちは、けーすけです。   最初に。Node.jsがどうとか、そういう話は書いていません。もっと基本的なところです。JSでリクエスト送ってサーバで処理するって言うajaxみたいなところです。   XMLHttpRequest非同期なデータの通信を実現するための便利なAPIです。HTTPリクエストとリアルタイムWEBとか関係するであろうところです。   先日、JSのモーダルダイアログで3択のダイアログを作りました。このモーダルダイアログの入力から処理を分岐して、サーバにコマンドを送る処理です。コマンドといってもHTTPリクエストにPOSTをくっつけて送るだけのものです。ローカルで動かしたときはうまくいきましたが、問題は下記です。   URLはhttp://cloud.hoge.jp/index.phpです。モーダルダイアログとか受け取り側のPHPとか書いてませんがご了承ください。   //modal.htmlの戻り値は1,2,3のいずれかです。 window.onload = function(){ var action = showModalDialog("http://hoge.jp/modal.html",window,"dialogWidth:300px;dialogHeight:200px");   if(action==1){    function_hoge(action);    ・・・(中略)・・・    alert('hoge1');  } else if(action==2){    function_hoge(action);    var xhr= new XMLHttpRequest();    xhr.open("POST","http://sub.hoge.jp/modal_cmd.php",TRUE);    str_post = 'hoge1='+action+'&hoge2='+str_msg;    xhr.send(str_post);    alert('hoge2');  } else {    alert('hoge3');  } } この場合、必ずalert('hoge3');が表示されます。   オリジンがそれぞれ違う点が問題となります。http://cloud.hoge.jp/index.phphttp://hoge.jp/modal.htmlhttp://sub.hoge.jp/modal_cmd.php   http://sub.hoge.jp/modal_cmd.phpにポストでhoge1hoge2という値を送ると何かしてくれるプログラムです。cloudもsubもhoge.jpのサブドメインだから大丈夫だろうという考えの元でやっていました。1.モーダルダイアログは表示できますが、戻り値は取れません。2.xhr.send(str_post);はできません。   よって、同一ドメインのローカルだと問題なく動作して、複数ドメインをまたいだ検証環境だと動作しないということでした。
  • テクログ

    慎重かつ大胆なWEBデザインヒアリングのポイント

    アイスといえばブラックモンブラン、なかむです。 前回、WEBディレクターというお仕事について紹介しました。今回はクライアントへのヒアリングについてまとめてみます。   クライアントへのヒアリングを基に、デザイナーへ伝えデザインを興してもらわなければならないので、本質をしっかり捉えないと何度も何度もやり直しになってしまいます。その中でも大事な3つのポイントをご紹介します。 1.事前準備を忘れずに 当然のことですが、クライアントの業界についてざっくりと知っておきましょう。   ・競合他社・業界全体のデザインテイスト・主なコンテンツ   これらを知っておくことで、だいたいどういうウェブサイトにするのか想像することができます。 2.“キッカケ”を確認する   新たにウェブサイトを作るにしても、リニューアルするにしても何らかの“キッカケ”が必ずあります。 「新事業の立ち上げをする」、「今のデザインが古い」、「簡単に更新できるようにしたい」、「お問い合わせを増やしたい」など確認しておくことで、クライアントの意図を理解できたり、こちらからの提案がしやすくなります。 3.イメージを具体的に共有する クライアントから具体的な指示があれば楽ですが、大抵はボンヤリとしたイメージで伝えてきます。   「女性向けなカワイイデザイン」、「赤い色」、「ふんわりとした」などなど   そういったイメージをいただいた時は、私が思う参考サイトを用意してクライアントに見てもらいます。実際に見てもらうことで、「あーでもない、こーでもない」と意見をもらうことができ、イメージしやすくなります。   普段からはてなブックマークなどで、いいなと思ったウェブサイトをブックマークしておき、すぐクライアントに見てもらえるように準備しておきましょう。   ちなみに私が思う上記にあったイメージはこちらです。   【女性向けなカワイイデザイン】     【赤い色】     【ふんわりした】     これらを意識することで、一からやり直しという事態は避けることができるかと思います。 可能性はゼロではありませんが・・・
  • テクログ

    素のPHPとJSでSentryにエラーを送信する

    Sentryのインストール方法は シゲさん が書いてくれるはずです。 弊社製のFuelPHPのSentryパッケージは ヤマジュンの記事 の通りです。 今回は、素のPHPとJSでSentryに送信してみます。 1. raven-phpのインストール Composerが使えるなら、Composerを使いましょう。 https://packagist.org/packages/raven/raven 今回は原始的に、GitHubからZIPをDLして使ってみます。 もちろん、Submodule管理でも良いです。 https://github.com/getsentry/raven-php DLして解凍したディレクトリの"lib/Raven"を、適切な場所に配置します。 フレームワークを使っているなら"Vendor/Raven"とかになります。 2. PHPからSentryに送信 以下、サンプルコードです。 // Autoloader.phpの読込 // Composerを使っているのなら、代わりに vendor/autoload.php を読み込んで下さい。 // その際、これは不要です。 require_once 'Vendor/Raven/Autoloader.php'; Raven_Autoloader::register(); // Raven_Clientクラスのインスタンスを生成 $client = new Raven_Client('http://xxx:yyy@example.com:[ポート番号]/[id]'); // メッセージを送信 $client->captureMessage('hello world!'); // 例外を送信 try { throw new Exception('Uh oh!'); } catch (Exception $e) { $client->captureException($e); } URLの類は、Sentry側で確認して下さい。 エラーハンドラ内で $client->captureException するのが基本と思います。 尚、composer.jsonを見ると、raven-php自体はPHP5.2.4以上で動くようです。 3. JSからSentryに送信 以下、サンプルコードです。 if (typeof Raven != 'undefined') { Raven.config('http://xxx@example.com:[ポート番号]/[id]').install(); } URLの類は、Sentry側で確認して下さい。 これで、JSのエラーが発生するとSentryに自動送信されます。 任意送信の方法は ヤマジュンの記事 を参考にして下さい。 4. 備考 ヤマジュンの記事 にも書かれていますが、Sentryへの送信時にHTTP通信が発生するので、ログのノリで仕込んでレスポンスが低下して泣くハメにならないよう、注意が必要そうです。