読者です 読者をやめる 読者になる 読者になる

WebEngine

web、プログラミング関係について書いていきます。あなたの優しい眼差しがブログの成長につながりますのでどうぞよろしく。

jQueryでAjaxを扱う

前提


Ajaxを使うメリット

非同期通信ができることです。 具体例を挙げると

  • ユーザのストレスを軽減できる
  • サーバへの負荷を軽減できる

というメリットがあります。もちろんデメリットもありますが、ほかのサイトでいろいろ考察されているので、 ここでは流します。


いろいろ書き方があるみたいだけど

ajaxで検索すると、結構いろんな書き方が紹介されています。

$.ajax({
    url: "test.html",
    success: function(data) {
       console.log("success");
    },
    error: function(data) {
       console.log("error");
    }
});
$.ajax({
    url: "test.html",
}).success(function(data) {
    console.log("success");
}).error(function(data) {
    console.log("error");
});

調べてみると上記2つの書き方は旧式の書き方のようです。
今回は下の書き方で統一します。

$.ajax({
    url: "test.html",
}).done(function(data) {
    console.log("success");
}).fail(function(data) {
    console.log("error");
});

これがベストプラクティス、というわけではないようですが、今回はとりあえずこの記述法で 実装します。


サンプルコード

AjaxCSVJSON形式のデータを取得し、出力するというサンプルをつくってみたいと思います。 HTMLファイルにjavascriptの関数が入っていたりするので、よかったらリファクタリングにも挑戦してみてくださいね。(人任せ)

1.index.html

<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="utf-8">
    <title>ajax</title>
    <script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
    <script src="script.js"></script>
  </head>
  <body>
    <input type="button" onClick="output(0)" value="output_data0">
    <input type="button" onClick="output(1)" value="output_data1">
    <input type="button" onClick="output_json()" value="output_data_json">
    <div id="output_zone"></div>
  </body>
</html>


2.script.js

function output(num) {
  clear();

  $.ajax({
    url: "data" + num + ".csv"
  }).done(function(result) {
    var tmp_ary = result.split("\n");
    // console.log(tmp_ary);
    for (var i = 0; i < tmp_ary.length; i++) {
      $("#output_zone").append(tmp_ary[i]).append("<br>");
    }
  }).fail(function(data) {
    console.log(data);
  });

}

function output_json() {
  clear();

  $.getJSON("data.json", function(json) {
    for (var i = 0; i < json.student.length; i++) {
      var student = json.student[i];
      $("#output_zone").append(student.name + " : " + student.age).append("<br>");
    }
  });

}

function clear() {
  $("#output_zone").empty();
}


3.data0.csv

Takeda,20
Sakurai,45
Hashimoto,36


4.data1.csv

Takeda Yuri, woman
Sakurai Kaoru, woman
Hashimoto Takuya, man


5.data.json

{"student" : [
  {
    "name" : "Takeda",
    "age" : 20
  },
  {
    "name" : "Sakurai",
    "age" : 45
  },
  {
    "name" : "Hashimoto",
    "age" : 36
  }
]}


HTMLファイルであるindex.htmlドラッグアンドドロップとかしても動きません。これはクロスドメイン制約があるためです。


ドキュメントルートに設置するか、PHPのビルトインサーバを立てるかして、http://localhost/hogehoge/~というような感じでアクセスしましょう。

左のボタンを押せばdata0.csvの情報が、中央のボタンを押せばdata1.csvの情報が出力されるはずです。
そして、右のボタンを押せばJSON形式であるdata.jsonが出力されます。

広告を非表示にする

Node.jsでいろんな形式のデータを扱う

注意事項

以下のファイルの文字コードはすべてUTF-8で実装しているので、Windows環境などでは、日本語が 文字化けする可能性があります。それらを踏まえた上で、テスト用のテキストなどに日本語 を使うことは避けていますが、やはり、環境によっては上手くいかないことがあることを ご理解ください。


対象となるデータ形式

  1. JSON
  2. XML / RSS
  3. CSV


1. JSON

javaScriptrといえばJSONですね。 下のようなdata.jsonを用意しました。

{                                                                 
  "title" : "-- programming --",
  "languages" : [
    {"id":1000, "name":"Java"},
    {"id":1001, "name":"Ruby"},
    {"id":1002, "name":"PHP"},
    {"id":1003, "name":"Python"},
    {"id":1004, "name":"JavaScript"}
  ]
}

そして、こちらが上のJSONファイルを読み込んだり、パースしたりする json_read.jsです。

var fs = require('fs');                                                             

var json_data = fs.readFileSync("data.json", "utf-8");
var obj = JSON.parse(json_data);

