WebEngine

だらだらと綴る技術系メモ

ComposerでSmartyを入れて遊ぶだけ

Composer

最近のPHPerには必須のツール。PHP系ライブラリをインストールする際、依存関係を標準的に管理してくれる。(ある ライブラリをインストールした際、あのライブラリも要るのかあ、という状況を解決してくれる)

Smarty

PHPのテンプレートエンジン。nodeでいうEJSなどである。

ComposerをMacにインストール

環境はMac OS Sierraでやっていきます。 まず、Composerのインストーラcurlで取得、その後インストーラPHPで実行します。

curl -sS https://getcomposer.org/installer | php

次にcomposer.pharを移動します。

mv composer.phar /usr/local/bin/composer

入れたComposerのバージョンを確認するにはcomposer -Vで調べます。


Smartyを入れる

なんか適当にディレクトリをつくって、その中に潜りましょう。

mkdir smarty_app
cd smarty_app


先にcomposer.jsonを書いてインストールしても良いですが、面倒なのでcomposer requrieというコマンドを 使います。このコマンドを使った場合、composer.jsonは勝手に作成されます。

composer require smarty/smarty


現時点でのsmarty_appの中の構成はこのような感じになっているはずです。

composer.json    composer.lock   vendor

vendorの中を見ると、ちゃんとsmartyが入っています。

必要最小限の構築

次にtemplatesというディレクトリと、templates_cというディレクトリを作成します。
そして、このtemplates_cの権限を変えます。

mkdir templates
mkdir templates_c
chmod 777 templates_c

このtemplates_cというディレクトリは必須です。ここではあんまり良くないですが、777で許可しています。
イメージとしては、templatesというディレクトリに入っているテンプレートが、自動的にコンパイルされて templates_cに入ります。(cはコンパイルのcみたいですね)

使ってみる

index.phpsmarty_app直下につくります。

<?php
require_once 'vendor/autoload.php';

ini_set('date.timezone', 'Asia/Tokyo');
define('MY_TITLE', 'TEST');

$smarty = new Smarty();

// 使うテンプレートが入っているディレクトリを指定
$smarty->setTemplateDir('./templates/');

$smarty->assign('hello', 'Hello, Smarty!!');
$smarty->assign('today', new DateTime());
$smarty->assign('animal', array('rabbit','cat','dog'));

$smarty->display('index.tpl');


つづいて、templates内にhader.tplindex.tplを作成。

header.tpl

<!DOCTYPE html>
<meta charset="utf-8">
<title> {$page_title} </title>


index.tpl

{*
  コメントアウト
*}

{include file='header.tpl' page_title={$smarty.const.MY_TITLE}}

{* 普通の変数 *}
<p>{$hello}

{* メソッド *}
<p>{$today->format('Y/m/d (D)')}

{* 予約変数 *}
<dl>
  <dt>現在のタイムスタンプ
  <dd>{$smarty.now}

  <dt>現在処理中のテンプレートファイル名
  <dd>{$smarty.template}

  <dt>Smarty version
  <dd>{$smarty.version}
<dl>

{* 配列を逆順でループ(step=-1だから) *}
<ul>
{section name=i loop=$animal step=-1}
  <li>{$animal[i]}
{/section}
</ul>


一応smarty_app内の構造を記しておきます。

|--composer.json
|--composer.lock
|--index.php
|--templates
|  |--header.tpl
|  |--index.tpl
|--templates_c
|--vendor

つくったら、PHPのビルトインサーバを立てるなりして、http://localhost/~なんかでアクセスします。
成功していればブラウザ上に、Smartyのバージョンや現在の日付なんかが表示されるはずです。
templates_c内を見ると、コンパイルされたファイルがあるのもわかるはずです。

参考

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で取得できます。なにか行いたい 場合、先に使えそうなモジュールがないか調べるのも手であることを覚えておきましょう。


参考