テスト環境から本番環境へのファイル適用

1月 26th, 2008 admin

いつも設定ファイルをこうやって書いて

<?php
	//本番用
	define("FILE_UPLOAD_DIR","/xxx/yyy/xxx/");
	//テスト用
	//define("FILE_UPLOAD_DIR","/aaa/bbb/");
?>

subversionでignore属性つけてあるから完璧。とか思ってたんだけど。

よく考えたらapp_controller.phpとかで

<?php
	if($_SERVER['HTTP_HOST'] == "www.example.com"){ //本番環境のホスト名
		//本番環境
		config("dependent_settings");
	}else{
		//テスト環境
		config("test_dependent_settings");
	}
?>

って環境変数で設定ファイルを切り替えるようにしておけば、テスト環境と本番環境のファイルがまったく同じにできるんだと下記のページをみて気が付いた。

CakePHP 環境に応じてDBの設定を変える | Shin x blog
http://www.1×1.jp/blog/2006/09/cakephp_db_config.html

デプロイの方法とか今まで全然調べてなかったことなのでもうちょっと調べてみようと思う。みんなきっといいツールを使ってる(作ってる)はず。

PHPフレームワーク比較2008

1月 16th, 2008 admin

調査機関Gを利用してフレームワーク名の検索回数を元にフレームワークの人気を調査してみた。

01.PNG

参考までにmojaviをいれたけどやっぱり第1世代なのね・・・

11.PNG
と思っていたら日本(だけ)ではまだまだ現役のようです。

CakePHPからAkelosに入門

1月 15th, 2008 admin

Blog-side Akelosにしました

この記事を読んでしまったおかげで
CakePHPへの「あの配列地獄はなんなんとかならんのか」という違和感が不満へと変わってしまった

ということでAkelosに入門することにしてみる。

前書き

XAMPPでAkelosのテスト
・ユーザの管理をする
・ユーザにはそれぞれ管理者レベルみたいな属性がつく
こんなのを作りたいと思います。

ファイルを配置する

http://www.akelos.org/download
から最新版をダウンロード(0.8)
subversionからのインストールを薦めているけど、僕の環境ではなぜかチェックアウトが出来なかった。

今回はドキュメントルートの下にbasicというフォルダを作ってそこにそのまま配置した。
0.PNG

データベースを用意

あらかじめ3つのデータベースを作っておく、本番用、開発用、テスト用(ユニットテスト)
SQLiteが使えないXAMPPのPHP4なのでMySQLを使います。

CREATE DATABASE `basic` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;
CREATE DATABASE `basic_dev` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;
CREATE DATABASE `basic_tests` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;

インストール

http://localhost/basic/

にアクセスしてインストーラを起動、
1.PNG
・DBの設定を入力
・言語の設定(関係ないかもしれないけどjaをenより前に移動した)
2.PNG

マイグレーションファイルを作成

RoRを使っていれば知っていると思うのですが、データベースのテーブルを作ったり、カラムを追加したりっていう作業ははマイグレーションという仕組みで管理します。
便利というよりは、この仕組みを使うことでスキーマの変更を必ずファイルに記録するようになるってのが個人的には嬉しいです。

app/installers/basic_installer.php

<?php

class BasicInstaller extends AkInstaller
{
 function up_1(){

     $this->createTable('users',
        'id,'.
        'email,'.
        'password,'.
        'authority_id,'.
        'is_active'
    );

     $this->createTable('authorities',
        'id,'.
        'level,'.
        'desctiption'
        );
 }

 function down_1(){
     $this->dropTables('users','authorities');
 }
}

?>

こんなファイルを作ります。
up(次)とdown(前)の状態を記述することでデータベースのスキーマをバージョン管理できます。
さっそくupさせてみましょう

C:\xampp\htdocs\basic>php script/migrate Basic install

するとデータベースにusersとauthoritiesというテーブルが作成されています。
3.PNG

scaffold

C:\xampp\htdocs\basic>php script/generate scaffold user
C:\xampp\htdocs\basic>php script/generate scaffold authority

4.PNG
これで

http://localhost/basic/user/

http://localhost/basic/authority/

に一覧・追加・編集・削除・詳細表示ができる画面ができあがっています。
CakePHPでいうbakeですね。

リレーション

users.authority_idとauthorities.idを連携させます。
まず、モデルの設定から
model/user.php

<?php

class User extends ActiveRecord
{
	var $belongs_to = 'authority';
}

?>

model/authority.php

<?php

class Authority extends ActiveRecord
{
	var $has_many = 'users';
}

?>

user”s”って複数形になっているのに注意

次はコントローラー
controllers/user_controller.php

<?php

class UserController extends ApplicationController
{
	var $models = 'user, authority';

    function show()
    {
        $this->user = $this->User->find(@$this->params['id'], array('include' => 'authority'));
    }

最後に入力フォーム
views/user/_form.tpl

<?php  echo $active_record_helper->error_messages_for('user');?>

    <p>
        <label for="user_email">_{Email}</label><br />
        <?php  echo $active_record_helper->input('user', 'email')?>
    </p>

