2013年11月29日金曜日

[MySQL]、[php] 分類のindex管理(1)

[MySQL]、[php] 支払と収入の分類項目をデータベースで管理する


2013/11/25の更新によって追加した機能についてどのように実装していったか書き残しておこうと思います。

今回の変更点

・収入と支払の分類項目をindex管理する。(php、DB設計)
・全ユーザー共通の分類項目を用意。(DB設計)
・ユーザーが独自に設定した項目は他のユーザーには表示されない(DB設計)
・ユーザーが独自に設定した項目を設定するページ作成。(php)
・ユーザー独自の分類項目を「使わない」設定にした後も支出・支払一覧には表示させる。(DB設計)

項目としてはDB設計の変更がメインですね。新しい設定ページが必要だったので時間がかかったのは結局phpのコーディングですが。

改造の動機・問題点

これまでのページでは分類を下のように書いていました。

<select  name="type" id="type" >
<?php 
$bunrui_array = array("交通費","食費","消耗品","交際費","サークル","研究室","その他");
for ($i=0; $i<count($bunrui_array); $i++){
 print('<option value="'.$bunrui_array[$i].'">'.$bunrui_array[$i].'</option>');
}
?>
</select>

この問題点は、2つ

  1.  文字列で格納しているので拡張させづらい
  2.  全ユーザーが作成者の指定した分類項目でしか分類できない 

index管理は口座の設定をできるようにした部分で一度実装しているので、それを応用して行います。んで作る途中で気づいたことは、

  • ユーザーが独自の分類項目を削除したときどんな挙動をさせたら良いのか? 
  • データベースから削除してしまっては今までのデータを見るときに表示されないので困る。 

となるとデータベース上には保存しておく必要があるなと、フラグで管理するのが適切ということになりました。 そんなこんなで最初に書いたリストにあるように開発していくのですが、内容は次の記事に

次の記事

[MySQL]、[php] 分類のindex管理(2)



2013年11月19日火曜日

【注意点】[php] sprintf関数でSQL文を生成する時

今回の学習

sprintf関数を使ってLIKEやDATEFORMATなど%を使うSQL文を生成する時、%は%%としましょう。

参考にしたサイト
http://d.hatena.ne.jp/niconico_licoco+wu/20130117/1358398457

受け取った変数をエスケープするためにsprintf関数を用いてSQL文を作ってクエリに投げるといったやり方をしばしば行います。(私は基本的にこの方法で統一してます)

例えばこんな感じで使ってます(ユーザーの口座情報を取得するクエリ)

$sql = sprintf('SELECT a.name, u.id FROM user_accounts u 
                  JOIN accounts a ON u.account_id=a.id 
                  WHERE u.user_id=%d ORDER BY ID ASC',
    (mysql_real_escape_string($user_id))
);
$result = mysql_query($sql) or die(mysql_error());

ここからが困った時の様子

この時に、SQL文で%を使う場合(LIKEとか、DATEFORMATとか)があります。
例えば自分のアプリケーションではユーザーの今月の収入データを取得します

$sql = sprintf("SELECT SUM(income.amount) AS sum_income
   FROM income 
   WHERE user_id=%d
    AND date >= DATE_FORMAT(NOW(), '%Y-%m-01')
    AND date < ADDDATE(DATE_FORMAT(NOW(), '%Y-%m-01'), interval 2 month)
                     GROUP BY income.user_id ", 
   mysql_real_escape_string($user_id)
);
$result = mysql_query($sql, $link) or die(mysql_error());

です。この時、上のようにsprintfを使って実行すると......

"Query was empty"

クエリがありませんと?! いやいや、んなまさか?
試しにエスケープしてた部分に適当に値を入れてデータベースに直接SQL文を実行すると値が返ってくる。

ん?ん?ん? 普段ならこの直接SQLを打って間違ってる箇所洗い出して見つかるのだが、今回は分からない。

SQLをコーテーションで囲うだけにして単なる文字列として生成してみると...
$sql = "SELECT SUM(income.amount) AS sum_income
   FROM income 
   WHERE user_id=0
    AND date >= DATE_FORMAT(NOW(), '%Y-%m-01')
    AND date < ADDDATE(DATE_FORMAT(NOW(), '%Y-%m-01'), interval 2 month)
                     GROUP BY income.user_id ";
