トップページphp
1001コメント321KB

【PHP】フレームワーク CakePHP 11ホール目【v1.3】

■ このスレッドは過去ログ倉庫に格納されています
0001nobodyさん2011/02/16(水) 21:52:35ID:zCTGjUMq
CakePHPは、Ruby on Railsの概念の多くを取り入れた、Rails流の高速開発とPHPの機動性を兼ね備えたフレームワークです
CakePHPから派生したLithium(li3)も専スレできるまではここでどうぞ
質問するときはCakePHPのバージョンを書きましょう

※sage推奨
※質問時もsageること
※他フレームワークとの比較等はスレ違いです
テンプレは>>1-5くらい

■本家
http://www.cakephp.org/
APIドキュメント
http://api.cakephp.org/
the Bakery
http://bakery.cakephp.org/
CakeQs
http://cakeqs.org/
CheatSheet (PDF)
http://cakephp.org/files/Resources/CakePHP-1.2-Cheatsheet.pdf
github - cakephp
http://github.com/cakephp

■日本語公式
http://cakephp.jp/
フォーラム
http://cakephp.jp/modules/newbb/
cookbook(マニュアル)
http://book.cakephp.org/ja
0002nobodyさん2011/02/16(水) 22:01:14ID:???
終了
0003nobodyさん2011/02/16(水) 23:30:29ID:???
CGI厨さん遅いよ
0004nobodyさん2011/02/17(木) 00:27:39ID:???
Userというモデルから $this->User->find("all");
とすると、Userという配列の下に情報が入っている配列を取得するのですが、
Userの部分をなくしたものを取得することはできないでしょうか?

一つ一つデータ取る時、$item['User']['api']ではなく、$item['api']だけ書くほうが楽なもので。

