PHPでオブジェクト指向プログラミング
■ このスレッドは過去ログ倉庫に格納されています
0001nobodyさん
2005/04/17(日) 16:55:57ID:iM4mgYnJPHPによるOOPについて語りましょう。
0699nobodyさん
2005/09/03(土) 18:22:35ID:JcQXpRDz俺みたいなやつの質問にこたえてくれて
会社でPHPつかえるやついなくてな、皆javaばかりで
おれだけPHPだから肩身せまくてな
これからもよろしくたのむよ
0700nobodyさん
2005/09/03(土) 18:53:52ID:???$aをメソッド内のローカル変数として使いたいのか
それともフィールド変数として他のメソッドからも使いたいのか
どっちが目的なのかわからん。
0701nobodyさん
2005/09/03(土) 19:00:47ID:???この程度の内容にPHP4、PHP5、Javaで違いはないんだが(書式以外で)。
オマイがカスすぎて他の社員から相手にされてないだけではないのか。
0702nobodyさん
2005/09/03(土) 19:15:26ID:???>会社でPHPつかえるやついなくてな、皆javaばかりで
>おれだけPHPだから肩身せまくてな
オマエ、どうみてもPHP使えないだろ? 下手するとPHPだけじゃなくプログラミング自体素人か。
Javaは絶対習得できそうにないからPHPでもやらせとけ、って感じしかしないのだが。
0703nobodyさん
2005/09/03(土) 19:37:49ID:fR+7vSEm本の読み方を間違ってる。
0704nobodyさん
2005/09/03(土) 19:39:05ID:JcQXpRDzもともと営業ではいったからな
プログラミング歴は3週間目だ。
これで月給38万ももらってていいのか。
0705nobodyさん
2005/09/03(土) 20:12:15ID:???営業で入ったにしても日本語が下手すぎるね。
まぁ給料貰えるうちに頑張れ。
なんでthisを多用するかって事だけど、先の例だと
setterっぽく使いたかったのかな?変数publicだけど・・・。
その本を読み進めて行くと、多分その疑問は解凍されると思うよ。
0706nobodyさん
2005/09/03(土) 23:51:44ID:???インピーダンスミスマッチについてどうお考えですか?
仕事でPHPでオブジェクト指向で進めようとしていますが、
PHPの効率のよさはオブジェクト指向ではないやり方によるものだった
ってことはありませんか?
0707nobodyさん
2005/09/03(土) 23:59:36ID:???営業で入って、プログラミング歴3週目で、>>688 で書いている
"最近PHP5に移行したんだが" が激しく一致しない。。。
0708nobodyさん
2005/09/04(日) 01:10:09ID:???3週間前PHP4の本渡されて勉強した後、最近新たにPHP5の本渡されて勉強しはじめたんでないか?
彼の中ではすでに「最近PHP5でクラスを自作しました」とかになっていると思われ。
0710nobodyさん
2005/09/04(日) 03:05:09ID:???いい身分だな。
何も教えてやりたい気分も萎えそうだが
オブジェクト指向を理解していない奴と一緒にソフト開発することほど
ウザイことはないから少しだけ教えてやる。
0712nobodyさん
2005/09/04(日) 03:07:29ID:???PHP5でオブジェクト指向ををやるのに本が少なすぎる?
ならJavaの本を買え。
結城浩の「Java言語で学ぶデザインパターン入門」
これ嫁。これ読めばPHP5で無理矢理オブジェクト指向するよりも
オブジェクト指向は素早くすんなり理解できる。
何と言ってもオブジェクト指向といえばJavaと言われているくらいだからな。
0713nobodyさん
2005/09/04(日) 03:12:09ID:???純粋論者はインスタンスフィールド$aをprivateにすべきだと主張する傾向にあることをよく覚えておけ。
そのときは$aに対するgetter/setterを定義するることをお忘れ無く。
PHP5からは__getや__setなんてものもあるらしいな。
どんなメリットがあるのかわからんので
自力でgetA(), setA($a)を定義してはいるが。
メソッド引数で定義されている$aはローカル変数で
フィールドの$aとは異なる。
そのときの重複を避けるために$this->aという記法を用いる。
0714nobodyさん
2005/09/04(日) 03:14:50ID:???Javaのfinalに相当する最初の一回しか代入を許されない変数を定義できないのだろうか?
でないと不変クラスを作れない予感が。
0715nobodyさん
2005/09/04(日) 03:16:30ID:???機能が強化されてもnamespaceが使えないのが非常に残念だ。
Facadeパターンなどを実現しづらい。Javaですっきりと実現できる
デザインパターンがPHP5ではあまりにも中途半端でアクセス権の管理があまりにも杜撰になる。
0716nobodyさん
2005/09/04(日) 04:32:10ID:???PEARみたいな公式の出すらPHP4との互換性保持のため
ほぼ全てのフィールドがvar宣言。メソッドも同様。
0717nobodyさん
2005/09/04(日) 06:15:04ID:???0718nobodyさん
2005/09/04(日) 08:21:13ID:???無理にJava目指すことは無いんじゃないかな。
OOPを知りつつ、OOPの考え方で
OOPじゃない簡単な実装だってできるだろうし。
0720nobodyさん
2005/09/04(日) 08:27:14ID:???0721nobodyさん
2005/09/04(日) 10:11:49ID:???できるようだが。
ttp://www.php.net/manual/ja/language.oop5.final.php
0722nobodyさん
2005/09/04(日) 17:13:11ID:???PEAR::MDB2というのがあるが、
今ベータ版。
MDB1がPHP4対応であるのに対してMDB2はPHP5対応。
よってこれからのPEARはPHP5によってすべて生まれ変わる。
0723nobodyさん
2005/09/04(日) 17:20:23ID:xhmaGAtHあのーfinalなクラスやメソッドを定義できるのは知ってるんですけどー
やりたいことはfinalなフィールド(メンバ変数、プロパティ、属性)やローカル変数を定義したいんですけどー
constしか使えないんですかぁ?
const CONSTANT = 'aa';
とかはできるんだけどさあ。
const CONSTANT2;
と宣言だけしておいて
コンストラクタで
public __construct(Type $constant){
$this->CONSTANT2 = $constant;
}
と後から代入するってことができないんですけどー
こういうこともできなくて困ってるんですけどー
const CONSTANT3 = CONSTANT2.'連結'
0724nobodyさん
2005/09/04(日) 17:23:35ID:???pulic void doMethod(final Type type){
type = "aa"; //typeはfinal宣言されているので
//あとから代入するとエラーになるように、誤作動防止機能
//として使える。
}
これをPHP5でやると?
pulic function doMethod(constant Type $type){
$type = "aa"; //typeはfinal宣言されているので
//あとから代入するとエラーになるように、誤作動防止機能
//として使える、はずなのだが。
}
見事にエラーですか。
困っちゃったねえこりゃ
0725nobodyさん
2005/09/04(日) 17:24:52ID:???そこでPerl6ですよ。
ParrotVirtualMachineといい、コンパイラといいバイトコードといい
もろJavaのパクリですが。
0726nobodyさん
2005/09/04(日) 21:26:38ID:???Singletonでなんとかならんか?
ってか、phpならそうやって使うのが普通だと思うが?
なぜjavaに拘る.
# finally欲しいなぁ
0727nobodyさん
2005/09/04(日) 21:35:22ID:???同意。
Javaはコンパイル型。PHPはインタプリタ型。
だから同じ書き方・動作じゃないのは当たり前なんだけど。
例えば Javaでいう Interface みたいのを
スクリプト言語に入れるのは、なんか違うよね。
そういうのはコンパイル型の言語で素直にやりなよ、ということ。
0730nobodyさん
2005/09/05(月) 04:03:31ID:???JavaソースをPHP5ソースに変換するツールはおらぬのか?
0732nobodyさん
2005/09/05(月) 22:06:33ID:???いらないんじゃなくて、ナンセンスだってことでしょ。
スクリプト言語なのに、メソッド実装を強制するような事が。
実行時に文字列を読み込んで、
その場でインタプリタがクラス作っちゃうような事もできるのに。
Interfaceみたいのは、別にあっても良いと思うけど。
速度に問題出なければ。
0733nobodyさん
2005/09/05(月) 22:30:28ID:???Java使いがPHPを使う場合、またはPHP使いがJavaを学ぶ為って感じがする。
自分がそうだったし。
PHPでOOPだのDIだのなんだのすると速度的にかなりマイナスだしね。
0734nobodyさん
2005/09/05(月) 22:42:44ID:???静的型付けか動的型付けかということのような気がする。
0735nobodyさん
2005/09/05(月) 23:35:49ID:???0736nobodyさん
2005/09/06(火) 00:39:18ID:???0737nobodyさん
2005/09/06(火) 01:00:02ID:???0738nobodyさん
2005/09/06(火) 01:11:32ID:???0739nobodyさん
2005/09/06(火) 01:17:11ID:???setXXX(), getXxx() を__call()でオーバーロードするとか、そんな感じですかね。
DAO設計するときに役立ちそう。
0740nobodyさん
2005/09/06(火) 03:01:57ID:???dev-mlでもそのへんの改善案を検討しているみたいだけど。
基本的にPHPのマジックメソッドはどれもちょっと抜けてて使いにくい。
0742nobodyさん
2005/09/07(水) 12:48:27ID:???require()が無駄にリストアップされてしまう問題を
__autoload()によって解決できるとおもったらそれできんのかい?
>>740もオーバーライドができないってことは、かなり痛すぎる予感。
Javaの真似をして
とりあえず、すべてのクラスの頂点たるObjectクラスを実装して、
そのクラスにとりあえず__autoload()を
入れておくってか。
以後、すべてのクラスは、継承宣言をする予定がないときは、
かならずObjectクラスを継承するように予定変更する、と。
で、ObjectクラスにはJavaのObjectと同じように、
hashcode(), equals(), finalize(), wait(), notify()などを実装する。
少なくとも、equals()は重要。
Comparableインターフェースなども作っておく。でcompareTo()メソッドも
実装できるように。Cloneable, Serializableインターフェースも。
__autoload()を無理矢理オーバーライドするなら、
これしかないか?
__autoload()を他のメソッドでラップし、そのメソッドをサブクラスオーバーライドする。
でオーバライドしたらまたそのサブクラス内で__autoload()を実装し、オーバーライドした
メソッドを呼び出す。
っていうやりかたはうまくいかんか?
0743nobodyさん
2005/09/07(水) 13:08:31ID:???PHPで多重継承が必要な場面に遭遇したことないけど。
それが>>732の言わんとしてることじゃないの?
>>742
__autoloadのラッパ・・・?それじゃ__autoloadの意味ないじゃん。
ファクトリメソッド作るなら、そのメソッド内でrequireしたほうが話は早いわな。
とりあえず何を主張したいのかが不明瞭。
>>738と>>740への批判みたいなことを言いたいのだろうか?
0744nobodyさん
2005/09/07(水) 16:59:36ID:???多重継承しないように設計すれば良いだけでしょ。
Javaでしかデザインパターンしたこと無いのかも知れないけど…。
0745nobodyさん
2005/09/07(水) 21:56:51ID:???委譲や集約だけに任せるってのかい。
そっちのほうがもっとナンセンスに見えることもないか?
デザインパターンでも多重継承つかったサンプルが沢山あるのに。
それに、オブジェクトをディープコピーできるようになることを示すCloneableインターフェース、
オブジェクトを直列化できることを示すSerializableインターフェース、
これらが使えんだろ。
こういうインターフェースを定義したい場面ってのが結構ある。
あるクラスを継承したいが、すでに他のクラスによって継承されているので
これ以上継承できない、っていうとき、片方のクラスがインターフェースになっていれば助かる。
とくにマーカーインターフェースは使える。
>>732はメソッド実装を強制するためだけにインターフェースを使うつもりでいるらしいが、
マーカーインターフェースはメソッドなんかいらない。
Serializableはメソッドなんか一つもない。まさにクラスにマーカーをつけるかのように
インターフェースを実装できる。
このように、一つのクラスに、継承しながら複数のインターフェースを実装したい場合があるときに、
インターフェースは役に立つ。
デザインパターンの本を良く読んでいるならインターフェースを使ったサンプルはよく見かけると思うが。
インターフェースは便利だから使う。抽象クラスだけでは限界があるとき、
非常に役立つ。
無計画に使いすぎるとインターフェースの乱立が生じてとんでもないことにはなるが。
使い方さえ気をつければ非常に使える。
それから、定数を定義するときもインターフェースをよく使う。
実装はしないがタダ定数を置くだけ。define()を使えという意見もあるが、インターフェース名::定数名
という構文規則が守られちょっとわかりやすくなる。
0746nobodyさん
2005/09/07(水) 21:59:17ID:???インターフェースも使えないのはなにか違和感がある。
ここでクラスだけにしたら、クラスに多重継承させることを許してしまう。
というか、クラスで多重継承ができることを許さないといけなくなる。
そうするとC++のような混乱が生じ、ダイヤモンド継承とかわけのわからんことになる。
だからインターフェースは必要なんだと。
0747nobodyさん
2005/09/07(水) 22:15:56ID:???デザパタは大事だけど、PHP採用してるような現場でそこまで厳密なOOPが必要か?
とも思う。
現状のPHPが中途半端な状態にあるのは分かるけど、
中途半端なら回避すれば良いだけでしょ。
仕事でどうしてもPHP使えと言われていて、PHPの今の実装はこうです。となってる。
デザパタ知ってるなら、その考えを使って、
いま組めと言われている言語にあった、無理の無い設計をするのが普通じゃないのかな。
うまく骨抜きにして言語に合うように実装する。そんだけだろ。
0748nobodyさん
2005/09/07(水) 22:22:32ID:???「プログラミングで注意すべき部分を冗長にマーキングする」でかまわんけどなぁ・・・
ZendEngineにキャッシュが搭載されるのはPHP6からだっけ?
0749nobodyさん
2005/09/08(木) 00:05:46ID:???うむ。「インターフェイスがないと多重継承ができない」とか聞くと違和感覚える。
普段どんなインターフェイスの使い方してるのか気になったりする。
0750nobodyさん
2005/09/08(木) 00:42:45ID:???Adapterパターンとかな。(代替手段として委譲するのもあるがな)
0751nobodyさん
2005/09/08(木) 01:01:24ID:???0752nobodyさん
2005/09/08(木) 02:07:18ID:???ところがそれら作られたものを使う人(クラス)には役に立たない。
0753nobodyさん
2005/09/08(木) 02:38:21ID:???代替って言うか常に委譲の方で良いじゃん。
interface不要って事だ。
0754nobodyさん
2005/09/08(木) 02:49:08ID:???execute()を持つAというinterface
それを実装したクラスB1とB2が有ったとする。
で、利用するコード
$a[] = new B1();
$a[] = new B2();
$a[] = new C1();
foreach ($a => $obj) {
$obj->execute();
}
ここでC1はたまたまexecute()を持つAを実装でないクラス。
PHPはこれでエラーが起きない。
0755nobodyさん
2005/09/08(木) 02:55:41ID:???何をしたいのかも明確にできない。type hintingみたいな機能もあるけど
Javaと違ってmainメソッドを必ずしもクラスにする必要は無いわけだし。
0756nobodyさん
2005/09/08(木) 03:33:10ID:???まあわかってやれよ。こういうことだろ?
interface A { public function execute(); }
class B1 implements A { public function execute() { ・・・ } }
class B2 implements A { public function execute() { ・・・ } }
class C1 /* doesn't implement A */ { public function execute() { ・・・ } }
$a = array(new B1(), new B2(), new C1());
foreach ($a as $obj) $obj->execute(); // interface Aなんて初めからあってもなくても結局変わらん
つまり、PHPのinterfaceはインスタンスの型を制限する役割は全く果たせないってこった。
ただJavaライクな文法があれば、Javaに慣れている人間同士で意思の疎通や理解がしやすくなり、結果的にデザパタも組みやすくなるって面もある罠。
その点では大きな利点といえる。
しかし、飽くまで可読性・保守性に関する利点であって、PHPの言語仕様上の利点ではない。
現にPHPでデザパタは多くの場合、単に「通念的」にしか実装できないことが多いが、その限りでは文法上どんなデザパタもinterfaceなしで実装できることになる。
0757nobodyさん
2005/09/08(木) 08:45:11ID:???まあ PHP 的には以下のようにするのが限界かな。
foreach ($a => $obj) {
if ($obj instanceof A) {
$obj->execute();
}
}
もしくは duck-typing な感じで、
foreach ($a => $obj) {
if (method_exists($obj, 'execute')) {
$obj->execute();
}
}
とか。
0758757
2005/09/08(木) 08:54:45ID:???■$a をコレクションにして Iterator を使った場合
while ループの中で A obj = (A) iterator.next(); とした時に
C のインスタンスが ClassCastException で引っかかる
■$a を A の配列にした場合
配列に C1 のインスタンスを代入しようとした時点でエラー
となるわけで、どっちかっつーと PHP の扱い方のほうが便利じゃない?
0760nobodyさん
2005/09/08(木) 10:46:30ID:???だからその「便利じゃない」って点こそが肝なんだよな、結局。
書けるコードに制限を設けることで意図を明確にできるわけで。
0761nobodyさん
2005/09/08(木) 11:52:57ID:???0762nobodyさん
2005/09/08(木) 13:09:48ID:???インスタンスの型を制限する役割はないといっても
メソッドに引数で制限できるから
インターフェースはわりと使えるもんだよ
0763nobodyさん
2005/09/08(木) 15:49:09ID:???JavaならばC1の書き直し、
状況によってはinterface A自体の見直しも必要になってくる。
AやC1が外部のライブラリならその修正も困難。
(まあ、そのためにAdapterパターンがあるのかもしれないが
Adapterパターンの多用は冗長になるなどの欠点をしばしば指摘される。)
そういう点でPHPのような動的な型付け言語は柔軟性があるのだと思う。
でも>>754のコードが意図的なのかどうかというのを
コメントなしに伝える事が不可能な点が問題。
メソッドの引数で伝えるのは状況が限られる。
柔軟性か信頼性かって事だ。
0765nobodyさん
2005/09/08(木) 18:58:07ID:???0766nobodyさん
2005/09/09(金) 21:00:51ID:TEZpGZnS$this->hoge = "fuga";
って初期化やるのと、
プロパティー宣言部に最初から
var $hoge = "fuga";
ってやるのと、どう違うの?
何となく、プロパティー宣言部に書いておいた方が速い気はするけど
何か問題はある?
0767nobodyさん
2005/09/09(金) 23:19:57ID:???0768nobodyさん
2005/09/10(土) 00:32:17ID:Gaffkz1Oいいことにインスタンスを引数で持ちまわすのではなくて
使うたびにgetInstanceするのって間違ってますか?
0769nobodyさん
2005/09/10(土) 00:34:55ID:???JavaとPHPとその他一部を除く多くのオブジェクト指向言語を否定するわけね。
0771nobodyさん
2005/09/10(土) 00:38:34ID:???おk
>>767
Javaに毒されすぎ。
それはもはやオブジェクト指向じゃなくてクラス指向だよ。
要らないとは言わないし、あると便利な局面があるのも分かるけどPHPとJavaは別の言語なんだから。
>>768
むしろ常套手段かと。
0775nobodyさん
2005/09/10(土) 12:53:29ID:???少なくとも>>741や>>745みたく「Interfaceがないと多重継承ができないからダメだ」とか
言ってる奴にはオブジェクト指向語らないで欲しい。
0779名無しさん@そうだ選挙に行こう
2005/09/11(日) 01:31:18ID:dmsH6X+Kどう実装してる?
1 setPropertyと別に、setPropertiesを作って、可変長引数を受け取る
2 setPropertyと別に、setPropertiesを作って、一つの配列(コンテナ)を受け取る
3 setPropertyを、可変長引数の受け取りもできるようにする
4 setPropertyを、配列(コンテナ)の受け取りもできるようにする
どれが一番いいんだろ?
0780779
2005/09/11(日) 01:36:41ID:???setErrorとsetErrorsを用意して
配列で受け取ってる=2
みたいだけど。
それが無難ですかね。
0781名無しさん@そうだ選挙に行こう
2005/09/11(日) 02:04:57ID:???俺も2かな。
どんなプロパティなのかにもよるけど、3や1もありうる。
4だけは混乱したから使わない。
0782名無しさん@そうだ選挙に行こう
2005/09/11(日) 12:25:07ID:???ものすごく都合よく解釈した広い意味で
0783名無しさん@そうだ選挙に行こう
2005/09/11(日) 14:06:04ID:???非常に嘆かわしいことに、インチキなJavaの入門書には、
「JavaではC++の多重継承の代用品としてInterfaceというものがあります」
なんて、腐りきった解説が今でもあったり・・・ すごく哀しい。
0784名無しさん@そうだ選挙に行こう
2005/09/11(日) 14:08:59ID:???Java登場初期の頃にそう言われていたのは事実。
デザインパターンとかが普及してきてから変わってきた。
0785名無しさん@そうだ選挙に行こう
2005/09/11(日) 16:00:13ID:???昔はそれが常識で事実だったみたいな言い方はよくない。
0786名無しさん@そうだ選挙に行こう
2005/09/11(日) 16:12:44ID:???発想が意味分からないな。
0787名無しさん@そうだ選挙に行こう
2005/09/11(日) 16:34:34ID:???0788名無しさん@そうだ選挙に行こう
2005/09/11(日) 17:19:05ID:???0789名無しさん@そうだ選挙に行こう
2005/09/11(日) 18:43:04ID:???0790名無しさん@そうだ選挙に行こう
2005/09/11(日) 18:46:55ID:???C++だが、参考になると思う。
0791nobodyさん
2005/09/12(月) 19:02:44ID:???$sql = "select * from $table"
みたいに
$sql = "select * from $this->table"
と書いたらエラーになるのってキモくね?
この気持ちをどうしたらいいですか。
0794nobodyさん
2005/09/12(月) 21:17:25ID:???0796nobodyさん
2005/09/14(水) 06:17:54ID:uQ+GcINS(StatementDAO,ThreadDAO等)
結合しなきゃならないケースが出てきた。
結合の場合、DAOってどうすればいいの?
0797nobodyさん
2005/09/14(水) 19:20:52ID:???DAOというよりはDataMapperに近い考え方なのかな。んで、
「さて結合の場合はどうしよう?」ってのがO/Rマッピングの課題の1つじゃなかったっけか。
自分の場合、例えば都道府県名とかあるレコードの属性に関する情報はgetterで結合しちゃってる。
呼び出しを冗長にしたくない場合はgetDetail()なんかのメソッドを作ってそっちを結合専用にしている。
複雑な結合を含むselectが必要な場合は、そのselectがどのテーブルを基にしたものかを判断し、
そのテーブル(用のクラス)にメソッドを追加してる。
0798nobodyさん
2005/09/16(金) 02:45:16ID:???ちょっとまて。
それではclassだけで多重継承ができるという誤解を生むぞ。
A extends B, C, D,E {}
を許す結果になるぞ。
それに>>788は勘違いしている。
それから、>>775は
>>741や>>745が
「Interfaceがないと多重継承ができないからダメだ」と言っていると
勘違いしているがそんなことはどこにも書いていない。
「interfaceがないと多重継承ができない」とは書いてはあるが
それがダメだなんてことはどこにも書いていない。
勘違いしすぎ。だから>>788や>>753, >>727のような誤解をする者が出てくる。
■ このスレッドは過去ログ倉庫に格納されています