fuelPHPでアプリケーションを作る前に知っておきたかったこと
はじめに
fuelPHPを使っていたら、あとからあとから、
こんな便利機能あったのかよ!自分で実装しちゃったよ...。
というのが出てきたので、今からfuelPHPを書き始める人のためにここに書いておきます。
といっても全部リファレンスに書いてあることなので、
リファレンスちゃんと読めって話だったのですが。
namespaceや独自のライブラリはbootstrap.phpに記述すれば簡単に増やせる。
bootstrap.phpに登録しさえすれば、自分の思うとおりにパッケージを切り分けられます。
fuelはMVCを基本としていますが、これを使えばドメイン駆動設計したり、
modelにならないようなクラスを置くための場所を作ったりなど、
柔軟に開発できます。
FuelPHPを使って開発する時に最初にやったこと | tech.ewdev.info
論理削除ができる。
通常、モデルはModelクラスを継承して作りますが、
Model_Softを継承してモデルを作り、削除フラグを設定すると論理削除ができます。
リレーションを使った論理削除もできますし、簡単に復元もできます。
論理削除モデル - Orm パッケージ - FuelPHP ドキュメント
一括読み込みと遅延読み込みが選べる
ORMを使ってリレーションのあるレコードを取得するとき、
リレーションの子に当たるレコード情報を一括で取得するか、必要になってから取得するか選ぶことができます。
デフォルトは遅延取得になっています。
はじめに - Relations - Orm Package - FuelPHP ドキュメント
コアの拡張が簡単にできる
fuelPHPではコアを継承して全く同じクラス名でbootstrap.phpに設定を書くと、
あたかも元からそれがcoreのクラスだったかのように動いてくれます。
自分はそれを知らなかったので、herokuで自作coreを使うために、
githubのfuelを自分のリポジトリにfolkしてcomposerに読み込ませるという
アホなことをしました...とほほ。
Core の拡張 - 概要 - FuelPHP ドキュメント
herokuにfuelphpを載せる時の注意
herokuにfuelphpを載せるとき、
fuelphpのpackageやcomposerでインストールしたライブラリ郡が邪魔になります。
ではどうするかと。
結論から言うとfuel/packages とfuel/vendorをgitの管理下から削除してください。
git remove --cached
これで大丈夫です。
以下説明。
composerでインストールしたライブラリ郡はgitのsubmodule扱い?になっており、
そのままherokuにpushすると、submoduleの参照先無いけど?っていうエラーが出ます。
remote: No submodule mapping found in .gitmodules for path 'fuel/vendor/composer/installers'
こんなかんじの。
ではどうするか。
これらのファイルはgitの管理下から外してしまって構いません。
herokuにpushした際にcomposerが実行されると、
composer install が行われ、
Core、Package、Vendorは再構成されます。
fuelPHPをnginx+php-fpmで動かすときの設定
apacheでfuelPHPを動かす時と違って、
nginxをwebサーバーとして使う場合はphp-fpmを利用するのが一般的です。
その際nginxにはmod_rewiteのモジュールが無いので、
自分でパスの書き換えを行わないといけません。
といっても大したことではないです。
nginxの設定ファイルは/etc/nginx/conf.d/以下で基本的な設定はdefault.confに記述します。
<?php location / { try_files $uri $uri/ @handler; } location @handler { rewrite ^ /index.php?/$request_uri; } location ~^/index.php$ { fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; client_max_body_size 100M; }
上の2つはパスの書き換えで、下の設定はphp-fpmの設定です。
【Laravel入門】モデルとリレーション
はじめに
Laravelのリレーションについてメモがてらまとめていきたいと思います。
バックナンバー的なもの。
【Laravel入門】 インストールから起動まで - 人生の恥は書き捨て
【Laravel入門】ルーティング - 人生の恥は書き捨て
【Laravel入門】Bladeテンプレート - 人生の恥は書き捨て
【Laravel入門】データベース接続とマイグレーション - 人生の恥は書き捨て
モデルとリレーション
今回言っているモデルというのはlaravelのeloquent機能の話です。
データベースにArticlesというテーブルがあることを仮定します。
準備
tableはmigarateを使って作ります。
<?php use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Migrations\Migration; class CreateArticleTable extends Migration { /** * Run the migrations. * * @return void */ public function up() { Schema::create('articles', function($table) { $table->increments('id'); $table->string('title', 20); $table->text('contents'); $table->timestamps(); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::dropIfExists('articles'); } }
eloquentモデルの基本操作
次にモデルファイルapp/models/article.phpを作ります。
<?php class Article extends Eloquent{ }
Laravelだと、これだけでもうデータベースへのアクセスができるようになります。
例えば
<?php $articles = Article::all();
で全件取得ができます。
<?php $first_article = Article::find(1);
でid=1のarticleが取得できます。
クエリービルダーのメソッドを使ってより詳細な操作ができます。
<?php $article = Article::where('title', 'article_title')->first();
とすると、titleがarticle_titleであるarticleのうち最初の1件が取得できます。
クエリービルダーのメソッドの詳しい使い方はここに書いてあります。
DB:クエリービルダー
リレーション
articleにはカテゴリーがあって、
一つのカテゴリーに複数のarticleが所属していると考えます。
categoryもmigrateで作ります。
<?php use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Migrations\Migration; class CreateCategoryTable extends Migration { /** * Run the migrations. * * @return void */ public function up() { Schema::create('categories', function($table) { $table->increments('id'); $table->string('cat_name', 20); $table->timestamps(); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::dropIfExists('categories'); } }
次にカテゴリーのモデルを作ります。
<?php class Category extends Eloquent{ }
で、カテゴリーが複数のarticleを持っているので、
カテゴリーから見てarticleはhasManyで、articleから見てカテゴリーはbelongsToです。
それぞれの設定をモデルに書いていきます。
category.php
<?php class Category extends Eloquent{ public function article(){ return $this->hasMany('Article'); } }
article.php
<?php class Article extends Eloquent{ public function category(){ return $this->belongsTo('Category'); } }
これだけです。
Articleから自分の所属しているカテゴリーを取得したいときは、
<?php Article::find(1)->category
のようにして取得します。
おわりに
LaravelのEloquentは思った以上に書くことがなくて簡単でした。
あと、リレーションはCakeとかFuelだと専用の設定みたいなのに書きますが、
Laravelだと普通にメソッドとして書くのがちょっと新鮮でした。
こっちのほうが使いやすい気がします。
Apache Solrをデータインポートハンドラでmysqlと同期する
はじめに
solrのインストールについては以前書きました。
Apache Solrのインストール - 人生の恥は書き捨て
今回は、mysqlのデータをデータインポートハンドラを使ってsolrに取り込みます。
環境
solr 4.9.0
mysql 5.6.19
Apache Solrをデータインポートハンドラでmysqlと同期
ライブラリのインストール
solrはjavaで動いているので、
mysqlサーバーにアクセスするためにmysql-connector-javaを入れます。
cd /usr/local/src wget http://dev.mysql.com/get/Downloads/Connector-J/mysql-connector-java-5.1.31.tar.gz/from/http://cdn.mysql.com/ tar -zxvf index.html mv mysql-connector-java-5.1.31-bin.jar /usr/local/solr/example/lib/mysql-connector-java-5.1.31-bin.jar
パスを通します。
vim /usr/local/solr/example/solr/collection1/conf/solrconfig.xml
<lib dir="../../../contrib/extraction/lib" regex=".*\.jar" /> <lib dir="../../../dist/" regex="solr-cell-\d.*\.jar" /> <lib dir="../../../contrib/clustering/lib/" regex=".*\.jar" /> <lib dir="../../../dist/" regex="solr-clustering-\d.*\.jar" /> <lib dir="../../../contrib/langid/lib/" regex=".*\.jar" /> <lib dir="../../../dist/" regex="solr-langid-\d.*\.jar" /> <lib dir="../../../contrib/velocity/lib" regex=".*\.jar" /> <lib dir="../../../dist/" regex="solr-velocity-\d.*\.jar" /> <!-- Additional Setting --> <lib dir="../../lib/" regex="mysql-connector-java-\d.*\.jar" /> <lib dir="../../../dist/" regex="solr-dataimporthandler-\d.*\.jar" /> <lib dir="../../../contrib/dataimporthandler/lib/" regex=".*\.jar" />
80行目くらいにライブラリの読み込みの記述があるので、
そこにAdditional Setting以下の3行を足します。
これでmysqlと連携できます。
データベースの準備
データベースを用意します。
mysql> DESC member; +-------------+------------------+------+-----+-------------------+-----------------------------+ | Field | Type | Null | Key | Default | Extra | +-------------+------------------+------+-----+-------------------+-----------------------------+ | id | int(11) unsigned | NO | PRI | NULL | auto_increment | | name | varchar(32) | YES | | NULL | | | updated | timestamp | NO | | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP | | catchPhrase | text | YES | | NULL | | +-------------+------------------+------+-----+-------------------+-----------------------------+
中にダミーのデータを入れておきます。
mysql> select * from member; +----+----------------+---------------------+--------------------------------------------+ | id | name | updated | catchPhrase | +----+----------------+---------------------+--------------------------------------------+ | 1 | Honoka Kosaka | 2014-08-07 13:40:51 | ファイトだよ! | | 2 | Umi Sonoda | 2014-08-07 13:41:26 | ラブアローシュート! | | 3 | Kotori Minami | 2014-08-07 13:43:11 | はいちゅんちゅん(・8・) | | 4 | Hanayo Koizumi | 2014-08-07 13:41:41 | だれかたすけてー! | | 5 | Rin Hoshizora | 2014-08-07 13:43:28 | にゃんにゃんにゃ〜ん | | 6 | Maki Nishikino | 2014-08-07 13:41:58 | まきちゃんかわいいかきくけこ | +----+----------------+---------------------+--------------------------------------------+
データインポートの設定
データインポートの設定ファイルを宣言
vim /usr/local/solr/example/solr/collection1/conf/solrconfig.xml
ファイル末尾のの前に
<requestHandler name="/dataimport" class="org.apache.solr.handler.dataimport.DataImportHandler"> <lst name="defaults"> <str name="config">data-config.xml</str> </lst> </requestHandler>
を追加します。
ここで、data-config.xmlにデータインポートの設定を書くよ、と宣言しています。
schema.xml
solrにどのようにデータを保存してインデックスをつけていくかを設定します。
デフォルトで設定がたくさん書いてあるので、それを使ってもいいです。
自分はこのようにしました。
<?xml version="1.0" encoding="UTF-8" ?> <schema name="lovelive" version="1.4"> <field name="_version_" type="long" indexed="true" stored="true"/> <types> <fieldType name="long" class="solr.LongField" omitNorms="true" /> <fieldType name="string" class="solr.StrField" sortMissingLast="true" omitNorms="true" /> <fieldType name="timestamp" class="solr.TrieDateField" /> <fieldType name="text_cjk" class="solr.TextField"> <analyzer class="org.apache.lucene.analysis.cjk.CJKAnalyzer" /> </fieldType> <fieldType name="text_ja" class="solr.TextField"> <analyzer> <tokenizer class="solr.JapaneseTokenizerFactory" mode="search"/> <filter class="solr.JapaneseBaseFormFilterFactory"/> <filter class="solr.JapanesePartOfSpeechStopFilterFactory" tags="lang/stoptags_ja.txt" enablePositionIncrements="true"/> <filter class="solr.CJKWidthFilterFactory"/> <filter class="solr.StopFilterFactory" ignoreCase="true" words="lang/stopwords_ja.txt" enablePositionIncrements="true" /> <filter class="solr.JapaneseKatakanaStemFilterFactory" minimumLength="4"/> <filter class="solr.LowerCaseFilterFactory"/> </analyzer> </fieldType> </types> <fields> <field name="id" type="long" indexed="true" stored="true" required="true" /> <field name="name" type="text_ja" indexed="true" stored="true" /> <field name="catchPhrase" type="text_ja" indexed="true" stored="true" /> </fields> <uniqueKey>id</uniqueKey> <defaultSearchField>name</defaultSearchField> <solrQueryParser defaultOperator="AND" /> </schema>
フィールドにはtypesで定義した型を設定します。
フィールドには更に、indexed、stored、などの属性が設定できます。
indexed: trueにすると、インデックス、ソートなどができる。
stored: 値をsolrに保存する。
などなど詳しくはここに英語ですが載っています。
SchemaXml - Solr Wiki
日本語の形態素解析はkuromojiを使用しています。
data-config.xml
データをインポートするときのmysqlの設定を書いていきます。
<dataConfig> <dataSource name="ratings" driver="com.mysql.jdbc.Driver" url="jdbc:mysql://127.0.0.1:3306/lovelive" user="ユーザー名" password="パスワード" /> <document> <entity name="member" query="select * from members" deltaQuery="select id from members where created >= '${dataimporter.last_index_time}'" deltaImportQuery="select * from members where id=${dataimporter.delta.id}"> <field column="id" name="id" /> <field column="name" name="name" /> <field column="catchPhrase" name="catchPhrase" /> </entity> </document> </dataConfig>
queryではfull-importする際のsqlを設定しています。
dataQueryとdataImportQueryではdelta-importする際のsqlを設定しています。
あとはsolrのメニューからcoreを選んで
dataImportをExcuteすればmysqlのデータをsolrにインポートできます。
【Laravel入門】データベース接続とマイグレーション
はじめに
Laravelの初歩的なところについて、
何回かに分けてメモを書いています。
【Laravel入門】 インストールから起動まで - 人生の恥は書き捨て
【Laravel入門】ルーティング - 人生の恥は書き捨て
【Laravel入門】Bladeテンプレート - 人生の恥は書き捨て
マイグレーションとは
マイグレーション(migration)はデータベース構成のバージョン管理ツールのようなものです。
マイグレーションを使うことで、
- マイグレーションスクリプトを書いておけば、全く同じ構成のデータベースを作ることができる。
- 設定を追加するときには、スクリプトを書き足してmigrateすれば簡単に設定を追加。
- rollbackで新しい設定の追加前にもどせる。
- 一つのスクリプトでmysqlだけでなくsqliteや他のDBの設定も可能。
といったことができます。
今回はユーザーテーブルを作ってみることにします。
database接続の設定
app/config/database.phpに接続の設定が書いてあります。
connectionsの部分のdatabase名やuser名、passwordなどを適切に設定してください。
マイグレーションファイルの作成
artisanコマンドが使える場所で、
php artisan migrate:make CreateUserTable
を実行します。CreateUserTableの部分はお好きな様に。
すると2014_08_03_132022_CreateUserTable.phpというような、
作成日時+指定した名前.phpのファイルが
app/database/migration/以下に作成されます。
このファイルにデータベースの設定内容を書いていきます。
ファイルを開くと
<?php use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Migrations\Migration; class CreateUserTable extends Migration { /** * Run the migrations. * * @return void */ public function up() { // } /** * Reverse the migrations. * * @return void */ public function down() { // } }
こんな感じになっていると思います。
upの部分には新しく追加したい操作を、
downのところにはrollbackする時の操作を書いていきます。
テーブル作成の操作を書くとこんな感じ。
<?php use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Migrations\Migration; class CreateUserTable extends Migration { /** * Run the migrations. * * @return void */ public function up() { Schema::create('users', function($table) { $table->increments('id'); $table->string('username', 20); $table->string('password', 64); $table->timestamps(); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::dropIfExists('users'); } }
upにはusersテーブルを作るように、downにはテーブルを消すように書いてあります。
書き終わったら。migrationを実行します。
php artisan migrate
実行するか確認されるのでEnterしましょう。
するとデータベース内にusersテーブルが作成されます。
mysql> desc users; +------------+------------------+------+-----+---------------------+----------------+ | Field | Type | Null | Key | Default | Extra | +------------+------------------+------+-----+---------------------+----------------+ | id | int(10) unsigned | NO | PRI | NULL | auto_increment | | username | varchar(20) | NO | | NULL | | | password | varchar(64) | NO | | NULL | | | created_at | timestamp | NO | | 0000-00-00 00:00:00 | | | updated_at | timestamp | NO | | 0000-00-00 00:00:00 | | +------------+------------------+------+-----+---------------------+----------------+
ここで、認証用のremember_tokenカラムを追加したいと思います。
tableの作成と同様に、
php artisan migrate:make ModifyUserTable
として、設定追加用のファイルを作ります。
<?php use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Migrations\Migration; class ModifyUserTable extends Migration { /** * Run the migrations. * * @return void */ public function up() { Schema::table('users', function($table) { $table->string('remember_token', 100); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::table('users', function($table) { $table->dropColumn('remember_token'); }); } }
そして
php artisan migrate
すると
mysql> desc users; +----------------+------------------+------+-----+---------------------+----------------+ | Field | Type | Null | Key | Default | Extra | +----------------+------------------+------+-----+---------------------+----------------+ | id | int(10) unsigned | NO | PRI | NULL | auto_increment | | username | varchar(20) | NO | | NULL | | | password | varchar(64) | NO | | NULL | | | created_at | timestamp | NO | | 0000-00-00 00:00:00 | | | updated_at | timestamp | NO | | 0000-00-00 00:00:00 | | | remember_token | varchar(100) | NO | | NULL | | +----------------+------------------+------+-----+---------------------+----------------+ 6 rows in set (0.00 sec)
という風にカラムが追加できます。
更に、
php artisan migrate:rollback
とするとremember_tokenカラムを追加する前に戻すことができます。
rollbackする際に class not foundのエラーが出ることがあります(僕は出ました)。
この際は composer dump-autoload として、ファイルを読み込み直すと正しく実行できます。
Laravel + Twitter-l4でTwitter連携
はじめに
LaravelでTwitterApiを利用してみようと思いまして、
Laravel便利だし、きっとLaravel用のTwitterApiのライブラリもあるだろ、
と思って探したらTwitter-l4というのがあったので使ってみました。
https://github.com/thujohn/twitter-l4
Laravelの導入は以下を参考にどうぞ
【Laravel入門】 インストールから起動まで - 人生の恥は書き捨て
導入
インストール
composerを利用して、ライブラリをインストールします。
composer.jsonのrequierに "thujohn/twitter": "dev-master" を追加します。
"require": { "laravel/framework": "4.2.*", "thujohn/twitter": "dev-master" },
そしてコンソールでcomposer update します。
自分の場合はcomposer.pharをcomposerにリネームしてグローバルに置いているので,
composer update ですが、そうじゃない人は php composer.phar update ですかね。
あとかなり時間かかる(5分以上)ことがあって、
しかもその間コンソールに何も出ないので、おかしいかな?と疑いますが、
正常に動いていると思うので、気長に待ちましょう。
逆にエラーのときはすぐにエラーが表示されます。
次にLaravelからライブラリを読み込ませます。
app/config/app.phpを編集します。
providers の部分に 'Thujohn\Twitter\TwitterServiceProvider', を追加します。
'providers' => array( 'Illuminate\Foundation\Providers\ArtisanServiceProvider', 'Illuminate\Auth\AuthServiceProvider', . . <中略> . . 'Illuminate\Workbench\WorkbenchServiceProvider', 'Thujohn\Twitter\TwitterServiceProvider', ),
aliasesの部分に 'Twitter' => 'Thujohn\Twitter\TwitterFacade', を追加します。
'aliases' => array( 'App' => 'Illuminate\Support\Facades\App', 'Artisan' => 'Illuminate\Support\Facades\Artisan', . . <中略> . . 'View' => 'Illuminate\Support\Facades\View', 'Twitter' => 'Thujohn\Twitter\TwitterFacade', ),
設定
Laravel内に自分のTwitter アプリケーションの設定を書きます。
Twitterアプリはhttps://apps.twitter.com/で作ります。
作ったアプリのkeyなどをLaravelに設定します。
まず、設定ファイルの作成です。
コンソールで php artisan config:publish thujohn/twitter を実行します。
すると app/config/packages/thujohn以下に設定ファイルができます。
app/config/thujohn/twitter/config.php
<?php // You can find the keys here : https://dev.twitter.com/ return array( 'API_URL' => 'api.twitter.com', 'API_VERSION' => '1.1', 'USE_SSL' => true, 'CONSUMER_KEY' => '', 'CONSUMER_SECRET' => '', 'ACCESS_TOKEN' => '', 'ACCESS_TOKEN_SECRET' => '', );
ここに作ったアプリの情報をそれぞれ入力してください。
これで導入は終わりです。
使ってみる
では設定が終わったので早速使ってみましょう。
app/routes.phpに書いていきます。
最近のツイートの取得
<?php Route::get('/', function() { return Twitter::getUserTimeline(array('screen_name' => 'アカウントのスクリーンネーム', 'count' => 20, 'format' => 'json')); });
これでスクリーンネームを指定したアカウントの最新ツイート20件が取得できます。
ちなみに、formatはobject、json、arrayの3種類から選択出来て、defaultだとobjectになっています。
メンションの取得
<?php Route::get('/', function() { return Twitter::getMentionsTimeline(array('count' => 20, 'format' => 'json')); });
参考サイト
Twitter-l4
https://github.com/thujohn/twitter-l4
TwitterApiのクエリ
http://dx.24-7.co.jp/twitterapi1-1-rest-api/