nigoblog

技術系会社のCEOブログ~私的編~

ウェブイチをcodeigniterで実装する-第一回-

CodeIgniter徹底入門

CodeIgniter徹底入門


前回のブログレコメンドアルゴリズム超入門 - nigoblogでウェブイチウェブイチ
のβ版を作ったと報告しました。

今回はそのウェブイチをcodeigniterで実装し直すまでを報告します。

  1. codeigniterとは?
  2. codeigniter Assetファイルの置き場
  3. データベースの設定
  4. オートロードの設定
  5. コントローラーの実装
  6. モデルの実装
  7. ビューの実装

以上の流れで説明します。
ちなみに第一回とありますが、もしかして今後連載するかもしれないので一応つけときました。

codeigniterとは?

概要

訳すと「コードに火をつけろ!!」
かっこいいすね(若干違うけど)
簡単にいうとフレームワーク
ただし軽量
一般的にwebのフレームワークというとcakePHPRuby on Railsなんかがイメージにあるかと思いますが、基本それと同じです。
ただし、上の2つと比較してめちゃくちゃ軽い!!
もともとのファイルが少なく、自由度が高いというのが特徴です。
命名規則なんかは厳密ではないのですが、上記2つに習って名付ければあまり不便ではないかと。
というわけで軽いというのが魅力のcodeigniter

ダウンロード

このリンクからダウンロードできます。トップ :: 日本CodeIgniterユーザ会
ここはさらにユーザーズガイドなども乗っておりその充実さも魅力の一つ!
ダウンロードしたファイルを今回はMAMPでテストするのでhtdocs以下にダウンロードしたファイルを置きます。この辺はそれぞれ開発環境があると思うのではしょります。いつか開発環境についても言及したいと思います。
すると次のような構成になります。今回webichiの場合

htdocs/
    webichi/
        application/
        system/
        user_guide/
        user_guide_ja/

主にapplication/ の中身を色々いじっていきます。
他にもありますがとりあえずこれだけ、次はcss, img, jsなどのAssetファイルの置き場についてです。

codeigniter Assetファイルの置き場

css, img, jsはそれぞれこのように配置します

htdocs/
    webichi/
        application/
        css/
        img/
        js/
        system/
        user_guide/
        user_guide_ja/

これだけ!!よく置き場がどこかわからないというので、ポイントです。ビューからアクセスする方法は後に説明します。

データベースの設定

次はデータベースの設定です。まずapplication以下は次のようになります。

application/
    cache/
    config/
    core/
    controllers/
    errors/
    helpers/
    hooks/
    libraries/
    languages/
    logs/
    models/
    views/
    third_party/

色々ありますが、まずはconfigから。
configの中にdatabase.phpがあります。
それは次のようになっています。
config/database.php

<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');

$active_group = 'default';
$active_record = TRUE;

$db['default']['hostname'] = 'localhost';
$db['default']['username'] = '';
$db['default']['password'] = '';
$db['default']['database'] = '';
$db['default']['dbdriver'] = 'mysql';
$db['default']['dbprefix'] = '';
$db['default']['pconnect'] = TRUE;
$db['default']['db_debug'] = TRUE;
$db['default']['cache_on'] = FALSE;
$db['default']['cachedir'] = '';
$db['default']['char_set'] = 'utf8';
$db['default']['dbcollat'] = 'utf8_general_ci';
$db['default']['swap_pre'] = '';
$db['default']['autoinit'] = TRUE;
$db['default']['stricton'] = FALSE;

このファイルの username, password, database を指定することでデータベースに接続ができます。

オートロードの設定

次もconfig以下にあるautoload.phpをみていきます。
config/autoload.php

<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');

$autoload['packages'] = array();

$autoload['libraries'] = array('database');

$autoload['helper'] = array();

$autoload['config'] = array();

$autoload['language'] = array();

$autoload['model'] = array('item_model');

例によってコメントは消しています。まずlibrariesを書き換え、ここにdatabaseとすることでデータベースと接続できます。
オートロードがなければコントローラやモデルでライブラリを使うたびにロードしなければいけませんが、オートロードを使えばいちいちそれをする必要がありません。model のところは後に説明します。

コントローラーの実装

