PHPでCSVダウンロード画面を作ったがCSVファイルを開くとエラーが表示される件

PHPでCSVダウンロード画面を作ったのですが、

ダウンロードしたCSVファイルをエクセルで開くと

エラーが表示されてしまうので調べました。

エラー内容は、以下のようなものです。

開こうとしているファイル ‘***.***’ の形式は ファイル拡張子が示す形式と異なります。

Excel は ‘xxxx.csv’が SYLK ファイルであることを確認しましたが、読み込むことができません。ファイルにエラーが含まれるか、SYLKファイル形式でない可能性があります。異なるファイル形式でそのファイルを開くには、[OK]をクリックしてください。

テキストエディタでCSVファイルを開いてみても、

おかしな点は見つかりませんでした。

同じエラーで困っている方がいらっしゃるようです。

CSVファイルの先頭を「ID」で始めるとSYLK形式として

読み込もうとするためこのようなエラーが発生するようです。

マイクロソフトのサポートページには、回避策として

先頭の文字列”ID”の前にスペースを入力する方法が掲載されていました。

■参考
【Excel】SYLK ファイルであることを確認しましたが、読み込むことができません

[PJ98]CSV形式で保存したファイルをExcelで開くとエラー発生

画像ファイル共有にはpiwigoがオススメ

社内でHP用の写真素材を共有したいということがあり、

フォトギャラリーシステムを探しましたが、

インストールの簡単さ、見た目の良さ、機能の豊富さから

piwigoを使用することに決めました。

一番の決め手は、手元にある大量の画像ファイルを

FTPでアップし、これを読み込んでくれる機能でした。

管理画面から1ファイルずつアップロードとかになると

使えなかったのですが、この機能のおかげで非常に助かりました。

インストール

piwigoダウンロードページからzipファイルをダウンロードします。

「Download Package」を選びました。

ダウンロードしたzipファイルを解凍してサーバーにアップします。

またpiwigo用のデータベースをMySQLで作成しておきます。

サーバーにアップロードできたら、ブラウザからインストールフォルダにアクセスします。

フォルダに権限を設定していないと、_data/フォルダに権限がないというような

エラーメッセージが表示されますので、_data/に権限777を設定します。

Give write access (chmod 777) to "_data/" directory at the root of your Piwigo installation

Piwigoインストール

Piwigoインストール

データベース設定に、作成したデータベース情報を入力します。

管理設定に、Piwigoの管理ユーザー情報を入力します。

以上が入力できたら「インストールを開始する」ボタンをクリックします。

Piwigoインストール完了

Piwigoインストール完了

インストール完了画面が表示されます。

local/configフォルダに書き込み権限がなかった場合、

「local/config/database.inc.php の設定ファイル作成に失敗しました。」

と表示されますので、「設定ファイルをダウンロードします。」をクリックして

database.inc.phpをダウンロードします。

念の為に、database.inc.phpを開いて中身を確認しておきます。

記載されている内容が「その他の解決は、上のボックスにあるテクストをコピーし、”local/config/database.inc.php”に貼り付けます。」

のボックス内のテキストと同じかを確認します。

確認できたら、database.inc.phpを「local/config」フォルダ内にアップロードします。

アップロードできたら、「ギャラリーへ」ボタンをクリックします。

「こんにちは ○○さん, あなたのPiwigoフォト・ガラリーが何も入っていません!」みたいな

メッセージが表示されますので、「写真を追加する」をクリックして

管理画面に遷移します。

uploadフォルダに権限がないとメッセージが出た場合は、

メッセージ通りにuploadフォルダに権限777を設定します。

以上でインストールは完了です。

今回は、手元にある大量の素材ファイルを一括でpiwigoに登録したかったので、

FTPでアップロード⇒同期という方法を使用します。

管理画面上で「FTP + 同期」タグを選択します。

「クイックスタート」に手順が書いてありますので、この通りに進めます。

1.「galleries」フォルダに画像ファイルをアップロードします。

「galleries」フォルダ内にフォルダを作成してもかまいません。

警告にもありますが、ディレクトリおよびファイル名には、文字、「-」「_」「.」の記号のみ含んでください。空白、アクセント符号は含まないでください。

今回、日本語のフォルダ名、ファイル名を使用していたのですが、

日本語は使用不可でした。

