PHPでOOPat PHP
PHPでOOP - 暇つぶし2ch100:1 ◆SWtzLesEmM
07/07/11 12:59:29
例外処理
URLリンク(www.phppro.jp)

2. PHPで例外処理
URLリンク(www.phppro.jp)

PHP5の基本 > 例外処理
URLリンク(www.shigeweb.jp)

phpspot - 例外処理
URLリンク(phpspot.net)

PHP4ではエラー処理といえば、
if ( ($err = func()) != "" ) {
  die("エラーです");
}
のように戻り値のチェックをしていましたが、エラーというものは、呼び出し側がエラー制御を行うのではなく、呼ばれた側で、どういうエラーがあったか、というものがあった方が自然で、呼ばれた側がエラー処理を行うため、モジュールの場合より再利用性が高くなるでしょう。
更に上記では、どういうエラーが起こってエラーが出ているのかということが想像しにくいですね。
そこで try~catch です。

■例外処理
URLリンク(www.atmarkit.co.jp)
プログラミングにエラー処理は避けて通れない事項だ。
とはいえ、関数やメソッドからの戻り値を毎回エラーチェックするのは煩雑で面倒でもある。
その煩雑さを回避するため、文法として例外処理を持っている言語もある。
PHP5もそれに倣って、言語仕様として例外処理をサポートした。
文法的にはC++やJavaと同様に、try{ }で投げられた例外をcatch{ }で処理するという流れになる。

↑とのことですが、汎用性のある関数やメソッドにしたい場合、エラーが発生したときの処理を書く場所は、関数やメソッドを使う方(呼び出す側)にすることもあるでしょうか?
=戻り値をチェックするというのは、古いやり方なんでしょうか?


101:1 ◆SWtzLesEmM
07/07/11 13:07:20
>>96
PHPプロのメルマガ読んで、知ったかぶりなだけですw
お互いがんばりましょう☆(・∀・)


102:nobodyさん
07/07/11 14:16:38
いやさ,まず公式マニュアルを読む癖を付けようぜ

103:nobodyさん
07/07/11 14:44:53
MVCじゃないとOOPなんて意味ないですかr

104:nobodyさん
07/07/11 17:30:14
( д)      ...。。

105:nobodyさん
07/07/12 02:57:31
MVCもデザインパターンの一種じゃなかったっけ?

106:nobodyさん
07/07/12 08:06:18
>>100
なんかphpspotのその文はおかしいな。
エラー処理は例外を使おうがそうじゃなかろうが変わらない。
呼ばれた側はどういうエラーがあったか返す責任があるし、
呼んだ側は返ってきたエラーをチェックする責任がある。
エラーが起きた時の挙動を自分で決めれるならその場で処理すれば良いし、
そこではまだ決められないならさらに上位へreturnなりthrowすれば良い。



107:nobodyさん
07/07/14 15:28:38 w3CTKtks
OOPってのはアプリケーションをモノに見立てて、それを構成している部品をクラスとして定義する、ってとこまではなんとなく理解した。

例外処理?なにそれうまいの?

108:nobodyさん
07/07/14 18:34:23
ダンボールの味がするお

109:nobodyさん
07/07/14 19:32:25
おまいらオブジェクト指向に騙されてるよ。ただのデータ型に過ぎない。

110:nobodyさん
07/07/14 19:46:31 w3CTKtks
今、習作としてプロフィールスクリプト(っていうのも大袈裟なぐらいショボイやつ)を書いてるんだけど、どうにも悩む。悩む。
とりあえず、
-質問と答え(Entry)
--セッタ(SetQuestion,SetAnswer)
--ゲッタ(GetQuestion,GetAnswer)
-それらのEntryを編集したり、操作したりする(ManageEntry)
--POSTされたデータにEntryの値を変更する(EditEntry)
-プロフィール自体(Profiel)
--質問と答えを出力(ViewProfiel)
こんなクラスたちを作ったんだけどなんかおかしい気がしてならない。
とくにManageEntryのとことか。
ManageEntryでEntryオブジェクトの配列Entriesを作っといてそれをそのクラス内で操作とか?は?え?
OOPムズイ、ナキタイ


スレ汚しスマソ

111:nobodyさん
07/07/14 21:29:40
どんな物を作ってるのかよく分からないけど
ぱっと見で確実に言える事は、個別のクラスが多すぎ。
半分くらい継承とメソッドの追加で済みそう。
今のままだと拡張もやり難そう。

プロフィールが"profiel"なのはつっこんだ方が良いのかな。

CakeとかSynfonyみたいな、ライブラリじゃないフレームワークを
使い込んでソース読んだら、どう設計したらよいか一気に分かるよ。

112:nobodyさん
07/07/14 22:22:33 w3CTKtks
継承とメソッドの追加ってどうやるんですか><;
正直どうやったらいいのか全くわからん。
プロフィール?え?あ?あはあは。

113:nobodyさん
07/07/15 00:13:47
きめぇ