実装の前に簡単にMVCモデルですが、基本的にMVCそれぞれのディレクトリの中には
データベースのテーブルに対応するファイル(ビューならディレクトリ)
を作成します。今回使うデータベースは
items
users
likes
とあるのでMVCそれぞれ一つづつ作成します。今回はとりあえずトップページのみ作成ということでitemsのMVCを作成します。
まずファイル名は
item.php
としました。cakeだと色々怒られそうな名前ですが…
それでは実装ファイルを載せます
contollers/item.php

<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');

class Item extends CI_Controller {
	
	public function index()
	{
		$this->load->model('item_model', 'items');
		$data['items'] = $this->items->get_items();
		$this->load->view('items/index', $data);
	}
}

cakeやrailsをやったことがあれば簡単にわかると思いますが、一応説明します。
itemクラスにそれぞれのビューに対応するメソッドを作成します。今回はトップページだけなのでindex()のみ
最初にモデルを読み込みます。さっきオートロードでやったのにと思いますが、読み込みます。
まずモデルのファイル名、次にそのメソッド内で使う変数名を記述します。
次に配列に代入するようにitem_model内のメソッドget_items()の結果を読み込みます。
最後に対応するviewをロードします。変数をviewメソッドの引数に追加するとそのviewで変数がつかえます。

モデルの実装

次のようになります。
models/item_model.php

<?php

	class Item_model extends CI_Model{
		
		function __construct(){
			parent::__construct();
		}
		
		function get_items(){
			$query = $this->db->order_by('id', 'random');
			$query = $this->db->get('items', 10);
			return $query->result();
		}
	}

モデルクラスを作ります。これもcakeやrailsをやっていればわかると思います。
このモデルを呼び出すと使えるメソッドを書いていきます。
get_items()はテーブルitem内にある要素をランダムに呼び出し、返すというメソッドとなります。(コードを読んで直感的にわかるのもcodeigniterのいいところ)

ビューの実装

これは長くなるので要点だけ説明します。
まずcssなどは

<link rel="stylesheet"  href="../css/bootstrap.css" >

のように呼びます。
次に変数は

<?php print_r($items); ?>

のように呼びます。
つまりコントローラーの引数で配列を渡し、その配列の引数が変数名となります。(文字だとゴチャゴチャ)
これくらいでしょうか。
あとは普通にforeachなども使えます。

以上で説明を終わります。
codeigniterはドキュメントがしっかりしているので習得が用意だと思います。
cakeが重いと思ったら是非試してみては!?

最後に今回作成したファイルはgithubにあげたので是非参考にしてください。
nigohiroki/webichi · GitHub
それでは!

レコメンドアルゴリズム超入門

集合知プログラミング

集合知プログラミング

本日とあるwebアプリケーションのβ版をリリースしたので、そこに使われているメイン技術のレコメンドアルゴリズムを超入門という形で紹介します。

  1. 参考図書
  2. レコメンドアルゴリズムとは?
  3. レコメンドアルゴリズムの概要
  4. webアプリケーションの紹介

参考図書

これはトップにあるようにオライリー集合知プログラミングという本を使用しました。

レコメンドアルゴリズムとは?

Amazonのトップページに行くと、「あなたへのオススメ」のような欄がありますよね。
同様にyoutubeなどもオススメ機能があります。
そのようなコンテンツは全てレコメンド(推薦)アルゴリズムを用いております。
簡単にいうと
「ユーザーの行動からそのユーザーの好みを分析するアルゴリズム」
です。
簡単じゃないですね笑
とにかくオススメ機能などを実装するにあたって欠かせないアルゴリズムのことです。

レコメンドアルゴリズムの概要

簡単にフローを説明します

データセットを用意

ユーザーの行動を分析するにあたって、ある程度そのユーザーが行動をしていないといけません。
そのユーザーの行動(Amazon: 購入、閲覧 . Youtube: 閲覧、コメント など)をデータセットとして保持します。

類似度を計算

分析したら、また別の(全ての)ユーザーの行動を分析します。
そうすると似たような行動をするユーザーが現れます。
そのどれくらい似ているかの指標を類似度として、次のように計算します。

length = sqrt((x1-x2)^2 + (y1-y2)^2 + ... + ... )