全て半角英数に置き換えました。

2.同期化する

「galleries」フォルダへのアップロードが終わったら、

管理画面メニューの「ツール」から「同期化」をクリックします。

フォルダとファイルを一緒に同期化する場合は、

「ファイル構造とデータベースを同期化する」で

「ディレクトリ + ファイル」にチェックを入れます。

最初に実行する場合は、「シミュレーション」の

「シミュレーションのみ実行する (データベースは更新されません)」に

チェックを入れてエラーが発生しないか確認した方がよいでしょう。

エラーが発生しないことが確認できたら、このチェックを外し再度実行します。

これだけで、自動で同期化してくれます。

フォルダ名を日本語にしたい場合は、同期化後に変更できます。

Piwigoで簡単に画像ファイルの共有ができるようになりましたので、

同じように悩んでいる方はぜひPiwigoをお試しください。

PHPで日付計算する方法のまとめ

PHPで「現在から○日後」「ある日から○カ月後」の日付を求めたい

ということがよくあるのでまとめてみました。

strtotimeを使います。

strtotimeは、「英文形式の日付をUnixタイムスタンプに変換する」関数です。

int strtotime ( string $time [, int $now = time() ] )

以下のように使用します。

strtotime("now");

strtotime("+1 day");

strtotime("next Thursday");

1週間後の日付を求める場合は以下のように書きます。

echo date('Y-m-d', strtotime('+1 week'));

1か月と10日後の日付はこうなります。

echo date('Y-m-d', strtotime('+1 month 10 days'));

ある特定の日から○日前というのも求められます。

strtotimeの2番目の引数に、特定の日を入れます。

echo date('Y-m-d', strtotime('+1 month', strtotime('2014-03-12')));

上記は、「2014年3月12日の1カ月後の日付」を表示します。

CakePHPでログイン認証

CakePHPでログイン認証を実装します。
パスワードを暗号化して保存しますので、ユーザー編集画面でパスワードをデフォルトで空欄にし、入力した場合のみ変更する実装にします。

まずはユーザーテーブルを作成。

