タイトルにある通り、今回の記事はまだ未実装、というか実現できていないことについて。
ということで、もし解決策をご存知の方がいらっしゃれば、何卒ご教授くださいますようお願い致します。
ストアドプロシージャについては、こちらの記事がわかりやすいかと。
ストアドプロシージャの基本的ななにか – Qiita
https://qiita.com/setsuna82001/items/e742338eb93e3a48ba46
こちらの記事によると、ストアドプロシージャとは「データベース上での一連の処理に、名前をつけて関数のように呼び出して使用できるもの」とのこと。
データベース上で動作が完結するので、開発言語に依存しません。
FuelPHPについて、公式サイトはこちらから。
FuelPHPは、PHP5.3以上を対象に開発されたWebフレームワークです。
他のフレームワークに比べて規約が少なく、また高速で軽量なため、使いやすいのが特徴です。
こちらのサイトもご参考に。
高速で軽量なフレームワークFuelPHPを使う
http://www.buildinsider.net/web/bookphplib100/096
そして、今回実現したいのは、この両方を利用して、データベースからデータを取得する方法についてです。
実行するストアドプロシージャはこんな感じ。
1> EXEC dbo.user_month_report @year =2017, @month =12; 2> go
※実際に動作させているものとは異なります。
こちらをターミナルで実行すると、望んだとおりの結果が得られます。
したがって、ストアドプロシージャ自体には問題はなさそう。
が、こちらを下記のように FuelPHP で実行すると、結果が何故か bool(true) が返ってきます。
$result = DB::query("EXEC dbo.user_month_report @year =2017, @month =12;"); $result->execute();
ストアドプロシージャに問題がないようなので、十中八九 FuelPHP が原因というのは分かるのですが、その解決策がどうしてもわかりません。
FuelPHPのドキュメントにも、ストアドプロシージャの実行方法についての記述がないため、そもそも対応していないのでしょうか。
ちなみに、FuelPHPのフォーラムに、「DB Class with mysql – select from stored procedure」という、今回の状況に似たような投稿があったのは見つけました。
その中で、DB::query()の第二引数の$typeに SQL クエリタイプとして「DB::SELECT」を指定するといいとの記述があったので試してみましたが、残念ながら結果は変わりませんでした。
参考にしたフォーラムの投稿はこちら。
DB Class with mysql – select from stored procedure
https://fuelphp.com/forums/discussion/4299
新しいライブラリやフレームワークを使うのは、やはり難しいですね。
使用頻度は高めだけど、良く忘れるので備忘録として。
今回は今回は子要素を上下左右で中央揃えにするやり方について。
なお、同じ方法で画像の中央揃えも実現できます。
HTML、CSSのコードはこんな感じ。
<!-- HTML --> <div id="parent"> <!-- 親要素 --> <div id="child"></div> <!-- 子要素 --> </div>
/* CSS */ #parent { background-color: blue; height: 200px; width: 200px; position: relative; } #child { background-color: green; height: 100px; width: 100px; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); -webkit-transform: translate(-50%, -50%); -moz-transform: translate(-50%, -50%); }
このとき重要となってくるのが、親要素に指定された position: relative; と、子要素に指定された position: absolute; です。
これがあることで、子要素が表示される際の基準位置が親要素の左上となります。
そして、子要素の top、left をそれぞれ50%とすることで、子要素の左上の位置を親要素の中央に来るようにしています。
が、これでは左下に移動しすぎなので、transform: translate(-50%, -50%); で子要素の縦横それぞれの50%分だけ左上に移動させて、ちょうど親要素の上下中央に子要素が来るように調節しています。
やっていることは以上です。
他にも上下中央揃えする方法はあるようですが、今回の書き方を使ったところ、IEやSafariなど、表示が崩れやすいブラウザで表示した時に崩れなかったので、個人的にはおすすめの書き方です。
IEやSafariでデザイン崩れに悩まされている場合は、こちらの書き方をお試しになってみてはいかがでしょうか。
ランダムな整数の生成なら、rand() 関数が用意されていますが、今回は少数値が必要だったので、生成方法をご紹介。
PHPのマニュアルに掲載されていたものですから、少し調べればわかるやり方ではありますが、今後も使うことがあるだろうという事で、備忘録も兼ねています。
まずはランダムな整数の生成から。
こちらは簡単で、rand() 関数を使用するだけ。
// rand() 関数 int rand ( int $min , int $max ); // 実行例 $random = rand(1, 10);
引数は省略可ですが、指定した場合は、この範囲内で収まる値で乱数を返してくれます。
上記の実行例だと、1から10の範囲内の乱数が生成されます。
PHPマニュアルはこちらからご確認ください。
http://php.net/manual/ja/function.rand.php
お次はランダムな少数値の生成方法。
この場合は、mt_getrandmax()という、mt_rand() 関数が呼ばれた際に返される最大の値を返す関数を利用しています。
なお、mt_rand() はランダムな整数を生成する関数です。
乱数を返す機能としては rand() 関数との違いはなさそうですが、PHPマニュアルによると、rand()よりも4倍以上高速に乱数を生成してくれるのだとか。
ランダムな少数を返す関数は下記の通り。
// ランダムな少数値を返す function randomFloat($min = 0, $max = 1) { return $min + mt_rand() / mt_getrandmax() * ($max - $min); } // 実行例 $random = randomFloat(0, 100);
こちらを実行すると、0から100の範囲でランダムな少数値を返してくれます。
ちなみに、こちらの関数も引数は省略可です。
と、いう事で、ランダムな少数値の生成方法でした。
なお、0から1の間で乱数を返す関数でしたら、lcg_value() という関数もあるそうでしたが、こちらは乱数の精度があまりよくないとのこと。
また、値の範囲が0から1というのも、少し汎用性が悪い場合がありそうですから、小数値の乱数生成なら上記の関数がおすすめです。
とりあえず、IEへの不満感がさらに募った一件でした。
タイトル通り、IEで画像が指定したサイズで正しく表示されないという現象が起きたので、その時の対処法についてまとめ。
SVGファイルを表示させようと、下記のようにimgタグを記述したのですが、IEで正しく表示されませんでした。
<img src="SVGファイルのパス" style="width: 25px; height:25px;" />
こちらの解決策としては、SVGファイルをそのものを編集してしまう方法が一番手っ取り早かったです。
今回参考にしたサイトはこちら。
IEやEdgeでSVGのサイズが変わってしまう問題の解決法!
https://www.cb21.co.jp/blog/tips/tips-svg-ie-edge.html
SVGファイルの編集は、まずSVGファイルを適当なテキストエディタで開きます。
そうすると、下記のようなデータとして表示されます。
<!--?xml version="1.0" encoding="utf-8"?--> <!-- Generator: Adobe Illustrator 18.1.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) --> <svg version="1.1" id="_x32_" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 512 512" style="width: 256px; height: 256px; opacity: 1;" xml:space="preserve"> <style type="text/css"> .st0{fill:#4B4B4B;} </style> <g> <path class="st0" d="M378.409,0H208.294h-13.176l-9.314,9.315L57.017,138.101l-9.314,9.315v13.176v265.513 c0,47.36,38.528,85.896,85.895,85.896h244.811c47.361,0,85.888-38.535,85.888-85.896V85.896C464.297,38.528,425.77,0,378.409,0z M432.493,426.104c0,29.877-24.214,54.091-54.084,54.091H133.598c-29.877,0-54.091-24.214-54.091-54.091V160.592h83.717 c24.884,0,45.07-20.179,45.07-45.071V31.804h170.114c29.87,0,54.084,24.214,54.084,54.091V426.104z" style="fill: rgb(75, 75, 75);"></path> <path class="st0" d="M180.296,296.668l-4.846-0.67c-10.63-1.487-14.265-4.978-14.265-10.104c0-5.78,4.309-9.817,12.383-9.817 c5.653,0,11.305,1.62,15.745,3.764c1.886,0.942,3.903,1.487,5.789,1.487c4.845,0,8.612-3.63,8.612-8.616 c0-3.226-1.481-5.921-4.71-7.939c-5.384-3.372-15.476-6.06-25.572-6.06c-19.781,0-32.436,11.171-32.436,27.998 c0,16.15,10.232,24.898,28.938,27.454l4.846,0.67c10.903,1.48,14.129,4.846,14.129,10.229c0,6.326-5.247,10.766-14.939,10.766 c-6.727,0-12.111-1.745-19.645-5.921c-1.616-0.942-3.634-1.62-5.788-1.62c-5.115,0-8.885,3.91-8.885,8.756 c0,3.226,1.616,6.326,4.713,8.344c6.054,3.764,15.878,7.8,28.798,7.8c23.823,0,35.934-12.24,35.934-28.795 C209.097,307.84,199.273,299.356,180.296,296.668z" style="fill: rgb(75, 75, 75);"></path> <path class="st0" d="M281.108,259.382c-4.577,0-7.939,2.43-9.556,7.674l-16.69,54.51h-0.402l-17.634-54.51 c-1.745-5.244-4.978-7.674-9.551-7.674c-5.653,0-9.692,4.176-9.692,9.287c0,1.347,0.269,2.834,0.67,4.175l23.286,68.104 c2.96,8.477,6.727,11.57,12.652,11.57c5.785,0,9.555-3.093,12.516-11.57l23.282-68.104c0.406-1.341,0.674-2.828,0.674-4.175 C290.664,263.558,286.76,259.382,281.108,259.382z" style="fill: rgb(75, 75, 75);"></path> <path class="st0" d="M364.556,300.836h-18.841c-5.114,0-8.344,3.1-8.344,7.806c0,4.713,3.23,7.814,8.344,7.814h6.193 c0.538,0,0.803,0.258,0.803,0.803c0,3.505-0.265,6.598-1.075,9.014c-1.882,5.796-7.67,9.426-14.669,9.426 c-7.943,0-12.921-3.903-14.939-10.096c-1.075-3.365-1.48-7.8-1.48-19.648c0-11.842,0.405-16.15,1.48-19.516 c2.018-6.325,6.867-10.228,14.67-10.228c5.924,0,10.362,1.885,13.859,6.724c2.695,3.777,5.387,4.852,8.749,4.852 c4.981,0,9.021-3.638,9.021-8.888c0-2.151-0.674-4.035-1.752-5.921c-4.842-8.204-15.071-14.264-29.877-14.264 c-16.287,0-28.935,7.408-33.644,22.204c-2.022,6.466-2.559,11.576-2.559,25.038c0,13.454,0.538,18.573,2.559,25.031 c4.709,14.802,17.357,22.204,33.644,22.204c16.286,0,28.668-8.204,33.374-22.881c1.617-5.111,2.29-12.645,2.29-20.716v-0.95 C372.362,303.664,369.538,300.836,364.556,300.836z" style="fill: rgb(75, 75, 75);"></path> </g> </svg>
ここで注目するのは、3行目のsvgタグです。
<svg version="1.1" id="_x32_" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 512 512" style="width: 256px; height: 256px; opacity: 1;" xml:space="preserve">
このタグに、width(横幅)とheight(縦幅)が指定されているので、こちらを任意のサイズに変更します。
今回は、縦横共に25pxにしたいので、下記のように修正しました。
<svg version="1.1" id="_x32_" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 512 512" style="width: 25px; height: 25px; opacity: 1;" xml:space="preserve">
あとは、この修正後のSVGファイルをimgタグで指定するだけで、先程指定した 25px × 25pxのサイズで無事に画像が表示されました。
もっとスタイリッシュな対処法があるのかもしれませんが…今回はこのような方法で対応しました。
アイコンのサイズが確定している場合には有効な方法ですね。
SVGファイルでお困りの際は、是非お試しください。
気になるニュースがあったのでご紹介。
資生堂が開発したというシステムで、名前は「Optune(オプチューン)」と言います。
こちらの「Optune(オプチューン)」は、なんとその人の肌質やその時の気候、さらにはその時の気分にマッチした美容液を提供するしてくれるIoTマシンなのだとか。
利用方法としては、スマートフォンアプリで肌を撮影すると、その日の気候やユーザの気分・コンディションなどのデータともにクラウドで解析し、専用のマシン「Optune Zero(ベータ版の名称)」で最適な美容液や乳液を配合し、抽出してくれるのだそうです。
マシンには、ユーザーの肌に合わせて選ばれた3種類の美容液と2種類の乳液を、5本のカートリッジでセットし、1000パターン以上の組み合わせから解析結果に基づいた最適な配合パターンの美容液が提供されるとのこと。
β版の発売が2018年春に予定されており、販売数や価格は現時点では未定です。
詳細についてはこちらのニュースサイトの記事もご覧ください。
資生堂「IoT化粧品」来春提供 その日の肌をチェック、配合をチェンジ
http://www.itmedia.co.jp/news/articles/1711/27/news127.html
資生堂、その時々の肌環境にマッチするIoTスキンケアシステム「Optune」発表
https://k-tai.watch.impress.co.jp/docs/news/1093527.html
資生堂のブランドマネージャー曰く「肌の状態は日々揺れ動いているため、最適だと思って買っていたものがいつの間にか最適ではなくなっている」とのこと。
そしてOptuneには、こうした肌の状態に最適化し(Optimize)、Tune(調律)するという意味が込められているとのことです。
こちらのシステムのターゲットは、肌や体質の変化を感じる3~40代女性とのことですが、現在20代の私も興味津々です。
お値段が張りそうですから、購入までには至らない可能性の方が高いですが、店頭などにお試しがあったら是非体験してみたいですね。
PHPで多次元の連想配列のソートをする機会があったので、備忘録として。
ソートには、「array_multisort()」という複数または多次元の配列をソートできる関数を利用します。
array_multisort()関数のマニュアルについてはこちらから。
http://php.net/manual/ja/function.array-multisort.php
今回はサンプルとして、下記のようなデータを使用します。
こちらのデータを、年齢と誕生月の昇順で並び替えを行います。
$data = array( array("no" => "1", "name" => "田中", "age" => 30, "birth_month" => 6), array("no" => "2", "name" => "鈴木", "age" => 15, "birth_month" => 8), array("no" => "3", "name" => "山田", "age" => 22, "birth_month" => 11), array("no" => "4", "name" => "遠藤", "age" => 30, "birth_month" => 9) );
まず、ソートしたい列のデータを取り出し、ソート用の配列を作ります。
今回は、年齢と誕生月でソートしたいので、$tmp_age と $tmp_bmonthという配列を用意し、それぞれに年齢と誕生月のデータを格納します。
foreach ($data as $key => $value) { $tmp_age[$key] = $value["age"]; // $tmp_age に年齢データ格納 $tmp_bmonth[$key] = $value["birth_month"]; // $tmp_bmont に誕生月データ格納 }
ソート用の配列に各データを格納出来たら、array_multisort()関数でソートします。
関数の引数には、「ソートしたい列データの配列」、「ソート順」、「ソート条件」という組み合わせを条件分だけ繰り返し、最後にソートしたい連想配列を指定します。
なお、「ソート順」、「ソート条件」については省略可能で、省略した場合は昇順になります。
array_multisort($tmp_age, SORT_ASC, // 年齢データを昇順でソート $tmp_bmonth, SORT_ASC, // 誕生月データを昇順でソート $data); // ソートしたい連想配列
なお array_multisort()は、成功した場合には TRUE を、失敗した場合に FALSE を返します。
ソート後の連想配列を var_dump で取り出してみた結果がこちら。
array(4) { [0]=> array(4) { ["no"]=> string(1) "2" ["name"]=> string(6) "鈴木" ["age"]=> int(15) ["birth_month"]=> int(8) } [1]=> array(4) { ["no"]=> string(1) "3" ["name"]=> string(6) "山田" ["age"]=> int(22) ["birth_month"]=> int(11) } [2]=> array(4) { ["no"]=> string(1) "1" ["name"]=> string(6) "田中" ["age"]=> int(30) ["birth_month"]=> int(6) } [3]=> array(4) { ["no"]=> string(1) "4" ["name"]=> string(6) "遠藤" ["age"]=> int(30) ["birth_month"]=> int(9) } }
年齢・誕生月で正しくソートできました。
単に連想配列の昇順・降順のみでしたら、asort() や arsort() を利用すれば良いのですが、多次元の連想配列で、かつソートの条件が複数の場合は、ソート用の配列が要るなど、少しややこしかったですね。
が、今後利用する機会が多々ありそうなやり方でしたので、きちんと覚えたいと思います。
現在開発中のWebシステムでjQueryでの要素追加メソッドを使うことがあったのですが、すぐに忘れてしまうのでまとめてみました。
ちなみに私は、.after()や.before()などは、名前の通りのメソッドなのでわかりやすいし覚えやすいのですが、.append()や.prepend()あたりを忘れやすいです。
$('div').after('追加要素');
一番わかりやすいし、使いやすいので、比較的利用頻度が高めなメソッドです。
指定した要素のすぐ後ろに、要素を追加します。
上のコードを実行するとこんな感じになります。
なお、今回掲載しているサンプルコードでは、div要素に対して、p要素を追加しています。
<div>基準となるdiv要素</div> <p>追加したp要素</p> <!-- after()で追加したp要素 -->
似たようなメソッドとして、.insertAfter()があります。
$('追加要素').insertAfter('div');
実行結果は、上で記載した.after()と同じになります。
追加したい要素と、追加の基準となる要素の順番が逆になるので、こちらは少し分かりにくい印象を受けます。
$('div').before('追加要素');
こちらは.after()と似ていますが、指定した要素のすぐ前に要素を追加するメソッドです。
分かりやすいですが、今まで書いたコードの中ではそこまで使用頻度は高くなかったです。
<p>追加したp要素</p> <!-- before()で追加したp要素 --> <div>基準となるdiv要素</div>
こちらのbeforeにも、似たようなメソッドとして、.insertBefore()があります。
$('追加要素').insertBefore('div');
こちらの実行結果は、上で記載した.before()と同じになります。
$('div').appand('追加要素');
こちらも良く使うメソッド。
指定した要素の中に、要素を追加します。
<div> <b>元々記述してあったb要素</b> <p>追加したp要素</p> <!-- append()で追加したp要素 --> </div>
なお、要素を追加するときは、指定した要素内(今回はdiv要素)の一番後ろに要素が追加されます。
似たようなメソッドとしては、.appendTo()があります。
$('追加要素').appendTo('div');
実行結果は上で記載した.append()のサンプルと同じ結果になります。
$('div').before('追加要素');
こちらは.append()メソッドと似ていますが、指定した要素の中の一番前に要素が追加されます。
<div> <p>追加したしたp要素</p> <!-- prepend()で追加したp要素 --> <b>元々記述してあったb要素</b> </div>
こちらは使用頻度は低め、というかまだ実際に使ったことはないですね。
こちらにも似たようなメソッドとして、.prependTo()があります。
$('追加要素').prependTo('div');
実行結果は上で記載した.prepend()のものと同じです。
ざっくりとまとめましたが、要素を追加するメソッドとしてはこのあたりを知っていればいいかと思います。
他にも.wrap()メソッドという、指定した要素で対象の要素を囲むメソッドもありますが、こちらは使う機会はあまりないかと思い、割愛させていただきました。
もし間違っている場合は、そっとご指摘をお願いします。
昨日この仕様でハマったので覚え書きもかねて。
JavascriptのDate.parse()とは、カッコ内の日時文字列を解析して、1970年1月1日 00:00:00からのミリ秒数に変換してくれる関数です。
具体的には下記のように使用します。
Date.parse('Thu, 1 Nov 2017 13:41:00 GMT+0900'); // =1509511260000
が、この解析できる日付文字列の形式が限られており、よくデータベースで用いられている「YYYY-MM-DD HH:II:SS」形式の日付文字列を入れてしまうとNaNを返すとのこと。
どうやら文字列の中にハイフンが入っていることが原因のようです。
また、Date.parse()だけではなく、new Date()のなかにハイフンを用いた日付文字列を入れた場合でも、同じくNaNを返す仕様になっているとのこと。
なお、一部のブラウザでは、ハイフンにも対応しているようで Google Chrome では、「YYYY-MM-DD HH:II:SS」形式でも、正しくミリ秒数が返ってきました。
普段使用しているブラウザが Google Chrome だったため、他ブラウザで動作検証するまで気が付きませんでした。
こちらの仕様については、ハイフンをスラッシュに置換することで対応できました。
具体的なコードはこちら。
Date.parse([日付文字列].replace(/-/g , "/"));
replace関数を用いて、ハイフンをスラッシュに置換することで、無事日付のミリ秒数が取得できました。
以上、今回私がハマったJavascriptの関数でした。
そもそも、日付をミリ秒数に変換するなんてこと早々しないので、実際に触ってみるまで、こんな仕様になっているとは全く知りませんでした。
原因がわかってしまえば対処は難しくありませんでしたが、知らないと原因特定までに時間がかかりそうな仕様でしたので、Javascriptで日付を扱うときは十分お気を付けください。
少し前のことになりますが、11月11日(土)、12日(日)に静岡大学浜松キャンパスで開催されていた「テクノフェスタ in 浜松」に行ってきましたので、こちらのイベントレポです。
テクノフェスタについてはこちらの静大のHPもご確認ください。
第22回 テクノフェスタ in 浜松
http://www.eng.shizuoka.ac.jp/campuslife/festa/
様々な展示や体験ブースがありましたが、今回のお目当てはこちらの2ブース。
静岡大学生向けの時間割管理のスマートフォンアプリや、学生が開発したブロック崩しゲームが展示されていました。
ゲームに夢中になっているお子様が多く、ブースの写真は撮影できませんでした。
ブースの対面の壁には、各アプリのQRコードが貼られており、こちらから自由にインストールすることが可能でした。
「RTK宝探し・リターンズ」という実験が行われており、プレイヤーは司令部と探検部に分かれて構内に隠された宝箱を探すというものでした。
RTK(Realtime Kinematic、リアルタイムキネマティック)とは、「GNSS基準局受信機を固定化して、もう一方の受信機で移動しながら各観測位置をリアルタイムに測位していくこと」です。
詳細については、こちらの「静岡大学・浜松キャンパスにGNSS基準局受信機」をご覧ください。
あまり詳しくない工学系の展示でも、こういうイベントだとつい足を止めてみてしまいます。
専門外の技術に興味をもてる良い機会でした。
また、大学祭も同日開催していたため、高校生やお子様連れのご家族の方が多くいらっしゃいました。
特に、子供向けの実験を行える「キッズ・サイエンス」ブースは大盛況でした。
子供向けとありましたが、成人済みの私も是非体験してみたかったですね。