PHP初心者を卒業し、オブジェクト指向でプログラミングしたいです。


今日、本屋さんに行ってきましたが、どれも似たような内容です。
処理を上から順番に書いていくスクリプトっぽいphpの書き方から、
もうすこし大き目なものをオブジェクト指向でphpで書けるようにステップアップしたいのですが、
どうればよいのかよくわかりません。独学初心者から初めてまだ数か月、生意気とは思わず、温かいアドバイスをどうかお願いいたします。

サンプルコードの豊富なサイトや、おススメの本などがあれば教えてください。
よい勉強方法もよろしくお願いします。

回答の条件
  • 1人2回まで
  • 13歳以上
  • 登録:2011/10/18 22:31:22
  • 終了:2011/10/23 12:40:28

ベストアンサー

id:tdoi No.2

tdoi回答回数174ベストアンサー獲得回数752011/10/18 23:47:27

ポイント100pt

オブジェクト指向は市販の初心者向け解説本を読んだという前提で書かせてもらいます。

どの本を読まれたか分かりませんが、初心者向けの解説本の多くは、オブジェクト指向で実装する構文的な解説という認識でいます。オブジェクト指向開発をする理由についてはさらっとうわべをなでていることが多いと思うので、先にそれについて言わせてください。

まず、オブジェクト指向的なコードが素晴らしい訳ではないということは押さえてください。

ある一連の処理を順番に行うコードを逐次的に書くことは決して間違っていません。

実現する機能に対して、速く、正しいコードを書けるかどうかが問題で、スクリプト的な書き方が最適な場合もWebシステムにはよくあります。基本的には、入力を受けて、それに基づいたデータを取得し、HTMLなどとして成形して出力をするだけの場合が多いので。無意味にclassだnewだなどと書いて、オブジェクト指向っぽく書いても、読みにくくなったり開発に時間がかかってしまえば、適切ではないです。

なので、回答としてはオブジェクト指向的なコードを書くというよりは、ワンランク上の質のコードを書くという観点で書かせてもらいます。


ところで、どのようなときにオブジェクト指向などの考え方が必要なのかを考えてみてください。

一つは「速く、正しいコードを書ける」からです。語弊はありますが、もう少し具体的に言えば、重複した処理を書かずに済むからです。

重複した処理をまとめるために使われるのは、ループだったり、functionだったりもその方法の一つです。そういったものを、もう少し大きな粒度でまとめたものがオブジェクト言えるかもしれません。


ちょっと抽象的な話しにしてしまったので、少し具体的に考えてみます。

例えばですが、DBに商品情報が入っていて、それを管理するサイトを構築していたとしましょう。あるページでは商品リストを表示し、別なページでは商品の詳細情報を表示するかもしれません。

どちらのページも全てベタベタに書けばともにDBに接続するコードが含まれるでしょう。

そして、そのDBの接続のコードは関数としてまとめておこうというのが、当然の流れだと思います。

関数などを利用するのは、さきほどは、重複を省くためと言いましたが、別な側面としてコードが読みやすくするという効果も得ることができます。ベタベタとコードを書くと、次元の違う内容を並べて書く必要があります。商品コードXの商品の詳細説明を表示するというページがあったとすると、

$dbh = mysql_connect(....);
mysql_select_db(....);

$query = "SELECT * FROM items WHERE id = 'X'";
$result = mysql_query($query);
$item = mysql_fetch_assoc($result);

$comment = $item['comment'];

のように書けるでしょう。しかし、DBにどう接続するかといった次元の話と、商品の詳細説明を取得という次元の話が混同しています。こういった場合に少し関数でまとめてみると、

function connectDB() { .... }
function getComment($dbh, $id) { .... }

$dbh = connectDB();
$comment = getComment($dbh, 'X');

こんな感じに書けるでしょう。

この方がDBに接続して、そこからXという商品の詳細説明を取得するんだなというのが分かりやすいと思います。