[0] => Array
(
[User] => Array
(
[id] => 1
[api] => google
[coupon_id] => 6113
)
)
[1] => Array
(
[User] => Array
(
[id] => 2
[api] => agi
[coupon_id] => 5982

0005nobodyさん2011/02/17(木) 00:36:34ID:???
http://cakephp.1045679.n5.nabble.com/Find-Output-Thoughts-why-the-not-remove-ModelName-td1334722.html

同じような質問をしているのを見つけました。
しかし、回避方法みたいなものはないっぽいので、仕様と諦めるしかないのかな。
0006nobodyさん2011/02/17(木) 00:39:00ID:???
>>4
afterFind()をAppModelに書いて処理したらいいんちゃう?
でもFormHelperと連動しなくなるとおもうけど。
0007nobodyさん2011/02/17(木) 08:04:01ID:???
>>6

ぐぐぐ、やはり仕様ということで諦めるのが吉のようですね。
レスありがとうございます。m(_ _)m
0008nobodyさん2011/02/17(木) 08:07:45ID:???
複数のフィールドを一度に更新することはできないでしょうか?

マニュアルやcake辞典を読んだところ、

$this->Model->set('id',4);
$this->Model->saveField('buy_count', 3);
$this->Model->saveField('sold_out', 1);

このようにすれば、複数のフィールドを更新できるのですが、いくつものフィールドを
更新した場合、何行も繰り返さないといけない。。

こんなまどろっこしいことせずに、saveとconditionで一気に上書きするのがスマート
なやり方なのでしょうか。
0009nobodyさん2011/02/17(木) 09:32:36ID:???
>>8
$this->Model->save()
0010nobodyさん2011/02/17(木) 11:12:59ID:???
最近、フレームワーク無しのPHPプログラムを書いてるんだけど、
いつの間にかCake風の構成にしてた。

多重配列って長くなって面倒だけど、わかりやすいよね。
0011nobodyさん2011/02/17(木) 18:35:10ID:???
生成されたpotを弄ってviewの中のctpファイルはローカライゼーション出来るようになったんだけど、
バリデーション(モデル)とか
プログラム上での(コントローラー)表記を
ローカライゼーションしたい場合は
どうしたらいいの?
0012nobodyさん2011/02/17(木) 18:39:45ID:???
cakephpで質問です。

idを主キーにしていて

データの取り出しで
this->model->
findAllByName($hoge)
として
this->model->save($this->data)

した場合、上書き更新ではなく新レコード挿入になりますよね?
主キーでモデルのデータを取り出さない限り新レコード挿入になるのは分かるのですが、CakePHP仕様だと主キーを一つしか扱えないのでupdateAll()を使うしかないのでしょうか?

主キー以外のフィールドでの検索対象の
レコードを更新したい場合、
スマートなやり方だと、どういうやり方が一般的でしょうか?
0013nobodyさん2011/02/17(木) 19:00:48ID:???
findしてるのに$this->dataなのがよくわからん
idが$dataに含まれていれば更新になるよ
0014nobodyさん2011/02/17(木) 20:58:03ID:???
>>11
> バリデーション(モデル)とか
cakeplusというプラグインを使うか、
自分でエラーメッセージを置き換えるコードを書く。

> プログラム上での(コントローラー)表記を
コントローラーの好きなところで__()関数を書く。
0015nobodyさん2011/02/17(木) 21:41:32ID:???
>>13
idというフィールドを主キーにしていて
nameフィールドは主キーではありません。

findAllByNameしてレコードを特定していてもnameフィールドは主キーではないので、上書き更新されません。
新規レコード挿入になってしまいます。
0016nobodyさん2011/02/17(木) 22:02:41ID:???
テーブル名をつけるときに

users_codesのようにアンダーバーをつけてもいいですか?
その場合は外部からアソシエーションするときはusers_codes_idでok?


またフィールドにもbirth_dateのようにアンダーバーを使ってもいいですか?
0017nobodyさん2011/02/17(木) 22:41:35ID:???
>>15
横からだが、
$result = $this->Model->findAllByName($hoge);
これで取得できるデータには当然idが入ってるぞ。
ただ俺のほうでやったら、

$result = $this->Model->findAllByName($hoge);
debug($result); //データあり
debug($this->data) //NULL

だけどな。

>>16
試した事はないけど、users_codesの様に両方とも複数形で繋げると、
多分HABTMの中間テーブル扱いになっちゃうかもね。user_codesの様に1個目が単数系ならやったことある。
フィールドにアンダーバーはやってる。
0018nobodyさん2011/02/17(木) 23:48:53ID:???
>>17
絞り込む際のフィールドが主キーでなくても、それに合わせて上書き更新できるんですね!

ということは

$res=this->model->findAllByName($hoge);
this->model->save($result);
でいけるということですね!


普通、this->model->hoge
みたいにデータを取得しにいったら
自動的に$this->dataに結果が格納されるもんじゃなかったでしたか?
0019nobodyさん2011/02/17(木) 23:51:37ID:???
>>17
返信ありがとう!!!!
テーブルをuser_codesと名付けたとき
外部からアソシエーション組む際は
user_code_idってフォーインキーを用意してやればいいですか?
0020nobodyさん2011/02/18(金) 01:11:29ID:???
CakePHPだと仮に10万レコード(10フィールド)あるようなテーブルへのアクセスでもサクサク動きますか?

レコードが膨大な数になったときの工夫とかあるのかな?

それとユーザー写真をアップロードさせたら、どういうふうに管理すればいいですか?
データベース側はあくまでファイル名を記録しておいて、画像はwebroot/image/フォルダ内に一括して10万ファイルとかですか?
0021nobodyさん2011/02/18(金) 05:55:46ID:???
>>18
普通といわれても、やってみた結果がそうだっただけだからなぁ。
一応もっともらしい事を書くと、とあるModelのクラスのメソッドを呼んだだけで、
別のクラスであるControllerのメンバ変数に勝手に値を代入ってのは、
普通はしないと思うぞ。越権行為すぎる。

>>19
http://book.cakephp.org/ja/view/903/%E3%83%A2%E3%83%87%E3%83%AB%E3%81%A8%E3%83%87%E3%83%BC%E3%82%BF%E3%83%99%E3%83%BC%E3%82%B9%E3%81%AE%E8%A6%8F%E7%B4%84
一応、peopleテーブルはPersonモデルなのは、変な変換が入ったとかじゃなくって、
ほんとにそういう規約。

>>20
10万レコードも扱ったこと無いからわからん。
アップロード系のプラグインが英語圏製だけど一杯あるから探したらいいんじゃないかな。
プラグインが、10万レコード考慮してるかはしらんが。
最近のファイルフォーマットだと違うかもだけど、1ディレクトリ5000ファイルくらいにしといたほうがI/O的に良いんじゃない?
0022nobodyさん2011/02/18(金) 21:20:08ID:???
>>20
レコード数の多さはmysqlのチューニングの問題じゃないの?
ファイル管理はDB+非公開ディレクトリに小分けにすんのがいいんじゃないかね
0023nobodyさん2011/02/18(金) 22:31:57ID:???
ユーザー写真なら公開ディレクトで良いんでない?
非公開エリアにおいて、画像データ取得してGDで画像生成
する処理が発生するから負荷がかかるだろ。
0024nobodyさん2011/02/18(金) 22:35:20ID:???
GDは余計じゃないか?
fopen()して適切なheader()書いて出力するだけだろ。
そのほうがアクセスコントロールも出来るし。
まぁ必要なければ余計な処理だけどな。
0025222011/02/18(金) 23:50:40ID:???
>>24
んだ
0026nobodyさん2011/02/19(土) 01:07:14ID:???
フォルダに格納するときは下2桁ごとにフォルダわけたほうがいいですか?

10058.jpgは

pic/58/ フォルダの中に

17434.jpgは

pic/34/ フォルダの中にといった具合で
0027nobodyさん2011/02/19(土) 01:23:37ID:???
>>26
どうしたほうが良いかは要件と仕様しだいなんじゃないの?
ユーザーアップロードしたファイルの置き方は、CakePHPは特に関与しないし。
正解が無い部類の問題だから、
要件を満たす仕様を、見合った経験を持つアプリケーション設計者が考えるべき。
>>26>>20 だと思うんだけど、
この質問をするくらいのスキルなら、10万レコード・10万ファイルを扱うシステムを、
試行錯誤無しに設計するのは無理だと思うよ。
0028nobodyさん2011/02/19(土) 01:56:06ID:???
フォルダ分けるメリットって、ファイルを視認しやすい以外にない気がする。
0029nobodyさん2011/02/19(土) 02:43:57ID:???
>>24
cakeなんだからそこはMedia Viewを使ってほしい。
0030nobodyさん2011/02/19(土) 03:08:31ID:???
俺のサイトが一日数ヒットから10万ヒットに増えたらと思うとcakephp使うのが心配
0031nobodyさん2011/02/19(土) 06:06:42ID:???
>>28
1ディレクトリにあまりに多いファイルが入ってると、
ディスクI/Oが遅くなるって聞いたことがあるんだけど
0032nobodyさん2011/02/19(土) 07:28:08ID:???
質問です。
ブログでいうブログタイトルなどの、編集する可能性はあるけど複数のレコードは存在し得ない情報ってどの様にして管理すればいいのでしょうか?
単一レコードしか存在し得ないのにRDBMSで管理するのはどうなのかなぁと思い、悩んでいます。

ネイティブPHP使ってたときは、そういった設定項目を纏めたSettingsクラスというものを作り、そのインスタンスをシリアライズしてたんですが…

Cakeだとみなさんどうしていますか?
0033nobodyさん2011/02/19(土) 09:15:09ID:???
>>32
>ネイティブPHP使ってたときは、そういった設定項目を纏めたSettingsクラスというものを作り、そのインスタンスをシリアライズしてたんですが…
Configure::write('setting.title', 'ブログタイトル'); とかできるんで、
Settingsクラスというものになれているなら、bootstrapに設定を記述するのがいいのでは
0034nobodyさん2011/02/19(土) 13:48:40ID:???
WordPressだとsettingsテーブル的なのが存在してて、ブログ全体に関する設定はそこに突っ込まれてた気がする
setting_nameとvalueみたいな感じで
0035nobodyさん2011/02/19(土) 14:22:36ID:???
jQuery使いたいんだけど、JsHelper経由で扱う意味ってありますか?
viewにstaticで書いたほうが扱いやすい気がするけど。
0036nobodyさん2011/02/19(土) 15:19:39ID:???
パスワードを暗号化にして入力フォームでエラーで弾かれたとき、
パスワードが自動的に暗号化後の文字長になって再入力されています。

これってエラーがあった時は常にパスワードのところだけを空にしてリセットするってのが正しいのかな?
大手サイトとかも、空リセットしてますよね?
0037nobodyさん2011/02/19(土) 15:42:41ID:???
普通そうするだろ
0038nobodyさん2011/02/19(土) 15:45:56ID:???
ということは大手サイトも
個人ユーザーの暗号化前のパスワードは保持していないのかな?
それって普通?

結構同じパスワードをいろんなネットサービスにおいて使ってるんだけど、
サービスの運営はユーザーのパスワードは把握できない仕組み!?
0039nobodyさん2011/02/19(土) 15:52:20ID:???
パスワードを平文で保存してたら
漏れた時しゃれにならんぞ
0040nobodyさん2011/02/19(土) 15:59:40ID:???
でもメアドとかも平文で保存してるでしょ?本名も
0041nobodyさん2011/02/19(土) 16:09:05ID:???
何を言ってるの?Cake以前の話だろ。
0042nobodyさん2011/02/19(土) 16:18:50ID:???
>>35
例えば$js->linkとかでリンク先やパラメータに変数を渡したり
メッセージを国際化したいとかそういう時はJsHelper使ったら楽でしょ。

もちろんJsHelperだけでは足りない部分もあるから場面によって使い分ければいい。
0043nobodyさん2011/02/19(土) 16:19:05ID:???
>>41
まぁ、そういうな

>>40
通常は可逆式の暗号化をしておいて、
メール送信などで利用する時だけ
元のメアドに戻してメールするのが普通だよ。
0044nobodyさん2011/02/19(土) 16:59:48ID:???
>>35
JsHelperってjQueryなどの一部のメソッドをphpから呼べるみたいだけど、
正直jQuery書いたほうが書きやすいし、使う気にはなれないな。
普通にjQueryが書ける人ほど、あまり意味の無いヘルパーだと思ってる。

>>38
サイト運営者がユーザーのパスワード見れたらまずいだろう。
自分で運営してるほぼ個人サイトならともかく、
あまり信用できないバイトとかもスタッフに居るケースもあるんだぞ。
バイトが何かやらかしても、自分(自社)に責任が来るんだから、
パスワードの平文はやめとけ。

だから、パスワードはハッシュしか残さないのが普通だな。
非可逆なものだから、パスワードリマインダーは、
ユーザー登録と同様に、短時間有効なトークン付きの
パスワード再設定URLを、登録時のメールアドレスに送るのが良くある実装。
0045nobodyさん2011/02/19(土) 17:09:31ID:???
>>44
なるほど。勉強になるよ。
メアドとかはハッシュにするもんなの?
0046nobodyさん2011/02/19(土) 17:42:55ID:???
パスワードを完全ハッシュ化(難読化)する事って常識だと思うんだけどな・・・
会員制サイト作るならまずそこから勉強するだろ。
>>45は完全独学かよ。知識なさ過ぎる。
0047nobodyさん2011/02/19(土) 18:17:19ID:???
>>45
ヒント:ハッシュは非可逆暗号で作られている
0048nobodyさん2011/02/19(土) 18:21:28ID:???
>>46
会員制サイト作る際の、そういう細かい点まで教えてくれるサイトあったら教えて
0049nobodyさん2011/02/19(土) 18:25:35ID:???
cake使っていて知らないとは・・・?
0050nobodyさん2011/02/19(土) 19:55:20.04ID:???
CakePHPのctpを使いたくないです
テンプレートと入れ替える方法どこかに載ってないでしょうか
0051322011/02/19(土) 20:00:34.20ID:???
ありがとうございます。

>>33
なるほど、専用のクラスがあるんですね。
というか、Cookbookに載ってますね。勉強不足でした。

>>34
最初その方法を考えたんですが、前述のとおり違和感があったので悩んでました。
でも結構メジャーなWordPressがその方法を取っているってことは、パフォーマンス的には良い方法なんですかね?
0052nobodyさん2011/02/19(土) 21:05:10.89ID:???
WordPressの開発思想は独特だよ。
DRYを積極的に無視してクラスもなるべく作ってない。
メリットは、入り組んだクラス呼び出しや
汎化してぱっとみなんの処理か分かりにくいコードが少ない。
だからプログラミングが苦手な人でも、改造したいところを変えれば、
あまり他に影響させずに改造できる。
デザイナーなどの支持を得ての普及だね。
それもひとつのやり方だけど、
コードが読みにくいし俺はあまり好きじゃないな。

設定がDBにあるのは、そういった考えの下、
管理画面から変更できるようにするためだろうね。
WordPressは基本的に設定ファイルを変えて、アップロードとかする必要が無い。
0053342011/02/19(土) 22:02:05.74ID:???
>>51
パフォーマンス的にはSQLを一回投げる分悪くなりそうだけど、
>>52の言うように、管理画面からいろいろ設定を変えたりすることを考えると
DBで保持してた方が更新が楽な気がするなあ
「絶対固定!」って値ならファイルのどこかに書いちゃってもいいと思うけど
0054nobodyさん2011/02/19(土) 22:18:34.42ID:???
まったくお勧めはしないけどね。
WordPressはオープンソースで配布して使うから、
ブログ名の設定が管理画面から出来る必要があるだけだし。
そういう設定なんて早々変更はしないでしょ。
開発者が設定ファイルを変更するなんて簡単だし、
DBに入れるほうが余計なトラブルの元さね。
設定をDBに入れると、開発中のデバッグで泣きを見ると思うよ。
0055nobodyさん2011/02/20(日) 00:35:05.01ID:???
そうそう。外部ファイルにまとめられるならその方が良い。
0056nobodyさん2011/02/20(日) 02:37:47.09ID:???
俺は、サイト用の設定はDBでとアプリ用の設定はファイルでって言う風に分けてるよ。
使い回しする時に楽だからね。

サイト名とかサイト説明とかそういうのはDBで管理画面からいじれるように。
画像置き場のパス設定だとか外部APIのTokenみたいなのは設定ファイルに入れとくって感じで。
0057nobodyさん2011/02/20(日) 02:45:57.34ID:???
ん?Configure::write()を使えば設定ファイル書き換えできるんですよね?
それならDB使わなくても管理画面から弄れる様に出来ません?
0058nobodyさん2011/02/20(日) 03:08:54.00ID:???
>>57
違うよ。write()はConfigureクラスのインスタンスに書き込むんだよ。
0059nobodyさん2011/02/20(日) 03:24:35.31ID:???
>>58
Configure::storeを上手く使えばok?
0060592011/02/20(日) 03:31:43.25ID:???
ttp://logsoku.com/thread/pc11.2ch.net/php/1229669539/935-944
だめっぽいですね。結局DBか…。
0061nobodyさん2011/02/20(日) 11:43:48.57ID:???
セッションをDBに保存している場合、
定期的(?)に古いセッション情報を削除しているらしく、
そのタイミングでDB側が処理に詰まってしまう。
誰か解決方法教えてください。
0062nobodyさん2011/02/20(日) 16:20:03.81ID:???
通常のフォルダとSSL用のフォルダに分かれてるサーバーの場合、
どうやって配置すればいいんだろう?
0063nobodyさん2011/02/20(日) 16:31:12.20ID:???
http://hoge.com/username
へ行った時に

hoge.com/users/view/username
(usersがコントローラー、viewがアクション、usernameがパラメーター)

の内容を表示させるには
routes.phpをどのように表示させればいいでしょうか?

ここの部分以外は

http://hoge.com/controller/action/parameter

と通常の形にしたいです
0064nobodyさん2011/02/20(日) 18:00:18.41ID:???
これ使えないね、初心者用
0065nobodyさん2011/02/20(日) 19:54:03.09ID:???
>>63
usernameがパラメーターである条件が明確じゃないと
両方のパターンを共存させるのは無理くさいな
やるとしたらroutesじゃなくてrewriteの分岐だろうね
例えばusernameの先頭1文字が数値の場合はパラメータとして判別するとか
0066nobodyさん2011/02/20(日) 21:45:26.61ID:???
>>63
routesで先にユーザーページ以外のURLにマッチするパターンを羅列して振り分ければ?
あとはユーザーネームとしてあり得るパターンの正規表現を使うか
0067nobodyさん2011/02/21(月) 00:10:51.01ID:qx7ew/PU
フォームを全て空白で送信し、controller内で
if($this->User->validates()) {
echo "ok";
}else {
echo "ng";
}

だったときに必ずOKになってしまいます。
modelのvalidation定義で下記のようにしたらしたで、
条件を満たしてるのバリデーションエラーが出っ放しになります。
これって解決できますか?

public $validate = array(
'username'=>array(
array(
'rule' => 'alphaNumeric',
'required' => true,
'message'=>'Username has to be 10 to 20 alphaNumeric characters!'
),
array(
'rule' => 'isUnique',
'required' => true,
'message'=>'This username is already in use.'
),
array(
'rule' => array('between', 10, 20 ),
'required' => true,
'message'=>'Username has to be 10 to 20 alphaNumeric characters!'
)
),
)
0068nobodyさん2011/02/21(月) 00:24:48.77ID:qx7ew/PU
すみません、補足で質問させてください。

validationって基本的に if($this->User->save($this->data)){} と絡めて使いますよね。

他の判断条件も組み合わせた時、
入力フォームのバリデーションエラーも一緒に出力したい場合ってどうすればいいですか?

下記だと、まず他の条件を先に判定してしまうため、他の条件判断が満たされない場合は
$this->dataのバリデーションエラーが出力されません。何かスマートな方法をご教授くださいませ。

if(他の条件判断){
 if($this->User->save($this->data)){
 echo "saved!";
 }
}else{
echo " ERROR!! 他の条件が満たされていません!"
}
}


■ このスレッドは過去ログ倉庫に格納されています