2chのスレに全レスする(12ホール目 1-100)

2chのスレとは

2chのWebProg板にある、CakePHPスレッドがあります。この記事時点での最新スレッドは
【PHP】フレームワーク CakePHP 12ホール目【笑】
になります。

注意

  • 暇つぶし。基本的に質問形式のレスに回答していきます。*1
  • 回答がついてあるものもお構いなしです。
  • 気分でレスしていくので飛ばすレスもあります。
  • あと偉そうな書き方をすることが多いですが断定的に言ってるだけなのであんま気分を害さないでください。(´・ω・`)

>>5

携帯サイトとPCサイトをCakeで作るとき、

Router::connect('/m/', array('controller' => 'home', 'action' => 'index', 'prefix' => 'mobile'));
Router::connect('/m', array('controller' => 'home', 'action' => 'index', 'prefix' => 'mobile'));
Router::connect('/m/:controller/:action/*', array('prefix' => 'mobile'));

  • app_controller.php

function afterFilter() {
  if (!preg_match("/^m(\/)?/", $this->params['url']['url'])) {
   $this->redirect('/m/' . $this->params['url']['url']);
  }
  if ($this->isMobile) {
    $this->output = mb_convert_kana($this->output, 'k');
    $this->output = mb_convert_encoding($this->output, 'SJIS', 'UTF-8');
  }
}
こんな感じで振り分けたりしてるんだけど、

function show() {
$this->set('abc', $this->Model->find('all'));
}

function mobile_show() {
$this->set('abc', $this->Model->find('all'));
}
上記のようにコントローラにPC用と携帯用で全く同じ処理なのに
別々のアクションを作らないといけない。
これはしょうがないのかな?
もっとナイスな実装方法があれば助言お願いします


prefix => 'mobile'ではなく'mobile' => trueなどとしたほうが良い。
beforeFilter()などでviewを切り替える方法もあるが、同一URLとするとビューキャッシュととことん相性が悪い。
テーマも動揺にビューキャッシュの問題が出てくる。
同一アクション内で携帯、またはPC用の場合分けが必要な時こそKtaiLibraryを使えば良い。

>>15

$this->data の中にあるデータ全てに置換処理をしたい場合どうしたらいいですか

Setクラスにそんな便利なメソッドがありそうなものだけど無いので自作しましょう。
array_walk_recursive()と無名関数の組み合わせが一番楽だけど、無理ならメソッド作って再帰
cake/basic.phpのstripslashes_deep()のコードが参考になります。

>>22

バリデーションで、
同じフォームのある特定のselectのある選択肢が選択された時のみ、
ある input をrequiredにする、
ってできる?
↓これでできそうな気がするけど、同じフォームの値は取ってこれないのかな
http://book.cakephp.org/ja/view/1179/%E7%8B%AC%E8%87%AA%E3%81%AE%E3%83%90%E3%83%AA%E3%83%87%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%83%AB%E3%83%BC%E3%83%AB

独自のバリデーションを作成してその中で分岐する手もあるが、beforeValidate()でModel::$validateの個別ルールのrequiredを書き換えることで解決できるならそれが一番手っ取り早い。

<?php

class Post extends AppModel {

	public $validate = array(
		'hoge' => array
			'required' => array(
				'required' => false,
				'allowEmpty' => true,
			),
		),
	);

	public function beforeValidate() {
		$hogeRequired = !empty($this->data['Post']['piyo']) && $this->data['Post']['piyo'] == 2;
		$this->validate['hoge']['required']['required'] = $hogeRequired;
		$this->validate['hoge']['required']['allowEmpty'] = !$hogeRequired;
		return true;
	}

}

>>26

CakePHPってAppControllerやAppModelにかなり手を入れないと
使い物にならないよね。
あと、標準のコンポーネントやヘルパーはホント使い物にならない。
特にFormヘルパーは心の底から使えない。
こんな屑フレームワークが何故こんなに持てはやされているのか謎。

「かなり手を入れる」という意味は2つ推測できます。
・共通の処理を多く定義すること
・メソッドのオーバライドや便利メソッドを追加して挙動そのものをいっぱい変えること
前者の場合は、よりコンポーネント・ビヘイビア化をするべき時期に来たということです。
後者の場合、その変更が有益ならコアに統合するようにリクエストを送ることです。そうでないならば、その変更自体が良いプラクティスで無い可能性が高いと言えます。
どちらにしろ、どんな手の加え方なのかわからない以上、なんとも言えないところですが。
少なくとも自分はAppController, AppModelがほぼ使うコンポーネント群(コンポーネント、ヘルパー、ビヘイビア)の定義意外あまり書くものが無いようにできています。


標準のコンポーネントやヘルパーが使い物にならないなら、いったい何を使っているのでしょうか。
それはCakePHPという「ガワ」を使ってるだけの独自フレームワークと呼べるのではないでしょうか。


後半に関しては議論が分かれるところですが、2.0で改善されたものも非常に多くあります。
また、「使えない」と思ったらコアにフィードバック等を投げましょう。
それが全体として有用なら、一瞬で採用して取り込んでくれるポテンシャルが開発チームにはあります。
このような「使えない」という議論はかなりループしてるので、次から無視します。(どういう点が使えない、という具体的な話なら価値があります)

休憩

>>28-48ぐらいまで上の話題で流れているのでちょっと休憩。
あんまり議論っぽいことには突っ込みづらいです。
何故かというと話が長くなるからです。
あと相手の誤解と思われる部分や、情報が足りない場合に対して推測で話をするのがめんどいです。

>>49

Jsヘルパーって使ってますか?
複雑になるだけな気がするんですが、メリットがあったら教えてもらいたいです。

Jsヘルパーも、AjaxヘルパーもJavascriptヘルパーも、基本的なJavascriptの操作を提供するだけのもので、フロントエンジニアがいたり、自分でゴリゴリ書ける場合は自分で書くべきです。
ただし、バッファリングを行って所定の位置に吐き出すなどをしたい場合はこれを使ったほうがいいでしょう。
さもないとテンプレートにob_start()からはじまるPHPコードの「沼」が出来上がることでしょう。

>>50

$this->Model->getLastInsertID()
を使って他テーブルの外部IDを設定(ひもづけ)するのは危険かな?

例えばショッピングサイトで注文テーブルの注文IDを、注文内容テーブルの外部IDに設定するような場合。

処理の途中で別のINSERTが入った場合はどうなるんだろう・・・?

Model::save()直後には、Model::$idに新規レコードならばそのlastInsertId、更新ならばそのIDが入ります。
通常はそれを使ってください。また、別のINSERTが〜というのは、設計の問題です。そうならないように実装してください。


ここらへんからしばらくトランザクションの議論が続きますが、省略。
>>74の理解で合ってます。

>>99

パスワードの入力エリア2つにして、一方を確認用にするって
仕様が良くあると思いますが、この場合のバリデーションってどうしてます?

さんざ議論され尽くされてるので、フォーラムで検索とかしてください。
CakePHP2.0では、AuthComponent::password()がstaticになった恩恵で、モデルからも呼び出せます。あと、自動的にハッシュ化はしてくれなくなりました。



とりあえず今回は100まで。もうちょっと誰も答えてない質問とかに答えていきたいですね。

*1:Q. 全レスじゃないじゃん A. こまけぇこたぁいいんだよ!