tomoko2さんがどのようなコードを書いているか分かりませんが、もし、初心者だと感じているのであれば、まずは関数をうまく使えるように気をつけてみることをおすすめします。処理をまとめられるところはまとめるというのももちろんですが、一度しか使わずとも、「まとまった処理」を分けておき読みやすくすることも気をつけるといいと思います。

この「まとまった処理」というのが感覚的な言葉になってしまうのですが、その勘所をつかめるかどうかは、コードの質に大きく影響すると思います。


また、関数をなるべくということを言いましたが、これだけで事足りる場合も多いです。

では、どういうときにオブジェクト指向的な記述が必要になるかですが、複数の処理をひとまとめに、また、処理だけでなく状態もセットでひとまとめにしたいときでしょうか。例えばですが、さきほどのコードは、商品管理クラスのようなものがあり、裏でDBの接続などの処理を勝手にやってくれるものがあるとすれば、

$manager = new ItemManager();
$comment = $manager->getComment('X');
$manager->setComment('X', '....');

$comment = $manager->getComment('Y');

のようなことができ、読みやすいし、他の場所で商品情報を使う場合にも流用できます。

これは、

function connectDB() { .... }
function getComment($dbh, $id) { .... }
function setComment($dbh, $id, $comment) { .... }

というようなひとそろいの関数は、connectDB()で接続されたコネクションを共有することを明確化することができ、$dbhをグローバル変数にしたくない。という意図の結果と言えるかもしれません。

なので、関数を意識して開発をすすめ、このようなデータや関数の関連が生じた場合にはクラスにまとめるといいことがあるかもしれません。



といったものの、自分でクラスを作ることは当面はないと思っていていいと思います。

作ってみようとすることはいい勉強になると思いますが。


当面は、ライブラリやフレームワークとして提供されたクラスを使うことがメインとなるはずです。

多くのライブラリやフレームワークは、上記のような流れを踏まえて共通化したものをまとめたりしたものの結晶のようなものです。まずは、使ってみましょう。それが一番勉強になると思います。

詳細は割愛しますが、Smarty、PEARのライブラリ、Zend Framework、CakePHPなど機会があれば、積極的に使って、場合によってはそのライブラリの中も見てみましょう。

コメントに入力フォームのエラーチェックがうっとおしいと書かれてましたが、例えばですが、CakePHPではバリデーションのルールを記述しておくことで、バリデーション行なう仕組があったりします。

まずはオブジェクト指向的なフレームワークを使ってみてください。大抵の問題はすでにライブラリとして提供されているでしょう。


また、オブジェクト指向自体の理解を深める上で、デザインパターンについては勉強してください。なぜオブジェクト指向が有用なのかが見えてくるはずです。


もっと具体的にこういう処理をうまく記述したいんだけど・・・のようなものがあれば、こんな風にしたら?とは言えるのですが。


何かの参考になれば。

id:tomoko2

とても詳しく丁寧なご回答をありがとうございます。まずは独自関数、オブジェクトはライブラリーのものを利用、そのような導きが独学者にはなく、市販本にもないことから「オブジェクト指向で書かなくてはならないのではないか?」という観念にとらわれました。

if文分岐になる処理は適切な単位で関数化することから始めたいと思います。

ご回答ありがとうございました。

2011/10/23 12:39:21

その他の回答(1件)

id:tigerjp No.1

たいがあ回答回数19ベストアンサー獲得回数62011/10/18 23:13:44

ポイント15pt

サイトに掲載されているサンプルコードではなく、オープンソースのコードを検証してみてはいかがでしょうか。

多くのサンプルコードでは、関数化した方がコーディング量も少なく、クラス化するメリットも理解できないかと思います。


実働しているアプリケーションのコードを読むと、メインロジックのスマートさ、テンプテートによる高い保守性などが感じられます。

オモチャをいじくるように楽しみながら理解していけますので、クラス化でのコーディング方法も自然と身に付いてくるはずです。


EC-CUBE

http://www.ec-cube.net/