$result = mysql_query($sql, $link) or die(mysql_error());

これは動く!

sprintf関数が原因とわかりまして、初めてsprintf+MySQLで検索。
判明しました。sprintfの中で%は%%としなくてはいけないみたいです。%sとか%dで変換指定をするので、そのままじゃダメなのね。納得

ということで

sprintf()内で%を使いたいときは%%とする。

正解は
$sql = sprintf("SELECT SUM(income.amount) AS sum_income
   FROM income 
   WHERE user_id=%d
    AND date >= DATE_FORMAT(NOW(), '%%Y-%%m-01')
    AND date < ADDDATE(DATE_FORMAT(NOW(), '%%Y-%%m-01'), interval 2 month)
                     GROUP BY income.user_id ", 
   mysql_real_escape_string($user_id)
);
$result = mysql_query($sql, $link) or die(mysql_error());

2013年11月18日月曜日

色分けしたコードで投稿する方法

コードを投稿する際、色付けとかされているブロがあっていいな〜と思ってたので、早速調べて導入してみました。

SyntaxHighlighterって機能みたいなのでこちらをBloggerに導入することにしました。

参考にしたサイト
BloggerにおけるSyntaxHighlighterの使い方
BloggerにソースコードをハイライトするSyntaxHighlighterを導入する
ソースコードをハイライトするSyntaxHighlighter3.0を使いこなす

やることは、

  1. htmlのhead部分外部css読み込みをさせる
  2. クラスを指定した<pre>タグで囲む

この2つです。

以下、実際に導入した手順です。

1,htmlのhead部分に外部css読み込みをさせる

ブログ編集TOP -> テンプレート -> HTMLを編集 でテンプレートのhead部分に以下のコードを追加しました。

 <link href='http://alexgorbatchev.com/pub/sh/current/styles/shCore.css' rel='stylesheet' type='text/css'/> 
 <link href='http://alexgorbatchev.com/pub/sh/current/styles/shThemeDefault.css' rel='stylesheet' type='text/css'/> 
 <script src='http://alexgorbatchev.com/pub/sh/current/scripts/shCore.js' type='text/javascript'/> 
 <script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushCss.js' type='text/javascript'/> 
 <script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushJava.js' type='text/javascript'/> 
 <script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushJScript.js' type='text/javascript'/> 
 <script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushPhp.js' type='text/javascript'/>
 <script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushXml.js' type='text/javascript'>
 <script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushSql.js' type='text/javascript'/> 
 <script language='javascript'> 
  SyntaxHighlighter.config.bloggerMode = true;
  SyntaxHighlighter.defaults['toolbar'] = false;
  SyntaxHighlighter.all();
 </script>

自分はwebアプリ作っているのでCSS,JavaScript,php,html,SQLあたりが使えればいいのでこれらをインポートしました。
11行目はbloggerで使うため?
12行目は右側に?マークが出るのでそれを消すための設定です。

2,クラスを指定した<pre>タグor<script>タグで囲む

<pre class='brush: ***'>
コードの内容(<をエスケープ済)
</pre>


ちなみに、今回はhtmlを指定して埋め込んでます。
注意点としては

  • "<" がタグとして認識されてしまうので "&lt;" でエスケープすること。
  • scriptタグ使う場合でも、埋め込むコードに</script>タグがあった場合、ここだけ "&lt;/script>" としなくてはいけないことに注意してください。

ここで30分ぐらいつまりましたね。

こんなかんじです。綺麗にコードが見れるし行数もわかるので使う価値はあるかと思います。
プレビュー表示させるとscriptタグの方法は認識してくれないくて表示されないので、結局<pre>タグ使う方法で書いていくことになりそうです。

syntax error, unexpected '[', expecting ']'

今日気づいたバグ
ローカル環境でエラーは出ていなかったけどリモートに挙げたらあるページでこんなエラーが

【エラーの内容】


syntax error, unexpected '[', expecting ']'

シンタックスエラーはいわゆるケアレスミスのことが多いです。よくあるのは、;を忘れるミス
http://www.php-labo.net/tutorial/public/error.html


今回は "[" 書いたのに "]" ないぞってやつです。
実際にコード見たら

何故か[]でなく[[]]になってた〜なんででしょうね。とりあえず
unset($_SESSION['income']);

としたら難なく解決。