    <p>
        <label for="user_password">_{Password}</label><br />
        <?php  echo $active_record_helper->input('user', 'password')?>
    </p>
    <p>
        <label for="authority">_{Authority}</label><br />
        <?=$form_options_helper->select('user', 'authority_id', $Authority->collect($Authority->find(), 'level', 'id'));?>
    </p>
    <p>
        <label for="user_is_active">_{Is active}</label><br />
        <?php  echo $active_record_helper->input('user', 'is_active')?>
    </p>

こんなんで連携してくれるようになる
5.PNG

CakePHPとの違い

・コントローラー名は複数形(users)だがURLは単数形になる
・has_manyのときは相手を複数形の名前で指定する必要があってはまった

次回は

本当にRoRと似てるなーと大枠をつかめたので次回はユーザ認証を作ってみたいと思います。

CakePHP::携帯の端末ID(uid)で「かんたんログイン」

12月 13th, 2007 admin

よく考えたらCakePHPとは直接関係無いか・・・
usersテーブルでユーザ管理している場合のuidのセットとアンセット例
mobile_codeというカラムにuidを保存します。

uidの取得にはPEAR::Net_UserAgent_Mobileを使用しました。
説明不十分なところが多いですが脳内補完でお願いします。

user_controller.php

function add_mobile_code(){
	//セット
	if(isset($this->data['set'])){
		$this->cleanUpFields();

		$serialNumber = $this->_getMobileUID();

		$this->data['User']['id'] = $this->current_user_id;
		$this->data['User']['mobile_code'] = $serialNumber;
		if (empty($this->data['User']['mobile_code']) || $this->User->save($this->data)) {
			$this->Session->setFlash('かんたんログインを設定しました。');
		} else {
			$this->Session->setFlash('かんたんログインを設定できませんでした。');
		}
			$this->redirect('/users/add_mobile_code');
	}

	//解除
	if(isset($this->data['unset'])){
		$this->cleanUpFields();

		$this->data['User']['id'] = $this->current_user_id;
		$this->data['User']['mobile_code'] = "";
		if ($this->User->save($this->data)) {
			$this->Session->setFlash('かんたんログインを解除しました。');
		} else {
			$this->Session->setFlash('かんたんログインを解除できませんでした。');
		}
			$this->redirect('/users/add_mobile_code');
	}
}

function _getMobileUID(){
	//個別IDを取得
	vendor('PEAR/Net/UserAgent/Mobile');
	$mobObj = Net_UserAgent_Mobile::singleton();
	// get serial number
	$serialNumber = "";
	switch( true )
	{
	  case ($mobObj->isDoCoMo()):   // DoCoMoかどうか
	  case ($mobObj->isVodafone()): // softbankかどうか
		 if( method_exists( $mobObj, "getSerialNumber" ) )
			$serialNumber = $mobObj->getSerialNumber();
		 break;
	  case ($mobObj->isEZweb()):    // ezwebかどうか
		 if( isset( $_SERVER['HTTP_X_UP_SUBNO'] ) )
			$serialNumber = $_SERVER['HTTP_X_UP_SUBNO'];
		 break;
	  default:
		 break;
	}

	return $serialNumber;
}

add_mobile_code.thtml

<h2>かんたんログインの設定</h2>
<p>携帯の端末情報を登録することで次回ログインからIDとパスワードを省略できます</p>
<hr />
現在は「<?php if(!empty($me['User']['mobile_code'])){ ?>設定済み<?php }else{ ?>未設定<?php } ?>」です。

<hr />

<form action="<?php echo $html->url('/m/users/add_mobile_code/'); ?>" method="post" utn>

<?php echo $html->hidden("set");?>
<div class="submit">
	<?php echo $html->submit('かんたんログインを設定する');?>
</div>
</form>

<form action="<?php echo $html->url('/m/users/add_mobile_code/'); ?>" method="post" utn>

<?php echo $html->hidden("unset");?>
<div class="submit">
	<?php echo $html->submit('かんたんログインを解除する');?>
</div>
</form>
<ul class="actions">
<li><?php echo $html->link('トップに戻る', '/m/orders/add/');?></li>
</ul>

CakePHP::DoCoMoの端末ID(utn)取得で認証エラー

12月 13th, 2007 admin

CakePHPで構築したサイトで、DoCoMoの端末で端末ID(UID?)を取得しようとしても認証エラーで取得が出来ない・・・
原因は認証のところで$this->Session->valid();とセッションの正当性のチェックをしていたこと。

端末IDを取得するとユーザーエージェントが変更されるので、直前のアクセスと現在のアクセスでユーザーエージェントが違うということになり「セッションハイジャックじゃね?」と認証エラーになっていました。

あと少しはまったのが、CakePHPにおいてini_set(‘session.use_trans_sid’, 1);が効かない件で、よく読んでみたら/cake/libs/session.phpの__initSession()でini_set(‘session.use_trans_sid’, 0);に設定されていましたので/cake/libs/controllers/components/session.phpを/app/controllers/components/session.phpにコピーして、メソッドを上書きして解決しました。

↓こんな感じでモバイルとそうでないのを分けた

case 'php':
	if (!isset($_SESSION)) {
		if (function_exists('ini_set')) {
			if(defined('MOBILE')){
				ini_set('session.use_trans_sid', 1);
			}else{
				ini_set('session.use_trans_sid', 0);
			}
			ini_set('session.name', CAKE_SESSION_COOKIE);
			ini_set('session.cookie_lifetime', $this->cookieLifeTime);
			ini_set('session.cookie_path', $this->path);
		}
	}
break;