console.log(obj.title);
for (var i in obj.languages) {
  console.log(obj.languages[i].name);
}

node json_read.jsで実行すると、プログラミング言語がずらっと表示されるはずです。 非常に簡単ですね。

javaScriptのオブジェクトをJSONのデータに変換するには

var json_data = JSON.Stringify(obj);

とします。JSON.parse(json_data);と対になっていると考えると理解しやすいです。


2. XML / RSS

node.jsでXMLを扱うには、xml2jscheerioというモジュールを使います。
ここでは、jQueryライクにDOMへアクセスできるcheerioの方を使います。

cheerio

npm install cheerio

でインストールすることができます。

XMLは、data.xmlというファイルを用意しました。

<item>
  <name>pen</name>
  <price>120</price>
</item>
<item>
  <name>note</name>
  <price>150</price>
</item>
<item>
  <name>book</name>
  <price>540</price>
</item>

これを扱うファイルをxml_read.jsとして作成します。

var fs = require('fs'),
    che = require('cheerio');

var xml_data = fs.readFileSync("data.xml", "utf-8");
$ = che.load(xml_data);

$("item").each(function(i, el) {
  var name = $(this).children("name").text();
  var price = $(this).children("price").text();

  console.log(name + " : " + price);
});

node xml_read.jsと実行すると、モノと、その値段が表示されるはずです。
直観的にわかるかもしれませんが、cheerioモジュールのload()XMLファイルをパースしたものが、 $に入っています。そのあとは、jQueryのような構文で各要素の中身を取得していく感じになります。


3. CSV

node.jsでCSV形式のファイルを扱うにはcomma-separated-valuesというモジュールが要ります。

npm install comma-separated-values

でインストールできます。 以下はdata.csvになります。

ID, Name, Birthday
1000, Alice, 19990201
1001, Bell, 20010609
1002, Clara, 20001230

CSVファイルを扱うファイルが以下のcsv_read.jsです。

var fs = require('fs'),
    CSV = require('comma-separated-values');

var csv_data = fs.readFileSync("data.csv", "utf-8");
var data = new CSV(csv_data, {header:false});
var rec = data.parse();

for (var i = 0; i < rec.length; i++) {
  console.log(rec[i][0] + " : " + rec[i][1]);
}

node csv_read.jsで実行すると、IDと名前が表示されます。
1行目のヘッダ部分がいらない、という場合には、パース直後に、 rec.shift();と書けば、配列の先頭要素が削除されるので上手い具合になります。


まとめ

どのファイル形式を扱うにしても

  1. モジュールを読み込む
  2. fsのreadFileSync()を使ってデータを読み込む
  3. 読み込んだモジュールを使ってデータをパースする
  4. パースしたデータから必要な部分を取得したり、出力したりする

といった大まかな流れは変わりません。

また、基本的にnode.jsには便利なモジュールが多く、それらはほとんどnpmで取得できます。なにか行いたい 場合、先に使えそうなモジュールがないか調べるのも手であることを覚えておきましょう。


参考


Node.jsでSQLite3を使ってみる

環境

  • Ubuntu16.04
  • Node.js v7.7.1
  • npm 4.1.2


SQLite3をnpmでインストール

node.jsはサーバサイドでjavascriptを扱えるようにしたもの。当然、データベースも扱うことが できます。
今回はSQLiteというデータベースを使ってみます。ほかの選択肢としてはmongoDBなんかがあるみたいですね。

SQLiteはnpmを使ってインストールすることができます。

npm install sqlite3

実行時のディレクトリにnode_modulesというディレクトリができて、さらになかにsqlite3というディレクトリ が入ったはずです。


データを挿入する

SQLiteを直接立ち上げて、コマンドでテーブル定義などを行っても良いですが、今回は sqlite-insert.jsというスクリプトファイルを作成し、それを実行する過程でテーブル 定義などを行いつつ、データも挿入することにします。

var sqlite = require('sqlite3').verbose();                                          
var db = new sqlite.Database('test.sqlite');

db.serialize(function() {

  // テーブルがなければ作成
  db.run('CREATE TABLE IF NOT EXISTS students(name TEXT, age INT)');
 
  // プリペアードステートメントでデータ挿入
  var stmt = db.prepare('INSERT INTO students VALUES(?,?)');
  stmt.run(["Tanaka", 12]);
  stmt.run(["Sato", 13]);
  stmt.run(["Nakamura", 15]);
  stmt.finalize();

 });

db.close();

studentsテーブルは名前と年齢を管理するテーブルです。本当はIDなんかをつけた方が 良いのですが、今回はテストなので省略します。
実行はnode sqlite-insert.jsでできます。

