MySQL、CakePHP 2.3で「tinyint(1)」の Boolean型の動作を再確認
2018/03/21
MySQL、CakePHPで「tinyint(1)」のフィールドは Boolean型として認識
MySQLでの「tinyint(1)」のフィールドは Boolean型と認識するが...
MySQLの「tinyint(1)」の悲劇 Boolean型になるとは...
この記事に「結論が間違っています」コメントをいただきました。
そのために検証を行った結果、「tinyint(1)」のフィールドが「Boolean型」として処理されるのは MySQLの機能ではなく、CakePHPの機能によって起こっていることを確認しました。
※厳密な表現では、MySQLでは「tinyint(1)」で設定されたフィールドは Boolean型として処理する仕様となっているため、その定義に従って、CakePHPでは「0」「1」しか持てないように処理している、ということになるでしょう。
MySQLの定義については以下参照
http://dev.mysql.com/doc/refman/5.1/ja/numeric-type-overview.html
また、コメントでご指摘をいただいた通り、「tinyint(1)」を設定していても MySQLのテーブル上は -128~127まで保存されることを確認しました。
そして、「0」の場合は「False」、「0」以外の場合は「True」として扱うものと定義してあるようです。
Cakephpでの「tinyint(1)」のフィールドの扱い方
しかし、それを CakePHPで処理をするとちょっと違う結果になることを改めて確認しました。
具体的には、下記の様にテーブルを作成し、このテーブルをもとに CakePHPの bakeコマンドにて、Model、Controller、Viewを作成し、データの登録、一覧表示を行ってみました。
——————————————–
|
1 2 3 4 5 6 7 8 9 10 |
CREATE TABLE IF NOT EXISTS `testints` ( `id` int(11) NOT NULL AUTO_INCREMENT, `test1` tinyint(4) NOT NULL, `test2` smallint(6) NOT NULL, `test3` int(11) NOT NULL, `test4` bigint(20) NOT NULL, `created` datetime DEFAULT NULL, `modified` datetime DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; |
——————————————–
この状態でデータを登録すると、当たり前ですがデータは問題なく「-128」~「127」まで問題なく登録できました。
その次に、phpMyAdminなどで、test1の項目を「tinyint(1)」に変えてみたところ、大きな変化が現れました。
まず、一覧画面。
変更前
変更後
それまで -128、127などが編集されていた項目が「1」になり、0が編集されていた項目は nullに変わってしまいました。
また、入力画面では、通常のテキスト入力項目だったものが、チェックボックスの項目に変わってしまうという自動処理が行われていました。
変更前
変更後
Cakephpで入力形式を変えてみた場合
これをもとのテキスト形式の入力に戻す場合は、「/app/View/Testints/add.ctp」の 6行目に下記の様に「, array ( ‘type’ => ‘text’ )」を追加することでテキスト形式の入力に戻すことは可能です。
———————–
|
1 |
echo $this->Form->input('test1', array ( 'type' => 'text' ) ); |
———————–
ですが、テキスト形式で入力できるようにしたとして 0以外の数値が入力されてもデータベースには 1として保存されますので、実質 Boolean型としてしか使えませんので注意が必要です。
これが、前回の記事「MySQLの「tinyint(1)」の悲劇 Boolean型になるとは...」で陥っていたトラブルの原因でした。
そして、これは MySQLの Boolean型としての定義を、CakePHPの機能によって Boolean型としての処理として実装しているということが今回の実験で判明しました。
「tinyint(1)」以外の項目をチェック
さらに実験をしてみたところ、「tinyint(1)」以外の「「tinyint(2)」「tinyint(3)」では「tinyint(1)」のような変化はなく、「smallint(1)」「int(1)」も「tinyint(1)」のような変化はありませんでした。
ただ、「bigint」はさらなる衝撃な動作をしました。
なんと、「bigint(1)」のように設定すると、設定した数値の桁数分だけしか入力できなくなるのです。
例えば、
「bigint(1)」ならば、1桁しか入力できませんので「0~9」まで。
「bigint(2)」ならば、2桁しか入力できませんので「-9~99」まで。
といった感じ。
つまり、設定した数値の値に従って、入力エリアに自動的に「maxlength」が設定されるようです。(HTMLのソース上に maxlengthが設定してあるのを確認しました。)
ですが、これはあくまでも入力画面における処理であり、「tinyint(1)」の処理とは違うようで、下記の様に入力タイプを「text」と明示して設定すると、「maxlength」の制限はなくなり、通常通り「bigint(20)」と変わらない動きになりました。
また、入力画面上のみの処理のため、あらかじめ入力されていたデータは「tinyint(1)」の様に加工されることなくそのまま表示されていました。(入力画面でも入力されている値がそのまま表示されていました。)
———————–
|
1 |
echo $this->Form->input('test4', array ( 'type' => 'text' ) ); |
———————–
「tinyint(1)」の MySQL、CakePHPでの動作のまとめ
今回は、tinyint、smallint、int、bigintの 4つの型での検証ですが、その他の項目でも同じような動きをする項目があるかもしれません。
もし、そんなことをご存知の方がいらっしゃいましたら、情報提供をしていただけますと幸いです。
ちなみに、当然ですが「tinyint(0)」は設定することができません。
tinyint()を始め、MySQLの数値型についての詳細は、下記に解説記事を書いていますので、あわせて参照してください。
MySQLの数値型(int、tinyint、bigint、decimal、number、float)の解説
GoogleAdwords
GoogleAdwords
この記事が参考になったと思いましたらソーシャルメディアで共有していただけると嬉しいです!
関連記事
-
-
CakePHP4系でJSONレスポンスの処理ではwithStringBodyを使う。3との違い解説
responseの値を指定する方法は3系では「body」だが、4系では「withStringBody」になりる。加えてJSON形式なら「withType」で指定するなど4系では結構異なる処理がある。
-
-
CakePHP4で「app_local.php」「.env」を利用して環境ごとの定数を振り分ける方法
CakePHP4で.env、app_local.phpに定数を定義してそれを呼び出す方法の解説。Gitでは管理せず本番環境と開発環境とで異なる定数を定義するためそれを利用する方法。
-
-
CakePHP3でDocumentRootやtmp、webroot、logsなどのフォルダへのパスの定数
CakePHP3で特定フォルダのパスの定数を解説。root、DocumentRoot、app、config、webroot、tests、tmp、cache、vendor、コア、コアの srcが設定済み。realpath()関数を使うと柔軟なパス指定が可能。
-
-
CakePHP 2.3 コマンドラインからPHPのシェル実行の方法解説
CakePHP 2.3でコマンドラインから CakePHPで記述した処理を実行する方法を解説します。
-
-
CakePHP4系、CakePHP5系のexists()でカラムを指定して値の有無をチェックする方法解説
CakePHP4、5で指定したカラムに特定の値に該当のレコードの有無をチェックするにはexists()を使う。単純にカラムを指定する方法から複数条件をand、orで探すこともできる。
-
-
CakePHP3のfriendsofcake/searchでブックマークチュートリアルのタグ検索を実装
CakePHP3のCookbookにあるブックマークチュートリアル。ここで紹介されているタグで検索する処理を検索プラグイン「friendsofcake/search」で実現する方法を解説しました。
-
-
CakePHP5系で認証機能のAuthenticationプラグインをインストール・エラー発生注意
CakePHPのユーザ認証に使用するオフィシャルなプラグインAuthenticationだが、CakePHP5系では Authentication Ver.3系を使う必要があるが、公式ChiffonBookが間違えている。
-
-
CakePHP4で公開側と管理側のデザインテンプレートを分ける方法・setLayout()
CakePHP4でデフォルトのレイアウトファイル「default.php」は管理側に使用し、これとは別のデザインを公開側のページに設定したい、を実装する方法を解説。
-
-
CakePHP 2.3 Search Pluginで検索処理 その4前方一致検索、後方一致検索、不等号による検索、between句による範囲検索
CakePHPの検索プラグイン Search Pluginの検索処理の中で前方一致検索、後方一致検索、不等号による検索、between句による範囲検索の解説です。
-
-
CakePHP3のCakeDC/UsersのUserHelperでログアウトやreCAPTCHAをカスタマイズ
CakeDC謹製Usersプラグインの紹介。UserHelperを利用し、ログアウトのリンクや権限があるときのみ表示されるリンク、プロフィールページへのリンク、reCAPTCHAの設置方法などを解説。