114:nobodyさん
07/07/15 00:19:07
Synfony はつっこんだ方(ry

115:1 ◆SWtzLesEmM
07/07/26 10:21:49
>>106
>呼ばれた側はどういうエラーがあったか返す責任があるし、
>呼んだ側は返ってきたエラーをチェックする責任がある。

なるほど~(・∀・)
呼ぶ側と呼ばれた側のそれぞれでエラーの対処があれば、手堅いですね!
大変参考になりました。


116:1 ◆SWtzLesEmM
07/07/26 10:29:09
掲示板の続きを作りました。
DBにアクセスする機能をクラスにしてみました。
URLリンク(kameleon.s241.xrea.com)

動作サンプル
URLリンク(kameleon.s241.xrea.com)

なんか、>>55さんのアドバイスの形になってませんが…orz
とりあえず、DBアクセスをクラスの形にできたので一歩前進!!!\(^o^)/

117:1 ◆SWtzLesEmM
07/07/26 10:50:37
>>110
おー、ガンバレ~~~☆

>>111
(1) Entryクラス
文章を「書き込む」メソッド、「読む」メソッド、「書き換える(編集)」メソッド、「削除する」メソッドが用意されている。

(2) Entryクラスを継承して、質問用のクラスを用意
=質問のデータだけを操作できる

(3) Entryクラスを継承して、答え用のクラスを用意
=答えのデータだけを操作できる

というかんじになるんでしょうか?
どういうまとまりでクラスにすればいいのか、そこら辺がなんかよく分からないんですよねー(ノ∀`)


118:nobodyさん
07/07/26 10:57:58
どうしてPDOをry

119:nobodyさん
07/07/27 00:44:20
おんにゃにょこの
おっぱい
ぷぴにぷにだにょ~

120:nobodyさん
07/07/28 17:35:02
夏だな

121:nobodyさん
07/07/30 03:51:10
function &foo {
echo "ほげ"


こういうやつ、「リファレンスを返す」っていうんですか?
これはどういう処理をしているんでしょうか?
どこかで定義されているfoo()という関数に何かしているんですか?

122:nobodyさん
07/07/31 07:40:25
高機能な参照関数だな

123:nobodyさん
07/08/01 06:30:28 abLVM2kM
>>87
買ってしまっていたよ。Iteratorまで読んだけど、
分かったような分からないような気分。

説明が少ない&下手なのは分かった。

124:nobodyさん
07/08/01 22:18:22
分からない人に分かるように書いてないという意味では同意。
書いてあることを全て理解していこうとするとこんがらがってくるしね。
まぁいい頭の体操になったけど。
あんなサンプルのためのサンプルではなく、具体的な使い方と利点が書いてあるとOOP素人にも理解しやすかったかもね。

125:522
07/08/26 13:53:57 QzPwO1Nh
>>117
なんかCakePHP使ってみたんだけど質問と答えを操作するクラス作って云々みたいになって結局>>110と同じような感じになっちゃいましたとさ・・・
「モノ」に書く機能とか読む機能持たせていーの?おしえてえろいひと><

126:nobodyさん
07/08/26 14:28:30
お前が「モノ」をどう捉えるか次第だよ

127:nobodyさん
07/08/28 02:25:00
結局どうやってデータを保持したら、人間にとって分かりやすいか、コンピュータにとってやさしいかってことだろ。

128:nobodyさん
07/10/03 02:51:35
オブジェクト指向は木構造を再現しようとしているだけ。
インスタンスだのオブジェクトだのは枝、茎、葉、花、果実を作るというだけ。
mainでは結果(果実)だけをとりたいから枝やら茎やらは見えなくしとけってことだろ?

129:nobodyさん
07/10/03 16:27:59
>>128
まあそんな感じだ

130:nobodyさん
07/10/03 23:45:33
まぁ、ファイルの管理方法も木構造だし、インターネットなんていっても網状でなく、
サーバーを経由した木構造になってることから演算機が理解しやすいデータ構造は木構造である。
こういってしまっても過言ではないと思う。


例えば、手続き型は東京の小さなバイク便が地方への配達を頼まれても東京発で請け負うみたいなもの。
それに対して、OODはヤ○ト運輸が東京で頼まれた配達を一旦、地方の配送センターに送るようなもの。
配達する対象が少なければ、バイク便に頼んだ方が早いかもしれないけど、数が多くなるとヤ○ト運輸。

131:nobodyさん
07/10/05 01:16:19
うん、ここ数日でオブジェクト思考勉強してて分かったこと。
ちなみに128==130==漏れです。

・オブジェクト指向は木構造
・目的は種の存続、繁栄
・ここでのフローは一つずつだが、間にどれだけの枝が挟まるかは設計次第

クラス設計
 種(プリプロセッサ)から芽が出る(この時点では手続き型でも、OODでもない)
 根クラス…main関数、もしくはmainクラスの設計、遺伝子(設計の違いで木になるかどうかが決定)
 幹クラス…根から養分を吸い上げる(大まかな工程の分類)

オブジェクト生成
 枝クラス…効率的に日光を取得できるよう枝を伸ばす(コンストラクタ)
 葉クラス…光合成を行い、自己生産を行う(メソッド)
 葉緑素クラス…目立たない頑張り屋さん(ライブラリ)
 花クラス…実となるか枯れ落ちるか(オブジェクト)

実行結果
 果実クラス…土に還り、新たな種となりました(プロジェクト成功)

132:nobodyさん
07/10/05 20:07:34
なんかすぐ動いて実用的で簡単なサンプルください

133:nobodyさん
07/10/05 20:35:14
package hoge;


my $class=shift;

$ENV{'TZ'} = "JST-9";
my ($sec,$min,$hour,$mday,$mon,$year) = gmtime(time + 9*60*60);
my $obj={'sec'->$sec, 'min'->$min, 'hour'->$hour, 'mday'->$mday, 'mon'->$mon, 'year'->$year};

return bless $obj, $class;

1;



適当に書いてみた。あとは時間をゴニョゴニョするだけ、普通に作ったほうがメリット大きい気もするがキニシナイ!!
ヨウカソマソ参上===[・∀・]ノシ

134:131
07/10/05 23:40:29
実際に設計して、作ってみるとオブジェクト指向の本質は"同じことは出来るだけ"しない。
この論理で動いてるような気がしてきた。何でもかんでもオブジェクトにするのではなく、
運搬の頻度が激しいデータ、プログラム中で何度も使用するデータをオブジェクトにする。
そんな感じで合ってるのかな?あと、変数の受け渡しは原則、参照で行うみたいな。

135:131
07/10/06 13:37:33
何となく掴めてきた。もっかい木構造で表してみる。

根: プリプロセッサ、送信データ(実行役)
幹: main(効率よく栄養=処理を振り分ける)

[クラス]・・・大規模にもなるとこれが幾重にもネストされる。
  枝: コンストラクタ(葉に栄養=処理を割り振る、葉で生成された養分=オブジェクトを幹に伝える)
  葉: メソッド(オブジェクト=養分を生成する)
  花: オブジェクト(実行結果=果実の手前)

果実: 実行結果(主の繁栄=実行結果が真)

ちなみに実行結果が偽となるのは幹から花に至るまででエラーが起こった場合。


漏れルール
mainは基本的にクラスに指示を与える以外しない。

コンストラクタでオブジェクトの用意を行う。
メンバメソッドはオブジェクトの加工を行う。
コンストラクタからオブジェクトを返す。

mainは次に必要なオブジェクトを作るクラスへ処理を回す。

136:nobodyさん
07/10/07 12:52:54
日曜日1GET!
始めまして
まだPHP3ヶ月目ですが早くもオブジェクト指向で挫折><
ちなみに
・「基礎PHP」
・「PHP5であなたもウェブアプリが作れる!」
・「速効!図解プログラミングPHP + MySQL」
を参考書にしています。

分かりやすかったのは基礎PHPです。
掲示版からスケジュール管理に移るところで
Smarty関連を追加するため承継とか出てきてなるほどと思いました。

ただソース理解しても自分では何もできないんですけどねw

137:nobodyさん
07/10/07 19:12:30
掲示板の改良はどうします?


138:nobodyさん
07/10/07 21:04:45
丸投げします

139:nobodyさん
07/10/07 21:09:36
OOPで作ったやつの
ソースとかうpったら
なんか色々言ってもらえるんかな?
このスレでは

140:nobodyさん
07/10/07 21:46:16
>>139
自分も変なソースですけど味見してもらえます?
恥ずかしいです><

141:nobodyさん
07/10/08 09:30:37
>>133
これをどうやって使えばいいんですか

142:nobodyさん
07/10/08 19:27:30
なかなか面白いブログを発見しました。
ぜひ皆さんに見てもらって意見聞きたいな^^

URLリンク(blogs.itmedia.co.jp)


143:nobodyさん
07/10/09 22:34:59
MVCのコントローラについてどこまでクラスにするか迷っています・・・

144:nobodyさん
07/10/10 16:06:50
ハァ?

145:nobodyさん
07/10/12 03:46:51
意味わかんね
どこまでクラス?

146:nobodyさん
07/11/12 13:32:18
まずはモデルでしょ

147:nobodyさん
07/12/13 08:37:25 Q/a8rTy0
SPLって使ってる人実在するの?

URLリンク(jp2.php.net)

148:nobodyさん
07/12/14 02:09:52
例外はよく使う

149:nobodyさん
07/12/19 01:29:29
>>147
読み込んでも八割がた無駄なので使わない

150:nobodyさん
07/12/23 12:51:26
かしゆか誕生日おめでとう!
URLリンク(www.tkma.co.jp)


151:nobodyさん
07/12/24 10:55:41
>>149
つりですか?

152:nobodyさん
07/12/29 00:05:37 4ZpocZiG
MVCのCってどうやって書けばいいのかわからんぜ。

153:nobodyさん
07/12/29 02:00:56
その概念中でコントローラーが理解出来ないってやつ初めてみた

とりあえずView上で必要な操作を徹底的にControllerに切り離すが良い。
そしてModelからデータを引き出して必要があれば書き込み更新してやりなさい。

154:nobodyさん
07/12/31 19:44:35
ユーザークラスで新規登録処理をして、そのときにユーザークラスの中で
プロフィールクラスのオブジェクトを作ってプロフィールの登録もする

これってしいて言えば何パターン?

155:nobodyさん
07/12/31 19:47:57
ワンパターン

156:nobodyさん
08/01/01 00:16:32
パターンというかコンポジションでそ

157:nobodyさん
08/01/29 11:18:04
模範解答は無いけれど、以下の相互変換を行うクラス(ChStr)をみんなで
作ってみるという案はどうかな?
そして、これが出来たら、ログファイルに保存などの機能をつけ、
wikiみたいに編集が出来る機能を追加していくという感じに。

<編集>
-------------------------------------------------------------
= 2ch
'''2ch'''とは、総合掲示板のことである。
link:[URLリンク(www.2ch.net])<)">URLリンク(www.2ch.net<)
-------------------------------------------------------------

158:1 ◆SWtzLesEmM
08/01/29 11:29:32
>>157
OOPの勉強というよりも、どちらかというと正規表現の勉強になるでしょうか?
wikiのパーサーつくるなら、既存のwikiスクリプトや、PEARのText_Wikiが参考になるかもしれませんね。

URLリンク(www.phppro.jp)
PEAR::Text_Wiki 1.2.0RC1 リリース 2006年10月11日
URLリンク(labs.cybozu.co.jp)
Text_PukiWikiリリース

159:nobodyさん
08/01/29 11:43:55
>>158
C++のOOPの勉強として、文字列を簡単に扱うことが出来るクラスを
自作してみるという演習があったので、それをPHPでもやってみようかなと
思ったものです。
Cでは、文字列を結合したり、splitしたりするのが結構大変なので、
この演習が役に立ったなと思っていたのです。
PHPの場合は、関数を使えばそれで終わってしまうので、もう少し
ひねりを入れたものを考えて見ました。

正規表現を練習するというよりも、正規表現とhtmlの相互変換をする
クラスがあると、プログラムをする際、便利だなという事が実感
出来るのでは?という意味合いです。

(例)正規表現を格納し、html出力する過程。
$text に textarea タグの文字列を格納する。
$str = new ChStr($text);
echo "<html><body>";
$str->Write_html();
echo "</body></html>";

ほら、このクラスがあるとレイアウトを変えたりが、やり易い上に
再利用性が高いでしょ?みたいな。

160:1 ◆SWtzLesEmM
08/01/29 11:47:24
OOPの参考になる解説がありました。

PHPのclass、オブジェクト指向プログラミングに関する質問です。
URLリンク(q.hatena.ne.jp)

2番の回答者の解説が分かりやすいと思いました。
6番の回答者のサンプルコードも参考になりましたが、これは「インターフェース」の利用方法ではありませんね。><

インターフェイス
URLリンク(www.phppro.jp)
あるクラスが実装する必要があるメソッドの種類を、これらのメソッドの実体を定義することなく、指定するコードを作成できるようになります。
インターフェイスはキーワードinterfaceにより定義され、通常のクラスと同様に定義することができますが、メソッドの実装は全く定義されません。

161:1 ◆SWtzLesEmM
08/01/29 12:00:16
>>159
なるほど!(・∀・)
文字列を扱う処理は、いろんなところで出番がありそうですね!
wikiの文法(表記方法)が使える掲示板とか作れそう^^

162:nobodyさん
08/01/29 12:04:23
ChStr クラス の設計はこんな感じかな。

メンバ
private $m_str; // 正規表現文字列を格納する。

コンストラクタ
ChStr($str) // 正規表現の文字列を受け取る。

private メソッド
ch_to_html() // 正規表現をhtmlに変換する。

public メソッド
Write_html() // 格納している文字をhtmlで出力する。
Write_text() // 格納している文字を正規表現で出力する。

---------------------------------------------------
本当は、ログファイルへの保存や読み取りなどを機能として
考え、そのあたりまで含めたクラスの設計をした方が
いいんだろうけれど、まずは簡潔にする方向でいきます。
で、後々拡張の方向で。

163:1 ◆SWtzLesEmM
08/01/29 12:04:44
PHPのインターフェースは、Javaとかのインターフェースとはちょっと違っているみたいですねー。><
(…使ったことないので実感がありませんが^^)

PHPでは実装済みのinterfaceを多重に実装できない
URLリンク(blog.xole.net)
URLリンク(blog.xole.net)

164:1 ◆SWtzLesEmM
08/01/29 12:25:09
>>162
こんなかんじのプログラムと似ているかもしれませんねー。

60行で作るPHP用テンプレートエンジン
URLリンク(anond.hatelabo.jp)
>テンプレートの中身を置換する
>function convert_string($s)

↑置き換えるパターンに応じて、別々のメソッドを用意したら便利でしょうか?
= 文字サイズ変更、''' 強調、link: リンクとかの記法の置換を担当するprivateメソッド

165:1 ◆SWtzLesEmM
08/01/29 12:34:03
OOPの参考になる解説がありました。

関数、オブジェクト、クロージャ
URLリンク(d.hatena.ne.jp)
>オブジェクトは、データに処理がくっついたものです。
>array.map()のように、後に後に処理を追加していく書き方は、順にコードを追えるため読みやすく、また書きやすいです。

クロージャっていう仕組みは、PHPにはないですね?><
大は小を兼ねる…クロージャの代わりにオブジェクトが使えればとりあえずOKかな?(・∀・)

166:nobodyさん
08/01/29 13:15:31
>>161
>wikiの文法(表記方法)が使える掲示板とか作れそう^^

PEARのText_Wiki使えばよくね?

167:nobodyさん
08/01/29 13:18:38
>>164
> 置き換えるパターンに応じて、別々のメソッドを用意したら便利でしょうか?
本来ならば、そうなるでしょうね。それらはすべてprivateで作っておいて、
外部には、一つのインターフェースのみ(この例の場合はWrite_html()がそれに該当)
公開となるでしょう。
記号ごとに別々にメソッドを定義しておけば、記号とhtmlの関係が変わる時は、
どのメソッドを触ればよいかが分かるし、それを変更したことで、
他のメソッドには影響は無かったりします。
(これが構造化プログラムの場合は、目的のソースと目的ではないソースを
見極めるところから始まります。)

-------------------------------------------------------------------------
この ChStr に汎用性を持たせる場合は、Write_html()というよりも、
Get_html()とし、html文字列を return する事になるでしょう。
そうすると、別なプログラムで、「出力結果をファイルに保存する」という
使い方も出来ます。しかし、今回は初回なので、Write_html()とし、
メソッド内部で echo 使うことにします。

168:nobodyさん
08/01/29 13:22:48
>>166
学ぶために具体的に物を作るのと、実用性を考えて物を作るのは
別だと思う。なので、今回はこれでいいと考えている。
現に、初心者向けの書籍に載っているソースの実用性はゼロだ。

169:nobodyさん
08/01/29 13:59:05
とりあえず、全体構成の確認のために書いてみた。
ch_to_html()は、追記の必要性がある。
[chstr.php]
<?php
class ChStr {
// メンバ
var $m_str_reg; // 正規表現文字列を格納する。
var $m_str_html; // html文字列を格納する。
// コンストラクタ
// 正規表現の文字列を受け取る。
function ChStr($regstr) {
$this->m_str_reg = $regstr;
$this->ch_to_html();
}
// private メソッド
// 正規表現をhtmlに変換する。
function ch_to_html() {
// 改行を<BR>に変更する。
// nl2br($this->m_str_reg) 使った方がいいかも
$this->m_str_html = ereg_replace("\n","<BR>",$this->m_str_reg);
}
// public メソッド
// 格納している文字をhtmlで出力する。
function Write_html() {
echo $this->m_str_html;
}
// 格納している文字を正規表現で出力する。
function Write_text() {
echo $this->m_str_reg;
}
}
?>

170:nobodyさん
08/01/29 14:03:31
[index.html] 最初に開くファイル。
<html><body>
<form method="POST" action="./text.php"><textarea name="reg_text" cols=40 rows=4>
あああああ
いいいいい
ううううう
</textarea><br>
<input type=submit value=" 送 信 "></form>
</body></html>


[text.php]
<html><body>
<?php
include("./chstr.php");
$in_text = $_POST["reg_text"];
$chst = new ChStr($in_text);
$chst->Write_html();
?>
</body></html>

171:1 ◆SWtzLesEmM
08/01/29 14:10:04
>>166
確かにそうなんですが、「勉強のため」という目的もあるので、自分で作ってみるというのもありでしょうか?^^
でも、答えが分かっている問題を解くのは楽ですね。>Text_wiki

車輪の再発明 - Wikipedia
URLリンク(ja.wikipedia.org)
車輪の再発明とは、「広く受け入れられ確立した技術や解決法を無視して、同様のものを再び一から作ってしまう事」を意味する
ある技術の意味を理解させるために、意図的に車輪の再発明を行わせる場合がある


172:1 ◆SWtzLesEmM
08/01/29 14:19:35
wikiとか文字列を処理する仕組みは、「パーサー」とか「構文解析」っていうみたいですね(´∀`)

構文解析 - Wikipedia
URLリンク(ja.wikipedia.org)

今までにいろんな仕組みが考えられてきたみたい。
…本格的にやると奥が深そうだけど、一度仕組みを勉強しておいたら、いろいろ使えそうな予感!(・∀・)

↓wikiの仕組みを自分で作っている方は結構いるみたいですねー。

PHP用の汎用WikiParser作り中
URLリンク(tdiary.ishinao.net)
RandomNote/PHPについて
URLリンク(tbox.jpn.org)

173:nobodyさん
08/01/29 14:21:38
今後の課題と予定
・ch_to_html() の中身を書く。
・[text.php] の機能を充実(テキストファイルに保存するなど)させ、wikiを作る。
・上記とは別に、 ChStr クラスを使い、BBSを作る。
・ChStr クラスに clear()、SetStr() 等のメソッドをつけ加え、汎用性を持たせる。

174:1 ◆SWtzLesEmM
08/01/29 14:38:20
URLリンク(tbox.jpn.org)
RandomNoteのMain.phpは参考になるでしょうか?

preg_match
preg_replace
array_push
array_pop
などの関数を使って、文字列の切り貼りをしてるんですねー。

175:nobodyさん
08/01/29 14:39:05
OOPってより単にクラスの使い方書いてるように見えるのはまあいいとして
メソッドの中でstringをreturnせずにecho使うのは>>167で書いてるように汎用性って面もあるけど
処理と表示の分離って意味合いもあるからちゃんとstringで返したほうがいいよ

176:nobodyさん
08/01/29 15:39:09
>>175
> OOPってより単にクラスの使い方書いてるように見えるのはまあいいとして
OOPについて説明するとなると、具体的なソースコードとは離れた方が
良くなったりしますからね。
(クラスの使い方書いているように見えるとしても、)PHPでclassを
組む場合のメリットみたいな位置づけで学んでいこうと思っています。

> 処理と表示の分離って意味合いもあるからちゃんとstringで返したほうがいいよ
確かに汎用性以外にそういう目的もありますね。
次のものでstringで返すように書き換えます。

177:nobodyさん
08/01/29 18:16:08
htmlのformのコードもクラス化するのが本当の流れんだろうけれどな。
いきなりそれをやると分かりにくくなるかな・・・

178:に ◆lKs5QMUHoA
08/01/29 19:20:19
ChStrクラスのサンプルソースを投稿してた者ですが、
今までnobodyさんで書いてたけど、分かりにくくなるかと思ったので
酉入れるようにしてみます。

>>5に書いてあるように、オブジェクト指向は「変数を保持できる事」が
メリットだと思うのですが、これがWebアプリだとどうも実感が無かったりします。
リッチクライアントだと、マウスのクリックに合わせて、メソッドが呼び出され、
そのアプリケーションが終了するまでの間、各種オブジェクトの中の変数に
状態が保持されるという構造なので、そのメリットが感じられるのですが、
Webアプリでは、POSTする度にオブジェクトの変数の状態はリセット
されてしまうので、クラスを書いたとしても、結局はグローバル変数から
各種オブジェクトの変数に代入するみたいなコードを書かなくては
ならなくなってしまうので、このメリットがあるのかと思ってしまうのです。

これは、勉強不足だからなのでしょうか。。。

179:nobodyさん
08/01/29 22:51:04
>>160
他の人の話のほうがよっぽど核心を突いてるよ

180:nobodyさん
08/01/29 23:05:47
>>160のはてなのリンクの4番目の話、2chの別の板でも
読んだことがあるけれど、この話本当なの?
具体的に何処でどういう商売をしての話なんだろうか。
アプリケーションを売る話?それとも開発環境用のソフトを売る話?

181:nobodyさん
08/01/30 21:59:22
ピュアな意味でオブジェクトを操作したいなら
ボタンのクリックに関する全ての画面遷移に関してserializeとunserializeを管理する必要があるだろ

<?php

require_once("hiroyuki.class.php");

$hiroyuki = unserialize($_SESSION["hiroyuki"]

182:nobodyさん
08/01/31 07:20:40 NaJ3keB3
>>178
ユーティリティクラスの再実装みたいな事を熱心にやっても
あまり意味が無いと思いますよ。

まさにあなたの言う「いちいち書くのがめんどくさい」のを回避する為に
OOPがあるんだと思います・・・

OOPの勉強なら、簡単なWEBフレームワークを自作するのが一番良いよ。
知識の無い段階でいきなりPHPでOOPって無理だと思いますよ。

背伸びせず、まずjavaやC#を学習する方が近道かもしれないよ。

183:nobodyさん
08/01/31 08:15:31
.NET 以降の VisualBasic ってどうなの?

184:nobodyさん
08/01/31 17:31:43
MVCモデルにそって、ユーザの入力データと、CSVファイルのデータを
読み込んで表示させるというものを作ってみました。

ファイル:全部で5つ。index.phpを実行する。
cfcontrol.php
cfview.php
index.php
cfmodel.php
csv.txt

[csv]
aaa,bbb,ccc

[index.php]
<?php
include("./cfcontrol.php");
$form_str = $_POST["form"];
$in_str = $_POST["key"];
$form = new CFControl($form_str, $in_str);
?>

185:nobodyさん
08/01/31 17:32:35
[cfcontrol.php]
<?php
include("./cfview.php");
include("./cfmodel.php");
class CFControl{
function CFControl($form_str, $in_str){
if( ($form_str == "")or($form_str == "in") ){
$form = new CFView("index.php","in","");
$form->Write_HTML();
}elseif($form_str == "out"){
$da = new CFModel();
$dat = $da->ReadDat($in_str);
$form = new CFView("index.php","out", $dat);
$form->Write_HTML();
}
}
}
?>

186:nobodyさん
08/01/31 17:33:57
[cfmodel.php]
<?php
class CFModel{
var $m_csv_file;
// コンストラクタ
function CFModel(){
// 読み込むCSVファイルを指定
$this->m_csv_file = "csv.txt";
}
// データを取り出す。
function ReadDat($str){
$INFILE = fopen($this->m_csv_file,"r");
$line = fgets($INFILE, 1024);
fclose($INFILE);
$line = $line . ", " . $str;
return $line;
}
}
?>

187:nobodyさん
08/01/31 17:37:50
[cfview.php](1/2)
<?php
class CFView{
var $m_file; // POSTするファイル名
var $m_type; // 表示するフォームの種類。in か out
var $m_line; // 表示するデータ
// コンストラクタ
function CFView($file, $type, $line){
$this->m_file = $file;
$this->m_type = $type;
$this->m_line = $line;
}
// private
function in_html(){
echo "<html><body>";
echo '<form method="POST" action="' . $this->m_file . '">';
echo '<input type="hidden" name="form" value="out">';
echo '<input type="text" name="key"><input type="submit" value="送信">';
echo "</form></body></html>";
}

188:nobodyさん
08/01/31 17:39:35
[cfview.php](2/2)
// private
function out_html(){
echo "<html><body>";
echo '<form method="POST" action="' . $this->m_file . '">';
echo '<input type="hidden" name="form" value="in">';
echo "$this->m_line<br>";
echo '<input type="submit" value="戻る"></form></body></html>';
}
// public
function Write_HTML(){
if($this->m_type == "in"){
$this->in_html();
}elseif($this->m_type == "out"){
$this->out_html();
}
}
}
?>

189:nobodyさん
08/01/31 17:51:38
フレームワーク使えば?

190:に ◆lKs5QMUHoA
08/01/31 19:03:23
とりあえず、MVCに分けて枠組みを作ってみたけれど、
これをより抽象化させていって、「継承して使ってください」という
方向にするのか、それとも最初はクラスの数を増やさないように
しながら簡単なアプリケーションを作る方向にするべきか。
どっちの方向に持っていったほうがいいのか迷うな。。。

ま、そんなことを考える暇があったら手を動かしてみろという
話なのかもしれないが。。

191:nobodyさん
08/01/31 19:08:05
>>190
自分で考えるのも良いが、君が今やっていることを
やってしまっているのが、フレームワークだ。

まず既存のフレームワークがどうなっているのか参考しろ。

192:nobodyさん
08/01/31 19:44:25
俺も初心者だからこれが最善とは言い切れないけど
newするときに全部引数で渡すってのはナシじゃね?
分かりやすいところだけ書き出すと
[index.php]
$form = new CFControll();
[cfcontrol.php]
コンストラクタ()
{
 $form_str = $_POST['form'];
 $in_str = $_POST['key'];
 if(inだったら){
  $view = new CFView();
  $view->m_type = 'in';
  $view->Write_HTML();
 }
}
[cfview.php]
メンバ変数
var $m_file = 'index.php';
var $m_type = false;
var $m_line = null;

193:192
08/01/31 19:50:52
フレームワーク使ってみろっていうのは賛成
疎結合にとかDRYにっていうのがだんだんわかってきた
理解したところで戻ってきて~の方が結果的に早そう
俺はまだ勉強中だからそこまで行ってないけど

194:に ◆lKs5QMUHoA
08/01/31 19:56:23
>>192
> $view = new CFView();
> $view->m_type = 'in';
これみたいに、直接メンバにアクセスするのは構造的に良くないと聞いたことが
あるよ。「データをやり取りするのは、インターフェースを通じて」という原則を
守るべきだと。
そうしなければ、CFViewクラスを改変する人は、そのクラスを使っている人の
コードを考慮して、メンバの値や変数名を自由に変える事が出来なくなるから。

なので、私は、コンストラクタで値を渡しても良いし、コンストラクタで値を渡して
いなければ、値を渡すためのインターフェースを使って渡すようにする仕様が
適当かなと思っている。

195:192
08/01/31 20:08:35
汚染されちゃうけどコンストラクタで全部の値渡すよりはましじゃないかなあ
あとコンパイルするときに全部チェックしてくれる言語とそうじゃない言語ってのもある
phpなんだしゆるーくやればいいじゃん なんていうと怒られるかw

196:に ◆lKs5QMUHoA
08/01/31 20:13:09
今調べて知ったのだが、オーバーロードは PHP ではできないらしい。
だったら、コンストラクタで値を渡すよりも、インターフェースで値を
設定するような仕組みになるだろうね。
コンストラクタだと、一度値を設定したら、そのオブジェクトが破棄される
まで、再度設定が出来なくなるから。

197:nobodyさん
08/01/31 20:22:00
メンバ変数へのアクセスはsetter/getterを使う。これは議論の余地なし。
それを用意した上でコンストラクタに引数を渡すなら渡せば良い。
複雑で多くの設定をしなきゃならない時以外、
newした直後に使える状態になっている方が使いやすい。
> $view = new CFView();
> $view->m_type = 'in';
これをセットで書かなきゃならないなら、
> $view = new CFView('in');
と書きたい。



198:に ◆lKs5QMUHoA
08/01/31 20:26:00
私は>>197さんの意見に同意だ。
「このモジュールを使う場合、このように書いてくださいね。」
というコードは、なるべく少ない方がいいからね。
なので、とりあえず設定の値はコンストラクタにいれるという
設計で書いてみた。

199:に ◆lKs5QMUHoA
08/01/31 20:31:34
とりあえず、フレームワークを使ってみろという話が出ているが、
具体的にどのフレームワークを使って、どんなプログラムを書いて
みたらいいのか迷うなぁ。

とりあえずはこのあたりに載ってるものの、「和モノ」あたりからかな。
スレリンク(php板:3番)

フレームワーク自体の自作の話もいくつかあるみたいだ。
URLリンク(codezine.jp)

200:192
08/01/31 20:36:05
viewに渡すデータはセッタで渡したくならない?
あとinなのかoutなのか分岐させるとしたらそれはコントローラ側の仕事なんじゃないかなと思うんだけど違うかな

201:192
08/01/31 20:42:33
いや、見直したらそう書いてた
ごめん気にしないで

202:に ◆lKs5QMUHoA
08/01/31 20:46:31
>>200
> viewに渡すデータはセッタで渡したくならない?
表示させるデータはセッタがいいだろうね。

> あとinなのかoutなのか分岐させるとしたらそれはコントローラ側の
> 仕事なんじゃないかなと思うんだけど違うかな
>>185のソースがそれにあたるものだと思ってたけど。
if( ($form_str == "")or($form_str == "in") ){
 省略
}elseif($form_str == "out"){
 省略
}
コントローラは、POSTしてきた値を見て、必要なModelやViewを
選択し、実行する役割なので、それを実現したつもり。

203:に ◆lKs5QMUHoA
08/01/31 21:58:27
厳密にMVCを分けることは出来ない場合もあるということだけど、
CFControlクラスで、CFViewを使って表示する内容までもを
指定していする処理を書いていたのは間違いかな?

検索結果の表示や、データの更新の場合は、
Control→Model→View だけど、
ボタンを押した時の画面の展開のみの場合は、
Contol→View という流れとなり、Viewオブジェクトを
生成するクラスが異なるという処理でいいのかな?

204:に ◆lKs5QMUHoA
08/02/01 07:38:53
「とりあえずはフレームワークを使ってみろ」という返事がきそうだけど、
各クラスの役割は以下のような感じでいいかな?

Control
・POSTでデータを受け取り、その値に不正なものが無いかをチェック。
・変なところからのアクセスではないかをチェック。
・$_POST["Form"]の値をみて、それに必要な画面と処理を判断する。

Model
・SQLを発行し、データを受け取る。
・データをViewクラスに渡す。

View
・フォームを表示する。(フォームごとにクラスを分けたほうがいいのかは迷うな)
・データを1件受け取り、tableタグでレイアウトを調整し、表示する。

205:nobodyさん
08/02/01 09:44:17
とりあえずはフレームワークを使ってみろ

206:nobodyさん
08/02/01 11:08:23
自分なりに調べて見つけたPHPのサンプルを使った解説ページも
読むとwebアプリについて学べるのではないかと思っている。
やることが多くなったけれど、とりあえずは以下の3本だてで
勉強してみることになるのかな。

MVCに分けて、簡単なアプリを自作する。
(ログイン、メニュー、検索条件指定、検索結果、データ編集などの画面があるもの)

和モノフレームワークを使って学ぶ。
簡単なアプリを自作する。
スレリンク(php板:3番)

サンプルで理解! フォームデータの受け渡し
URLリンク(www.atmarkit.co.jp)

207:nobodyさん
08/02/01 12:06:10
ちいたんのソース見てみたけれど、
class CObject ってあって、必ずそれが継承されて作られてるよね。
これの都合って何なんだろう。(メリットは何?)
javaも.NETもこういう基本クラスがあるよね。

208:nobodyさん
08/02/01 12:19:15
全部のクラスに共通するメソッド等が実装できる

209:nobodyさん
08/02/01 13:06:22
>>208
サンクス。
でも、オーバーロードが出来ない場合は逆に足かせになる可能性もあるね。
例えば、継承されているクラスが沢山ある状況でObjectクラスに
メソッドを追加する場合とか。

210:nobodyさん
08/02/01 16:28:22
喋るのはコントローラとモデル
コントローラとビュー
基本的にはね

211:nobodyさん
08/02/01 16:49:11
少ない数のクラスを書いたり読んだりする程度であれば、すぐに分かるのだが、
フレームワークレベルのクラス構造となると、その構成が全く分からなくなって
来るんだよなぁ。何かコツのようなものはあるのかな?

処理の内容を追いかけると、次々に別のクラスに処理を渡す構造になっていて、
最後はあっけない、みたいな感じだ。

フレームワークを作る場合のクラスの設計手法を身につけるなどしないと
いけないのかも。
メンバに定義はしていないけれど、メソッドではその変数をエラーが
出ないように処理が書かれているっていう書き方は多いようだ。
そうしておけば、そのフレームワークを使う人は、クラスを継承して
メンバに値を代入するだけで良い。

212:nobodyさん
08/02/01 18:37:23
このサイト、説明は分かるのだが、具体的に作っているコードは
MVCのうちどれにあたるのかがいまいちです。
URLリンク(www.stackasterisk.jp)

Result.php は、Viewにあたるものという解釈でいいんですよね?

213:nobodyさん
08/02/01 18:47:22
PHPでMVC関連のサイトを紹介で貼っておきます。

特集:第3回 PHPを思うままに操れるようになる「MVC」と「Smarty」 (1/4)
URLリンク(www.itmedia.co.jp)

214:nobodyさん
08/02/01 18:50:51
2004年って・・・・・・・

215:nobodyさん
08/02/01 20:08:38
OOPに取り付かれている人のブログ

ハタさんのブログ : : php
URLリンク(blog.xole.net)


216:nobodyさん
08/02/02 07:42:39
PHPでね、イベントドリブンなWEBフレームワークとか自作してみるといいかも。

例えば、サブミットボタンの処理ハンドラがオーバーライドで記述可能で
そこでフォーム値をモデルに渡して処理させるみたいなやつ・・

「POST」や「GET」とかローレベルの概念は全て隠蔽されてて
フレームワークにイベント発生時のロジックだけ記述して終わりみたいなの・・・

そしてPHPであれこれ試行錯誤したあと、ASP.NETとか参考にするとね
PHPでOOPするバカらしさに気付くかもしれない・・・OTL

217:に ◆lKs5QMUHoA
08/02/02 08:25:40
ASP.NET は、ちょっとだけやってみたことあるけど、概念的に違和感が
あって、やらなくなったな。
ある程度Webアプリを学んだ事のある人には便利なんだろうけれど、
初めて学ぶ人には、ドキュメントが少なすぎだし、いきなりイベントドリブンで
やるのはどうかと思った。

で、まずは、Webアプリの基礎をやるという意味合いでPerlをやってみた。
で、今はPHPをやっている。PHPそのものがOOPに完全な対応をしていない
ので、これで大規模なアプリを組むことも無いかなと思っている。
対応したとしても、それからノウハウが出てくるので、さらに数年先になる。

でも、学ぶ時は、既存のモジュールを使って早くやるのよりも、モジュール
なしの状態で、モジュールを作ってみる方がいいので、とりあえず今は
PHPでOOPです。

218:nobodyさん
08/02/02 09:56:37
>>217
多分、その違和感のある概念がOOPの本質だと思うよ。
そしてその概念は、洗礼された実装に触れることでしか
身につかないとも思うんだ。

初心者こそイベントドリブンを真っ先に学習したほうがいいよ。
最終的に、理解し易く安全な実装方法に結びつくと思うからね。

PHPでOOPで実装ってケースはありだとは思うけど、
概念は別で学習した方が効率的だと思うんだ。

219:nobodyさん
08/02/02 13:32:52
OOPに取り付かれているとか良くわからんw

普通にプログラミングしていると使うだろ?

switchに取り付かれているとかそういうレベルに聞こえるんだが。


220:nobodyさん
08/02/02 15:21:16
MVCモデルでプログラミングする場合、Model から View へ処理を渡す経緯は、
どっちが正しいのかな?
・Control クラスのメソッド内で、Model クラスと View クラスのインスタンスを生成する。
 Control クラスが、Model からデータを受け取り、View クラスへデータを渡し、
 描画指示を出す。
・Model クラスのメソッド内で、View クラスのインスタンスを生成する。
 Model クラスが、Viewクラスへデータを渡し、描画指示を出す。
 Control クラスは、View クラスを一切操作しない。

それとも、こういうところまでは理論的には定めていないので、
ケースバイケースであり、どちらがよいというものは無いということかな?

221:nobodyさん
08/02/02 15:36:53
お前は何を言ってるんだ

222:1 ◆SWtzLesEmM
08/02/02 16:44:49
PHPでイベントドリブンですか?(・∀・)

…こんなのありました。^^
PHP イベントドリブン に一致する日本語のページ 約 10,600 件

●PRADO
URLリンク(www.pradoframework.com)
>PRADO はコンポーネントベースかつイベントドリブンなウェブアプリケーションを開発するためのPHP5フレームワークです。

●S2Prado.PHP5
URLリンク(labs.s2php5.jp)
URLリンク(blog.xole.net)
>S2Baseの方は待望のPRADO対応。

●Piece Framework
URLリンク(trac.piece-framework.com)
>Piece_Unityは、Visual BasicやDelphiのようなイベントドリブンなフレームワークです。

●Delphi for PHP
URLリンク(www.codegear.com)
URLリンク(orz.qzlab.com)
>イベントドリブンなロジックの実装が容易に実現する。

●Pharon
URLリンク(pharon.lolipop.jp)
>最大の特徴は、wizard によりイベントドリブン型のスケルトンを自動作成することです。

223:1 ◆SWtzLesEmM
08/02/02 17:00:36
インターネット越しにイベント処理をさせるのが、WEBプログラミングの特徴ですね。
イベントドリブンは、PHPよりもむしろFlash/Flexとかで使われる仕組みなのでしょうか?

レガシーの中心でのOOP
URLリンク(kaede.to)
>Webプログラミングにおいて、ブラウザとのやり取りがレガシー(古典的)なデータ交換に過ぎず、これがWebプログラミングを難しくしている
>Webは1ページごとに毎回セッションが起動し、ドキュメントを表示するとすぐ終了する。
>オブジェクト指向プログラミングにおける利点の1つであるイベントドリブンなプログラミングは不可能だ。
>何しろ1セッションに1イベントしか発生しないのだから。
>と同時にセッション状態を保存する必要も出てくる。

URLリンク(www.adobe.com)
>インタラクティブ性に優れたイベントドリブンなインタフェイス

URLリンク(www.atmarkit.co.jp)
>イベント処理によってアプリケーションを構築する手法はイベント駆動型(イベントドリブン)と呼ばれます。

URLリンク(www.azul.systems-noel.jp)
>Flex2はイベントドリブンなので、ビューに起こったイベントをコントローラのリスナでキャッチするように意識すれば、MVCの分離はきれいにできるようになっています。
>なんかほんとにJavaのSwingを使ってるような気分になりますね。

URLリンク(bitmap.dyndns.org)
>イベントドリブンモデルには、主に以下の 4 つのオブジェクトが登場する。

224:1 ◆SWtzLesEmM
08/02/02 17:05:16
>>220
>・Control クラスのメソッド内で、Model クラスと View クラスのインスタンスを生成する。
こっちの方が、Controlにまとまっている分だけスッキリしており、分かりやすいコードになるんじゃないでしょうか?

225:nobodyさん
08/02/02 17:24:12
>>224
レスありがとうございます。
1番目の方にすると、Modelクラスから取得したデータを
Viewクラスに渡すことになるので、その分余計にメモリや
CPUを消費してしまうのでは、と心配になって聞いてみましたが、
考えてみると、コードの見易さなどを優先するのがOOPですので、
そちらの方がいいですね。

でも、フレームワークのソースなどを見ていると、
各クラスが、メンバに、別のクラスへのリファレンスを持ってたり
するので、もっと理論に従った組み方があるのかも、と思っています。

226:nobodyさん
08/02/02 17:36:37
>>184
ファイル:全部で8つ。index.phpを実行する。
抽象クラスと具象クラスに実装を分けてみました。
csv.txt(※前回と同じ)
index.php
cfcontrol.php

アブストラクトとして実装
cfview.php
cfmodel.php

コンクリートとして実装
data_model.php
index_view.php
output_view.php

227:nobodyさん
08/02/02 17:38:02
[config.php]
<?php

// 実際の処理を行うスクリプトをインクルード
include("./index_view.php");
include("./output_view.php");
include("./data_model.php");
// 最初に呼ばれるビューのプレフィックス設定
define ('INDEX_VIEW_PREFIX', "Index");
// モデルクラスのプレフィックス設定
define ('MODEL_PREFIX', "Data");
?>
[index.php]
<?php
include("./cfcontrol.php");
$view_key = $_POST["view_key"];
$data = $_POST["data"];
$app = new CFControl($view_key, $data);
$app->Execute();
?>

228:nobodyさん
08/02/02 17:39:03
[cfmodel.php]
<?php
class CFModel
{
var $file_name; // 読み込むファイル名
function CFModel() {}// コンストラクタ
function Execute($param) // パブリックメソッド
{
return $this->_OnExecute($param);
}
function _OnExecute($param) // 仮想メソッド
{
trigger_error('オーバーライドしてね。', E_USER_ERROR);
}
}
?>
[cfview.php]
<?php
class CFView
{
var $file_name; // POSTするファイル名
function CFView() {} // コンストラクタ
function Execute($param) // パブリックメソッド
{
return $this->_OnExecute($param);
}
function _OnExecute($param) // 仮想メソッド
{
trigger_error('オーバーライドしてね。', E_USER_ERROR);
}
}
?>

229:nobodyさん
08/02/02 17:39:58
[cfcontrol.php]
<?php
include("./cfview.php");
include("./cfmodel.php");
include("./config.php");
class CFControl
{
var $_view_key; // 呼び出すビューのプレフィックス
var $_data; // モデルに渡すデータ
function CFControl($view_key, $data) // コンストラクタ
{
$this->_view_key = $view_key;
$this->_data = $data;
}
function Execute() // パブリックメソッド
{
// モデルオブジェクト動的生成
$model_class_name = MODEL_PREFIX . 'Model';
$model = new $model_class_name();
$param = $model->Execute($this->_data);
// ビューオブジェクト動的生成
$view_key = $this->_view_key;
if ($view_key == "") $view_key = INDEX_VIEW_PREFIX;
$view_class_name = $view_key . 'View';
$form = new $view_class_name();
$form->Execute($param);
}
}
?>

230:nobodyさん
08/02/02 17:40:48
[data_model.php]
<?php
class DataModel extends CFModel
{
function DataModel() // コンストラクタで取得先のファイル設定
{
$this->file_name = 'csv.txt';
}
function _OnExecute($param) // オーバーライドメソッド
{
$INFILE = fopen($this->file_name,"r");
$data = fgets($INFILE, 1024);
fclose($INFILE);
$data = $data . ", " . $param;
return $data;
}
}
?>

231:nobodyさん
08/02/02 17:41:48
[index_view.php]
<?php
class IndexView extends CFView
{
function IndexView() // コンストラクタでPOST先のファイル設定
{
$this->file_name = 'index.php';
}
function _OnExecute($param) // オーバーライドメソッド
{
echo "<html><body>";
echo '<form method="POST" action="' . $this->file_name . '">';
echo '<input type="hidden" name="view_key" value="Output">';
echo '<input type="text" name="data"><input type="submit" value="送信">';
echo "</form></body></html>";
}
}
?>

232:nobodyさん
08/02/02 17:42:29
[output_view.php]
<?php
class OutputView extends CFView
{
function OutputView() // コンストラクタでPOST先のファイル設定
{
$this->file_name = 'index.php';
}
function _OnExecute($param) // オーバーライドメソッド
{
echo "<html><body>";
echo '<form method="POST" action="' . $this->file_name . '">';
echo '<input type="hidden" name="form" value="Index">';
echo "$param<br>";
echo '<input type="submit" value="戻る"></form></body></html>';
}
}
?>

233:に ◆lKs5QMUHoA
08/02/02 19:04:13
>>226-232
サンプルソースありがとうございます。
抽象クラスの書き方に慣れてますね。私はこのあたりを
しっかりとやってなかったのでちょっと苦手です。
ま、しっかりと勉強していきたいと思います。(^^;

ソースを読んでいて、1点気になったので質問をしたいのですが、
class CFView と class CFModel において、以下のように
パブリックメソッドと仮想メソッドを作り、パブリックメソッドから
仮想メソッドを実行する形式にソースを書いた理由は何でしょうか?
出来ましたら、この設計にした意図を教えていただきたいと思います。

function Execute($param) // パブリックメソッド
{
return $this->_OnExecute($param);
}

function _OnExecute($param) // 仮想メソッド
{
trigger_error('オーバーライドしてね。', E_USER_ERROR);
}

234:に ◆lKs5QMUHoA
08/02/02 19:24:37
>>218
レスありがとうございます。
イベントドリブンそのものは、VBでWindowsアプリを組んでやったことがあるので
すぐに入れたのですが、Webアプリを作る際、イベントドリブンでしかやった事が
無いというのは致命的だと思ったので、PerlやPHPでやってみています。
(ASP.NETは、便利ではあるが、IISを使えとか、.NET Frameworkを使えとか
非常に限定される。)

構造化プログラミングで、あまり命名規則を考えずにプログラムをしていると、
グローバル変数や関数が多くなった時、その把握が出来なくなったりする
わけなのですが、そういう苦労する体験をした後、OOPを習うと、その便利な部分が
見えてくるわけです。OOPは経験による結論的な理論だな、と理解できるわけです。
その理解のために、とりあえず、苦労をする方法(PHP で 0 から OOP)で
やってみているのです。
今は、このように考えています。

235:nobodyさん
08/02/02 19:59:40
人間て暖かいにゃぁ
ポカ・ポカ テンキュー

236:nobodyさん
08/02/02 21:30:36
>>233
PHP4では全てパブリックだけど例えばC#では以下の実装になるんだ
public object Execute(object parpam)
protected virtual object _OnExecute(object parpam)

CFControlから_OnExecuteメソッドを隠蔽する意図なんだよ。
_OnExecuteはCFViewやCFModelのサブクラスにだけ見えれば十分なんだ。

237:に ◆lKs5QMUHoA
08/02/03 11:17:44
>>235
暖かいですねぇ。


>>236
なるほど。ありがとう。

238:に ◆lKs5QMUHoA
08/02/03 14:47:56
ソースを読んでいて気になった点がありますので、質問させていただきます。
includeの構成についてです。まず、各ファイルに書かれているincludeの部分をまとめます。

[index.php]
include("./cfcontrol.php");
[cfcontrol.php]
include("./cfview.php");
include("./cfmodel.php");
include("./config.php");
[config.php]
// 実際の処理を行うスクリプトをインクルード
include("./index_view.php");
include("./output_view.php");
include("./data_model.php");

これは、MVCフレームワークは、以下の3つのファイルであり、
[cfcontrol.php][cfmodel.php][cfview.php]
それを拡張する形で、残りの6つのファイルを付け加えた形
なので、このようなincludeの構成ということでよろしいのでしょうか。

239:に ◆lKs5QMUHoA
08/02/03 14:50:55
includeをばらばらとさせるよりも、以下のように整理したほうが
となんとなく思ったりもしたのです。

[index.php]
include("./config.php");

[config.php]
include("./cfcontrol.php");
include("./cfview.php");
include("./cfmodel.php");
include("./index_view.php");
include("./output_view.php");
include("./data_model.php");

240:nobodyさん
08/02/03 15:27:26
MVC?な俺にはここが一番わかりやすかった
実例コードが載ってるのがいい

PHPでMVC第1回:前編
URLリンク(www.stackasterisk.jp)


241:nobodyさん
08/02/03 15:52:25
javaのサイト見ろよ

242:nobodyさん
08/02/03 16:56:56
やけに伸びるな

243:に ◆lKs5QMUHoA
08/02/03 19:47:22
ソースコードをちょっとだけ改変したものを作ってみた。
メモとかを残していく都合もあると思ったから、HP解説してみた。
URLリンク(www.geocities.jp)
本当は、>>1さんがソースの管理とかもしてくれたりしたら、うれしいw

244:nobodyさん
08/02/04 01:44:33

いちいちzipを解凍する気にならない

245:nobodyさん
08/02/04 09:02:58
>>243
CFViewクラスに具体的な実装をしちゃダメなんだよ。
そもそもHTMLのフォーム処理とかは、あとでPEARとか使えばいい。

サブクラスをうまく呼び出す仕組みだけを実装していくんだ。

246:nobodyさん
08/02/04 14:12:44
>>244
> サブクラスをうまく呼び出す仕組みだけを実装していくんだ。
kwsk

247:nobodyさん
08/02/04 23:36:13
>>246
構造化プログラミングはルーチンを呼ぶ方向で実装すると思うけど
OOPではルーチンに呼ばれる方向で実装して行く感じだよ。

大枠の骨組みだけを抽象クラスで作成して、処理は具象クラスで行うんだ。
インターフェイスさえ同じならあとで個別にパーツを交換出来たりするからね。

だったら基底クラスのメソッドなんて数個で十分じゃないかと思うんだ。
やたら複雑でよくばりな機能のクラスなんて、再利用の価値がないからね。

248:に ◆lKs5QMUHoA
08/02/05 01:28:01
>>247
レスありがとうございます。
> 構造化プログラミングはルーチンを呼ぶ方向で実装すると思うけど
> OOPではルーチンに呼ばれる方向で実装して行く感じだよ。
私は、継承を活かした設計をした事が無かったので、ちょっと方向性を
誤ってしまったようですね。

Viewは、表示をつかさどるのだから、html表示を請け負うのでは、と
思っていたのですが、それよりも抽象的な枠組みを定義するという
ことですね。

となると、html表示は(PEARを使わないのであれば、)htmlタグの
記述を行うCF_HTMLクラスを作り、Viewの具象クラス内で
インスタンスを生成ということですよね?

249:nobodyさん
08/02/05 08:55:19
>>248
HTML処理のヘルパクラス作成はあまりOOPの勉強にならないとも思うんだ。
もう既に頭の中で実装出来ているだろうし、引数を関数で処理するだけでしょ?

それよりも例えばPEARのHTML_QuickFormやテンプレートレンダラのSmartyを
Viewと連携させる仕組みとかを考えたりした方がよっぽど面白いよ。

すべてをフルスクラッチするプログラミングの方向性は必ずしも得策じゃないよ
既存のライブラリやコンポーネントを上手く利用するのもOOPの要素なんだよ。

250:nobodyさん
08/02/05 11:06:34
OOPで継承を用いた設計について調べてみた。(OOP理論の入門ではなく、
継承を用いた設計などが入った解説)
この連載は良いかもしれない。

オブジェクト指向プログラミング超入門
.NETでオブジェクト指向プログラミングを始めよう
URLリンク(www.atmarkit.co.jp)

特に第6回は、今まで出てきていた話題だと思う。
Objectクラスで仮想メソッドToStringをもち、それから派生したクラスは、
オーバーロードをする仕組みを図説していて分かりやすい。

第6回 階層の頂点に立つクラス
URLリンク(www.atmarkit.co.jp)

251:nobodyさん
08/02/05 11:52:25
>>250
PHPのプログラマにも非常に参考になると思いますよ。

.NETの世界はクラスベースなので初めからOOPの思考で実装します。
関数が作れないので構造化思考のVB6プログラマとか、クラスをnewせずに
引数を大量に渡すスタティックメソッドを呼んだりしてしまいます・・・

PHPはC言語での関数モジュールを呼び出す実装スタイルに近いので
やはりクラスを使って構造化プログラミングをしちゃいがちですね。

普及しているPHP4がOOP対応不十分なのと、開発環境が貧弱であることも
PHPでOOPがなかなか利用されない原因になってたりしますよね。

プロテクテッドメソッドの概念とかIDEがないと、なんでそうするのか
なかなか理解出来ないとも思いますしね。

252:nobodyさん
08/02/05 11:56:50
いくらかのデータを登録し、その内容を検索するWebシステムで使用する
クラス構成で、Viewに絞った構成を考えてみた。

[View]
├[認証]
├[個人情報入力]
├[メニュー]
├[検索指定]
├[検索結果]

別の案として、[View]から[Input View]と[Output View]の
二つを継承し、さらに以下のような継承も浮かんだけれど、
継承して分ける必要性は無さそうなので、上記の方が良いように思う。

[Input View]
├[認証]
├[個人情報入力]

[Output View]
├[メニュー]
├[検索指定]
├[検索結果]

253:nobodyさん
08/02/05 12:16:06
>>252
[View]
├[LoginView]
├[InsertView]
├[MenuView]
├[SelectView]
├[ResultView]

こんな感じ?

254:nobodyさん
08/02/05 13:28:44
Debug用出力のメソッドをView(基底クラス)に追加するといいだろうね。
各画面([LoginView] [InsertView] [MenuView] ・・・)で
エラー確認用のメソッドをオーバーロードする形で。
開発中はPOSTで受け取ったデータとかを画面上部に表示しながら動作確認する
っていうのは、よくやるからね。

Objectクラスを継承する形にするのは、このスレでは共通したメソッドの
実装という理由だ。という話だったけど、リファレンス関係の処理で
便利だという話がサイトに載っているようだね。
このあたりの考え方も活かすと良いかもしれない。
ただ、PHPのOOPだとうまく実装出来ないかもしれないが。
>>207-209 >>250

255:nobodyさん
08/02/05 13:44:31
Modelクラスも以下のメソッドを追加するという感じで設計すると良いのかな。

Select // データ取り出し
Delete // 削除
Insert // 新規追加
Update // 既存データの更新

>>228に載ってる既存のクラスには Execute があるけれど、
これも残しておくべきかな?

256:に ◆lKs5QMUHoA
08/02/05 19:03:57
案がいくつか出てきたので、前回の駄目なソースを破棄して
またソースコードをリニューアルしようかと思ったが、
いざやり始めてみると、データベースを管理する基底クラスの
設計を具体的にどうするかをきめないといけなくなり、それを
どうするかで迷っている。。。

概ね以下のような感じにしたいと思ってるんだけどね。
DB格納の基底クラス:CFDB
テキストファイルに保存するクラス:Text_DB extend CFDB
PostgreSQLに保存するクラス:PostgreSQL_DB extend CFDB
MySQLに保存するクラス:MySQL_DB extend CFDB

で、この3つのいずれかのインスタンスを Model のメンバに持たせる。
現在のコード(CFModelのメンバ)
var $file_name; // 読み込むファイル名
更新案のコード
var $m_db; // データベースを格納。

257:nobodyさん
08/02/05 20:33:23
>>255
普通は機能をメソッドに振り分けると思うけど
コントローラのメソッド内で以下の様に
操作出来たら面白くない?

// モデルにフォーム値を渡してデータ書き込み
$insert = $this->models['InsertModel'];
$insert->setItem('name',  $_POST['name']);
$insert->setItem('title', $_POST['title']);
$insert->setItem('body',  $_POST['body']);
$insert->execute();

// ビュー表示用にデータをロードする
$select = $this->models['SelectModel'];
$data = $select->execute();

>>256
自分なりに試行錯誤で機能を実装してみるのも楽しいかもね。
誰か>>252のアプリ作成に必要な要求仕様作ってよ。

258:に ◆lKs5QMUHoA
08/02/05 23:02:08
>>257
要求仕様案

私は眼鏡屋(○○支店の店長)をやっている。
顧客の情報(名前、住所、性別、生年月日、・・・)を管理したい。

・眼鏡を購入した顧客の情報を登録しておき、ある一定期間経つと
新しい眼鏡を購入する案内のDMを発送したい。
→条件検索をしたい。
・登録した情報を検索し、どんなお客様かをすぐに確認出来るようにする。
→例えば、苗字を聞いて、詳細が分かるようにする。
・眼鏡の定期的なメンテナンスで、訪問してきたら、その対応履歴を
登録しておきたい。
→眼鏡のクリーニング、シリコンパッド(鼻にあてるやつ)の交換など
・定期的なメンテナンスは無料であるので、全く店に来ない客には、
その無料案内のDMを発送したい。
→今回は、複数の店舗にまたがった処理はいらない。
・他の社員に勝手に情報を触られないように、認証を通すようにする。

眼鏡の在庫管理は、このシステムとは別。

これは、プログラムの規模が大きくなりすぎるようであれば、
もちろん内容を変えてもいいです。「顧客の情報を登録し、
それを検索する」という流れだと、勉強用サンプルとして非常に
良いのでは、と思いました。

259:に ◆lKs5QMUHoA
08/02/05 23:21:24
[データの入力例]
氏名:茂名
フリガナ:モナー
性別:男性
生年月日:H1/3/3
住所:東京都・・・
コメント:ふちなしタイプを希望している。

眼鏡購入日:2007/1/5
眼鏡の型番:2ch

[2007/1/5に購入した2ch]のメンテナンス履歴
2007/2/5:クリーニング
2007/3/15:ネジの交換
2007/5/1:クリーニング、曲がったフレームの修正


顧客のデータ1件に、眼鏡の購入日がつながり、さらに、メンテナンス履歴が
つながる構成になるけれど、今回は勉強用なので、「顧客のデータ1件=眼鏡の購入日1件」
としてもいいかもね。
再度購入したら、顧客の個人情報を0から入力しなおすみたいな。

260:に ◆lKs5QMUHoA
08/02/06 01:36:05
View の Debug メソッドの仕様もどうするかで迷っている。
Execute($param)したあと、Debugとか、もしくは、
Debugの中でExecute($param)を呼び出す処理だと、
<html>タグのそとに確認データが出力されてしまう。

Debug モードを on にすれば、<body>タグの上部に
テーブルで区切ってデータが表示されるとかかな。
だったら、メンバにDebugモードを追加かな。
という感じに考えてる。

みんなどう思う?

261:nobodyさん
08/02/06 09:30:01
>>258
ちょっとしたシステムじゃん・・ (´・ω・)
それこそ既存のフレームワーク使用する案件だよ。

>>260
ディレクティブ付けたechoやvar_dump埋め込みで十分だと思うよ。
むしろその機能を実装するより、デバッガ環境構築した方がいい・・・

OOPに対する基本的概念への理解があまりにも無さ過ぎると思うんだ。
>>255にしても、Executeメソッドに呼ばれる仕組み作ってんのに、
なんで新しいメソッド実装して直接呼びたがるんだろう?

あれほどインタフェイスだけで実装するんだと(ry
それよりコントローラの実装仕様どうするの?

262:1 ◆SWtzLesEmM
08/02/06 10:44:17
>>243
>URLリンク(www.geocities.jp)

↓動作サンプルを設置しました。
URLリンク(ssurl.net)

↓コードに関するコメントのまとめ(>>184-226辺り)
URLリンク(ssurl.net)

263:nobodyさん
08/02/06 11:45:05
>>262
非常に乙です。m(_ _)m

>>226だけど >>1さんにここまでやって貰っちゃって申し訳ないし
これぞOOPってサンプルを必死に実装してアップするんでしばしお待ちを・・


264:nobodyさん
08/02/06 13:18:03
>>263
はやくアップしろよなw

俺がそれ見て勉強して、いつかエロイ人になったら
お前を雇ってやるよ! 感謝しろ


265:に ◆lKs5QMUHoA
08/02/06 16:04:09
>>262
動作サンプルまでつけていただいて、ありがとうございます。
過去ログも、そのままコピペするんじゃなくて、色をつけたり
分類したりすると非常に分かり易いですね。

ShiftJISだったりとか、スペース2個というのは標準じゃないとかは
気づいてたのですが、そこまで治していただいて申し訳ないです。

266:nobodyさん
08/02/06 16:34:44
MVCって難しいね。

267:nobodyさん
08/02/06 17:31:55
>>266
別にわかんなくったって、やってけるから大丈夫。
無理に背伸びする必要は無い。

268:に ◆lKs5QMUHoA
08/02/06 20:19:07
フレームワークの解説に関するサイトを見つけました。
ここで概要をつかんだ後、実際に触れてみるといいかもしれない。

ASP.NET vs. Struts
フレームワーク徹底比較[前編]
URLリンク(www.atmarkit.co.jp)

この文章書いてる人、ネットワーク関連の書籍でよく見かけるよね。

269:nobodyさん
08/02/07 10:03:39
>>261
> OOPに対する基本的概念への理解があまりにも無さ過ぎると思うんだ。
> >>255にしても、Executeメソッドに呼ばれる仕組み作ってんのに、
> なんで新しいメソッド実装して直接呼びたがるんだろう?

> あれほどインタフェイスだけで実装するんだと(ry

ちいたんのフレームワークは、Modelにinsertやdelを持ってるからそれを
参考に設計してみたんだけど。
URLリンク(php.cheetan.net)

俺はこれから勉強していくところなので理解がないのは認めるが、
このあたりはどういう見解なのかを教えて欲しい。
今回作るMVCフレームワークは、学習用なのでもっと簡潔な
レベルなのを想定しているとか、ちいたん作っている人がOOPに
関する理解が無いだけだとか。

270:nobodyさん
08/02/07 10:24:36
>>269
フレームワーク実装に正解も不正解も無いと思うけどね・・

例えば
・クラスを使った構造化的メソッド呼び出し
$model->insert();
$model->del();
よりも
・ポリモーフィズム
$insert->execute();
$del->execute();
のほうがインターフェイスが規定されていて
簡潔で安全だと説明したかったんだよ。

insertメソッドやdelメソッドを呼ぶ文脈が規定されていたらどう?
insertオブジェクトのexecuteメソッドならオブジェクトが
文脈をコントロール出来るでしょ? どうかな?

学習用だからこそ『呼ばれる仕組み』で実装しようとしているんだよ。

271:nobodyさん
08/02/07 10:55:50
>>270
レスサンクス。となると、
class CInsert extend CView、class CDel extend CView、・・・
みたいな設計にするということ?

ちょっと大雑把になってるけど、CInsertはこんな感じに実装するとか。
(テーブルのフィールドは、a,b,cという場合。)
class CInsert extend CView{
var $field_a;
var $field_b;
var $field_c;

function setItem($field, $data){
if($field == "a"){
$field_a = $data;
}
if($field == "b"){
$field_b = $data;
}
if($field == "c"){
$field_c = $data;
}
}

function _OnExecute($param){
$fp = fopen($file_name,"a");
$write_line = $field_a . "," . $field_b . "," . $field_c;
fwrite($fp,$write_line);
fclose($fp);
}
}

272:nobodyさん
08/02/07 11:32:07
じゃ、用件仕様はこんな感じで良いのか?

[認証]
→・ID、パスワードにて認証
 ・認証成功で[メニュー]へ移動

[メニュー]
→・(新規)[個人情報入力]、[検索指定]画面へ移動するボタンがある

[個人情報入力]
→・名前、性別 を登録

[検索指定]
→・氏名のキーワードを含む検索、性別指定が出来る。

[検索結果]
→・条件に一致するデータを一覧で出す。
 ・個人情報を修正したい場合は、ここから[個人情報入力]へ移動する。
 ・個人情報を削除したい場合は、ここで削除ボタンを押す。

273:nobodyさん
08/02/07 12:35:22
>>271今こんな感じ。
[DataModel.php]
<?php
/**
 * データModel抽象クラスです。
 */
class DataModel extends Model
{
# @access private
var $_items;

# @access public
var $file_name;

# @access public
function setItem($key, $value)
{
$this->_items[$key] = $value;
}

# @access public
function getItem($key)
{
return $this->_items[$key];
}
}
?>

274:nobodyさん
08/02/07 12:36:19
[InsertModel.php]
<?php
/**
 * データ追加Model抽象クラスです。
 */
class InsertModel extends DataModel
{
# @access sealed
function & _onExecute(&$param)
{
return $this->_OnInsert(&$param);
}
# @access protected
function & _onInsert(&$param)
{
trigger_error('オーバーライドして下さい。', E_USER_ERROR);
}
}

275:nobodyさん
08/02/07 12:37:26
[SampleInsertModel.php]
<?php
/**
 * データ追加 サンプルクラスです。
 */
class SampleInsertModel extends InsertModel
{
# @access protected
function & _onInsert(&$param)
{
// ここで初めてユーザ定義のメソッドを実行する。
// FWからここが呼ばれるまで待ってるのがポイント!
// INSERTイベントの処理ハンドラに記述するともとれるね。
return $this->_saveData();
}
/**
* ユーザ定義のプライベートメソッド
*/
# @access private
function _saveData()
{
// リクエストは以下のインターフェイスで取得。
$value = $this->getItem('hoge_data');
// ここで初めてHogeHogeする。
// DBオブジェクト呼ぶなりご自由に!
return $data;
}
}
?>

276:nobodyさん
08/02/07 13:59:04
細かい指摘になるけれど、継承関係の勉強中なので質問で書き込みします。

[InsertModel.php]
class InsertModel extends DataModel
function & _onExecute(&$param)  のところは、
return $this->_OnInsert(&$param);  となっているけれど、
return $this->_onInsert(&$param);  が正しいという解釈で良いのですよね?

277:nobodyさん
08/02/07 14:16:55
>>273-275
ソースのサンプルサンクス。
イメージしてたよりも継承が多いですね。

全体ソースコードの可読性よりも、クラス単位での
再利用性を考えた場合は、このような構成になる
のでしょうね。早く慣れないといけません。

278:nobodyさん
08/02/07 15:36:22
まだ中身が出来ていない状況なので、修正の必要はあるだろうけど、
こんな感じでドキュメントもまとめていくと、分かりやすくなるだろうね。

■SampleInsertModelクラス[SampleInsertModel.php]
Model - DataModel - InsertModel - SampleInsertModel

◎概要
DBへのデータの記録、読み取りを行うクラス。

◎メンバ一覧
[publicコンストラクタ]
SampleInsertModel()

[publicメソッド]
setItem($key, $value):setter。フィールド名を指定し、データを登録する。
getItem($key):getter。フィールド名を指定し、データを取得する。
Execute($param):setItemでセットしたデータをDBに記録する。

◎使用例
$model = new SampleInsertModel(); // クラスのインスタンスを生成する。
$model->setItem('Name', 'Tarou'); // [Name]フィールドに[Tarou]を登録する。
$model->setItem('Sex', 'man'); // [Name]フィールドに[man]を登録する。
$model->Execute(); // setItemで登録したデータをDBに書き込む。

279:nobodyさん
08/02/07 23:22:51
>>263 ひとまず出来ました・・疲れました・説明は後でアップしようと思います・・
URLリンク(proxy.f3.ymdb.yahoofs.jp)

280:に ◆lKs5QMUHoA
08/02/07 23:27:16
>>279
乙です。じっくりソースを読んでみます。

281:に ◆lKs5QMUHoA
08/02/08 08:04:01
せっかくプログラムを作っていただいたのだから、みんなでその説明文章をまとめるといいかもね。
例えば、こんな感じでhtmlで書いておいて、ファイル名をクリックすると、その詳細の説明のページに飛ぶとか。

[abstract]
  [controls]
    空
  [models]
    DataModel.php、DeleteModel.php、InsertModel.php、SelectModel.php、UpdateModel.php
  [views]
    HtmlQuickFormSmartyView.php、RenderView.php
[controls]
  MainControl.php、SkeletonControl.php
[data]
  空
[framework]
  Base.php、Control.php、Model.php、View.php
[lib]
  Request.php
[models]
  SampleInsertModel.php、SampleSelectModel.php、SkeletonSelectModel.php
[smarty]
  [cashe]
    空
  [templates]
    index_tmple.html、output_tmple.html
  [templates_c]
    空
[views]
  HtmlQuickFormSmartyIndexView.php、HtmlQuickFormSmartyOutputView.php
  IndexView.php、OutputView.php、SkeletonView.php

app.log、appconf.php、csv.txt、hoge.txt、index.php、Main.php、userconf.php

282:nobodyさん
08/02/08 08:10:57
>>281
>>279ですがphpDocumentorで今作っているのでちょっと待っててね。

283:nobodyさん
08/02/08 08:52:15
phpDocumentorにソース読み込ませて吐かせただけです。
URLリンク(proxy.f3.ymdb.yahoofs.jp)
フォルダ内のindex.htmlです、荒いですがご容赦を。

とりあえずトライアルなんでまだリファクタ出来そうだけど・・

[コントローラの処理]
_form_onLoad
_buttonHoge_onClick

[モデルの処理]
_onSelect
_onInsert

[ビューの処理]
_onRender

上記のイベントハンドラにユーザ処理を記述して
フレームワークに呼んでもらう構造になってます。
>>216を実装したつもりです・・・
有名なハリウッドの法則です。

[カプセル化]は良いとして、やはり[継承]と[ポリモーフィズム]を
うまく使うのは最初難しいかもしれない・・
これらの実装もデザパタとしてライブラリ化されたものに過ぎないけどね。

284:nobodyさん
08/02/08 09:26:17
ファイルが見れん・・・

285:nobodyさん
08/02/08 11:03:39
OOP FW ソース
URLリンク(proxy.f3.ymdb.yahoofs.jp)
OOP FW ドキュメント
URLリンク(proxy.f3.ymdb.yahoofs.jp)

すいません再アップしました、ドキュメントにControlが反映されてませんでした。

286:nobodyさん
08/02/08 11:20:06
サンクス

287:nobodyさん
08/02/08 11:51:38
全体構成の把握はまだ出来てないけれど、只今、ソース解析中・・・
いちゃもんつけるつもりじゃないけれど、気になった点を2つ。

Control.phpのPOSTされたSubmitボタン名取得のところは
クラス化されてないのはどうしてなのでしょうか?
さらに非常にクラスが多くなって面倒になるから?

class Control extends Base
var \$_view_calss;
このメンバはあえてclassにしてない理由はあるのでしょうか。

288:nobodyさん
08/02/08 12:39:56
>>287
POSTされたサブミットボタン名取得部分は説明の通りです・・
今その部分をC#でのデリゲートで実装しようと思ってます。

Viewクラスexecuteのところもこのままでは$eパラメータが
コントローラから任意に渡せないので検討中です。

オブジェクトにexecute以外のパブリックメソッドを
実装しないのが目標です・・(※アクセサ以外)

289:nobodyさん
08/02/08 13:12:48
クラスの継承関係が結構複雑になってますね。
Documentsいただいても、追いかけていって、全体構造を把握するのが結構大変。
例えば、SampleInsertModelからその元を追っていくと、以下のような継承構造。
Base - Model - DataModel - InsertModel - SampleInsertModel

俺のメモとして、SampleInsertModelを追いかけていった様子をまとめておく。

■Base(抽象)クラス[fw/framework/Base.php]
●パブリックメソッド
& execute(&$param, $e) →アプリのログを記録する。_onExecute(&$param, $e)を実行
●プロテクテッドメソッド
_onExecute(&$param, $e) →サブクラスでオーバーライドして使用。

■Model(抽象)クラス[fw/framework/Mode.php]
●プロパティ
$src_file_name; // 読み込むファイル名
$dst_file_name; // 書き込むファイル名

290:nobodyさん
08/02/08 13:15:33
■DataModel(抽象)クラス[fw/abstract/models/DataModel.php]
●フィールド
$_items; // コントロール値のハッシュを保存
●パブリックメソッド
setItem($key, $value) // コントロール値を受け取り、$_itemsに代入
getItem($key) // $_itemsの値を返す。

■InsertModel(抽象)クラス[fw/abstract/models/InsertDataModel.php]
●シールドメソッド
& _onExecute(&$sender, $e) →onInsert(&$sender, $e)
●プロテクテッドメソッド
& _onInsert(&$sender, $e) →オーバーライドして使用する。

■SampleInsertModelクラス[fw/models/SampleInsertModel.php]
●プロテクテッドメソッド
$ _onInsert(&$sender, $e) →ここにユーザ定義のコードを記述する。_saveData()を実行
●プライベートメソッド
_saveData() →現在未実装。

291:nobodyさん
08/02/08 13:32:42
こうやってみてみると、クラスを継承する際の設計思想が見えてくるな。
どの段階で実装を替えるかを考えた場合、どのクラスを置き換えれば良いかも分かる。

しかし、俺はこれまでフレームワークの構成などをじっくり読んだりしたことが無いので、
つい、ここまでクラスを継承させるメリットがあるのかなとか思ってしまう。
なんか、1つのメソッドを実装するのに、1回継承してるって感じだよね。

例えば、Model(抽象)クラスの $src_file_name を別のものにする場合、
それ以降のクラスが全部影響するかの確認が必要なわけだから、
Model(抽象)クラス以降のものをすべて一つのクラスにまとめて書いても
同じなんじゃないかと思えてしまう。
こういうのとは別な場面で、継承しているメリットがあるってことかな?

292:nobodyさん
08/02/08 13:51:09
ちょっと紹介しておきますね。

フレームワークを使った開発のメリット、デメリットを教えてください
URLリンク(q.hatena.ne.jp)

特集:第1回 フレームワーク「Struts」の基礎を知る (3/8)
フレームワークのメリットとデメリット
URLリンク(www.itmedia.co.jp)

293:nobodyさん
08/02/08 15:31:59
Control の & _onExecute(&\$param, \$e) で
\$this->_view_calss = \$view_calss;
というコードがあるけれど、右辺の \$view_calss って、
何処でも定義されてないですよね?
このまま動かすと、nullが入るだけのように思えるんだけど。

294:nobodyさん
08/02/08 16:04:40
Viewクラスの継承関係で、かいつまんだ一覧を書いておきます。
個別にはDocに書いてはあるけれど、こういう書き方みると分かりやすくない?

Base - View - RenderView - IndexView

■Base(抽象)クラス[fw/framework/Base.php]
(省略)

■View(抽象)クラス[fw/framework/View.php]
●プロパティ
$post_file; // POSTするファイル名

■RenderView(抽象)クラス[fw/abstract/views/RenderView.php]
●プロテクテッドメソッド
& _onExecute(&$sender, $e) // _onRender(&$sender, $e)を呼ぶ
& _onRender(&$sender, $e) // サブクラスにてオーバーラードする。

■IndexViewクラス[fw/views/IndexView.php]
●コンストラクタ
$this->post_file = 'index.php';
●プロテクテッドメソッド
& _onRender(&$sender, $e) // オーバーライド
 →html出力する。テキストボックスと送信ボタン

295:nobodyさん
08/02/08 16:20:36
>>293
1行上のフックハンドラ実行の結果を渡している。

296:nobodyさん
08/02/08 16:41:04
ロードメソッド[MainControl::_form_onLoad(&$sender, $e)]が(POSTパラメータが
無い場合に呼ばれるメソッド)呼ばれるまでの経緯をたどってみたが、非常に複雑だ。。。

[fw/index.php]が実行される。
Mainクラスのインスタンスが生成され、execute(&$app, $e)が実行される。
Base:: & execute(&$param, $e) にて、 Base:: & _onExecute(&$param, $e)が実行される。
これは、Main::execute(&$app, $e)にてオーバーライドされている。
Controlクラスのインスタンスが生成され、execute(&$app, $e)が実行される。
Base:: & execute(&$param, $e) にて、 Base:: & _onExecute(&$param, $e)が実行される。
これはControl:: & _ onExecute(&$param, $e)にてオーバーライドされている。
Control:: & _onExecute(&$param, \$e) にて、Control::_hookedUpControler(&\$sender, \$e)を呼び出す。
Control::_hookedUpControler(&\$sender, \$e) にて、Control::_form_onLoad(&$sender, $e)を呼ぶ。
これはMainControl::_form_onLoad(&$sender, $e)にてオーバーライドされている。
MainControl::_form_onLoad(&$sender, $e) が実行される。

継承関係
Base - Control - MainControl
Base - Main

297:nobodyさん
08/02/08 17:33:12
リンク

symfony入門(1):symfonyで始めるPHPフレームワーク
URLリンク(codezine.jp)

Zend Framework入門(1):フレームワークの全体像とインストール
URLリンク(codezine.jp)

298:に ◆lKs5QMUHoA
08/02/08 18:46:07
>>285のファイルが落とせない・・・

299:nobodyさん
08/02/08 19:33:52
>>298 見れるはずですが・・以下はどうですか?
Eclipceでのデバッグ画面です
URLリンク(proxy.f3.ymdb.yahoofs.jp)

300:nobodyさん
08/02/08 22:21:47
>>298どうでしょうか?
URLリンク(briefcase.yahoo.co.jp)

301:nobodyさん
08/02/08 22:24:55
なんでPHP4文法でやってんの?

302:に ◆lKs5QMUHoA
08/02/08 23:53:42
>>300でいけました。サンクスです。

303:に ◆lKs5QMUHoA
08/02/09 01:49:09
これは、>>1さんのサイトでは、「入力フォームを作ってみる」とは
別で、「フレームワークを作ってみる」の演習という位置づけにした
方がいいかもしれないね。

これからの流れとしては、上のほうにあるように、このソースを
解読・改変していくための補助ドキュメント作成の方向と、
このフレームワークを使ってみる人のためのドキュメント作成
(チュートリアルみたいなもの)になるだろうね。
出来る範囲でみんなで手伝っていってみましょう。

このフレームワークは、MFCみたく、あらかじめ準備された
クラスのメソッド中に書き加えていくスタイルなのかな?
それとも、VBみたいにそういうソースコードを全部隠蔽
してしまう方向でいくのかな?ちょっと気になった。

304:に ◆lKs5QMUHoA
08/02/09 02:12:22
こうやってソースを読んでみると、これまで抽象的に聞いていた
フレームワークを使ったプログラミングのメリットとデメリットが実感できるね。

今まで、システムを組む際はOOPやフレームワークを使う方向にするべきだと
思ってたけれど、そうでもなく、状況や目的に合わせて選択する
というのが良い事が分かってきたような気がする。

小規模で全体概要を把握したいとか、移植性を考える場合は、フレームワークよりも、
クラスライブラリを使うスタイルの方が良い場合もありそうだ。

305:に ◆lKs5QMUHoA
08/02/09 08:12:13
MVCでフレームワークを自作する方向と、クラスライブラリを自作する方向の
2つの方向をやってみて、それぞれのメリットとデメリットを確認していけば、
システムを作る場合の検討材料に出来ると思う。

何でもフルスクラッチしていき、なるべく依存性は無いようにし、(言語の
バージョンくらいに収めるとか)その組み合わせでアプリを作る、みたいな。

306:nobodyさん
08/02/09 09:45:19
再度リファクタしてみました。
URLリンク(briefcase.yahoo.co.jp)

[Controlクラス]
・リクエストオブジェクトの参照の重複の削除
・サブクラスでのフックハンドラ処理修正
・Viewオブジェクトの実行方法修正
※これはViewオブジェクトハンドリングの自由度をました反面、
ユーザからの取り回しが煩雑になったかもしれませんね・・

[Modelクラス]
・継承関係の見直し、ItemBaseクラスの導入などです・・
MVCの継承関係が美しくないですが・・

>>291
リファクタしながら構成を練っていってますが
継承クラスでの責任が小さい単位で分割されていると
大きく修正が入った時も楽だと思います。

>>303
MFCもVB6もフックハンドラに処理を記述していく方式なので
それを参考にしています、サンプルFWも自由にいじってもらって
参考にしてもらえたら良いと思います。
>>305クラスライブラリ方式もいいかもしれないですね。

307:nobodyさん
08/02/09 10:20:45
フレームワークのメリットとデメリットにおいて、なるべく具体例を書いた形でまとめてみた。

【メリット】
1.ビューとロジックの切り分けが出来る。(共同作業時に便利)
 URLリンク(www.atmarkit.co.jp)
2.定型的なコードを何度も書かなくてよくなる。
 例えば、ASP.NETでは、POSTの値を取得して・・・などの事を考えなくて良い。
 テキストボックスやボタンも、画面にドラッグするだけ。
3.ソースコードが自動的にフレームワークの規約に従った記述方法となり、
全体的な処理構成が把握しやすく、メンテナンスが楽になる。
 例えば、構造化プログラミングならば、まず全体構成(どの関数がどんな役割を
 持っているかなど)を把握し、そこから問題部分を探すことになる。
 フレームワークの場合は、まずはこのイベントハンドラの部分を見れば良いなという事が分かる。

【デメリット】
1.フレームワーク自体の使い方を学ばなければならない。
・言語の基本ルールとは異なった、フレームワーク特有の記述方法があるため、すぐに組めない。
 ASP.NETでは、IsPostBack の概念を学ばなければならない。
 URLリンク(www.atmarkit.co.jp)
 ちいたんでは、function action( &$c )とか、$c->という書き方と機能を把握しなければならない。
 URLリンク(php.cheetan.net)
・フレームワーク自体にも得手・不得手など特徴があり、それを把握しなければならない。
 ASP.NETはIISが必要な為、自動的にサーバOSはWindowsが必須となり、依存性がある。
 ASP.NETとStrutsの比較は、以下のサイトを参照
 URLリンク(www.atmarkit.co.jp)
2.フレームワーク自体に問題があると対処が困難。
 例えば.NET Framework のバグは、開発元の不具合修正を待つしかない。
 オープンソースのフレームワークであっても、ソースコードが大量な為、把握が出来ない。

308:nobodyさん
08/02/09 11:01:52
QA方式で書いてみた。

Q:どんな時にフレームワークを使った方がいいの?
・短期間で仕上げなければならない時(この場合はフレームワークの使い方を把握しているのが前提)
・チームで分担してシステムを組む時
・バージョンアップを行うなど、長期的な運用が想定される時

Q:フレームワークがあまり向かない場合は?
・個人で小規模アプリを組む時。(一度組んで終わりの場合など)
・そのアプリの全体構成をすみずみまで把握しておきたい場合
・サーバの移植を想定しなければならないなど、環境があまり固定出来ない場合
このような状況の場合は、クラスライブラリの使用を検討すると良い。

309:nobodyさん
08/02/09 11:18:48
何かフレームワークを使ったとして、そのフレームワークがいつまでメンテされるか
判らないことを考えると、バージョンアップをするようなアプリの開発に向いていると
いえるかどうかは、かなり怪しいと思う。

310:nobodyさん
08/02/09 11:25:52
>>309
そういうケースもあるから入れるか迷ったんだよね・・・
だけど、現在の比較的規模の大きなアプリは何らかのフレームワークで
組まれている事実があるということで、書いてみた。
フレームワークのメンテが突然打ち切られるケースは無いと見ても
良いと思うけどね。事前に何らかのアナウンスがあるはず。

で、フレームワークそのものを入替える必要が生じた時は、もちろん
全部作り直しになるが、この労力は、フレームワークを使わない場合に
比べて楽だよね。という意見です。

311:nobodyさん
08/02/09 12:20:07
書いてみた、とかって適当かつ無責任な

312:nobodyさん
08/02/09 12:23:25
完璧な文章がいきなりかけるわけないんだから修正しながらでいいと思う。
適当だの無責任だのいうのなら、このスレに来なくて良いと思う。

313:nobodyさん
08/02/09 12:32:04
ひょっとして、つられた?

314:nobodyさん
08/02/09 15:20:46
つんでれた

315:nobodyさん
08/02/09 15:25:19
>>308
> Q:フレームワークがあまり向かない場合は?
> ・そのアプリの全体構成をすみずみまで把握しておきたい場合
全体構成を隅々まで把握してなんの意味があるのだろうか?
どうせ数日たったら忘れるんだし。

> ・サーバの移植を想定しなければならないなど、環境があまり固定出来ない場合
> このような状況の場合は、クラスライブラリの使用を検討すると良い。

PHP4、PHP5両対応のフレームワークもあるし、
いろんなデータベースに対応している場合もある。

フレームワークの開発というのは、そもそもが環境が固定されていないので
そういう場合にはなおさらフレームワークを使ったほうが良い。


316:nobodyさん
08/02/09 15:29:20
理解と記憶は別物だと思うけどな。

317:nobodyさん
08/02/09 16:52:42
>>315
> 全体構成を隅々まで把握してなんの意味があるのだろうか?
> どうせ数日たったら忘れるんだし。
じゃ、この項目は消しておきます。


> PHP4、PHP5両対応のフレームワークもあるし、
> いろんなデータベースに対応している場合もある。
> フレームワークの開発というのは、そもそもが環境が固定されていないので
> そういう場合にはなおさらフレームワークを使ったほうが良い。
PHPスレで言うのもなんだけど、ASP.NETなども含めた総論という考えだったんだけどね。
Windowsサーバなのかなどを気にするとか、PHP5のみ対応のフレームワークで
開発していて、PHP4しか対応していないサーバで動かすことになる場合を
という意味で、環境が固定されない書きました。

318:nobodyさん
08/02/09 17:04:40
修正案

Q:どんな時にフレームワークを使った方がいいの?
・短期間で仕上げなければならない時(この場合はフレームワークの使い方を把握しているのが前提)
・チームで分担してシステムを組む時
・バージョンアップや不具合修正など、納品後もメンテナンスが想定される時

Q:フレームワークがあまり向かない場合は?
・個人で小規模アプリを組む時。(一度組んで終わりの場合など)
・サーバの移植を想定しなければならないなど、環境があまり固定出来ない場合
 このような状況の場合は、クラスライブラリの使用を検討すると良い。

319:nobodyさん
08/02/09 22:32:17
あえてPHP4の構文でやってるのは、PHP4との互換性を保つため?
PHP5でやっちゃうと、PHP4の環境で動かなくなるから。

320:に ◆lKs5QMUHoA
08/02/10 03:19:14
ChStrクラスの件を再開しようかな。

321:1 ◆SWtzLesEmM
08/02/10 18:45:04
>>300
>URLリンク(briefcase.yahoo.co.jp)
ソースコードを見てビックリ!(・∀・)
コメントが丁寧に書いてあり、OOPを学習する上でとても助かります!
貴重なサンプルを提供していただき、どうもありがとうございました。m(_~_)m

現時点で、バージョンがOOP_FW_02とOOP_FW_03の2つあるみたいですが、とりあえずOOP_FW_02の方をまとめページに掲載させていただきました。
URLリンク(ssurl.net)

>>281
URLリンク(ssurl.net)
ちょっとずつ読んでますが、全部はまだ理解できないです。(´;ω;`)
レスも参考にしてみます。
(=分からないことでも、検索で調べるときのヒント・手掛かりになるので)

322:nobodyさん
08/02/10 22:19:07
>>321
乙です。m(_ _)m
>>306ですが今後は
・認証の仕組み
・ロギングの仕組み
・エラーハンドリングの仕組み
・バリデイトの仕組み
・トークンの仕組み
・リダイレクトの仕組み
・入力→確認→完了の仕組み
・コアオブジェクトの実行権限の仕組み
など実装していく予定です・・

でも、こればっかりやってるわけにいかないので
気長に見守ってやって下さい。

323:に ◆lKs5QMUHoA
08/02/11 02:31:35
>>321
乙です。分かりやすくまとまっていますね。
私も少しずつ読んでいって理解しようと思っています。
他のものに比べ、コメントが多いのが助かりますよね。


>>322
読むほうも時間がかかると思いますので、
一気にやらなくていいと思います。(^^;

324:に ◆lKs5QMUHoA
08/02/11 02:35:18
MVCフレームワークを作っていただいてる流れとはおもいっきり違う事をいうけれど。

>>1さんのOOPで掲示板を作るところは、もう少しクラスを分けたほうが
いいと思ったので、自分なりに作ってみました。

index.phpに、いろいろと処理を詰め込んでいるような感があったので、
それを分ける考え方です。
しかし、DBはテキストベースにしているとか、書き込み欄と表示欄を
同じページにしているなど、基本構成から大幅に変えています。(^^;

URLリンク(www.geocities.jp)
OOPの勉強として、簡易なBBSを作ってみました。
BBS Version1(2008.2.11)

325:に ◆lKs5QMUHoA
08/02/11 08:27:05
クラス間のデータのやり取りにおいて、Listクラスを使う設計にしたけれど、
PHPの場合はハッシュでよかったような気がする件。
まだまだ未熟だな・・・

今後は、これを構造化指向へ変換したプログラムを作り、うpする予定です。
この両方のプログラムを見比べてみることで、OOPのメリットとデメリットが
見えてくるかもしれません。

326:nobodyさん
08/02/11 10:26:11
OOPの継承やポリモーフィズムについての概念やそのコードの書き方に
ついては分かったけれど、その設計方法のノウハウの文章はぐぐっても
なかなか見当たらない。
「設計というのはそれぞれで目的次第」といってしまえばそうだけど、
hiroxpepeさんのソースや、.NET Framework や java の各クラスの
継承関係の設計を見ていると、何か共通したものを感じる。
その具体的な方針と、それを取る理由がはっきりとは分からない・・・

何か良い文章を見かけた、もしくは知っている方は、お願いします。

327:nobodyさん
08/02/11 10:50:14
◎「メンテナンスを行う場合」の比較

【構造化指向の場合】
ソースコードに書かれている関数とグローバル変数が、どういう階層で組まれているか
(どの関数でどの関数が使われているか。また、どのグローバル変数を使っているのか)
は、その関数の処理内容と、その関係などを把握してからでないと、手をつけられない。
新しくグローバル変数や、関数を追加する場合。また、ローカル変数を宣言する場合は、
その名前がソースコード内で使われているかを都度チェックしなければならないので、
面倒である。

【オブジェクト指向の場合】
ソースコードそのものがクラス単位で分けられているため、手をつける場所がすぐに
分かる。他のクラスに影響するのは、そのクラスとのインターフェースを変更した場合のみ。
新しくメンバやメソッドを追加する場合は、そのクラスの中で使われているメンバや
メソッドを確認するだけなので、対象となる範囲が狭く、チェックが楽。
また、プログラムそのものがクラスで部品化されるため、チームを組んで、分担作業で
プログラミングがやり易い。

【注意】
構造化プログラミングであっても、関数やグローバル変数の名前の付け方を工夫すれば、
もちろん対応は可能である。そのため、メンテナンスを想定する場合は、
オブジェクト指向でなければならないわけでもない。
オブジェクト指向は、構造化指向に比べて特別に「これが出来る」というものではなく、
構造化指向で不便に感じる部分の便利機能である。


次ページ
最新レス表示
レスジャンプ
類似スレ一覧
スレッドの検索
話題のニュース
おまかせリスト
オプション
しおりを挟む
スレッドに書込
スレッドの一覧
暇つぶし2ch