プリペアードステートメントについては、以前MySQLで書いた記事があるので、そちらを参考にしてみてください。


データを取得する

つづいて、データベースからデータを取得するスクリプトを書いてみます。
ファイル名はsqlite-fetch.jsとでもしておきましょう。

var sqlite = require('sqlite3').verbose();                                          
var db = new sqlite.Database('test.sqlite');
 
db.serialize(function() {

  db.each("SELECT * FROM students", function(err, row) {
    console.log(row.name + ":" + row.age);
  });

});

db.close();

node sqlite-fetch.jsで実行します。
まあ、見ての通り、ターミナルにデータを表示するだけです。取得の際コールバック関数を 使っているのがnodeっぽいですよね。

ちなみに、いつのまにかtest.sqliteというファイルができているかと思いますが、そこに挿入した データが入っています。


参考

Expressを使ってみる

Expressってなに

Node.jsのウェブアプリケーションフレームワークです。Node.jsのフレームワークKoaRailsライクなSailsなんかがありますが、おそらくExpressがもっとも有名ではないかと 思います。


準備

  • 環境:macOS Sierra10.12.3

とりあえず本家サイトのインストール手順にしたがって環境を整えます。

mkdir express_test
cd express_test
npm init

express_testというディレクトリを作成、そこへ移動。npm initpackage.jsonというファイルを つくります。このコマンドを実行すると、いろいろ質問されますが、一つの質問を除いては、ただリターンキー(エンターキー) を押していくだけで良いです。
例外の質問とは

entry point: (index.js)

という項目です。
ここでは、メインのファイル名を入力します。今回はapp.jsとしました。
上手くpackage.jsonが作成されれば、次のコマンドでExpressをインストールします。

npm install express --save

グローバルでインストールしても良かったのですが、動かなかったときが怖いので、express_testディレクトリ内 にのみ入れました。

ハローワールド

メインファイルであるapp.jsを作成し、次のように書きます。

var express = require('express')
var app = express()

app.get('/', function (req, res) {
  res.send('Hello, Express!!')
})

app.listen(3000, function () {
  console.log('Listening on port 3000!')
})

作成したら、ターミナルで

node app.js

と実行します。

ブラウザのURL欄にhttp://localhost:3000/と打ち込んで Hello, Express!!と出力されれば成功です。

参考

広告を非表示にする

MacにNode.jsをインストールする

前提条件

  • 2017.2.19現在の情報
  • homebrewインストール済み
  • 現在node.jsが入っていない
  • 黒い画面を操作できる

手法

node.jsをインストールする方法はいろいろあるのですが、今回はnodebrew というものを使います。nodebrewでは複数のnode.jsを切り替えたりして 使うことができます。Rubyのrbenvに近い感じです。node.jsは開発が盛んに行われているので、急な仕様変更 にも対応できるように注意する必要があります。

本題

とりあえずnodebrewをインストールします。

brew install nodebrew

入ったか確認するには、nodebrew -vwhich nodebrewと 入力すれば良いです。

nodebrewが入ったら、次はnode.jsをインストールしていきます。
インストールできるnode.jsは

nodebrew ls-remote

で確認できます。

今回は最新版をインストールしたいと思います。
最新版をインストールするには

nodebrew install-binary latest

と打ち込めば良いです。
特定のバージョンのnode.jsをインストールしたい場合はlatestの部分を v7.1.0のようにすれば良いです。

ちなみに、僕の場合はインストールの際、このようなエラーが出ました。

Fetching: https://nodejs.org/dist/v7.5.0/node-v7.5.0-darwin-x64.tar.gz
Warning: Failed to create the file
Warning: /Users/home/.nodebrew/src/v7.5.0/node-v7.5.0-darwin-x64.tar.gz: No
Warning: such file or directory
                                                                           0.0%
curl: (23) Failed writing body (0 != 941)

参考にさせていただいたサイトに対処法がのっていたので、そのまま採用させていただきました。 こういうのは非常にありがたいですね。(リンクは下にあります)
このようにディレクトリを作成した結果、上手くいきました。

mkdir -p ~/.nodebrew/src

nodebrewに入れたnode.jsのバージョンを確認するには

nodebrew list

と入力します。

下の方がcurrent: noneとなっているはずです。これは、使用するnode.js が選択されていない状態を指します。

nodebrew use  v7.5.0

とすることで使用するnode.jsのバージョンを指定することができます。もう一度nodebrew listと 入力すると、current: noneだった箇所が指定したバージョンになっているはずです。

最後にパスを通します。

echo 'export PATH=$PATH:/Users/user_name/.nodebrew/current/bin' >> ~/.bashrc

