Laravel で OAuth ログインをやる
自作webサイトにて、TwitterやFacebookのアカウントでログインする機能を付ける方法
手っ取り早いのが one-auth を使う。けど、ドキュメントがちょっとわかりにくくて、結局はよく知らん人が Youtube にアップロードしたTutorial 動画 http://www.youtube.com/watch?v=xlUFiZhwFiE を見た。
インストール
インストールは簡単。トップディレクトリにて下記のコマンド
$ php artisan bundle:install oneauth $ php artisan migrate
次に oneauth bundle を application/bundles.php へ使うと宣言。とりあえず初期状態から始めたらこんな感じになるはず。
<?php return array( 'docs' => array('handles' => 'docs'), 'oneauth' => array('auto' => true), );
使用例 〜サービスのID などを設定。
各サービス種設定をします。必要最低限でいい。
bundles/oneauth/config/api.php
<?php return array( 'facebook' => array( 'id' => '', // Application ID 'secret' => '', // Secret 'scope' => 'email', // Scope, Email情報を取るとかそんなの ), 'twitter' => array( 'key' => '', // Consumer key 'secret' => '', // Consumer Secret ), // ... その他もろもろ );
callback などそこら辺のURLを設定
<?php return array( 'registration' => 'user/social_register', 'login' => 'user/social_login', 'callback' => 'connect/callback', 'registered' => '/', 'logged_in' => '/', );
この場合だと、
1. 初期登録は http://localhost/index.php/user/social_register
2. ログインは http://localhost/index.php/user/social_login
3. 各サービスからリターンされてきた時に受け取るURL http://localhost/index.php/connect/callback
になりますよ。そんなわけで、Twitter などで使用する場合、Callback URL は http://
使用例 〜 データベースのスキーマなど
こんな感じ。ここで重要なのは、provider_name, social_uid の2つが必須
CREATE TABLE `provider` ( `id` int(11) unsigned NOT NULL AUTO_INCREMENT, `provider_name` varchar(10) NOT NULL DEFAULT '', `social_uid` bigint(11) NOT NULL, `created_at` datetime NOT NULL, `updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`id`), KEY `provider_social_uid_idx` (`social_uid`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
使用例 〜 ユーザ側を作成
application/routes.php に下記の一行を頭のほうに追加。意味はわかるよね…
<?php Route::controller(Controller::detect());
魔法のコントローラファイルを作成。よくわからんけど、callbackの時に使うっぽい
application/controller/connect.php
<?php class Connect_Controller extends OneAuth\Auth\Controller {}
リダイレクトされてきて、認証などが成功した時にする処理を書きますよっと。
application/controller/user.php
<?php class User_Controller extends OneAuth\Auth\Controller { public function action_term () { return View::make("user.term"); } public function action_social_login() { $user_data = Session::get('oneauth'); // ユーザデータ取得 $provider = Provider::where_provider_name($user_data['provider']) ->where_social_uid($user_data["info"]["uid"])->first(); // 削除 Session::forget('user_data'); // ログインできたかで移動先変更 if (!is_null($provider)) { Auth::login($provider->id, true); return Redirect::to('user/terms'); } return Redirect::to('/'); } public function action_social_register () { $user_data = Session::get("oneauth"); // ユーザデータ取得 $provider = Provider::where_provider_name($user_data['provider']) ->where_social_uid($user_data["info"]["uid"])->first(); if (!is_null($provider)) { Auth::login($provider->id, true); return Redirect::to('user/terms'); } $provider = new Provider; $provider->social_uid = $user_data["info"]["uid"]; $provider->name = $user_data["provider"]; // プロバイダー情報を保存 $provider->save(); Auth::login($provider->id, true); // 削除 Session::forget('user_data'); return Redirect::to('user/terms')->with( 'success', 'welcome! Thank you to join the slide :)'); } }
後はテンプレート
「Connect to Twitter」とかリンクはこんな感じのタグを埋め込んで
<div>{{ HTML::link('connect/session/twitter', 'Login with Twitter', array('class' => "btn")) }}</div> <div>{{ HTML::link('connect/session/facebook', 'Login with Facebook', array('class' => "btn")) }}</div>
やればよし。
ログインの後は、 /user/term に飛ぶのでその簡単なテンプレを用意してやればヨロシ。
application/view/user/term.blade.php
<html> <head><title>Welcome!</title></head> <body>Welcome :) </body> </html>
Laravel のメモ書き
メモ書き Laravel PHP
1. 基本的にMVC
2. 少しいじったけど、突貫物から中規模物に向いてる感じっぽい
3. /controller/action/arg1/arg2 とかできるけど、ルータで自分で独自のを仕向ける事が前提、最悪ルータに無名関数でアクションを書くことも出来るのがミソ。
4. routes.php には、配列などに納めて書くのではなく、ベタ書き。
routes.php の感じ
<?php Route::get('/', function() { return View::make('home.index'); });
ルート(/)アクセスは、applications/views/home/index.blade.php を見る。home.index でそういう意味になるっぽい
<?php Route::get('t/(:any?)', array('uses' => 'item@top'));
applications/controllers/item.php にある Item_Controller の action_top を呼び出す。
呼び出された item.php は View のインスタンスを返したらいいっぽい。
<?php /* applications/controllers/item.php */ class Item_Controller extends Base_Controller { public function action_top(){ $query = Item::where("name", "=", URI::segment(2)); if ((int)($query->count()) === 0) return Response::error('404'); $books = $query->get(); // name にはpath_info を、items にはDBにある情報を Item/top.blade.php に渡す $result = View::make('Item.top') ->with("name", URI::segment(2)) ->with("items", $items); return $result; } }
Item クラスは applications/models/Item.php にある。これでDBの情報取れる。楽。対多など関連性を持たせるには、関数作って、中で return $this->belong_to("hoge"); とかやるっぽい。
<?php /* applications/models/Item.php */ class Item extends Eloquent { public static $table = 'items'; }
テンプレートタグは blade と言われているのを使うっぽい。独自+PHPを実行する、みたいな?
erl_crash.dump
なんか久しぶり(三ヶ月ぶり)にいじってたら、こんな(erl_crash.dump)ファイルが出来てもうた。
どう解析するんだコレと思って調べたら、ここに載ってた
引用
Hi - Having problems with Rabbitmq starting for the first time. It uses Erlang which crashes on startup and creates the erl_crash.dump file. I'm thinking it could be permissions problems but would like to check this file out as I have checked everything I can think of. Dies running as root as well as user. I read that you can use Erlang Enterprize to read the dump file - is there a utility that I can use to do this? Thanks for any help!
レス
$ erl ... 1> webtool:start().
との事なので、erl_crash.dump が出来たディレクトリでコマンドを実行。
あとはブラウザで localhost:8890 とURLに打ち込んで開いたら分かります
てなわけで個人的なメモ書き
進めるとこんなページが出るので、CrashDumpViewerに✔
上にCrashDumpViewerが出るのでそのページを開いて入力フォームが出てくるのでファイル名(erl_crash.dump)を入れてokを押したらdump情報出てくるのでどうにかなりますよっと。
まぁそんな感じ
PHP のSJIS
増永 玲 さんが、おー、となるライブラリを作ってはって、確かにたまに知りたいけど見なかったことにしてる所だなぁ、と思った。と同時に別のことでちょっと気になったこと。
玲さんが作られたライブラリとは全く関係ありませんよっと。そんで眠たいので雑。
ややこしいことに PHP でサポートされる文字エンコーディングにはエイリアスがあって SJIS の場合は Shift_JIS, SHIFT-JIS, x-sjis と それぞれの大文字小文字違いも同じ扱いなので そのへんを isSjis() というメソッドのあたりで処理してます。
の x-sjis と SHIFT-JIS と Shift_JIS の扱いがそれぞれ大文字小文字違いも同じ扱いってのが少し気になって、Pythonでも CP932
と shift_jisx0213
とか微妙な差はあったはずよなぁ、と思ったのです。で、実際 Shift_JIS と SHIFT-JIS はどやつを見てるのかしらと気になるわけでしす。
で、こーいうのはドキュメントよりソース見たほうが速いっつー事で見て行ったら、libmbflってのに行き着くわけで、さぁどうなってるかな、と。
とりあえず PHP から見える、対応しているエンコード一覧はこんな感じ。
php-shell
php > print_r(mb_list_encodings());
Array
(
[0] => pass
[1] => auto
[2] => wchar
...
[30] => SJIS
[31] => eucJP-win
[32] => SJIS-win
[33] => CP932
[35] => JIS
[36] => ISO-2022-JP
[37] => ISO-2022-JP-MS
[38] => Windows-1252
[39] => Windows-1254
[40] => ISO-8859-1
ではでは、ソース見学。ざっと見たところ「mbfl_name2encoding」っていう関数がエンコード名解決をしている気配。
サンプルとして、mb_convert_encoding の実態
php-src/ext/mbstirng/mbstring.c
2948 MBSTRING_API char * php_mb_convert_encoding(const char *input, size_t length, const char *_to_encoding, const char *_from_encodings, si ze_t *output_len TSRMLS_DC)
...
2963 /* new encoding */
2964 if (_to_encoding && strlen(_to_encoding)) {
2965 to_encoding = mbfl_name2encoding(_to_encoding);
2966 if (!to_encoding) {
2967 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown encoding \"%s\"", _to_encoding);
2968 return NULL;
2969 }
2970 } else {
2971 to_encoding = MBSTRG(current_internal_encoding);
2972 }
で、だ、「mbfl_name2encoding」はというと、
php-src/ext/mbstirng/libmbfl/mbfl/mbfl_encoding.c
133 static const mbfl_encoding *mbfl_encoding_ptr_list = {
134 &mbfl_encoding_pass,
135 &mbfl_encoding_auto,
136 &mbfl_encoding_wchar,
137 &mbfl_encoding_byte2be,
138 &mbfl_encoding_byte2le,
...
167 &mbfl_encoding_sjis_open,
168 &mbfl_encoding_sjis_docomo,
169 &mbfl_encoding_sjis_kddi,
170 &mbfl_encoding_sjis_sb,
171 &mbfl_encoding_sjis_mac,
172 &mbfl_encoding_sjis2004,
173 &mbfl_encoding_utf8_docomo,
174 &mbfl_encoding_utf8_kddi_a,
175 &mbfl_encoding_utf8_kddi_b,
176 &mbfl_encoding_utf8_sb,
177 &mbfl_encoding_cp932,
178 &mbfl_encoding_cp51932,
179 &mbfl_encoding_jis,
180 &mbfl_encoding_2022jp,
...
210 &mbfl_encoding_koi8r,
211 &mbfl_encoding_koi8u,
212 &mbfl_encoding_armscii8,
213 &mbfl_encoding_cp850,
214 &mbfl_encoding_jis_ms,
215 &mbfl_encoding_2022jp_2004,
216 &mbfl_encoding_2022jp_kddi,
217 &mbfl_encoding_cp50220,
218 &mbfl_encoding_cp50220raw,
219 &mbfl_encoding_cp50221,
220 &mbfl_encoding_cp50222,
221 NULL
222 };
...
226 mbfl_name2encoding(const char *name)
227 {
228 const mbfl_encoding *encoding;
229 int i, j;
230
231 if (name == NULL) {
232 return NULL;
233 }
234
235 i = 0;
236 while ((encoding = mbfl_encoding_ptr_list[i++]) != NULL){
237 if (strcasecmp(encoding->name, name) == 0) {
238 return encoding;
239 }
240 }
241
242 /* serch MIME charset name */
243 i = 0;
244 while ((encoding = mbfl_encoding_ptr_list[i++]) != NULL) {
245 if (encoding->mime_name != NULL) {
246 if (strcasecmp(encoding->mime_name, name) == 0) {
247 return encoding;
248 }
249 }
250 }
251
252 /* serch aliases */
253 i = 0;
254 while ((encoding = mbfl_encoding_ptr_list[i++]) != NULL) {
255 if (encoding->aliases != NULL) {
256 j = 0;
257 while ((*encoding->aliases)[j] != NULL) {
258 if (strcasecmp((*encoding->aliases)[j], name) == 0) {
259 return encoding;
260 }
261 j++;
262 }
263 }
264 }
265
266 return NULL;
267 }
長ったらしいけど仕方ない。
さてさて、ここで比較されているのは「mbfl_encoding_ptr_list」の値。比較には「strcasecmp」関数使われているので、大文字小文字は関係なしになってますね。これで疑問一つ解消。 では「mbfl_encoding_ptr_list」とはというと、上でconstで定期されてますねっと。こやつ、殆ど PHPの「mb_list_encodings」関数の返り値と似てます。
で、だ、この「mbfl_encoding_ptr_list」の中にある構造体は「mbfl_encoding」という構造体らしく、こやつの要素はこんな感じ。
php-src/ext/mbstirng/libmbfl/mbfl/mbfl_encoding.h
134 typedef struct _mbfl_encoding {
135 enum mbfl_no_encoding no_encoding;
136 const char *name;
137 const char *mime_name;
138 const char *(*aliases);
139 const unsigned char *mblen_table;
140 unsigned int flag;
141 } mbfl_encoding;
flagっつーのが何なのかわからないけど、まぁ大体わかりますよね?nameが実際名、aliases がエイリアス名、mime_name が通変的な名前?
で、実際にはこんな感じで使われてる。
php-src/ext/mbstirng/libmbfl/filters/mbfilter_cp932.c
61 static const char *mbfl_encoding_cp932_aliases = {"MS932", "Windows-31J", "MS_Kanji", NULL};
62
63 const mbfl_encoding mbfl_encoding_cp932 = {
64 mbfl_no_encoding_cp932,
65 "CP932",
66 "Shift_JIS",
67 (const char *(*))&mbfl_encoding_cp932_aliases,
68 mblen_table_sjis,
69 MBFL_ENCTYPE_MBCS | MBFL_ENCTYPE_GL_UNSAFE
70 };
C の構造体を見るのがかなり久しぶりで、こういう書き方だっけな、という状態ですが、まぁ、コレだと「name->CP932」「mime_name->Shift_JIS」「aliases -> {"MS932", "Windows-31J", "MS_Kanji", NULL}」
で、だ、「SJIS, Shift_JIS, SHIFT-JIS, x-sjis」それぞれ違いはと、いう話なんですが、sjisの処理系は5つに分かれておりまして、mbfilter_(cp932|sjis|sjis_2004|sjis_mac|sjis_mobile|sjis_open) となっておりますよっと。
それぞれ必要部分だけ書きだしてみるとこんな感じ
php-src/ext/mbstirng/libmbfl/filters/mbfilter_cp932.c
61 static const char *mbfl_encoding_cp932_aliases = {"MS932", "Windows-31J", "MS_Kanji", NULL};
62
63 const mbfl_encoding mbfl_encoding_cp932 = {
64 mbfl_no_encoding_cp932,
65 "CP932",
66 "Shift_JIS",
67 (const char *(*))&mbfl_encoding_cp932_aliases,
68 mblen_table_sjis,
69 MBFL_ENCTYPE_MBCS | MBFL_ENCTYPE_GL_UNSAFE
70 };
php-src/ext/mbstirng/libmbfl/filters/mbfilter_sjis.c
64 static const char *mbfl_encoding_sjis_aliases = {"x-sjis", "SHIFT-JIS", NULL};
65
66 const mbfl_encoding mbfl_encoding_sjis = {
67 mbfl_no_encoding_sjis,
68 "SJIS",
69 "Shift_JIS",
70 (const char *(*))&mbfl_encoding_sjis_aliases,
71 mblen_table_sjis,
72 MBFL_ENCTYPE_MBCS | MBFL_ENCTYPE_GL_UNSAFE
73 };
php-src/ext/mbstirng/libmbfl/filters/mbfilter_sjis_2004.c
48 static const char *mbfl_encoding_sjis2004_aliases = {"SJIS2004","Shift_JIS-2004", NULL};
49
50 const mbfl_encoding mbfl_encoding_sjis2004 = {
51 mbfl_no_encoding_sjis2004,
52 "SJIS-2004",
53 "Shift_JIS",
54 (const char *(*))&mbfl_encoding_sjis2004_aliases,
55 mblen_table_sjis,
56 MBFL_ENCTYPE_MBCS | MBFL_ENCTYPE_GL_UNSAFE
57 };
php-src/ext/mbstirng/libmbfl/filters/mbfilter_sjis_mac.c
47 static const char *mbfl_encoding_sjis_mac_aliases = {"MacJapanese", "x-Mac-Japanese", NULL};
48
49 const mbfl_encoding mbfl_encoding_sjis_mac = {
50 mbfl_no_encoding_sjis_mac,
51 "SJIS-mac",
52 "Shift_JIS",
53 (const char *(*))&mbfl_encoding_sjis_mac_aliases,
54 mblen_table_sjis,
55 MBFL_ENCTYPE_MBCS | MBFL_ENCTYPE_GL_UNSAFE
56 };
php-src/ext/mbstirng/libmbfl/filters/mbfilter_sjis_mobile.c
47 static const char *mbfl_encoding_sjis_docomo_aliases = {"SJIS-DOCOMO", "shift_jis-imode", "x-sjis-emoji-docomo", NULL};
48 static const char *mbfl_encoding_sjis_kddi_aliases = {"SJIS-KDDI", "shift_jis-kddi", "x-sjis-emoji-kddi", NULL};
49 static const char *mbfl_encoding_sjis_sb_aliases = {"SJIS-SOFTBANK", "shift_jis-softbank", "x-sjis-emoji-softbank", NULL};
50
51 const mbfl_encoding mbfl_encoding_sjis_docomo = {
52 mbfl_no_encoding_sjis_docomo,
53 "SJIS-Mobile#DOCOMO",
54 "Shift_JIS",
55 (const char *(*))&mbfl_encoding_sjis_docomo_aliases,
56 mblen_table_sjis,
57 MBFL_ENCTYPE_MBCS | MBFL_ENCTYPE_GL_UNSAFE
58 };
59
60 const mbfl_encoding mbfl_encoding_sjis_kddi = {
61 mbfl_no_encoding_sjis_kddi,
62 "SJIS-Mobile#KDDI",
63 "Shift_JIS",
64 (const char *(*))&mbfl_encoding_sjis_kddi_aliases,
65 mblen_table_sjis,
66 MBFL_ENCTYPE_MBCS | MBFL_ENCTYPE_GL_UNSAFE
67 };
68
69 const mbfl_encoding mbfl_encoding_sjis_sb = {
70 mbfl_no_encoding_sjis_sb,
71 "SJIS-Mobile#SOFTBANK",
72 "Shift_JIS",
73 (const char *(*))&mbfl_encoding_sjis_sb_aliases,
74 mblen_table_sjis,
75 MBFL_ENCTYPE_MBCS | MBFL_ENCTYPE_GL_UNSAFE
76 };
php-src/ext/mbstirng/libmbfl/filters/mbfilter_sjis_open.c
61 static const char *mbfl_encoding_sjis_open_aliases = {"SJIS-open", "SJIS-ms", NULL};
62
63 const mbfl_encoding mbfl_encoding_sjis_open = {
64 mbfl_no_encoding_sjis_open,
65 "SJIS-win",
66 "Shift_JIS",
67 (const char *(*))&mbfl_encoding_sjis_open_aliases,
68 mblen_table_sjis,
69 MBFL_ENCTYPE_MBCS | MBFL_ENCTYPE_GL_UNSAFE
70 };
長ったらしいです。ですがフォーマットが統一されているので、いいですよね?
さてさて、「mbfl_name2encoding」の処理を見ると、
- 「mbfl_encoding_ptr_list」を一から見て、中の name を見て比較、ありゃ返す
- 「mbfl_encoding_ptr_list」を一から見て、中の MIME を見て比較、ありゃ返す
- 「mbfl_encoding_ptr_list」を一から見て、中のエイリアスを見て比較、ありゃ返す。
- 見つからん時は NULL
で、「mbfl_encoding_ptr_list」はというと、上記に書いた感じで順番に並んでます。
Shift-jis 周りだけを見るとこんな感じ
php-src/ext/mbstirng/libmbfl/mbfl/mbfl_encoding.c
164 &mbfl_encoding_sjis,
...
167 &mbfl_encoding_sjis_open,
168 &mbfl_encoding_sjis_docomo,
169 &mbfl_encoding_sjis_kddi,
170 &mbfl_encoding_sjis_sb,
171 &mbfl_encoding_sjis_mac,
172 &mbfl_encoding_sjis2004,
...
177 &mbfl_encoding_cp932,
そんなわけで
- 「Shift-JIS」と銘打った場合、「mbfl_name2encoding」の処理手順から見て、エイリアスに「SHIFT-JIS」がある「SJIS」(mbfl_encoding_sjis)と等価になります。
- 「Shift_JIS」と銘打った場合、「mbfl_name2encoding」の処理手順から見て、MIMEに当てはまるので「SJIS」と等価になります。
- 「x-sjis」と銘打った(ry
そんな訳で、パフォーマンスの差はありますが、「SJIS, Shift_JIS, SHIFT-JIS, x-sjis」は変換する文字コードの種類は同じです。
ちょっとでもパフォーマンスが気になる、という人は「Shift-JIS」や「Shift_JIS」や「x-sjis」を「SJIS」に変換して投げてやればいいと思うんです。
そんじゃーね
XDebug でパフォーマンスチューニング
タイトル通り。
ちなみに私はMAMP使ってますけど、多分他のLAMPとかでも行ける。
MAMP で XDebug を使う方法は、 http://geek.michaelgrace.org/2011/08/xdebug-cachegrind-and-mamp-on-mac-osx/ とか見て。 てか書きたいことは全部ここに書いてる。
MAMP のバージョンは2.0.1。
/Applications/MAMP/bin/php/php5.4.4/conf/php.ini を編集
ファイルの一番下に下記の設定を追加する。 もしくは [Xdebug]という所があれば、そこにある値を下記の設定にならって変更。
[xdebug] zend_extension="/Applications/MAMP/bin/php/php5.4.4/lib/php/extensions/no-debug-non-zts-20100525/xdebug.so" xdebug.profiler_enable = 1 ;xdebug.profiler_output_name = cachegrind.out.%t-%s xdebug.profiler_output_dir = "/tmp"
MAMP リスタート
MAMP にアクセスする度に、 /tmp に cachegrind.out~ というファイルが作成されます。作成されていればok。
この cachegrind.out~ ってのはXdebugがプロファイリングした結果のファイルです。生で見たら何となく分かるような状態のフォーマットですが、人が見て理解するには程遠いですので https://github.com/jokkedk/webgrind を入れてちょっとだけでも見やすくします。
webgrind を Githubから任意のディレクトリに落としてきて、MAMPの設定でそこへ向けさせる
別にMAMPでなくてもいいのですが、むしろMAMP以外のほうがいいのですが、割と面倒なので。
あ、でも、MAMP Pro だと Virtual Hostの設定で、切り替えができるみたいだよ☆
(コマンドラインで一発で変えられるのを作ってもうたがな…)
アクセス
アクセスすればプロファイル結果が見れて、どこが重いかが見れます。
まぁ、大体はキャッシュせずに無駄にDBへアクセスしてたりするのが原因だったりするんですがねHAHAHA……orz
参考
Erlang で MySQL(メモ書き)
まだよくわかってないけどメモ書き
odbcやってみようかと思ったけどイマイチわからずなので、コレ使うのがいい気配 https://github.com/dizzyd/erlang-mysql-driver
git clone で落としてきて、rebar (https://github.com/basho/rebar)も落としてきて、ビルド。
使い方がまだよくわかってないので書かず。ただこんな感じみたい?
1. {ok, Res} = mysql: connect(PoolId, Host, Port, User, Password, Database, Reconnect).