【予約語に注意】FuelPHPでユーザ登録をしようとすると「Fuel\Core\Database_Exception [ 1064 (1064) ]: You have an error in your SQL syntax;」と出る
FuelPHPでユーザ登録をするとエラーが出る。
FuelPHPでユーザ登録をしようとすると以下のようなエラーが出た。
Fuel\Core\Database_Exception [ 1064 (1064) ]:
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'group, profile_fields, last_login, login_hash, created_at) VALUES ('test8', 'zGE' at line 1 [ INSERT INTO users (username, password, email, group, profile_fields, last_login, login_hash, created_at) VALUES ('test8', 'zGEG+uMfdUKF9EJ4dPFONfP4OKlu33BkVIr6wLUDa4M=', 'test8@mail.com', 1, 'a:0:{}', 0, '', 1556079498) ]
どうやらINSERT文自体が間違っているらしい。
カラム名に予約語が使われているときは「`」で囲う
SELECT、DELETE、または BIGINT などの特定の語は、テーブル名やカラム名などの識別子として使用するために予約されており、特別な取り扱いが必要となる。
今回の場合は、カラム名として使用されている「group」が予約語のため(group byで使用)、エラーが起きていたよう。
※参考
dev.mysql.com
そんな時はカラム名を「`(バッククォート)」で囲めば解決。
今回の場合だと以下のように実施。
INSERT INTO users (username, password, email, `group`, profile_fields, last_login, login_hash, created_at) VALUES ('test8', 'zGEG+uMfdUKF9EJ4dPFONfP4OKlu33BkVIr6wLUDa4M=', 'test8@mail.com', 1, 'a:0:{}', 0, '', 1556079498)
gontora.hatenadiary.com
これで直接DBでSQL文を実行してみると、無事データ登録が出来た。
FuelPHPが自動的に生成しているSQL文での予約語対策
しかし今回のSQL文はFuelPHPが自動的に生成しているので、実際のコードを実施したときは依然エラーが出る。
調べてみるとどうやら、config/db.php 等で設定している、使用しているデータベース設定の identifierを以下のように設定する必要があるそう。
'identifier' => '`',
これでカラム名がバッククォートで括られるように設定されるようだ。
db.phpファイル全体だとこんなイメージ。
<?php return array( 'active' => 'mysqli', 'mysqli' => array( 'type' => 'mysqli', 'connection' =>array( 'hostname' => 'localhost', 'database' => 'framework', 'username' => 'root', 'password' => 'root', 'persistent' => false, 'compress' => false, ), 'identifier' => '`', 'table_prefix' => '', 'charset' => 'utf8', 'caching' => false, 'profiling' => true, ), );
これで無事登録できました。
このへんはFuelPHPでもバージョンで違うよう。
最近のバージョンはデフォルトで設定されていないのかな?
※参考
teratail.com
「クラス名:nth-of-type(n)」で記載した場合、「クラスでn番目」ではなく、「要素でn番目」という数え方になる
「クラス名:nth-of-type(n)」で記載した場合、「クラスでn番目」ではなく、「要素でn番目」という数え方になる
「クラス名:nth-of-type(n)」で記載したときの挙動が気になったのでメモ。
以下の簡単なコードで動作を確認します。
簡単な動作確認用コード
HTML
<!DOCTYPE html> <html lang="ja"> <head> <link rel="stylesheet" href="style.css"> </head> <body> <div> <span class="a">その要素で1番目⇛aクラス</span> <span class="b">その要素で2番目⇛bクラス</span> <!-- クラスに適用されていたならこの要素は青色になる(class="a"の中で2番目のため)--> <span class="a">その要素で3番目⇛aクラス</span> <span class="b">その要素で4番目⇛bクラス</span> <!-- クラスに適用されていたならこの要素は青色になる(class="a"の中で3番目のため)--> <span class="a">その要素で5番目⇛aクラス</span> <span class="b">その要素で6番目⇛bクラス</span> </div> </body> </html>
CSS
.a:nth-of-type(1){ background-color: red; } .a:nth-of-type(2){ background-color: blue; } .a:nth-of-type(3){ background-color: yellow; } .a:nth-of-type(4){ background-color: green; }
※nth-of-type(n)は、疑似クラスの一種で、 n番目のその種類の要素にスタイルを適用
実施結果
まとめ
・「クラス名:nth-of-type(n)」で記載した場合、「クラスでn番目」ではなく、「要素でn番目」という数え方になる
・要素でn番目かつそのクラス名をもつものにスタイルが適用される
・「クラス名:nth-of-type(n)」で記載したときは、勘違いしやすいので注意(特に兄弟要素に同じ種類の要素があると間違えやすい)
コマンドラインでfuelPHPがインストールできないときの対策(syntax error near unexpected token `newline')
コマンドラインでfuelPHPがインストールできないときの対策(syntax error near unexpected token `newline')
コマンドラインでfuelPHPをインストールしようとしたら、以下のようなエラーがでました。
$ curl get.fuelphp.com/oil | sh % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 239 100 239 0 0 118 0 0:00:02 0:00:02 --:--:-- 118 sh: line 1: syntax error near unexpected token `newline' sh: line 1: `<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">'
Sassの変数と@mixinでレスポンシブデザインを作るときは@mixinの呼び出し順に注意
Sassの変数と@mixinで3パターンのレスポンシブデザインを作ろうとすると、CSSが適用されない
PC・タブレット・スマホの3パターンのレスポンシブデザインをSassの変数と@mixinで作ろうとして、CSSがうまく適用されませんでした。
結論としては、Sassの変数と@mixinでレスポンシブデザインを作るときは、ブレイクポイントの変数の用意の仕方で、@mixinの呼び出し順が異なります。
これによって一見CSSが適用されていないように見えてしまいます。
そもそも「Sassの変数と@mixinを使ってレスポンシブデザイン」を作る方法は?
こちらに素晴らしく分かりやすいサイトがございますので、こちらを御覧ください。
www.tam-tam.co.jp
本題:@mixinの呼び出し順について
用意したブレイクポイントの変数
$breakpoints: ( 'sm': 'screen and (max-width: 414px)', 'md': 'screen and (max-width: 768px)', 'lg': 'screen and (max-width: 1000px)', 'xl': 'screen and (max-width: 1200px)', ) !default;
用意したmixin
@mixin mq($breakpoint: md) { @media #{map-get($breakpoints, $breakpoint)} { @content; } }
@mixinでメディアクエリを呼び出す
正しい呼び出し順
.container { width: $site-width; @include mq(md) {//画面サイズが768pxまでの場合、styleを適用 width: 90%; } @include mq() {//画面サイズが414pxまでの場合、styleを適用 width: 80%; }
誤った呼び出し順
.container { width: $site-width; @include mq() {//画面サイズが414pxまでの場合、styleを適用 width: 80%; } //mq() で呼び出して適用したstyleが上書きされてしまう @include mq(md) {//画面サイズが768pxまでの場合、styleを適用 width: 90%; }
yarnでnode-sassのライブラリを使うと「An output directory must be specified when compiling a directory」とエラーが出る
単なる打ち間違いですが、わりとハマってしまったのでメモ。
jsonファイルの中身
{ "name": "test", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "build-css": "node-sass --include-path scss scss/style.scss css/style.css", "watch-css": "nodemon -e scss -x \"npm run build-css\"" }, "author": "", "license": "ISC", "devDependencies": { "node-sass": "^4.11.0", "nodemon": "^1.18.11" } }
node-sassのライブラリをbuild-cssというコマンドを作成して実施しようとしています。
ターミナルでの実行およびエラー画面
$ yarn build-css yarn run v1.15.2 $ node-sass --include-path scss scss/style.scss css/style.css An output directory must be specified when compiling a directory error Command failed with exit code 1. info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
yarnでbuild-cssを実行。
「An output directory must be specified when compiling a directory」、すなわち「ディレクトリをコンパイルするときは、出力ディレクトリを指定する必要があります。」と怒られていますね。
CSSのアニメーション機能を使って、扉から飛び出すように画像を表示させる
せっかく学習したのでCSS3のアニメーション機能を使って、扉から飛び出すような画像表示機能を作ってみます。
動作イメージ
最初は扉のような画像が表示されています。
扉にカーソルを重ねると勢いよく扉が開きます。
直後に勢いよく画像が飛び出してきます。
カーソルを画像から離すと画像は小さくなり、扉は閉まります。
論よりコード
HTML
<!DOCTYPE html> <html lang="ja"> <head> <link rel="stylesheet" href="style.css"> </head> <body> <div id="main"> <!-- 疑似要素:after,:beforeを付けるためにimgタグをspanタグで囲う --> <!-- imgタグのような閉じタグが無い要素は疑似要素が使えない --> <span class="wrap-img"><img src="img/image.png" alt=""></span> </div> </body> </html>
CSS
#main{ padding: 200px; } .wrap-img{ display: block; width: 800px; height: 800px; position: relative; z-index: 0; visibility: middle; box-sizing: border-box; transition: all .3s; } /*疑似要素:before,:after*/ /*html上には無いが、要素の前後に要素があるようにできる*/ /*htmlを汚さずにデザインのための要素を付けることが可能*/ .wrap-img::before, .wrap-img::after{ position: absolute; /* 画像より手前に表示するため */ z-index: 1; display: block; content: ''; box-sizing: border-box; top: 0; /* 親要素の半分の大きさの扉のため*/ width: 50%; height: 100%; background-color: rgba(208, 162, 67, 1); border: rgba(128, 0, 0, 1) 2px solid; box-sizing: border-box; /* 0.1秒待った後に0.3秒かけてwidthが変化する(扉が閉まる) */ transition: width .3s ease .1s; } /*左側の扉となる要素*/ .wrap-img::before{ left: 0; } /*右側の扉となる要素*/ .wrap-img::after{ right: 0; } .wrap-img:hover::before, .wrap-img:hover::after{ cursor: pointer; /*カーソルを重ねるとwidthを0にする(扉が開く)*/ width: 0; /* 0秒待った後に0.3秒かけてwidthが変化する */ transition: width .3s ease 0s; } img{ box-sizing: border-box; display: block; } img{ /* カーソルを重ねていないときの画像は小さく */ transform: scale(0.8, 0.8); transform: all .1s; } img:hover{ cursor: pointer; /* カーソルを重ねると画像は大きくなる */ transform: scale(1.2, 1.2); transition: transform .2s ease .1s; }
ポイントまとめ
・疑似要素:before,:afterを使うことで、htmlを汚さずにデザインのための要素を付けることが可能
・imgタグのような閉じタグが無い要素は疑似要素が使えない
・疑似要素のwidthを50%にし、positionを調整、z-indexで画像の手前に持ってくることで扉のように見せる
・扉にカーソルを重ねたらtransitionでwidthを0に変化させる(待ち時間や変化の早さを指定可能)
・扉が空いたら画像が飛び出てくるようにtransitionで画像の大きさが変化する早さを調整
基本的なクロージャの実践例の「モジュールパターン」は何が起きているの?
なんとなくクロージャーは分かったけど…
「JavaScriptのスコープの概念」や「クロージャーのメリット」は理解したけど、いまいち典型的なクロージャーのコードで何が起きているか分からなかったので調べてみました。
典型的なクロージャーのコードと分からんポイント
var module = (function() {//分からないポイント①: functionの前に"("がついて、function全体が()で囲われている var count = 0; return { increment: function() {//分からないポイント②:セミコロンの隣のfunctionという見慣れない記述 count++; }, show: function() { console.log(count); } }; })();//分からないポイント③:最後の謎の何も入っていない() //分からないポイント④:〇〇.関数名();でよく分からんけど関数を呼べる? module.show(); // 0 module.increment(); module.show(); // 1 console.log(count); // undefined
だいたいこのあたりがよく分からないポイントだと思います。
要点1:クロージャーは即時関数を使って記載されている
典型的なクロージャーのコードは即時関数というものを使って記載されています。
即時関数は、関数を定義すると同時に実行するための構文。
基本的な書き方
(function () { //処理 }());
引数と返り値
var result = (function (param1, param2) { return param1 + param2; }(1, 2)); console.log(result); //3
つまり「変数module」に、関数を定義したと同時にその「関数を実行した結果」が入っていることが分かります。ここでいう「関数を実行した結果」とは「returnの中身」ですね。
「console.log(module);」を実施すると「increment」と「show」という関数が入っているのが分かると思います。
var module = (function() {//分からないポイント①: functionの前に"("がついて、function全体が()で囲われている var count = 0; return {//分からんポイント②:returnに関数が入ってる increment: function() {//分からないポイント②:セミコロンの隣のfunctionという見慣れない記述 count++; }, show: function() { console.log(count); } }; })();//分からないポイント③:最後の謎の何も入っていない() //分からないポイント④:〇〇.関数名();でよく分からんけど関数を呼べる? module.show(); // 0 module.increment(); module.show(); // 1 console.log(module);//incrementとshowという関数が入っているのが分かる console.log(count); // undefined
開発ツールで見てみるとincrementとshowという関数が確かに入っていますね。
これで「分からないポイント①」と「分からないポイント③」は理解できたと思います。
要点2:JavaScriptで扱うものはすべてオブジェクトかオブジェクトのように使える
JavaScriptで扱うものはすべてオブジェクトかオブジェクトのように使えます。
オブジェクトにはプロパティとメソッドがあります。
オブジェクトの作り方と利用例
//testHumanというオブジェクトを作成 var testHuman = { firstName: "Hoge", lastName: "Fuga", sayHello: function(){ console.log("Hello") }// メソッドを作成 }; console.log(testHuman["firstName"]); // Hoge console.log(testHuman["lastName"]); // Fuga testHuman.sayHello();// Hello メソッドを実施
上記のtestHumanオブジェクトのsayHelloメソッド作成と同様の方法で、moduleオブジェクトのincrementメソッドとshowメソッドを作成していることが分かります。testHuman.sayHello();と同様の方法で、「module.increment();」「module.show(); 」を実施していることが分かります。
これで「分からないポイント②」と「分からないポイント④」は理解できたと思います。