PHPでOOP
■ このスレッドは過去ログ倉庫に格納されています
00011 ◆SWtzLesEmM
2007/02/23(金) 13:35:52ID:???プロシージャ指向(手続き型、構造化プログラミング)でもできますが、
オブジェクト指向を使った場合の恩恵を享受するために、
PHPでオブジェクト指向プログラミングの勉強をしてみましょう。
<目的>
PHP5でオブジェクト指向プログラミングを行なうための知識を習得する。
(PHP4のOOPもOK、このスレが1000に行く前にPHP6が出たらPHP6のOOPもOK)
<方向性>
・このスレは、プログラミング初心者、PHP初心者の勉強の場として利用することを前提にします。
・PHPのOOPの話題に限定します。
(Ruby、Python、Javaなど他言語のOOPについては、その言語のスレッドでお願いします。)
・PHPのOOP学習に役立つ本、WEBサイトの紹介をお願いします。
<その他>
・略記は、「OO」=「オブジェクト指向」、「OOP」=「オブジェクト指向プログラミング」でお願いします。
・質問をする人はなるべくトリップを付けましょう。
・荒らし、煽り、叩き、気違いは無視・無干渉でお願いします。
このスレで、今日から貴方もOOP!!!\(^o^)/
0162nobodyさん
2008/01/29(火) 12:04:23ID:???メンバ
private $m_str; // 正規表現文字列を格納する。
コンストラクタ
ChStr($str) // 正規表現の文字列を受け取る。
private メソッド
ch_to_html() // 正規表現をhtmlに変換する。
public メソッド
Write_html() // 格納している文字をhtmlで出力する。
Write_text() // 格納している文字を正規表現で出力する。
---------------------------------------------------
本当は、ログファイルへの保存や読み取りなどを機能として
考え、そのあたりまで含めたクラスの設計をした方が
いいんだろうけれど、まずは簡潔にする方向でいきます。
で、後々拡張の方向で。
01631 ◆SWtzLesEmM
2008/01/29(火) 12:04:44ID:???(…使ったことないので実感がありませんが^^)
PHPでは実装済みのinterfaceを多重に実装できない
http://blog.xole.net/article.php?id=589
http://blog.xole.net/article.php?id=597
01641 ◆SWtzLesEmM
2008/01/29(火) 12:25:09ID:???こんなかんじのプログラムと似ているかもしれませんねー。
60行で作るPHP用テンプレートエンジン
http://anond.hatelabo.jp/20071030034313
>テンプレートの中身を置換する
>function convert_string($s)
↑置き換えるパターンに応じて、別々のメソッドを用意したら便利でしょうか?
= 文字サイズ変更、''' 強調、link: リンクとかの記法の置換を担当するprivateメソッド
01651 ◆SWtzLesEmM
2008/01/29(火) 12:34:03ID:???関数、オブジェクト、クロージャ
http://d.hatena.ne.jp/brazil/20060131/1138692196
>オブジェクトは、データに処理がくっついたものです。
>array.map()のように、後に後に処理を追加していく書き方は、順にコードを追えるため読みやすく、また書きやすいです。
クロージャっていう仕組みは、PHPにはないですね?><
大は小を兼ねる…クロージャの代わりにオブジェクトが使えればとりあえずOKかな?(・∀・)
0167nobodyさん
2008/01/29(火) 13:18:38ID:???> 置き換えるパターンに応じて、別々のメソッドを用意したら便利でしょうか?
本来ならば、そうなるでしょうね。それらはすべてprivateで作っておいて、
外部には、一つのインターフェースのみ(この例の場合はWrite_html()がそれに該当)
公開となるでしょう。
記号ごとに別々にメソッドを定義しておけば、記号とhtmlの関係が変わる時は、
どのメソッドを触ればよいかが分かるし、それを変更したことで、
他のメソッドには影響は無かったりします。
(これが構造化プログラムの場合は、目的のソースと目的ではないソースを
見極めるところから始まります。)
-------------------------------------------------------------------------
この ChStr に汎用性を持たせる場合は、Write_html()というよりも、
Get_html()とし、html文字列を return する事になるでしょう。
そうすると、別なプログラムで、「出力結果をファイルに保存する」という
使い方も出来ます。しかし、今回は初回なので、Write_html()とし、
メソッド内部で echo 使うことにします。
0168nobodyさん
2008/01/29(火) 13:22:48ID:???学ぶために具体的に物を作るのと、実用性を考えて物を作るのは
別だと思う。なので、今回はこれでいいと考えている。
現に、初心者向けの書籍に載っているソースの実用性はゼロだ。
0169nobodyさん
2008/01/29(火) 13:59:05ID:???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;
}
}
?>
0170nobodyさん
2008/01/29(火) 14:03:31ID:???<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>
01711 ◆SWtzLesEmM
2008/01/29(火) 14:10:04ID:???確かにそうなんですが、「勉強のため」という目的もあるので、自分で作ってみるというのもありでしょうか?^^
でも、答えが分かっている問題を解くのは楽ですね。>Text_wiki
車輪の再発明 - Wikipedia
http://ja.wikipedia.org/wiki/%E8%BB%8A%E8%BC%AA%E3%81%AE%E5%86%8D%E7%99%BA%E6%98%8E
車輪の再発明とは、「広く受け入れられ確立した技術や解決法を無視して、同様のものを再び一から作ってしまう事」を意味する
ある技術の意味を理解させるために、意図的に車輪の再発明を行わせる場合がある
01721 ◆SWtzLesEmM
2008/01/29(火) 14:19:35ID:???構文解析 - Wikipedia
http://ja.wikipedia.org/wiki/%E6%A7%8B%E6%96%87%E8%A7%A3%E6%9E%90%E5%99%A8
今までにいろんな仕組みが考えられてきたみたい。
…本格的にやると奥が深そうだけど、一度仕組みを勉強しておいたら、いろいろ使えそうな予感!(・∀・)
↓wikiの仕組みを自分で作っている方は結構いるみたいですねー。
PHP用の汎用WikiParser作り中
http://tdiary.ishinao.net/20050323.html
RandomNote/PHPについて
http://tbox.jpn.org/wiki/rnh/index.php?AboutPage.txt
0173nobodyさん
2008/01/29(火) 14:21:38ID:???・ch_to_html() の中身を書く。
・[text.php] の機能を充実(テキストファイルに保存するなど)させ、wikiを作る。
・上記とは別に、 ChStr クラスを使い、BBSを作る。
・ChStr クラスに clear()、SetStr() 等のメソッドをつけ加え、汎用性を持たせる。
01741 ◆SWtzLesEmM
2008/01/29(火) 14:38:20ID:???RandomNoteのMain.phpは参考になるでしょうか?
preg_match
preg_replace
array_push
array_pop
などの関数を使って、文字列の切り貼りをしてるんですねー。
0175nobodyさん
2008/01/29(火) 14:39:05ID:???メソッドの中でstringをreturnせずにecho使うのは>>167で書いてるように汎用性って面もあるけど
処理と表示の分離って意味合いもあるからちゃんとstringで返したほうがいいよ
0176nobodyさん
2008/01/29(火) 15:39:09ID:???> OOPってより単にクラスの使い方書いてるように見えるのはまあいいとして
OOPについて説明するとなると、具体的なソースコードとは離れた方が
良くなったりしますからね。
(クラスの使い方書いているように見えるとしても、)PHPでclassを
組む場合のメリットみたいな位置づけで学んでいこうと思っています。
> 処理と表示の分離って意味合いもあるからちゃんとstringで返したほうがいいよ
確かに汎用性以外にそういう目的もありますね。
次のものでstringで返すように書き換えます。
0177nobodyさん
2008/01/29(火) 18:16:08ID:???いきなりそれをやると分かりにくくなるかな・・・
0178に ◆lKs5QMUHoA
2008/01/29(火) 19:20:19ID:???今までnobodyさんで書いてたけど、分かりにくくなるかと思ったので
酉入れるようにしてみます。
>>5に書いてあるように、オブジェクト指向は「変数を保持できる事」が
メリットだと思うのですが、これがWebアプリだとどうも実感が無かったりします。
リッチクライアントだと、マウスのクリックに合わせて、メソッドが呼び出され、
そのアプリケーションが終了するまでの間、各種オブジェクトの中の変数に
状態が保持されるという構造なので、そのメリットが感じられるのですが、
Webアプリでは、POSTする度にオブジェクトの変数の状態はリセット
されてしまうので、クラスを書いたとしても、結局はグローバル変数から
各種オブジェクトの変数に代入するみたいなコードを書かなくては
ならなくなってしまうので、このメリットがあるのかと思ってしまうのです。
これは、勉強不足だからなのでしょうか。。。
0180nobodyさん
2008/01/29(火) 23:05:47ID:???読んだことがあるけれど、この話本当なの?
具体的に何処でどういう商売をしての話なんだろうか。
アプリケーションを売る話?それとも開発環境用のソフトを売る話?
0181nobodyさん
2008/01/30(水) 21:59:22ID:???ボタンのクリックに関する全ての画面遷移に関してserializeとunserializeを管理する必要があるだろ
<?php
require_once("hiroyuki.class.php");
$hiroyuki = unserialize($_SESSION["hiroyuki"]
0182nobodyさん
2008/01/31(木) 07:20:40ID:NaJ3keB3ユーティリティクラスの再実装みたいな事を熱心にやっても
あまり意味が無いと思いますよ。
まさにあなたの言う「いちいち書くのがめんどくさい」のを回避する為に
OOPがあるんだと思います・・・
OOPの勉強なら、簡単なWEBフレームワークを自作するのが一番良いよ。
知識の無い段階でいきなりPHPでOOPって無理だと思いますよ。
背伸びせず、まずjavaやC#を学習する方が近道かもしれないよ。
0183nobodyさん
2008/01/31(木) 08:15:31ID:???0184nobodyさん
2008/01/31(木) 17:31:43ID:???読み込んで表示させるというものを作ってみました。
ファイル:全部で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);
?>
0185nobodyさん
2008/01/31(木) 17:32:35ID:???<?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();
}
}
}
?>
0186nobodyさん
2008/01/31(木) 17:33:57ID:???<?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;
}
}
?>
0187nobodyさん
2008/01/31(木) 17:37:50ID:???<?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>";
}
0188nobodyさん
2008/01/31(木) 17:39:35ID:???// 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();
}
}
}
?>
0189nobodyさん
2008/01/31(木) 17:51:38ID:???0190に ◆lKs5QMUHoA
2008/01/31(木) 19:03:23ID:???これをより抽象化させていって、「継承して使ってください」という
方向にするのか、それとも最初はクラスの数を増やさないように
しながら簡単なアプリケーションを作る方向にするべきか。
どっちの方向に持っていったほうがいいのか迷うな。。。
ま、そんなことを考える暇があったら手を動かしてみろという
話なのかもしれないが。。
0191nobodyさん
2008/01/31(木) 19:08:05ID:???自分で考えるのも良いが、君が今やっていることを
やってしまっているのが、フレームワークだ。
まず既存のフレームワークがどうなっているのか参考しろ。
0192nobodyさん
2008/01/31(木) 19:44:25ID:???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;
0193192
2008/01/31(木) 19:50:52ID:???疎結合にとかDRYにっていうのがだんだんわかってきた
理解したところで戻ってきて〜の方が結果的に早そう
俺はまだ勉強中だからそこまで行ってないけど
0194に ◆lKs5QMUHoA
2008/01/31(木) 19:56:23ID:???> $view = new CFView();
> $view->m_type = 'in';
これみたいに、直接メンバにアクセスするのは構造的に良くないと聞いたことが
あるよ。「データをやり取りするのは、インターフェースを通じて」という原則を
守るべきだと。
そうしなければ、CFViewクラスを改変する人は、そのクラスを使っている人の
コードを考慮して、メンバの値や変数名を自由に変える事が出来なくなるから。
なので、私は、コンストラクタで値を渡しても良いし、コンストラクタで値を渡して
いなければ、値を渡すためのインターフェースを使って渡すようにする仕様が
適当かなと思っている。
0195192
2008/01/31(木) 20:08:35ID:???あとコンパイルするときに全部チェックしてくれる言語とそうじゃない言語ってのもある
phpなんだしゆるーくやればいいじゃん なんていうと怒られるかw
0196に ◆lKs5QMUHoA
2008/01/31(木) 20:13:09ID:???だったら、コンストラクタで値を渡すよりも、インターフェースで値を
設定するような仕組みになるだろうね。
コンストラクタだと、一度値を設定したら、そのオブジェクトが破棄される
まで、再度設定が出来なくなるから。
0197nobodyさん
2008/01/31(木) 20:22:00ID:???それを用意した上でコンストラクタに引数を渡すなら渡せば良い。
複雑で多くの設定をしなきゃならない時以外、
newした直後に使える状態になっている方が使いやすい。
> $view = new CFView();
> $view->m_type = 'in';
これをセットで書かなきゃならないなら、
> $view = new CFView('in');
と書きたい。
0198に ◆lKs5QMUHoA
2008/01/31(木) 20:26:00ID:???「このモジュールを使う場合、このように書いてくださいね。」
というコードは、なるべく少ない方がいいからね。
なので、とりあえず設定の値はコンストラクタにいれるという
設計で書いてみた。
0199に ◆lKs5QMUHoA
2008/01/31(木) 20:31:34ID:???具体的にどのフレームワークを使って、どんなプログラムを書いて
みたらいいのか迷うなぁ。
とりあえずはこのあたりに載ってるものの、「和モノ」あたりからかな。
http://pc11.2ch.net/test/read.cgi/php/1197383840/3
フレームワーク自体の自作の話もいくつかあるみたいだ。
ttp://codezine.jp/a/article.aspx?aid=104
0200192
2008/01/31(木) 20:36:05ID:???あとinなのかoutなのか分岐させるとしたらそれはコントローラ側の仕事なんじゃないかなと思うんだけど違うかな
0201192
2008/01/31(木) 20:42:33ID:???ごめん気にしないで
0202に ◆lKs5QMUHoA
2008/01/31(木) 20:46:31ID:???> viewに渡すデータはセッタで渡したくならない?
表示させるデータはセッタがいいだろうね。
> あとinなのかoutなのか分岐させるとしたらそれはコントローラ側の
> 仕事なんじゃないかなと思うんだけど違うかな
>>185のソースがそれにあたるものだと思ってたけど。
if( ($form_str == "")or($form_str == "in") ){
省略
}elseif($form_str == "out"){
省略
}
コントローラは、POSTしてきた値を見て、必要なModelやViewを
選択し、実行する役割なので、それを実現したつもり。
0203に ◆lKs5QMUHoA
2008/01/31(木) 21:58:27ID:???CFControlクラスで、CFViewを使って表示する内容までもを
指定していする処理を書いていたのは間違いかな?
検索結果の表示や、データの更新の場合は、
Control→Model→View だけど、
ボタンを押した時の画面の展開のみの場合は、
Contol→View という流れとなり、Viewオブジェクトを
生成するクラスが異なるという処理でいいのかな?
0204に ◆lKs5QMUHoA
2008/02/01(金) 07:38:53ID:???各クラスの役割は以下のような感じでいいかな?
Control
・POSTでデータを受け取り、その値に不正なものが無いかをチェック。
・変なところからのアクセスではないかをチェック。
・$_POST["Form"]の値をみて、それに必要な画面と処理を判断する。
Model
・SQLを発行し、データを受け取る。
・データをViewクラスに渡す。
View
・フォームを表示する。(フォームごとにクラスを分けたほうがいいのかは迷うな)
・データを1件受け取り、tableタグでレイアウトを調整し、表示する。
0205nobodyさん
2008/02/01(金) 09:44:17ID:???0206nobodyさん
2008/02/01(金) 11:08:23ID:???読むとwebアプリについて学べるのではないかと思っている。
やることが多くなったけれど、とりあえずは以下の3本だてで
勉強してみることになるのかな。
MVCに分けて、簡単なアプリを自作する。
(ログイン、メニュー、検索条件指定、検索結果、データ編集などの画面があるもの)
和モノフレームワークを使って学ぶ。
簡単なアプリを自作する。
http://pc11.2ch.net/test/read.cgi/php/1197383840/3
サンプルで理解! フォームデータの受け渡し
ttp://www.atmarkit.co.jp/flinux/rensai/mysql5_03/mysql5_03a.html
0207nobodyさん
2008/02/01(金) 12:06:10ID:???class CObject ってあって、必ずそれが継承されて作られてるよね。
これの都合って何なんだろう。(メリットは何?)
javaも.NETもこういう基本クラスがあるよね。
0208nobodyさん
2008/02/01(金) 12:19:15ID:???0209nobodyさん
2008/02/01(金) 13:06:22ID:???サンクス。
でも、オーバーロードが出来ない場合は逆に足かせになる可能性もあるね。
例えば、継承されているクラスが沢山ある状況でObjectクラスに
メソッドを追加する場合とか。
0210nobodyさん
2008/02/01(金) 16:28:22ID:???コントローラとビュー
基本的にはね
0211nobodyさん
2008/02/01(金) 16:49:11ID:???フレームワークレベルのクラス構造となると、その構成が全く分からなくなって
来るんだよなぁ。何かコツのようなものはあるのかな?
処理の内容を追いかけると、次々に別のクラスに処理を渡す構造になっていて、
最後はあっけない、みたいな感じだ。
フレームワークを作る場合のクラスの設計手法を身につけるなどしないと
いけないのかも。
メンバに定義はしていないけれど、メソッドではその変数をエラーが
出ないように処理が書かれているっていう書き方は多いようだ。
そうしておけば、そのフレームワークを使う人は、クラスを継承して
メンバに値を代入するだけで良い。
0212nobodyさん
2008/02/01(金) 18:37:23ID:???MVCのうちどれにあたるのかがいまいちです。
ttp://www.stackasterisk.jp/tech/php/phpMvc01_01.jsp
Result.php は、Viewにあたるものという解釈でいいんですよね?
0213nobodyさん
2008/02/01(金) 18:47:22ID:???特集:第3回 PHPを思うままに操れるようになる「MVC」と「Smarty」 (1/4)
ttp://www.itmedia.co.jp/enterprise/0402/19/epn01.html
0214nobodyさん
2008/02/01(金) 18:50:51ID:???0215nobodyさん
2008/02/01(金) 20:08:38ID:???ハタさんのブログ : : php
http://blog.xole.net/category.php?k=php
0216nobodyさん
2008/02/02(土) 07:42:39ID:???例えば、サブミットボタンの処理ハンドラがオーバーライドで記述可能で
そこでフォーム値をモデルに渡して処理させるみたいなやつ・・
「POST」や「GET」とかローレベルの概念は全て隠蔽されてて
フレームワークにイベント発生時のロジックだけ記述して終わりみたいなの・・・
そしてPHPであれこれ試行錯誤したあと、ASP.NETとか参考にするとね
PHPでOOPするバカらしさに気付くかもしれない・・・OTL
0217に ◆lKs5QMUHoA
2008/02/02(土) 08:25:40ID:???あって、やらなくなったな。
ある程度Webアプリを学んだ事のある人には便利なんだろうけれど、
初めて学ぶ人には、ドキュメントが少なすぎだし、いきなりイベントドリブンで
やるのはどうかと思った。
で、まずは、Webアプリの基礎をやるという意味合いでPerlをやってみた。
で、今はPHPをやっている。PHPそのものがOOPに完全な対応をしていない
ので、これで大規模なアプリを組むことも無いかなと思っている。
対応したとしても、それからノウハウが出てくるので、さらに数年先になる。
でも、学ぶ時は、既存のモジュールを使って早くやるのよりも、モジュール
なしの状態で、モジュールを作ってみる方がいいので、とりあえず今は
PHPでOOPです。
0218nobodyさん
2008/02/02(土) 09:56:37ID:???多分、その違和感のある概念がOOPの本質だと思うよ。
そしてその概念は、洗礼された実装に触れることでしか
身につかないとも思うんだ。
初心者こそイベントドリブンを真っ先に学習したほうがいいよ。
最終的に、理解し易く安全な実装方法に結びつくと思うからね。
PHPでOOPで実装ってケースはありだとは思うけど、
概念は別で学習した方が効率的だと思うんだ。
0219nobodyさん
2008/02/02(土) 13:32:52ID:???普通にプログラミングしていると使うだろ?
switchに取り付かれているとかそういうレベルに聞こえるんだが。
0220nobodyさん
2008/02/02(土) 15:21:16ID:???どっちが正しいのかな?
・Control クラスのメソッド内で、Model クラスと View クラスのインスタンスを生成する。
Control クラスが、Model からデータを受け取り、View クラスへデータを渡し、
描画指示を出す。
・Model クラスのメソッド内で、View クラスのインスタンスを生成する。
Model クラスが、Viewクラスへデータを渡し、描画指示を出す。
Control クラスは、View クラスを一切操作しない。
それとも、こういうところまでは理論的には定めていないので、
ケースバイケースであり、どちらがよいというものは無いということかな?
0221nobodyさん
2008/02/02(土) 15:36:53ID:???02221 ◆SWtzLesEmM
2008/02/02(土) 16:44:49ID:???…こんなのありました。^^
PHP イベントドリブン に一致する日本語のページ 約 10,600 件
●PRADO
http://www.pradoframework.com/wiki/index.php/Ja:What_is_PRADO
>PRADO はコンポーネントベースかつイベントドリブンなウェブアプリケーションを開発するためのPHP5フレームワークです。
●S2Prado.PHP5
http://labs.s2php5.jp/s2prado.php5
http://blog.xole.net/article.php?id=553
>S2Baseの方は待望のPRADO対応。
●Piece Framework
http://trac.piece-framework.com/piece-unity/wiki/ja/Start
>Piece_Unityは、Visual BasicやDelphiのようなイベントドリブンなフレームワークです。
●Delphi for PHP
http://www.codegear.com/jp/products/delphi/php
http://orz.qzlab.com/yamagw/index.php?Delphi%20for%20PHP%A4%CE%BB%C8%A4%A4%CA%FD
>イベントドリブンなロジックの実装が容易に実現する。
●Pharon
http://pharon.lolipop.jp/
>最大の特徴は、wizard によりイベントドリブン型のスケルトンを自動作成することです。
02231 ◆SWtzLesEmM
2008/02/02(土) 17:00:36ID:???イベントドリブンは、PHPよりもむしろFlash/Flexとかで使われる仕組みなのでしょうか?
レガシーの中心でのOOP
http://kaede.to/~canada/doc/2005/07/06/
>Webプログラミングにおいて、ブラウザとのやり取りがレガシー(古典的)なデータ交換に過ぎず、これがWebプログラミングを難しくしている
>Webは1ページごとに毎回セッションが起動し、ドキュメントを表示するとすぐ終了する。
>オブジェクト指向プログラミングにおける利点の1つであるイベントドリブンなプログラミングは不可能だ。
>何しろ1セッションに1イベントしか発生しないのだから。
>と同時にセッション状態を保存する必要も出てくる。
http://www.adobe.com/jp/devnet/flex/articles/framework_beta_print.html
>インタラクティブ性に優れたイベントドリブンなインタフェイス
http://www.atmarkit.co.jp/fwcr/rensai/flex203/01.html
>イベント処理によってアプリケーションを構築する手法はイベント駆動型(イベントドリブン)と呼ばれます。
http://www.azul.systems-noel.jp/item_9.html
>Flex2はイベントドリブンなので、ビューに起こったイベントをコントローラのリスナでキャッチするように意識すれば、MVCの分離はきれいにできるようになっています。
>なんかほんとにJavaのSwingを使ってるような気分になりますね。
http://bitmap.dyndns.org/blog/archives/001215.html
>イベントドリブンモデルには、主に以下の 4 つのオブジェクトが登場する。
02241 ◆SWtzLesEmM
2008/02/02(土) 17:05:16ID:???>・Control クラスのメソッド内で、Model クラスと View クラスのインスタンスを生成する。
こっちの方が、Controlにまとまっている分だけスッキリしており、分かりやすいコードになるんじゃないでしょうか?
0225nobodyさん
2008/02/02(土) 17:24:12ID:???レスありがとうございます。
1番目の方にすると、Modelクラスから取得したデータを
Viewクラスに渡すことになるので、その分余計にメモリや
CPUを消費してしまうのでは、と心配になって聞いてみましたが、
考えてみると、コードの見易さなどを優先するのがOOPですので、
そちらの方がいいですね。
でも、フレームワークのソースなどを見ていると、
各クラスが、メンバに、別のクラスへのリファレンスを持ってたり
するので、もっと理論に従った組み方があるのかも、と思っています。
0226nobodyさん
2008/02/02(土) 17:36:37ID:???ファイル:全部で8つ。index.phpを実行する。
抽象クラスと具象クラスに実装を分けてみました。
csv.txt(※前回と同じ)
index.php
cfcontrol.php
アブストラクトとして実装
cfview.php
cfmodel.php
コンクリートとして実装
data_model.php
index_view.php
output_view.php
0227nobodyさん
2008/02/02(土) 17:38:02ID:???<?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();
?>
0228nobodyさん
2008/02/02(土) 17:39:03ID:???<?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);
}
}
?>
0229nobodyさん
2008/02/02(土) 17:39:58ID:???<?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);
}
}
?>
0230nobodyさん
2008/02/02(土) 17:40:48ID:???<?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;
}
}
?>
0231nobodyさん
2008/02/02(土) 17:41:48ID:???<?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>";
}
}
?>
0232nobodyさん
2008/02/02(土) 17:42:29ID:???<?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>';
}
}
?>
0233に ◆lKs5QMUHoA
2008/02/02(土) 19:04:13ID:???サンプルソースありがとうございます。
抽象クラスの書き方に慣れてますね。私はこのあたりを
しっかりとやってなかったのでちょっと苦手です。
ま、しっかりと勉強していきたいと思います。(^^;
ソースを読んでいて、1点気になったので質問をしたいのですが、
class CFView と class CFModel において、以下のように
パブリックメソッドと仮想メソッドを作り、パブリックメソッドから
仮想メソッドを実行する形式にソースを書いた理由は何でしょうか?
出来ましたら、この設計にした意図を教えていただきたいと思います。
function Execute($param) // パブリックメソッド
{
return $this->_OnExecute($param);
}
function _OnExecute($param) // 仮想メソッド
{
trigger_error('オーバーライドしてね。', E_USER_ERROR);
}
0234に ◆lKs5QMUHoA
2008/02/02(土) 19:24:37ID:???レスありがとうございます。
イベントドリブンそのものは、VBでWindowsアプリを組んでやったことがあるので
すぐに入れたのですが、Webアプリを作る際、イベントドリブンでしかやった事が
無いというのは致命的だと思ったので、PerlやPHPでやってみています。
(ASP.NETは、便利ではあるが、IISを使えとか、.NET Frameworkを使えとか
非常に限定される。)
構造化プログラミングで、あまり命名規則を考えずにプログラムをしていると、
グローバル変数や関数が多くなった時、その把握が出来なくなったりする
わけなのですが、そういう苦労する体験をした後、OOPを習うと、その便利な部分が
見えてくるわけです。OOPは経験による結論的な理論だな、と理解できるわけです。
その理解のために、とりあえず、苦労をする方法(PHP で 0 から OOP)で
やってみているのです。
今は、このように考えています。
0235nobodyさん
2008/02/02(土) 19:59:40ID:???ポカ・ポカ テンキュー
0236nobodyさん
2008/02/02(土) 21:30:36ID:???PHP4では全てパブリックだけど例えばC#では以下の実装になるんだ
public object Execute(object parpam)
protected virtual object _OnExecute(object parpam)
CFControlから_OnExecuteメソッドを隠蔽する意図なんだよ。
_OnExecuteはCFViewやCFModelのサブクラスにだけ見えれば十分なんだ。
0238に ◆lKs5QMUHoA
2008/02/03(日) 14:47:56ID:???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の構成ということでよろしいのでしょうか。
0239に ◆lKs5QMUHoA
2008/02/03(日) 14:50:55ID:???となんとなく思ったりもしたのです。
[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");
0240nobodyさん
2008/02/03(日) 15:27:26ID:???実例コードが載ってるのがいい
PHPでMVC第1回:前編
ttp://www.stackasterisk.jp/tech/php/phpMvc01_01.jsp
0241nobodyさん
2008/02/03(日) 15:52:25ID:???0242nobodyさん
2008/02/03(日) 16:56:56ID:???0243に ◆lKs5QMUHoA
2008/02/03(日) 19:47:22ID:???メモとかを残していく都合もあると思ったから、HP解説してみた。
ttp://www.geocities.jp/narutobakijp2/
本当は、>>1さんがソースの管理とかもしてくれたりしたら、うれしいw
0244nobodyさん
2008/02/04(月) 01:44:33ID:???いちいちzipを解凍する気にならない
0245nobodyさん
2008/02/04(月) 09:02:58ID:???CFViewクラスに具体的な実装をしちゃダメなんだよ。
そもそもHTMLのフォーム処理とかは、あとでPEARとか使えばいい。
サブクラスをうまく呼び出す仕組みだけを実装していくんだ。
0247nobodyさん
2008/02/04(月) 23:36:13ID:???構造化プログラミングはルーチンを呼ぶ方向で実装すると思うけど
OOPではルーチンに呼ばれる方向で実装して行く感じだよ。
大枠の骨組みだけを抽象クラスで作成して、処理は具象クラスで行うんだ。
インターフェイスさえ同じならあとで個別にパーツを交換出来たりするからね。
だったら基底クラスのメソッドなんて数個で十分じゃないかと思うんだ。
やたら複雑でよくばりな機能のクラスなんて、再利用の価値がないからね。
0248に ◆lKs5QMUHoA
2008/02/05(火) 01:28:01ID:???レスありがとうございます。
> 構造化プログラミングはルーチンを呼ぶ方向で実装すると思うけど
> OOPではルーチンに呼ばれる方向で実装して行く感じだよ。
私は、継承を活かした設計をした事が無かったので、ちょっと方向性を
誤ってしまったようですね。
Viewは、表示をつかさどるのだから、html表示を請け負うのでは、と
思っていたのですが、それよりも抽象的な枠組みを定義するという
ことですね。
となると、html表示は(PEARを使わないのであれば、)htmlタグの
記述を行うCF_HTMLクラスを作り、Viewの具象クラス内で
インスタンスを生成ということですよね?
0249nobodyさん
2008/02/05(火) 08:55:19ID:???HTML処理のヘルパクラス作成はあまりOOPの勉強にならないとも思うんだ。
もう既に頭の中で実装出来ているだろうし、引数を関数で処理するだけでしょ?
それよりも例えばPEARのHTML_QuickFormやテンプレートレンダラのSmartyを
Viewと連携させる仕組みとかを考えたりした方がよっぽど面白いよ。
すべてをフルスクラッチするプログラミングの方向性は必ずしも得策じゃないよ
既存のライブラリやコンポーネントを上手く利用するのもOOPの要素なんだよ。
0250nobodyさん
2008/02/05(火) 11:06:34ID:???継承を用いた設計などが入った解説)
この連載は良いかもしれない。
オブジェクト指向プログラミング超入門
.NETでオブジェクト指向プログラミングを始めよう
http://www.atmarkit.co.jp/fdotnet/basics/oop_index/index.html
特に第6回は、今まで出てきていた話題だと思う。
Objectクラスで仮想メソッドToStringをもち、それから派生したクラスは、
オーバーロードをする仕組みを図説していて分かりやすい。
第6回 階層の頂点に立つクラス
http://www.atmarkit.co.jp/fdotnet/basics/oop06/oop06_01.html
0251nobodyさん
2008/02/05(火) 11:52:25ID:???PHPのプログラマにも非常に参考になると思いますよ。
.NETの世界はクラスベースなので初めからOOPの思考で実装します。
関数が作れないので構造化思考のVB6プログラマとか、クラスをnewせずに
引数を大量に渡すスタティックメソッドを呼んだりしてしまいます・・・
PHPはC言語での関数モジュールを呼び出す実装スタイルに近いので
やはりクラスを使って構造化プログラミングをしちゃいがちですね。
普及しているPHP4がOOP対応不十分なのと、開発環境が貧弱であることも
PHPでOOPがなかなか利用されない原因になってたりしますよね。
プロテクテッドメソッドの概念とかIDEがないと、なんでそうするのか
なかなか理解出来ないとも思いますしね。
0252nobodyさん
2008/02/05(火) 11:56:50ID:???クラス構成で、Viewに絞った構成を考えてみた。
[View]
├[認証]
├[個人情報入力]
├[メニュー]
├[検索指定]
├[検索結果]
別の案として、[View]から[Input View]と[Output View]の
二つを継承し、さらに以下のような継承も浮かんだけれど、
継承して分ける必要性は無さそうなので、上記の方が良いように思う。
[Input View]
├[認証]
├[個人情報入力]
[Output View]
├[メニュー]
├[検索指定]
├[検索結果]
0253nobodyさん
2008/02/05(火) 12:16:06ID:???[View]
├[LoginView]
├[InsertView]
├[MenuView]
├[SelectView]
├[ResultView]
こんな感じ?
0254nobodyさん
2008/02/05(火) 13:28:44ID:???各画面([LoginView] [InsertView] [MenuView] ・・・)で
エラー確認用のメソッドをオーバーロードする形で。
開発中はPOSTで受け取ったデータとかを画面上部に表示しながら動作確認する
っていうのは、よくやるからね。
Objectクラスを継承する形にするのは、このスレでは共通したメソッドの
実装という理由だ。という話だったけど、リファレンス関係の処理で
便利だという話がサイトに載っているようだね。
このあたりの考え方も活かすと良いかもしれない。
ただ、PHPのOOPだとうまく実装出来ないかもしれないが。
>>207-209 >>250
0255nobodyさん
2008/02/05(火) 13:44:31ID:???Select // データ取り出し
Delete // 削除
Insert // 新規追加
Update // 既存データの更新
>>228に載ってる既存のクラスには Execute があるけれど、
これも残しておくべきかな?
0256に ◆lKs5QMUHoA
2008/02/05(火) 19:03:57ID:???またソースコードをリニューアルしようかと思ったが、
いざやり始めてみると、データベースを管理する基底クラスの
設計を具体的にどうするかをきめないといけなくなり、それを
どうするかで迷っている。。。
概ね以下のような感じにしたいと思ってるんだけどね。
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; // データベースを格納。
0257nobodyさん
2008/02/05(火) 20:33:23ID:???普通は機能をメソッドに振り分けると思うけど
コントローラのメソッド内で以下の様に
操作出来たら面白くない?
// モデルにフォーム値を渡してデータ書き込み
$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のアプリ作成に必要な要求仕様作ってよ。
0258に ◆lKs5QMUHoA
2008/02/05(火) 23:02:08ID:???要求仕様案
私は眼鏡屋(○○支店の店長)をやっている。
顧客の情報(名前、住所、性別、生年月日、・・・)を管理したい。
・眼鏡を購入した顧客の情報を登録しておき、ある一定期間経つと
新しい眼鏡を購入する案内のDMを発送したい。
→条件検索をしたい。
・登録した情報を検索し、どんなお客様かをすぐに確認出来るようにする。
→例えば、苗字を聞いて、詳細が分かるようにする。
・眼鏡の定期的なメンテナンスで、訪問してきたら、その対応履歴を
登録しておきたい。
→眼鏡のクリーニング、シリコンパッド(鼻にあてるやつ)の交換など
・定期的なメンテナンスは無料であるので、全く店に来ない客には、
その無料案内のDMを発送したい。
→今回は、複数の店舗にまたがった処理はいらない。
・他の社員に勝手に情報を触られないように、認証を通すようにする。
眼鏡の在庫管理は、このシステムとは別。
これは、プログラムの規模が大きくなりすぎるようであれば、
もちろん内容を変えてもいいです。「顧客の情報を登録し、
それを検索する」という流れだと、勉強用サンプルとして非常に
良いのでは、と思いました。
0259に ◆lKs5QMUHoA
2008/02/05(火) 23:21:24ID:???氏名:茂名
フリガナ:モナー
性別:男性
生年月日:H1/3/3
住所:東京都・・・
コメント:ふちなしタイプを希望している。
眼鏡購入日:2007/1/5
眼鏡の型番:2ch
[2007/1/5に購入した2ch]のメンテナンス履歴
2007/2/5:クリーニング
2007/3/15:ネジの交換
2007/5/1:クリーニング、曲がったフレームの修正
顧客のデータ1件に、眼鏡の購入日がつながり、さらに、メンテナンス履歴が
つながる構成になるけれど、今回は勉強用なので、「顧客のデータ1件=眼鏡の購入日1件」
としてもいいかもね。
再度購入したら、顧客の個人情報を0から入力しなおすみたいな。
0260に ◆lKs5QMUHoA
2008/02/06(水) 01:36:05ID:???Execute($param)したあと、Debugとか、もしくは、
Debugの中でExecute($param)を呼び出す処理だと、
<html>タグのそとに確認データが出力されてしまう。
Debug モードを on にすれば、<body>タグの上部に
テーブルで区切ってデータが表示されるとかかな。
だったら、メンバにDebugモードを追加かな。
という感じに考えてる。
みんなどう思う?
0261nobodyさん
2008/02/06(水) 09:30:01ID:???ちょっとしたシステムじゃん・・ (´・ω・)
それこそ既存のフレームワーク使用する案件だよ。
>>260
ディレクティブ付けたechoやvar_dump埋め込みで十分だと思うよ。
むしろその機能を実装するより、デバッガ環境構築した方がいい・・・
OOPに対する基本的概念への理解があまりにも無さ過ぎると思うんだ。
>>255にしても、Executeメソッドに呼ばれる仕組み作ってんのに、
なんで新しいメソッド実装して直接呼びたがるんだろう?
あれほどインタフェイスだけで実装するんだと(ry
それよりコントローラの実装仕様どうするの?
02621 ◆SWtzLesEmM
2008/02/06(水) 10:44:17ID:???>ttp://www.geocities.jp/narutobakijp2/
↓動作サンプルを設置しました。
http://ssurl.net/so2o
↓コードに関するコメントのまとめ(>>184-226辺り)
http://ssurl.net/h8bu
■ このスレッドは過去ログ倉庫に格納されています