PHPでOOP
PHPを使ってプログラミングするとき、
プロシージャ指向(手続き型、構造化プログラミング)でもできますが、
オブジェクト指向を使った場合の恩恵を享受するために、
PHPでオブジェクト指向プログラミングの勉強をしてみましょう。
<目的>
PHP5でオブジェクト指向プログラミングを行なうための知識を習得する。
(PHP4のOOPもOK、このスレが1000に行く前にPHP6が出たらPHP6のOOPもOK)
<方向性>
・このスレは、プログラミング初心者、PHP初心者の勉強の場として利用することを前提にします。
・PHPのOOPの話題に限定します。
(Ruby、Python、Javaなど他言語のOOPについては、その言語のスレッドでお願いします。)
・PHPのOOP学習に役立つ本、WEBサイトの紹介をお願いします。
<その他>
・略記は、「OO」=「オブジェクト指向」、「OOP」=「オブジェクト指向プログラミング」でお願いします。
・質問をする人はなるべくトリップを付けましょう。
・荒らし、煽り、叩き、気違いは無視・無干渉でお願いします。
このスレで、今日から貴方もOOP!!!\(^o^)/ 初心者にもわかるようにメリットぐらいかいてよ・・。 インスタンスとインヘリタンスがまぎわらしい(なぜか変換・・・ オブジェクトと関数の本質的な違いと使い分け
ttp://d.hatena.ne.jp/toku-hiro/20060826
var とか this って何だ?
ttp://d.hatena.ne.jp/toku-hiro/20060902
アクセサメソッド
ttp://d.hatena.ne.jp/toku-hiro/20061022
継承、 オブジェクトコンポジション
ttp://d.hatena.ne.jp/toku-hiro/20061129
ttp://d.hatena.ne.jp/toku-hiro/20061203
>>2
ttp://d.hatena.ne.jp/toku-hiro/20060826
この説明見てなるほどな〜〜〜!と思いました^^
>(1) オブジェクトと関数の本質的な違いと使い分け
>コーディング上の本質的な違いは「変数を保持できるか否か」に尽きます!
>関数を定義するときには、(グローバル変数を除き)引数として関数の外部から渡し、return で返すことしかできませんが、クラスは内部で変数を定義でき、クラスの実体のオブジェクトはどこからでも内部変数を引き出すことができます。
>定義関数の return であれもこれも返したいのにうまく返せず、煩雑な配列に格納して返す…といったことが減ると思います。
>あれもこれも引数として渡したいとき、または、あれもこれもreturnしたいときは、関数よりクラスの方が遥かに簡単です。
「クラス」という仕組は便利そうですね。クラスを考えた奴、偉い!
>>3
なんかプログラミングって、カタカナ用語がたくさん登場しますよね><
クラスって聞いたら学校の「教室」を連想しちゃう><
>>7
>Webでオブジェクト指向
>http://pc10.2ch.net/test/read.cgi/php/1133489897/
>こっちじゃ何故駄目なんだ?
そっちも参考に眺めています。
あと、プログラマー板にもあるオブジェクト指向関係のスレもちょっと眺めています。
PHPに的を絞った情報が欲しいので、専用のスレを立ててみました。
もちろん、JavaやRuby、Pythonとかも使えればいいけど、そこまで手を広げる時間がないので、とりあえず今の段階ではPHPで勉強。
PHPを使っていて、オブジェクト指向プログラミングのやり方を勉強したい人がいたら一緒に勉強していきましょう。
よろしく(・∀・) >>9
ちげーよ
自分のサイトの宣伝して
「この説明見てなるほどな〜〜〜!と思いました^^」
と書いてるところがだよ >>11
OOPのメリット聞かれたから自分で見つけた参考サイト出して自分の所感言っただけだろ。
聞くだけで何もしない厨より、アクティブな>>1に好感が持てたが。
って擁護すると自演って言うのかな? まあ、PHPでOOPなんてのは、今までて来たtoku-hiroさん以外にも
書いている人は多そうだから(俺は知らないけど)
他のも出せば、>>1の疑いは晴れるんじゃないかな。 PHPのオンラインマニュアルがよくまとまってますねw(当たり前?)
http://jp2.php.net/zend-engine-2.php
第19章 クラスとオブジェクト (PHP 5) http://www.mogurin.net/index/php.obj.inc.html
PHP4のOOPについて、簡単な説明がありました。
PHP5のOOPは、PHP4のOOPに変更が加えられているので、ちょっと違う部分があります。 >>18
わかった。
オブジェクトの
オブとはすなわち飯富。飯富厩舎所属だということ。
オブジェクトの
ジェクトトはすなわちジェクト。FF10のジェクトだということ。
オブジェクトを利用すると何がいいのか一言でまとめて とりあえず簡単なWEBアプリケーションを作りながらOOPの勉強をしてみたいです。
OOPで掲示板を作ってみたいです。
(1)最初はOOPを使わないで掲示板を作ってみる
(2)次にOOPで同じ掲示板を作ってみる
という流れにすると、対比によってOOPが理解しやすくなるでしょうか?
=始めに完成形ありきと。 掲示板の機能としては、
(1)名前とタイトルと本文を入力&投稿できる。
(2)投稿の一覧(タイトル+投稿日時)が表示できる。
(3)投稿の詳細内容(1つ1つの投稿を個別に閲覧)が表示できる。
という最低限の機能で作ってみて、
後から徐々に機能を追加して拡張してみましょう。 データベースは普段MySQLを使ってます。
文字化け対策が面倒くさいので、文字コードはUTF-8(UTF-8N)にしときます。
テーブル名は、message
カラムは、
message_id (int not null auto_increment) ←主キーにする
name (text)
title (text)
message (text)
create_date (datetime または年月日時分秒の14桁でvarchar(14))
の5個にしてみましょう。
テーブル名やカラム名の付け方は、
複数形(messages)と単数形(message)のセットで命名したりとか、
主キーは単に「id」としておく方が分かりやすいでしょうか?
ラーメンの具でメンマが9切れのっているか10切れのっているかという違い…些細なことはどうでもいいか。
MySQL5.0で、phpMyAdminを使って、oop_testというデータベースを1個新設しました。
その中にテーブルを1個作りました。
CREATE TABLE `message` (
`message_id` int(11) NOT NULL,
`name` text,
`title` text,
`message` text,
`create_date` datetime default NULL,
PRIMARY KEY (`message_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
日付はとりあえずdatetime型にしておきました。
MySQL4.0を使っている人は、上記のSQL文から「DEFAULT CHARSET=utf8」という句を削らないとエラーになると思います。 画面は、>>23の(1)〜(3)の3画面を用意すればOKかな?
画面(ハリボテ)を先に作ってみて、それにプログラムを付けて動くようにしてみます。
(1)入力ページ input.php
(2)一覧ページ list.php
(3)詳細ページ message.php
http://itpro.nikkeibp.co.jp/article/COLUMN/20070214/261859/
「HTML画面をそのまま仕様書に」,5カ月で1000画面を構築した就職サイトPuffの高速開発手法
>>25
主キーをオートインクリメント(連番の)の設定にしておくのを忘れてました。orz
CREATE TABLE `message` (
`message_id` int(11) NOT NULL auto_increment,
`name` text,
`title` text,
`message` text,
`create_date` datetime default NULL,
PRIMARY KEY (`message_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
定番のhelloを表示w
class hello {
var $aisatu = "こんにちは";
}
$re = new hello();
$aisatu = $re->aisatu;
echo $aisatu;
読み図ら買ったら適当に改行して #オブジェクト学校のhelloクラスを作る
class hello {
#このクラスに生徒である$aisatu君がいる
#彼に「こんにちは」という言葉を覚えさせる
var $aisatu = "こんにちは";
#放課後なので括弧で閉じる
}
#クラスの風景を覗くための魔法
$re = new hello();
#生徒$aisatu君に「こんにちは」を言わせるための魔法を矢で飛ばす。
#魔法で生徒$aisatu君の$は壊れてしまい、以下のような記述になる。。
$aisatu = $re->aisatu;
#魔法にかかった生徒挨拶君をおまえらのディスプレイに召還する。
echo $aisatu; コードの解説なんてしなくても見ればわかる。
「なぜOOP」か、だとか、
こういう場合にOOPが役立つ、というのを具体的なコードで示してくれ namespace は結局 PHP5 では実装されなかったんだね・・・・
悲しい。悲しすぎる。 >>22 (1)最初はOOPを使わないで掲示板を作ってみる
OOPを使わないで作った簡単な掲示板をアップしてみます。
>>26
ファイルは、他に掲示板のトップページと、DB接続関係のデータを入れたファイルを用意しました。
WEBサーバのルート直下にデプロイした場合を想定しています。
/index.html 掲示板のトップページ
/db.php データベースの接続関係のデータのファイル
/input.php メッセージ入力ページ
/list.php メッセージ一覧ページ
/message.php メッセージ詳細ページ index.htmlの内容は以下の通りです。
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>掲示板メニュー</title>
</head>
<body>
<h1>掲示板メニュー</h1>
<div id="menu">
<ul>
<li><a href="input.php">メッセージ入力</a></li>
<li><a href="list.php">メッセージ一覧</a></li>
</ul>
</div>
</body>
</html>
db.phpの内容は以下の通りです。
<?php
/**
* データベース
*/
//本番環境ドメイン名
define("DOMAIN", "xrea.com");//ドメイン名に含まれる文字列を指定
//MySQL設定(本番環境とテスト環境で切替え)
if (ereg(DOMAIN, $_SERVER['SERVER_NAME'])) {
//本番環境
define("DBSERVER", "localhost");
define("DBUSER" , "username");
define("DBPASSWORD", "password");
define("DBNAME", "oop_test");
} else {
//テスト環境
define("DBSERVER", "localhost");
define("DBUSER" , "test_username");
define("DBPASSWORD", "test_password");
define("DBNAME", "oop_test");
}
(以下、続く) db.phpの続きです。
//MySQL接続関数
function db_connect() {
// MySQL 接続
$link = mysql_connect(DBSERVER, DBUSER, DBPASSWORD);
if (!$link) {
die('mysql_connect ERROR: ' . mysql_error());
}
// MySQL DB 選択
$db_selected = mysql_select_db(DBNAME, $link);
if (!$db_selected) {
die ('mysql_select_db ERROR: ' . mysql_error());
}
// MySQL 4.1以上 文字コードセット
mysql_query('SET CHARACTER SET utf8');
return $db_selected;
} db.phpの続き(その2)です。
//MySQLプリペアードステートメント関数(SQLインジェクション対策)
//(参考)http://www.php.net/manual/ja/function.mysql-query.php#70686
function mysql_prepare($query, $phs = array()) {
$phs = array_map(create_function('$ph', 'return "\'".mysql_real_escape_string($ph)."\'";'), $phs);
$curpos = 0;
$curph = count($phs)-1;
for ($i = strlen($query) - 1; $i > 0; $i--) {
if ($query[$i] !== '?') {
continue;
}
if ($curph < 0 || !isset($phs[$curph])) {
$query = substr_replace($query, 'NULL', $i, 1);
} else {
$query = substr_replace($query, $phs[$curph], $i, 1);
}
$curph--;
}
unset($curpos, $curph, $phs);
return $query;
}
?> input.phpの内容は以下の通りです。
<?php
/**
* メッセージ入力画面
*/
require_once("db.php");
db_connect();
//
$name = $_POST['name'];
$title = $_POST['title'];
$message = $_POST['message'];
$error_msg = "";
(以下、続く) db.phpの続きです。
//入力値バリデート
if (0 < strlen($name) && 0 < strlen($title) && 0 < strlen($message)) {
//DB保存処理
$create_date = date("Y/m/d H:i:s");
$sql = "INSERT message SET
name = ? ,
title = ? ,
message = ? ,
create_date = ? ";
$phs = array($name, $title, $message, $create_date);//プレースホルダーにバインドする変数
$sql_prepare = mysql_prepare($sql, $phs);
$result = mysql_query($sql_prepare) or die('SQL Error: ' . mysql_error());
//ページ移動
if ($result == TRUE) {
$url = "http://".$_SERVER['HTTP_HOST']."/test2/list.php";//メッセージ一覧
header("Location: ".$url);
exit;
}
} else {
$error_msg = "名前、タイトル、メッセージをすべて入力してください。";
}
?> >>41
間違えました。
>db.phpの続きです。
ではなくて、
「input.phpの続きです。」
でした。(・∀・)
あと、
>$url = "http://".$_SERVER['HTTP_HOST']."/test2/list.php";//メッセージ一覧
ではなくて、
$url = "http://".$_SERVER['HTTP_HOST']."/list.php";//メッセージ一覧
になります。
=ローカルでは、/test2というフォルダを作ってその中にいれていたので。
=本番環境では、ドキュメントルート直下を想定しているので、/test2/は不要
もう一回訂正してアップします。 >>41の訂正です。
input.phpの続きです。
//入力値バリデート
if (0 < strlen($name) && 0 < strlen($title) && 0 < strlen($message)) {
//DB保存処理
$create_date = date("Y/m/d H:i:s");
$sql = "INSERT message SET
name = ? ,
title = ? ,
message = ? ,
create_date = ? ";
$phs = array($name, $title, $message, $create_date);//プレースホルダーにバインドする変数
$sql_prepare = mysql_prepare($sql, $phs);
$result = mysql_query($sql_prepare) or die('SQL Error: ' . mysql_error());
//ページ移動
if ($result == TRUE) {
$url = "http://".$_SERVER['HTTP_HOST']."/list.php";//メッセージ一覧
header("Location: ".$url);
exit;
}
} else {
$error_msg = "名前、タイトル、メッセージをすべて入力してください。";
}
?>
(以下、続く) input.phpの続き(その2)です。
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>メッセージ入力</title>
</head>
<body>
<h1>メッセージ入力</h1>
<div id="menu">
<ul>
<li><a href="input.php">メッセージ入力</a></li>
<li><a href="list.php">メッセージ一覧</a></li>
</ul>
</div>
<?php echo $error_msg; ?>
<div id="input">
<form name="form_input" method="post" action="input.php">
<div id="name">名前<br>
<input type="text" name="name" value="<?php echo htmlspecialchars($name); ?>">
</div>
<div id="title">タイトル<br>
<input type="text" name="title" value="<?php echo htmlspecialchars($title); ?>">
</div>
<div id="message">メッセージ<br>
<textarea name="message"><?php echo htmlspecialchars($message); ?></textarea>
</div>
<input type="submit" name="submit" value="送信">
</form>
</div>
</body>
</html> list.phpの内容は以下の通りです。
<?php
/**
* メッセージ一覧画面
*/
require_once("db.php");
db_connect();
//
$page = intval($_GET['page']);
$max = 10;//1ページ当たりの最大表示件数
//ページング(ページ数は1から数える)
$sql = "SELECT count(*) AS total FROM message";
$result = mysql_query($sql) or die('SQL Error: ' . mysql_error());
if ($result) $row = mysql_fetch_array($result);
$total = $row['total'];//全メッセージ数
$page_total = ceil($total / $max);//全ページ数
if ($page < 1) $page = 1;
if ($page_total < $page) $page = $page_total;
//メッセージ取得
$sql = "SELECT * FROM message ORDER BY create_date DESC LIMIT ".(($page - 1) * $max) .",".$max;
$result = mysql_query($sql) or die('SQL Error: ' . mysql_error());
?> list.phpの続きです。
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>メッセージ一覧</title>
</head>
<body>
<h1>メッセージ一覧</h1>
<div id="menu">
<ul>
<li><a href="input.php">メッセージ入力</a></li>
<li><a href="list.php">メッセージ一覧</a></li>
</ul>
</div>
<div id="paging">
<?php
//ページング処理
echo "全".$total."件";
echo "(ページ".$page."目)";
for ($i = 1; $i <= $page_total; $i++) {
echo "<a href='list.php?page=".$i."'>".$i."</a> ";
}
?>
</div> list.phpの続き(その2)です。
<table border="1" cellpadding="5">
<tr bgcolor="#FFFF99">
<td>タイトル</td>
<td>投稿者名</td>
<td>投稿日</td>
</tr>
<?php
//メッセージ一覧
while ($rows = mysql_fetch_array($result)) {
echo "<tr>";
echo "<td><a href='message.php?message_id=".htmlspecialchars($rows['message_id'])."'>".htmlspecialchars($rows['title'])."</a></td>";
echo "<td>".htmlspecialchars($rows['name'])."</td>";
echo "<td>".htmlspecialchars($rows['create_date'])."</td>";
echo "</tr>";
}
?>
</table>
</body>
</html> message.phpの内容は以下の通りです。
<?php
/**
* メッセージ詳細画面
*/
require_once("db.php");
db_connect();
//
$message_id = intval($_GET['message_id']);
//メッセージ取得
$sql = "SELECT * FROM message WHERE message_id = ?";
$phs = array($message_id);//プレースホルダーにバインドする変数
$sql_prepare = mysql_prepare($sql, $phs);
$result = mysql_query($sql_prepare) or die('SQL Error: ' . mysql_error());
if ($result) {
$row = mysql_fetch_array($result);
}
?> message.phpの続きです。
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>メッセージ詳細</title>
</head>
<body>
<h1>メッセージ詳細</h1>
<div id="menu">
<ul>
<li><a href="input.php">メッセージ入力</a></li>
<li><a href="list.php">メッセージ一覧</a></li>
</ul>
</div>
<table border="1" cellpadding="5">
<tr>
<td bgcolor="#FFFF99">投稿者名</td>
<td><?php echo htmlspecialchars($row['name']); ?></td>
</tr> message.phpの続き(その2)です。
<tr>
<td bgcolor="#FFFF99">投稿日</td>
<td><?php echo htmlspecialchars($row['create_date']); ?></td>
</tr>
<tr>
<td bgcolor="#FFFF99">タイトル</td>
<td><?php echo htmlspecialchars($row['title']); ?></td>
</tr>
<tr>
<td bgcolor="#FFFF99">メッセージ</td>
<td><?php echo nl2br(htmlspecialchars($row['message'])); ?></td>
</tr>
</table>
</body>
</html> それでは、次行ってみよう!
>>22 (2)次にOOPで同じ掲示板を作ってみる
>>34
PHPコードとHTML表示を一緒にしてありますが、OOPではテンプレートシステムを使って、PHPコードとHTML表示部分を分離して、MVCにしてみたいです。
どういうクラスを作ればいいのか良く分かりません><
(1)コントローラー(+アクション)→input、list、message
(2)モデル→データベース接続処理も1つのクラスにするのでしょうか?
(4)ビュー→テンプレートシステムへの出力
というかんじで3個のクラスが必要でしょうか?
それぞれのクラスに必要なプロパティとメソッドを何にするか?
クラスを考えて、UMLでクラス図を作ってみたいです。 わかりにくいからWebサイトにまとめてくれ。PHP使いなんだし >>53
まとめサイトを設置しました。
ttp://kameleon.s241.xrea.com/dokuwiki/doku.php
最終的にMVCな構成を目標に
少しずつリファクタリングしていけばよいと思う
とりあえずDBアクセスを一箇所にまとめるモデルを作ってみるといいんじゃない
・全件取得
・1件取得
・1件追加
できるMessageクラスとかを作ってそこにDBアクセス(SQL)をまとめれ OOP勉強したいなら、実力不足のやつが書いたガラクタ掲示板スクリプトを
読むより、有名なオープンソースのスクリプトを読めばいいじゃん。
そもそも>>1の意味不明な独善なんかに付き合わなくてもOOPに関する情報
はいくらでも手にはいるし。 ど素人に肥大したコードを読ませて理解できると思ってる思考回路がカコイイ! >>59
ど素人はみんな、自分みたいな学習意欲も向上心もない人間だと思ってる
思考回路がカコイイ! >>59-61
全員カコワルイ!! 俺はカコイイ!!