id:tomoko2

ありがとうございます。ec-cubeはトレース開始したのですが、ちょっと量がおおく、この1/4程度の規模で何かないかなと思ってました。関数のほうがメリットがあるようなサイズでもあえてクラス化して解説を加えてあるものがあるとベストです。なかなか見つけることができません。。みなさんどうやってステップアップなさったのでしょうか。。

2011/10/18 23:16:42
id:tdoi No.2

tdoi回答回数174ベストアンサー獲得回数752011/10/18 23:47:27ここでベストアンサー

ポイント100pt

オブジェクト指向は市販の初心者向け解説本を読んだという前提で書かせてもらいます。

どの本を読まれたか分かりませんが、初心者向けの解説本の多くは、オブジェクト指向で実装する構文的な解説という認識でいます。オブジェクト指向開発をする理由についてはさらっとうわべをなでていることが多いと思うので、先にそれについて言わせてください。

まず、オブジェクト指向的なコードが素晴らしい訳ではないということは押さえてください。

ある一連の処理を順番に行うコードを逐次的に書くことは決して間違っていません。

実現する機能に対して、速く、正しいコードを書けるかどうかが問題で、スクリプト的な書き方が最適な場合もWebシステムにはよくあります。基本的には、入力を受けて、それに基づいたデータを取得し、HTMLなどとして成形して出力をするだけの場合が多いので。無意味にclassだnewだなどと書いて、オブジェクト指向っぽく書いても、読みにくくなったり開発に時間がかかってしまえば、適切ではないです。

なので、回答としてはオブジェクト指向的なコードを書くというよりは、ワンランク上の質のコードを書くという観点で書かせてもらいます。


ところで、どのようなときにオブジェクト指向などの考え方が必要なのかを考えてみてください。

一つは「速く、正しいコードを書ける」からです。語弊はありますが、もう少し具体的に言えば、重複した処理を書かずに済むからです。

重複した処理をまとめるために使われるのは、ループだったり、functionだったりもその方法の一つです。そういったものを、もう少し大きな粒度でまとめたものがオブジェクト言えるかもしれません。


ちょっと抽象的な話しにしてしまったので、少し具体的に考えてみます。

例えばですが、DBに商品情報が入っていて、それを管理するサイトを構築していたとしましょう。あるページでは商品リストを表示し、別なページでは商品の詳細情報を表示するかもしれません。

どちらのページも全てベタベタに書けばともにDBに接続するコードが含まれるでしょう。

そして、そのDBの接続のコードは関数としてまとめておこうというのが、当然の流れだと思います。

関数などを利用するのは、さきほどは、重複を省くためと言いましたが、別な側面としてコードが読みやすくするという効果も得ることができます。ベタベタとコードを書くと、次元の違う内容を並べて書く必要があります。商品コードXの商品の詳細説明を表示するというページがあったとすると、

$dbh = mysql_connect(....);
mysql_select_db(....);

$query = "SELECT * FROM items WHERE id = 'X'";
$result = mysql_query($query);
$item = mysql_fetch_assoc($result);

$comment = $item['comment'];

のように書けるでしょう。しかし、DBにどう接続するかといった次元の話と、商品の詳細説明を取得という次元の話が混同しています。こういった場合に少し関数でまとめてみると、

function connectDB() { .... }
function getComment($dbh, $id) { .... }

$dbh = connectDB();
$comment = getComment($dbh, 'X');

こんな感じに書けるでしょう。

この方がDBに接続して、そこからXという商品の詳細説明を取得するんだなというのが分かりやすいと思います。

tomoko2さんがどのようなコードを書いているか分かりませんが、もし、初心者だと感じているのであれば、まずは関数をうまく使えるように気をつけてみることをおすすめします。処理をまとめられるところはまとめるというのももちろんですが、一度しか使わずとも、「まとまった処理」を分けておき読みやすくすることも気をつけるといいと思います。