今はわからなくても良いのですが、これは平方根の定理(ピタゴラスの定理)をn次元(nは整数)に拡張したものです。
またこの状態だと単なる距離なのでさらに類似度として

similarly = 1 / (1 + length)

とします。つまり距離の逆数をとっています。このsimilarlyの値は0~1の範囲で1に近いほどユーザーの類似度が高いということになります。
逆数を取る理由としては距離のまま計算すると、膨大な数が現れること、
また大きい値の方が近いという指標を得たいということ。
分母で1を足しているのは、lengthの値が0でもうまくいくようにという理由です。

ランキングの計算

類似度から一番近いユーザーを決定します。

nearUser = MAX(similarly)

このような関数(メソッド)を想像してください。

アイテムの推薦

一番近いユーザーが扱った商品を推薦どんどん推薦します。

以上が簡単でしたがレコメンドアルゴリズムの流れです。

webアプリケーションの紹介

というわけで以上の技術を用いたアプリケーションを紹介します。
ウェブイチ
タイトルは「ウェブイチ」
簡単にアプリケーションの説明をします。

  • 10人の女の子の中から1, 2, 3位を決定します。
  • 2, 3位のみチェックし、送信します。
  • すると考えていた1位をコンピュータが計算して当てます。

使い方は以上。
自動で1位を判定するというところに上記のレコメンドアルゴリズムを用いています。


以上簡単でしたが、レコメンドアルゴリズムのお話でした。
ウェブイチの説明は今後もっと掘り下げていきたいと思います。

PHPUnitのインストール for Mac ~追記あり~

前回アジャイルサムライを読んだのですが、
V: アジャイルなプログラミング
の章で

ユニットテスト:動くことがわかる

というのがあったんですね。(p235)
つまり、アジャイル開発ではテストコードを書く必要があるよと。
そんなわけで早速テストコードを書くために、PHPUnitをインストールしました!!
が、これがかなり手こずったので覚書として。

ちなみにPHPUnitですがpearのライブラリの一部で、コードを書くとコマンドラインでテストが出来るという優れもの。
というわけでインストールするまでを以下に示します。
参考はこちら PHPUnitのインストール

pearphpunitを認識させる

次のコマンドを使います。
pear channel-discover pear.phpunit.de
するとpearphpunitという存在を知ることができます。
しかし自分がやった時には ~ failed のような感じのものが出てしまいうまくいきませんでした。
実際にでたエラーはこちら

Discovering channel pear.phpunit.de over http:// failed with message: channel-add: temp_dir is not writable: "/private/tmp/pear/temp" - You can change this location with "pear config-set temp_dir"
Trying to discover channel pear.phpunit.de over https:// instead
Discovery of channel "pear.phpunit.de" failed (channel-add: temp_dir is not writable: "/private/tmp/pear/temp" - You can change this location with "pear config-set temp_dir")

なぜかよくわからなかったのでググってみるとどうやらユーザー権限が違う模様。
それでpearのあるディレクトリで
ls -l
としたところ

drwxr-xr-x 3 root wheel 102 9 5 11:50 pear

のようなものが現れました。つまりroot権限でないとここにいろいろ手を加えられないと。
なのでルート権限で実行してみました。
sudo pear channel-discover pear.phpunit.de
すると
Adding Channel "pear.phpunit.de" succeeded
Discovery of channel "pear.phpunit.de" succeeded
とでたので無事成功。

pearPHPUnitをインストールする。

次は
pear install phpunit/PHPUnit
としてインストールしようとしました。
またしてもエラーが出てしまうので同様に
sudo pear install phpunit/PHPUnit
ルート権限で実行すると

追記

これで実行してください

sudo pear install -a phpunit/PHPUnit

~省略~
install ok: channel://pear.phpunit.de/File_Iterator-1.3.1
install ok: channel://pear.phpunit.de/Text_Template-1.1.1
install ok: channel://pear.phpunit.de/PHP_Timer-1.0.2
install ok: channel://pear.symfony-project.com/YAML-1.0.6
install ok: channel://pear.phpunit.de/PHP_TokenStream-1.1.3
install ok: channel://pear.phpunit.de/PHP_CodeCoverage-1.1.3
install ok: channel://pear.phpunit.de/PHPUnit_MockObject-1.1.1
install ok: channel://pear.phpunit.de/PHPUnit-3.6.12