隠しファイルである.bashrcに追記を行っています。user_nameの部分は自分のユーザ名を入力しましょう。
本当に追記されたか確認したい場合は

tail -n1 .bashrc

とでも打って確認してみましょう。

ターミナルを起動しなおし、node -vで指定したバージョンが出力されればオーケイです。
なお、Node.jsを入れるとnpmもセットで入ります。
npm -vでバージョンを確認することができます。


2017.3.2追記

ターミナルの調子が悪かったのかどうなのか理由は不明ですが、ターミナルを起動しなおすだけではnodeのパス が通らない現象が起きました。
そのときは、source ~/.bashrcとコマンドを打ち、.bashrc自体を読みなおしてやれば、上手くパス が通りました。

ちなみに、自分の環境では.bash_profilesource ~/.bashrcと追記してあります。
.bash_profile を読み込むと.bashrcも読み込まれる設定というわけです。
なので、環境によっては、パスを通すときの.bashrc.bash_profileに読みかえてもらえてもらえれば、と 思います。


参考


vimのカラースキーマをMolokaiにしただけ

Molokaiが結構良いみたいなので

  • Macのターミナルのvimでやっています(Windowsだとおそらくキツイ)

今までデフォルトのカラースキーマで満足していたのですが、ほかの人のvimを見て「いいな」と思い導入することにしました。
続きを見てもいいですが、僕が参考にした以下のサイトを見れば一発でできると思います。(それだけ簡単だった)
ponkiti’s blog VimのカラースキームをMolokaiに変更する

手順

ターミナルを開いて、以下のコマンドを順に実行します。

$ mkdir ~/.vim
$ cd ~/.vim
$ mkdir colors
$ git clone https://github.com/tomasr/molokai
$ mv molokai/colors/molokai.vim ~/.vim/colors/

.vimという隠しディレクトリを作成し、さらにその中にcolorsというディレクトリをつくります。そこに ネットからもってきたmolokaiをぶちこみます。 続いて.vimrcvimで開きます。(なければ作成) ファイルには以下のように追記します。

syntax on
set t_Co=256
colorscheme molokai

おまけ

なんか短くなってしまったのでvim関連で自分が最近驚いたことをメモしておきます。
:e .と入力するとvim内で現在いるディレクトリのエクスプローラが表示されます。地味に 便利。

参考


今さらながら == と === の挙動の違いをチェック

そもそもコレなんて呼ぶ

PHPjavaScriptで、いつも使っているけど、何て言うのか 覚えていますか?
ネット上とかで毎回見ているけど、意外とスルーしていたりします。
正解は

うーん、会話で使うには長いんですよね。普段は、「イコール1コ抜けてるよ」 とか言っていますね。

で、名前のとおり、=== の方が厳しく型をチェックしてくれます。というわけで === の方を使う ことが、PHPjavaScriptでは、特別なケースを除いて常識になっているわけです。
でも、実際にどんな動きをしているか理解しているのか、と言われたら微妙だということに 気づきました。

挙動チェック

上がjavaScript、下がPHPのコードです。

var str = "1";
var num = 1;

console.log( str == num ); // true
console.log( str === num ); // false
<?php
$str = '1';
$num = 1;

var_dump( $str == $num ); // true
var_dump( $str === $num ); // false

== は文字列を数値に変換してから比較を行います。 === は型変換を行うことなく評価を行うので、 javaScriptPHPともにfalseが返ってきていますね。この挙動を見ただけでも === を使うことの 意味が実感できると思います。

次に、Boolean(boolean)型を見てみましょう。
オペランドの片方がBooleanならば、その論理オペランドはtrueならば1に、そしてfalseならば0に変換さます。
=== ならば、もちろん厳密にチェックしてくれるのでfalseが返って来ます。

console.log( true == 1 ); // true
console.log( true === 1 ); // false
console.log( false == 0 ); // true
console.log( false === 0 ); // false
<?php
var_dump( 1 == true ); // true
var_dump( 1 === true ); // false
var_dump( 0 == false ); // true
var_dump( 0 === false ); // false


javaScriptPHPの違い

javaScriptの方は、最後の2行に注目していただければわかると思います。

console.log( undefined == null ); // true
console.log( undefined === null ); // false
console.log( undefined == "" ); // false
console.log( undefined === "" ); // false
console.log( null == "" ); // false
console.log( null === "" ); // false
<?php
var_dump( null == '' ); // true
var_dump( null === '' ); // false

PHPの方はnullが == で比較した場合、trueになっているんですね。この挙動は最新のPHP7で確認しても 変わっていませんでした。
それでも、 === で比較すれば、ちゃんとfalseが返って来てくれます。このことからわかることは...

ちゃんと === を使いましょう、ってことですかね。