この「まとまった処理」というのが感覚的な言葉になってしまうのですが、その勘所をつかめるかどうかは、コードの質に大きく影響すると思います。


また、関数をなるべくということを言いましたが、これだけで事足りる場合も多いです。

では、どういうときにオブジェクト指向的な記述が必要になるかですが、複数の処理をひとまとめに、また、処理だけでなく状態もセットでひとまとめにしたいときでしょうか。例えばですが、さきほどのコードは、商品管理クラスのようなものがあり、裏でDBの接続などの処理を勝手にやってくれるものがあるとすれば、

$manager = new ItemManager();
$comment = $manager->getComment('X');
$manager->setComment('X', '....');

$comment = $manager->getComment('Y');

のようなことができ、読みやすいし、他の場所で商品情報を使う場合にも流用できます。

これは、

function connectDB() { .... }
function getComment($dbh, $id) { .... }
function setComment($dbh, $id, $comment) { .... }

というようなひとそろいの関数は、connectDB()で接続されたコネクションを共有することを明確化することができ、$dbhをグローバル変数にしたくない。という意図の結果と言えるかもしれません。

なので、関数を意識して開発をすすめ、このようなデータや関数の関連が生じた場合にはクラスにまとめるといいことがあるかもしれません。



といったものの、自分でクラスを作ることは当面はないと思っていていいと思います。

作ってみようとすることはいい勉強になると思いますが。


当面は、ライブラリやフレームワークとして提供されたクラスを使うことがメインとなるはずです。

多くのライブラリやフレームワークは、上記のような流れを踏まえて共通化したものをまとめたりしたものの結晶のようなものです。まずは、使ってみましょう。それが一番勉強になると思います。

詳細は割愛しますが、Smarty、PEARのライブラリ、Zend Framework、CakePHPなど機会があれば、積極的に使って、場合によってはそのライブラリの中も見てみましょう。

コメントに入力フォームのエラーチェックがうっとおしいと書かれてましたが、例えばですが、CakePHPではバリデーションのルールを記述しておくことで、バリデーション行なう仕組があったりします。

まずはオブジェクト指向的なフレームワークを使ってみてください。大抵の問題はすでにライブラリとして提供されているでしょう。


また、オブジェクト指向自体の理解を深める上で、デザインパターンについては勉強してください。なぜオブジェクト指向が有用なのかが見えてくるはずです。


もっと具体的にこういう処理をうまく記述したいんだけど・・・のようなものがあれば、こんな風にしたら?とは言えるのですが。


何かの参考になれば。

id:tomoko2

とても詳しく丁寧なご回答をありがとうございます。まずは独自関数、オブジェクトはライブラリーのものを利用、そのような導きが独学者にはなく、市販本にもないことから「オブジェクト指向で書かなくてはならないのではないか?」という観念にとらわれました。

if文分岐になる処理は適切な単位で関数化することから始めたいと思います。

ご回答ありがとうございました。

2011/10/23 12:39:21
  • id:tdoi
    オブジェクト指向そのものについては、理解というか、イメージ持ってらっしゃいますか?
  • id:tomoko2
    はい。オブジェクト指向は市販の初心者向け解説本で理解しているという前提でアドバイスいただけますとあり難いです。よろしくお願いいたします。
  • id:tomoko2
    入力フォームのエラーをチェックしてたら、ものすごいif分分岐になるのが気持悪くて、
    入力フォーム処理、データベース読み出し処理、というようにキレイに分けたいのです。
    全くの初心者向けには書いて覚える教則本が沢山あるので、オブジェクト指向でphpプログラムを書く教則本もどこかに無いのかなと探しております。
    よろしくお願いします。
  • id:Kumappus
    フォームのエラーチェックはオブジェクト指向でも単純にはならないですよ。
    「フォームのエラーチェックをするありもののクラスライブラリ」を再利用するためのオブジェクト指向ならわかりますが。

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

絞り込み :
はてなココの「ともだち」を表示します。
回答リクエストを送信したユーザーはいません