と出たので無事成功と!!

phpunitのバージョンを確認する

で最後にバージョンの確認ですが、
phpunit
を実行すると次のようなものが現れました。

Warning: require_once(File/Iterator/Autoload.php): failed to open stream: No such file or directory in /usr/lib/php/pear/PHPUnit/Autoload.php on line 45

Fatal error: require_once(): Failed opening required 'File/Iterator/Autoload.php' (include_path='.:') in /usr/lib/php/pear/PHPUnit/Autoload.php on line 45

どうやらAutoload.phpの45行目がなんか変だよということなのですが、そんなこと言われても…という感じでした。
でディレクトリを/usr/lib/php/pear/PHPUnit/に移動してみたらどうだろう?
と思い、
移動して実行したところ、
/usr/lib/php/
の段階でうまくいきました。
原因や理由はさっぱりですけど。

phpunit
を実行したところ。

PHPUnit 3.6.12 by Sebastian Bergmann.

Usage: phpunit [switches] UnitTest [UnitTest.php]
phpunit [switches]


~省略~

となりました。バージョンは3.6.12ですね。


という感じで結構苦戦したので同じエラーが出てしまって出来ないという人は参考に!!

使い心地なんかはいつか書きます。

ではでは

追記

上記の原因ですが、単純にPATHが通ってないだけですね。
インストールのところで

sudo pear install -a phpunit/PHPUnit

とすることでPATHが通り実行出来るようになります。
理由はPATHかどうなのかは不明ですが…

MVCについて

前回ちらっと紹介したMVCについて説明していきます。

MVCとは

  • Model
  • View
  • Controller

のそれぞれの頭文字でアプリケーションの役割を分担することでよりわかりやすくコーディングするためのアプリケーションのこと。
とはいってもこれではよくわからないのでそれぞれ詳しく説明していきます。

Model

主にデーターベースについて。データーベースのテーブル一つにつき一つのモデルがあります。
具体的にはusersテーブルがあったらUser.phpのようなモデルファイルとなります。(とりあえずcakeっぽく説明、テーブルに対し、モデルは単数形)
User.phpに書くことは主に次のこと

  • アソシエーション
  • バリデーション

他にもあるかもしれないですが、今のところ自分が使ってるのはこれくらいです。
アソシエーションはモデル間の関係を表すもの。バリデーションはテーブルのカラムに入れるデータのルールを記載するところ。
アソシエーションには以下のような関係があります。

  • hasOne
  • hasMany belongsTo
  • hasAndBelongsToMany(HABTM)

hasOneは1対1, hasMany belongsToは1対N, HABTMはN対Nの関係を表します。
バリデーションはUserであれば名前は必須情報などのようなルールのこと。

View

主に見た目に関するもの。Controllerから受け取ったデータを出力するなど。
正直あまり説明するようなことはないのですが、処理をControllerに任せる分、エンジニアでないデザイナーの方でも編集できるような形になっています。
cakeではヘルパーが用意されており、フォームやリンクの記述がHtmlで書くのとは少し違います。
フォルダ構成としては
View/
Users/
index.ctp
add.ctp
Posts/
などのようにモデルに対応する形でフォルダ分けされております。さらにファイルは後に説明しますが、コントローラの各メソッドに対応しています。拡張子はhtmlではなくctp(たぶん、Cake TemPlete)をを用います。

Controller

主に処理に関するもの。cakeでアプリケーションを作る際には主にここのコーディングとなります。
命名規則はusersのコントローラであればUsersControllerのように複数系を用います。
ファイルはUsersController.phpのようになり、そこにクラスUsersControllerを作成します。
そのクラス内にメソッドを書く形で処理を書きます。
UsersControllerであれば

  • add() 新規登録
  • mypage() ユーザー情報を読み込む
  • logout() ログアウト

などが考えられます。
そこでそれぞれに対応するような処理を書いていきます。
先程も説明しましたが、基本的には各メソッド一つにつき、一つのViewがありますが、ログアウトなんかはViewがなくても実装できます。


以上簡単でしたがMVCモデルの説明です。
どうやらシンタックスハイライトが使えないみたいなのでコードは載せませんが、いつか対応した時に載せたいと思います。