CREATE TABLE `users` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` text,
  `username` text,
  `password` text,
  `deleted` smallint(6) DEFAULT '0',
  `created` datetime DEFAULT NULL,
  `updated` datetime DEFAULT NULL,
  PRIMARY KEY (`id`)
) ;

Userモデルを作成します。
app/Model/User.php
bakeで作成したものに、以下の内容を追加しました。

■パスワードの暗号化

App::uses('SimplePasswordHasher', 'Controller/Component/Auth');

AuthコンポーネントのSimplePasswordHasherを使用します。

    public function beforeSave($options = array()) {
        if (!$this->id) {
            $passwordHasher = new SimplePasswordHasher();
            $this->data['User']['password'] = $passwordHasher->hash($this->data['User']['password']);
        } else if ($this->id && $this->data['User']['password1']) {
            $passwordHasher = new SimplePasswordHasher();
            $this->data['User']['password'] = $passwordHasher->hash($this->data['User']['password1']);
		}
        return true;
    }

beforeSaveで、保存前にpasswordを暗号化します。
編集画面で、パスワード欄に何も入力しない場合は変更したくないので、変更画面(views/users/edit)のパスワードをpassword1として、これが入力されている場合に暗号化してpasswordにセットします。
登録画面では、暗号化して保存します。

■バリデーション
$validateで設定します。
パスワードは、登録画面のみ必須にしたいので、「’on’ => ‘create’」を指定します。
また、usernameは半角英数のみのユニークにしたいので、alphaNumericとisUniqueを指定します。
alphaNumericは日本語を通してしまうので、正規表現を使ってエラーチェックを設定します。

<?php
App::uses('AppModel', 'Model');
App::uses('SimplePasswordHasher', 'Controller/Component/Auth');

/**
 * User Model
 *
 */
class User extends AppModel {

    public function beforeSave($options = array()) {
        if (!$this->id) {
            $passwordHasher = new SimplePasswordHasher();
            $this->data['User']['password'] = $passwordHasher->hash($this->data['User']['password']);
        } else if ($this->id && $this->data['User']['password1']) {
            $passwordHasher = new SimplePasswordHasher();
            $this->data['User']['password'] = $passwordHasher->hash($this->data['User']['password1']);
		}
        return true;
    }

/**
 * Display field
 *
 * @var string
 */
	public $displayField = 'name';

/**
 * Validation rules
 *
 * @var array
 */
	public $validate = array(
		'name' => array(
			'notEmpty' => array(
				'rule' => array('notEmpty'),
				'message' => '必須入力です',
				//'allowEmpty' => false,
				//'required' => false,
				//'last' => false, // Stop validation after this rule
				//'on' => 'create', // Limit validation to 'create' or 'update' operations
			),
		),
		'username' => array(
			'notEmpty' => array(
				'rule' => array('notEmpty'),
				'message' => '必須入力です',
				//'allowEmpty' => false,
				//'required' => false,
				//'last' => false, // Stop validation after this rule
				//'on' => 'create', // Limit validation to 'create' or 'update' operations
			),
			'alphaNumeric' => array(
				'rule' => array('alphaNumeric'),
				'message' => '半角英数字のみ入力してください',
				//'allowEmpty' => false,
				//'required' => false,
				//'last' => false, // Stop validation after this rule
				//'on' => 'create', // Limit validation to 'create' or 'update' operations
			),
			'isUnique' => array(
				'rule' => array('isUnique'),
				'message' => 'このログインIDは既に登録されています'
			),
		),
		'password' => array(
			'notEmpty' => array(
				'rule' => array('notEmpty'),
				'message' => '必須入力です',
				//'allowEmpty' => false,
				'required' => true,
				'last' => true, // Stop validation after this rule
				'on' => 'create', // Limit validation to 'create' or 'update' operations
			),
		),
	);

	public function alphaNumeric($check) {
	    $value = array_values($check);  // 配列の添字を数値添字に変換して・・・
	    $value = $value[0];     // 最初の値を取る
	    return preg_match('/^[a-zA-Z0-9]+$/', $value);
	}
}

次にコントローラーを作成します。
app/Controller/UsersController.php

<?php
App::uses('AppController', 'Controller');
/**
 * Users Controller
 *
 * @property User $User
 * @property PaginatorComponent $Paginator
 */
class UsersController extends AppController {

/**
 * Components
 *
 * @var array
 */
	public $components = array('Paginator');

	function beforeFilter() {
		parent::beforeFilter();

		$this->Auth->allow('add', 'edit', 'logout');
	}

	function login() {
		$this->layout = 'simple';
		if ($this->request->is('post')) {
			if ($this->Auth->login()) {
				$this->redirect($this->Auth->redirect());
			} else {
				$this->Session->setFlash(__('Invalid username or password, try again'));
			}
		}
	}

	function logout() {
		$this->redirect($this->Auth->logout());
	}
	

/**
 * index method
 *
 * @return void
 */
	public function index() {
		$this->User->recursive = 0;
		$this->set('users', $this->Paginator->paginate());
	}

/**
 * view method
 *
 * @throws NotFoundException
 * @param string $id
 * @return void
 */
	public function view($id = null) {
		if (!$this->User->exists($id)) {
			throw new NotFoundException(__('Invalid user'));
		}
		$options = array('conditions' => array('User.' . $this->User->primaryKey => $id));
		$this->set('user', $this->User->find('first', $options));
	}

/**
 * add method
 *
 * @return void
 */
	public function add() {
		if ($this->request->is('post')) {
				$this->User->create();
				if ($this->User->save($this->request->data)) {
					$this->Session->setFlash(__('The user has been saved.'));
					return $this->redirect(array('action' => 'add_comp'));
				} else {
					$this->Session->setFlash(__('The user could not be saved. Please, try again.'));
				}
		}
	}
	function add_comp(){
	}

/**
 * edit method
 *
 * @throws NotFoundException
 * @param string $id
 * @return void
 */
	public function edit($id = null) {
		if (!$id && empty($this->request->data)) {
			throw new NotFoundException(__('Invalid user'));
		}
		if ($this->request->is(array('post', 'put'))) {
				if ($this->User->save($this->request->data)) {
					$this->Session->setFlash(__('The user has been saved.'));
					return $this->redirect(array('action' => 'edit_comp'));
				} else {
					$this->Session->setFlash(__('The user could not be saved. Please, try again.'));
				}
		} else {
			$options = array('conditions' => array('User.' . $this->User->primaryKey => $id));
			$this->request->data = $this->User->find('first', $options);
			$this->request->data['User']['password'] = null;
		}
	}
	function edit_comp(){
	}


/**
 * delete method
 *
 * @throws NotFoundException
 * @param string $id
 * @return void
 */
	public function delete($id = null) {
		$this->User->id = $id;
		if (!$this->User->exists()) {
			throw new NotFoundException(__('Invalid user'));
		}
		$this->request->onlyAllow('post', 'delete');
		if ($this->User->delete()) {
			$this->Session->setFlash(__('The user has been deleted.'));
		} else {
			$this->Session->setFlash(__('The user could not be deleted. Please, try again.'));
		}
		return $this->redirect(array('action' => 'index'));
	}
}

次に、AppController.phpで、Authコンポーネントの設定を行います。
app/Controller/AppController.php

<?php
/**
 * Application level Controller
 *
 * This file is application-wide controller file. You can put all
 * application-wide controller-related methods here.
 *
 * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
 * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
 *
 * Licensed under The MIT License
 * For full copyright and license information, please see the LICENSE.txt
 * Redistributions of files must retain the above copyright notice.
 *
 * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
 * @link          http://cakephp.org CakePHP(tm) Project
 * @package       app.Controller
 * @since         CakePHP(tm) v 0.2.9
 * @license       http://www.opensource.org/licenses/mit-license.php MIT License
 */

App::uses('Controller', 'Controller');

/**
 * Application Controller
 *
 * Add your application-wide methods in the class below, your controllers
 * will inherit them.
 *
 * @package		app.Controller
 * @link		http://book.cakephp.org/2.0/en/controllers.html#the-app-controller
 */
class AppController extends Controller {
    var $components = array('Session', 
            'Auth' => array(
                'authenticate' => array('Form' => array('scope' => array('User.deleted' => '0'),
														))
            ),
			);
}

最後にviewを作成します。
app/View/Users/add.ctp

<!-- app/View/Users/add.ctp -->
<div class="users form">
<?php echo $this->Form->create('User'); ?>
    <fieldset>
        <legend><?php echo __('Add User'); ?></legend>
        <?php echo $this->Form->input('username');
        echo $this->Form->input('password');
    ?>
    </fieldset>
<?php echo $this->Form->end(__('Submit')); ?>
</div>

ユーザー情報の編集画面です。
パスワードを「password1」にします。
app/View/Users/edit.ctp

<!-- app/View/Users/edit.ctp -->
<div class="users form">
<?php echo $this->Form->create('User', array('action'=>'edit')); ?>
    <fieldset>
        <legend><?php echo __('Add User'); ?></legend>
        <?php echo $this->Form->input('username');
        echo $this->Form->input('password1');
    ?>
    </fieldset>
<?php echo $this->Form->end(__('Submit')); ?>
</div>

ログイン画面です。
app/View/Users/login.ctp

<!-- app/View/Users/login.ctp -->
<div class="users form">
<?php echo $this->Session->flash('auth'); ?>
<?php echo $this->Form->create('User'); ?>
    <fieldset>
        <legend><?php echo __('Please enter your username and password'); ?></legend>
        <?php echo $this->Form->input('username');
        echo $this->Form->input('password');
    ?>
    </fieldset>
<?php echo $this->Form->end(__('Login')); ?>
</div>

EclipseのERMasterでER図を描く

では実際に、ER図を描いていきます。

ERMasterを使用できるように環境を設定する方法は、EclipseのインストールERMasterのインストールERMasterでER図作成を開始する、それぞれ過去の記事をご覧ください。

ERMasterのメニューにある「テーブル」をクリックします。
するとカーソルに「プラス」がついて、描画領域に新テーブルを作成できるようになります。

ERMaster

ERMaster

任意の場所で、左クリックすると、テーブルが作成されます。

ERMaster

ERMaster

作成されたテーブルをダブルクリックすると、テーブル情報の編集画面が立ち上がります。

ERMaster テーブル情報

ERMaster テーブル情報

物理名にテーブルの物理名を、論理名にテーブルの論理名を入力します。
今回は、ユーザーテーブルを作成します。
CakePHPでシステム開発を行うことが多いので、CakePHPのユーザーテーブルを意識して作成してみます。
物理名を「users」、論理名を「ユーザー」とします。

ERMaster テーブル情報

ERMaster テーブル情報

項目を追加するには、テーブル情報ボックスの中ほどにある「追加」ボタンをクリックします。
列情報ボックスが立ち上がります。

ERMaster 列情報

ERMaster 列情報

最初にプライマリキーのIDを作成します。
主キー、UNIQUE、AUTO_INCREMENTにチェックを入れます。
物理名を「id」、論理名を「ID」とし、型に「int」を選択します。

ERMaster 列情報

ERMaster 列情報

OKをクリックすると項目が追加されます。

ERMaster テーブル情報

ERMaster テーブル情報

次はユーザー名を作成します。
NOT NULLにチェックを入れ、物理名を「name」、論理名を「ユーザー名」とし、型に「text」を選択します。

ERMaster 列情報

ERMaster 列情報

同様にして、ログインID、パスワード、登録日時、更新日時を追加します。
登録日時の「created」および更新日時の「updated」ですが、この項目名で作成しておくと、
CakePHPが自動で登録・更新してくれるので、作成しておきます。

ERMaster テーブル情報

ERMaster テーブル情報

OKボタンをクリックすると、テーブル情報が反映されます。

ERMaster

ERMaster

物理名だけだとわかりずらいので、論理名も表示させましょう。
描画領域で右クリックして、メニューから「表示」⇒「ビューモード」と進み、「論理/物理」を選択します。

ERMaster 論理名を表示

ERMaster 論理名を表示

論理名と物理名が表示され、わかりやすくなりました。

ERMaster 論理名と物理名を表示

ERMaster 論理名と物理名を表示

この他にも、「表示」では表記法や表記レベルなど選択できますので、お好みに合わせてカスタマイズしてください。

最後に、実際にデータベース上にテーブル作成を行うためのSQL文を生成します。
描写領域で右クリックし、「エクスポート」⇒「DDL」をクリックします。

ERMaster SQL生成

ERMaster SQL生成

出力ファイルで出力先を選択し、OKをクリックすると、SQL文が出力されます。

ERMaster SQL文生成

ERMaster SQL文生成

実際に以下のようなSQL文が出力されました。

SET SESSION FOREIGN_KEY_CHECKS=0;

/* Drop Tables */

DROP TABLE users;




/* Create Tables */

CREATE TABLE users
(
	-- 主キー
	id int NOT NULL UNIQUE AUTO_INCREMENT COMMENT '主キー',
	name text NOT NULL,
	login text NOT NULL,
	password text NOT NULL,
	created datetime,
	updated datetime,
	PRIMARY KEY (id)
);



実際に使いだすと手放せなくなりますので、是非一度お試しください!

ERMasterでER図作成を開始する

EclipseとERMasterのインストールが終わったら、いよいよERMasterでER図の作成を始めます。
ER図を描き始める前に、プロジェクトの作成が必要です。
今回は、ER図を描くための前段階の準備になります。

EclipseのインストールERMasterのインストールは、それぞれ過去の記事をご覧ください。

まず、Eclipseを起動します。
今回はCドライブのpleiades以下にインストールしましたので、
c:\pleiades\eclipse\eclipse.exeをダブルクリックして起動します。

Eclipse

Eclipse

ワークスペースを選択します。

eclipse

eclipse

Eclipseが立ち上がったら、まずはプロジェクトを作成します。
[ファイル]⇒[新規]⇒[プロジェクト]をクリックしてください。

eclipse

eclipse

プロジェクトウィザードが開いたら、[一般]を開いて、表示されたプロジェクトを選択し、「次へ」ボタンをクリックします。

eclipse

eclipse

プロジェクト名に作成するプロジェクトの名前を入力します。
プロジェクト別にフォルダを分けたいときは、ロケーションで変更できます。
「完了」ボタンをクリックすると、プロジェクトの作成が完了です。

eclipse

eclipse

次に、ER図を作成します。
Eclipseメニューの[ファイル]⇒[新規]⇒と進み、[その他]を選択してください。
新規ウィザードが表示されます。

ERMaster

ERMaster

[ERMaster]⇒[ERMaster]を選択して、「次へ」ボタンをクリックします。

ERMaster

ERMaster

先ほど作成したプロジェクト名がウィンドウに表示されているので、これを選択します。
ファイル名は、作成するER図ファイルの名前になります。
ファイル名を入力して「次へ」ボタンをクリックします。

ERMaster

ERMaster

次に、使用するデータベースを選択します。
リストでは、MySQLやPostgreSQL、Oracle、SQLite、DB2など、主要なデータベースが選択できます。
データベースを選択して「完了」ボタンをクリックすると、新規ER図作成ウィザードは終了です。

ERMaster

ERMaster

これで、Eclipse上でER図を作成することができます。

ERMaster

ERMaster

EclipseにER-Masterをインストールする

EclipseにERMasterをインストールします。
Eclipse自体のインストールは、前回の記事をご参考ください。

Eclipseを起動したら、「ヘルプ」メニューをクリックし、「新規ソフトウェアのインストール」をクリックします。

ERMasterインストール

ERMasterインストール

インストール画面が表示されますので、「作業対象」に「http://ermaster.sourceforge.net/update-site/」を入力し追加をクリックします。
er-master2

リポジトリーの追加画面が表示されるので、名前を入力します。ここでは「ERMaster」としました。
er-master3

OKをクリックしてしばらく待つと、「ERMaster」が表示されるので、チェックを入れて「次へ」をクリックします。
er-master4

次のインストール詳細画面でも「次へ」をクリックします。
er-master5

ライセンスの内容を確認して、「完了」をクリックします。
er-master6

するとインストールが開始されます。

インストール完了前に再起動するか尋ねられますので、再起動を行ってください。

以上でインストールは終了です。

Eclipse日本語版をインストールする

DBの設計で、ER-Masterを使用しています。
ER図からエクスポートで、Table CreateのSQLを生成してくれるため非常に重宝しています。

パソコンを変更したので、新しい環境にER-Masterをインストールする作業をメモ。

まずはEclipseをインストールします。

日本語版をインストールしたいので、
MergeDoc Projectからファイルをダウンロードします。

現時点(2013/11/21)の最新版「Eclipse 4.3 Kepler Pleiades All in One」をクリックします。
使用したいパッケージを選択してダウンロードします。
重くしたくないので、「Platform」を選択します。

パソコンはWindows8 64bitなので、64bit Full Editionにします。

ダウンロードしたファイルを解凍します。
解凍すると、pleiadesというフォルダが生成され、この下にeclipseというフォルダがありますが、
ここにeclipseの本体が入ります。
pleiadesフォルダをコピーして、cドライブ直下に貼り付けます。
c:\pleiades\eclipseという構成になります。

c:\pleiades\eclipse\eclipse.exeを実行します。
以下のようなスプラッシュ画像が表示され、ワークスペース・ランチャーが立ち上がると、導入終了です。
eclipse

Google Chromeでコンソールに値を表示する方法

Javascriptのデバッグで、変数に入っている値を知りたいときには、

var hoge = "ほげ";
alert(hoge);

として、alertで表示させていました。

これはこれで便利なのですが、loop処理などでいちいちalertボックスを
表示させているのがメンドくさい場合もあります。
そういった場合は、

var hoge = "ほげ";
console.log(hoge);

としてください。

Google Chromeのデバッグツールで「Console」を表示させると
hogeにセットされている値を表示させることができます。
これは便利!

CakePHPでリダイレクトの際にパラメーターを設定する

CakePHPで、登録や変更処理が終わった後にリダイレクトする場合は以下のようにします。

$this->redirect(array('action' => 'index'));

これで、一覧画面にリダイレクトします。
コントローラーを指定したい場合は、以下のように指定します。

$this->redirect(array('controller' => 'orders', 'action' => 'index'));

編集画面等で、idを渡したい場合は以下のようにします。

$this->redirect(array('action' => 'edit', $id));

これで、「/コントローラー名/edit/id」というURLにリダイレクトします。

名前付きパラメーターを渡すこともできます。

$this->redirect(array('controller' => 'orders', 'action' => 'confirm', 'product' => 'pizza', 'quantity' => 5));

これで、「/orders/confirm/product:pizza/quantity:5」というURLにリダイレクトします。

ちょっとハマったのが、idをパラメーターとして渡したいときです。

$this->redirect(array('action' => 'edit', 'id' => 5));

としていたのですが、これだと「/コントローラー名/edit/id:5」というURLになってしまいます。
「’id’ => 」は不要で、

$this->redirect(array('action' => 'edit', 5));

とします。