|
 |
|
กระทู้รณรงค์ ตอน "มาเขียน php แบบ OOP กันเถอะ" คือผมก็เห็นว่า community ที่นี่มีคนเก่งเยอะ |
|
 |
|
|
 |
 |
|
คือผมก็เห็นว่า community ที่นี่มีคนเก่งเยอะพอสมควร
จะเป็นการดีถ้าจะเริ่มสอนคนที่เขียน php แบบ functional ให้เปลี่ยนมาเขียนแบบ OOP
เพราะที่ community นี้จะมีคนให้ถามเยอะครับ ^^
โดยส่วนตัวแล้วผมเห็นว่า หลายๆคนเริ่มเขียนแบบแยกไฟล์กันแล้ว แต่ก็ยังมีอีกหลายๆ คนยังเขียนแบบยาววววว ยืดกันอยู่
(สังเกตจาก code ที่เอามาถามกันน่ะคับ) ผมก็เลยเห็นว่าตอนนี้ภาษาอื่นๆ ก็พัฒนาไปค่อนข้างไกลแล้ว (support OO กันหมดแล้ว)
ผมก็เลยอยากให้เพื่อนๆ พัฒนาโคดเป็นแบบ OO กันให้มากขึ้นน่ะคับ ผมว่านะเขียนแบบ OOP โคดของเราจะเป็นระเบียบมากขึ้นคับ
จะเขียน php แบบ OOP ต้องใช้ PHP 5 ขึ้นไปนะคับ
ใครรู้ตัวว่าเก่ากว่า 5 upgrade ตามโลกได้แล้วนะคับ
(ตอนนี้ php 6 ก็กำลัง develop กันอยู่แล้วนะคับ)
ถ้าใครสงสัยว่า OO หรือ OOP คืออะไรลองอ่าน ที่นี่ดู
ส่วนว่าจะเริ่มเขียนยังไง ที่จริงที่ thaicreate ก็(เกือบจะ)มี tutorial เกี่ยวกับ class แล้ว ที่นี่ แต่เห็นว่ายังไม่เสร็จคับ
พอดีผมไป search เจอการเขียน php oop เบื้องต้นที่เป็นภาษาไทยลองเข้าไปดูๆ กันได้ ที่นี่ คับ
ส่วนผมลองเขียน แบบ OOP ง่ายๆ พอเป็นแนวคิดมาให้ดูมาให้ลองรันกันดูคับ
เป็นตัวอย่างการเขียนติดต่อกะ db เพื่อดึงข้อมูลธรรมดาคับ
เพียงแต่ถ้าเราเขียน OOP แบบนี้แล้ว sql เราจะรวมอยู่ที่ class class เดียว ไม่กระจัดกระจายไปหลายๆ ไฟล์
สามารถ reuse ได้หลายรอบโดยไม่ต้องเขียนใหม่
Code (PHP)
<?php
class CReturn {
const FAIL = false;
const SUCCESS = true;
public static function error($error_msg){
return array(self::FAIL, $error_msg);
}
public static function success($value){
return array(self::SUCCESS, $value);
}
}
class initDb {
private static $host = "localhost";
private static $user = "root";
private static $pass = "mysql";
private static $db = "db_test1";
public static function connect(){
$db_conn = mysql_pconnect(self::$host, self::$user, self::$pass) or die(mysql_error());
mysql_select_db(self::$db, $db_conn) or die(mysql_error());
mysql_query("SET NAMES UTF8;");
return $db_conn;
}
}
class DbAbstract {
protected $db_conn;
protected $table_name;
public $_data;
public function __construct($db_conn){
$this->db_conn = $db_conn;
}
protected function _get($sql){
$this->_data = null;
$result = mysql_query($sql);
if(mysql_errno($this->db_conn) !== 0)
return CReturn::error("Mysql error [".mysql_errno($this->db_conn)."] : ".$sql."<br />".mysql_error($this->db_conn));
while($res = mysql_fetch_assoc($result)) {
$this->_data[] = $res;
}
return CReturn::success(mysql_num_rows($result));
}
protected function getTableName(){
return $this->table_name;
}
public function getAll(){
return $this->_get("SELECT * FROM {$this->getTableName()}");
}
}
class DbTable1 extends DbAbstract {
protected $table_name = "table1";
public function getById($id){
return $this->_get("SELECT * FROM {$this->getTableName()} WHERE user_id = {$id}");
}
}
print "<pre>";
$db_conn = initDb::connect();
// แบบ error
$oTb1 = new DbTable1($db_conn);
list($result, $value) = $oTb1->getById("id_is_not_string");
print "<b>Query result</b> = ".var_export($result,true)."<br />";
print "<b>Num rows/Error msg</b> = '".$value."'<br />";
print "<b>data</b> = ".var_export($oTb1->_data,true)."<br />";
print "<br />";
// แบบ ดึงข้อมูลไม่เจอหรือไม่มีใน db
$oTb1 = new DbTable1($db_conn);
list($result, $value) = $oTb1->getById(5);
print "<b>Query result</b> = ".var_export($result,true)."<br />";
print "<b>Num rows/Error msg</b> = ".var_export($value,true)."<br />";
print "<b>data</b> = ".var_export($oTb1->_data,true)."<br />";
print "<br />";
// แบบดึงข้อมูลได้ 1 record
$oTb1 = new DbTable1($db_conn);
list($result, $value) = $oTb1->getById(1);
print "<b>Query result</b> = ".var_export($result,true)."<br />";
print "<b>Num rows/Error msg</b> = ".var_export($value,true)."<br />";
print "<b>data</b> = ".var_export($oTb1->_data,true)."<br />";
print "<br />";
// แบบดึงข้อมูลได้หลาย records
list($result, $value) = $oTb1->getAll();
print "<b>Query result</b> = ".var_export($result,true)."<br />";
print "<b>Num rows/Error msg</b> = ".var_export($value,true)."<br />";
print "<b>data</b> = ".var_export($oTb1->_data,true)."<br />";
print "<br />";
?>
ส่วน db ใช้แค่
Code sql
CREATE TABLE `table1` (
`user_id` int(11) NOT NULL auto_increment,
`fname` varchar(255) collate utf8_unicode_ci NOT NULL,
`lname` varchar(255) collate utf8_unicode_ci NOT NULL,
PRIMARY KEY (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=3 ;
INSERT INTO `table1` (`user_id`, `fname`, `lname`) VALUES
(1, 'นายกอ', 'ไก่'),
(2, 'นายขอ', 'ไข่');
ลองดูกันคับ
"ความคิดเปลี่ยน อนาคตก็เปลี่ยน แค่เปิดใจ"
ถ้าเราไม่เริ่มพัฒนาตัวเองตั้งแต่วันนี้ แล้วเราจะเริ่มวันไหน ใช่มั๊ยครับ !!
ร่วมสร้างสรรค์ community นี้ให้ดียิ่งๆ ขึ้นไปคับ
สงสัยเรื่องอะไรโพสถามพี่ๆ เค้าได้เลยคับ
Tag : - - - -

|
|
 |
 |
 |
 |
Date :
2009-05-14 11:58:32 |
By :
nut_t02 |
View :
138827 |
Reply :
419 |
|
 |
 |
 |
 |
|
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
ยกตัวอย่างได้ดีมาก ๆ ครับ 
|
 |
 |
 |
 |
Date :
2009-05-14 12:08:15 |
By :
webmaster |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
เห็นด้วยครับ ไม่ต้องไปคิดว่ามันยากน่ะครับ เพราะมันง่ายมากๆเลยอาจจะง่ายกว่า function อีกพอดีเคยเขียนอยู่
 
ของดีต้อง +1 ครับ
|
 |
 |
 |
 |
Date :
2009-05-14 12:18:28 |
By :
kanchen |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
 กำลังพยายามให้เป็น OOP แต่ก้อชอบเผลอเขียนแบบ ฟังก์ชั่น (เพระมันชิน ฮ่า ๆ ) 
|
 |
 |
 |
 |
Date :
2009-05-14 12:29:58 |
By :
หนุ่มคุง |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
สิ่งดีๆ ที่ควรปักหมุด เผื่อมีใครเอาโค๊ดดีๆ มาแปะอีก อิอิ
|
 |
 |
 |
 |
Date :
2009-05-14 12:55:22 |
By :
plakrim |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
ว่าจะลองเขียนหลายทีแล้ว
แต่ไม่มีเวลาซักที งานหน้าต้องลองใช้ดู
(ถ้ามันไม่เร่งนะ)
|
 |
 |
 |
 |
Date :
2009-05-14 20:14:42 |
By :
ttong |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
ผมว่าพอเราเขียนกันไปซักพักนึง ก็น่าจะพอรวบรวมโคดที่เราเอามา share กันออกมาได้เป็น framework ตัวนึงได้
ทีนี้ล่ะ เราก็จะมี framework สำเร็จรูปที่สร้างด้วยฝีมือพวกเราเองจริงๆ สามารถเอาไป apply กับโปรเจคใดๆ ก็ได้
เพียงแค่เปลี่ยนโคดนิดหน่อยเท่านั้นเอง
โดย framework ตัวนี้ไม่ได้เลิศเลออย่างจูมล่า หรือแมมโบ ที่แทบจะไม่กล้าแก้ core อะไรเลยเพราะกลัวทำงานไม่ได้
โดย framework ตัวนี้ก็ไม่ได้แย่ขนาดที่ทำออกมาแล้วใช้ได้แค่โปรเจคเดียว
ร่วม share กันไปคับ
เดี๋ยวก็สำเร็จเอง
โดยส่วนตัวแล้วผมก็พอมีที่ทำๆ เอาไว้บ้าง
รวมรวบ lib โน้น lib นี้มารวมกัน พยายามทำให้ configurable มากที่สุดเท่าที่จะเป็นไปได้
อาจไม่สมบูรณ์ เท่าใดนัก เพราะเขียนด้วยความรู้อันน้อยนิด
ก็รออาศัยเทพทั้งหลายในนี้ช่วยขัดเกลาเอาล่ะคับ แหะๆ ^^'
จะผิดจะถูกอย่างไรถ้าสงสัยก็โพสถามเลยคับ
แล้วมาช่วยกันเกลา
"ถ้ายังไม่คิดพัฒนา เราก็ยังล้าหลังเหมือนเดิมนะคับ"

ปล. ดูเหมือนเรื่อง OOP ที่นี่ยังไม่ค่อยเป็นที่น่าสนใจของคนทั่วไปในนี้นะคับ
ตัวอย่าง ก็เริ่มมีให้เห็น อันที่จริงเห็นมานานแล้วมากกว่าว่า concept การเขียนโปรแกรมแบบเดิมมันไม่ได้ผล
แต่ก็ไม่ได้สนใจที่จะเปลี่ยนแปลงมัน - -'
|
 |
 |
 |
 |
Date :
2009-05-14 20:42:16 |
By :
nut_t02 |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
ขอคุณกระทู้นี้ และท่านเทพฯ ทั้งหลายนะครับ 
|
 |
 |
 |
 |
Date :
2009-05-14 22:16:27 |
By :
panyapol |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
ทำไมหลายคนไม่ใช้ OOP
ตามความคิดของผมเอง ที่ประสบมาคือ
1. OOP จริงๆแล้ว ต้องมีประโยชน์ในการ reuse เป็นอันดับแรกในการเลือก สำหรับการออกแบบคลาส แล้วจะต้องสามารถ ถ่ายทอดคุณสมบัติ และมีแพทเทิร์นที่วางกันไว้ก่อน และควรจะมีเอกสารกำกับเพื่อคนที่ใช้จะได้สามารถเอาไปปรับใช้ได้ถูกต้อง ซึ่งต้องใช้เวลาการออกแบบคลาสให้ เป็นกลางๆ ไม่มากไม่น้อยไปสำหรับ เบสคลาส
2. เรื่อง interface กับ abstract class หลายๆคนยังไม่เข้าใจวิธีการทำงานของมัน ซึ่งมีเพิ่มขึ้นใน php5 นี้ ซึ่งหลักการทำงานของมัน อาจทำให้ Over head สำหรับหลายๆคน ทำให้ทำงานหนักมากกว่าเขียนแบบธรรมดามาก
3. การเขียนโดยใช้ OOP เป็นการทำให้เครื่อง ทำงานหนักเกินจำเป็น ในหลายกรณี
4. OOP ใน php ยังไม่สามารถเทียบกับภาษาอื่นได้ ซึ่งจะสามารถใช้แพทเทิร์น ต่างๆที่มีความแตกต่างกันได้หลากหลายตามแต่กรณีที่จำเป็น (แต่ตอนนี้ ก็ มี abstract กับ interface ให้ใช้)
5. เรื่องการออกแบบให้เป็นกลาง และสามารถปรับปรุงคลาสโดยการ inherit, implement นั้นเป็นงานที่ยากมาก มีเรื่อง scop ให้ต้องวางไว้ก่อน และการออกแบบกับโปรเจกต์บางที อาจมีส่วนที่ต้อง hard code ซึ่งเป็นส่วนที่ไม่สมควรใน Object คับ
6. คนที่จะใช้ OOP กับงานได้จริงๆนั้น ยังหาได้น้อยเพราะว่าจะใช้กับงานได้จริง ก็ต้องชำนาญพอสมควรก่อน ไม่งั้น ยังไงก็ต้องมานั่งแก้โค้ด ในคลาส ซึ่งอาจมีปัญหากับคลาสต่างๆ ที่สืบทอดกันไป ทำให้มีความเสี่ยงสูง
7. ผมว่า OOP เหมาะสำหรับโปรเจกต์ขาดกลาง ขึ้นไป ถึงจะคุ้มค่า
8. php เองไม่ค่อยมี library ให้เรียนมากซึ่งต่างกันกับภาษาอื่น ที่จำเป็นต้องเรียน standard library ซึ่งเป็น OOP มากมาย เช่น Java, Ruby เพราะ php เองเน้นให้ใช้งานแบบทั่วไปได้ไม่ค่อยเจาะจง และทำให้เรียนได้ง่ายกว่า(การตลาด) แต่ก็มี library ภายนอกหลายตัวที่ใช้ OOP ของ php5 ซึ่งคนส่วนใหญ่มักไม่ค่อยได้ใช้ library ภายนอกกัน
http://gunner.freetzi.com
|
 |
 |
 |
 |
Date :
2009-05-15 13:40:22 |
By :
pjgunner |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
ขอแก้โค้ดตัวเองหน่อยนะคับ ไม่รู้ว่าจะทำงานไหม ผมก็ยังไม่แน่ใจ ไม่รู้ว่า interface ประกาศเป็น static ได้ไหม
Code (PHP)
<?php
interface DBConnect{
public static function defaultConnect();
public static function connect();
}
class MySQLConnect implements DBConnect{
const DEF_HOST = 'localhost';
const DEF_USER = 'root';
const DEF_PASSWORD = '';
const DEF_DB = 'dbhanler';
public static function defaultConnect(){
return self::connect(self::DEF_HOST, self::DEF_USER, self::DEF_PASSWORD, self::DEF_DB);
}
public static function connect($host, $user, $pass, $db_name, $pconnect = false){
global $conn;
if($pconnect)
$conn = mysql_pconnect($host, $user, $pass);
else
$conn = mysql_connect($host, $user, $pass);
if(!$conn) exit( mysql_error() );
if( !mysql_select_db($db_name, $conn) ) exit('Cannot select database.');
mysql_query("SET NAMES UTF8");
return $conn;
}
}//DBHandler class
?>
|
 |
 |
 |
 |
Date :
2009-05-15 15:54:07 |
By :
pjgunner |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
ลืมบรรทัดที่ 4 ไปนิดนึงนะคับ
Code (PHP)
<?php
interface DBConnect{
public static function defaultConnect();
public static function connect($host, $user, $pass, $db_name, $pconnect = false);
}
class MySQLConnect implements DBConnect{
const DEF_HOST = 'localhost';
const DEF_USER = 'root';
const DEF_PASSWORD = '';
const DEF_DB = 'dbhanler';
public static function defaultConnect(){
return self::connect(self::DEF_HOST, self::DEF_USER, self::DEF_PASSWORD, self::DEF_DB);
}
public static function connect($host, $user, $pass, $db_name, $pconnect = false){
global $conn;
if($pconnect)
$conn = mysql_pconnect($host, $user, $pass);
else
$conn = mysql_connect($host, $user, $pass);
if(!$conn) exit( mysql_error() );
if( !mysql_select_db($db_name, $conn) ) exit('Cannot select database.');
mysql_query("SET NAMES UTF8");
return $conn;
}
}//DBHandler class
?>
|
 |
 |
 |
 |
Date :
2009-05-15 16:23:38 |
By :
nut_t02 |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
ผมก็อยากเขียนแนว oop นะครับ แต่เพื่อนร่วมงานเขาไม่เขียนนี้ซิ
เราเลยต้องเลยตามเลย
พวก framework ทั้งหลายก็อยากใช้ แต่ไม่ได้ใช้ซักที
อย่างว่าแหละครับไม่มีเวลาให้ทดลอง ทำเอาของใหม่มา
พอถึงกำหนดส่ง แล้วมันไม่ไ้ด้อย่างหวัง ก็โดนปรับ โดนด่าไปอีก
|
 |
 |
 |
 |
Date :
2009-05-15 17:17:37 |
By :
kuznetsova |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
555 อันนี้ผมก็เป็นคับ
ผมเลยใช้วิธีทำนอกเวลา แล้วเอาผล + วิธีเขียนมาให้ดูคับ
แล้วบอกว่ามันทำให้ชีวิตง่ายขึ้นอย่างไร
ได้ผลคับตอนนี้ศึกษากันใหญ่เลย !!

แต่ทั้งนี้ทั้งนั้นปัญหาหลักๆ น่าจะเป็นที่ผู้อาวุโสกว่าเราทั้งหลายใน office
เค้าอาจจะไม่ค่อยเห็นด้วยที่จะมีการเปลี่ยนแปลงอะไร
เอาเป็นว่าคิดว่าจะเริ่มผมก็ยินดีด้วยแล้วคับ
ดีกว่าอ่านประทู้นี้แล้วปล่อยผ่านมันต่อไป
|
 |
 |
 |
 |
Date :
2009-05-15 17:26:34 |
By :
nut_t02 |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
สิ่งไหนที่คิดว่าดี ควร หรือว่าไม่เหมาะสมอย่างไร ให้ผู้ใช้งานเลือกเอาครับ ว่าสะดวกอันไหน แต่ทุกความคิด ที่สนุบสนุนการเป็น Web Programmer ที่ดีผมก็ยินดีสนับสนุนครับ
หุหุ
|
 |
 |
 |
 |
Date :
2009-05-15 17:30:03 |
By :
ddsure |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
กำลังหัดเขียนอยุ่อะ
ชอบๆ เพลินดีครับ
ยังไม่ชำนาญเท่าไร
ผลงานล่าสุดของผม ก้เขียนปฏิทินด้วย OOP เนี้ยแหละ
http://www.danya-reload.com/home/article/viewArticle.php?id=42
|
 |
 |
 |
 |
Date :
2009-05-15 18:14:59 |
By :
danya |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
php จำเป็นต้อง backward compatibility สำหรับ oop ใน php4 ดังนั้น เมธอดที่ ไม่ได้เป็น static ก็ยังสามารถถูกเรียกได้ โดยไม่จำเป็นสต้องสร้าง instance แต่ไม่ควรอย่างยิ่งสำหรับการใช้งานแบบนี้นะครับ
ตย.
class Test{
public function tt(){
echo 'Test';
}
}
Test::tt(); // ทำงาน
สมมติว่า ลอง ให้เมธอดนี้ เรียกใช้ reference ของตัวเอง
class Test{
public $ok = 'ok';
public function tt(){
echo $this->ok;
}
}
Test::tt(); // คราวนี้ Error
ซึ่งอาจเป็นกับดัก ในการโค้ดนะครับ ควรออกแบบตามสถาปัตยกรรมใหม่ โดยใช้ static แยก เพื่อให้บ่งบอกสถานะการเรียกใช้ ว่า static ไม่สามารถใช้ reference ของตัวเองได้
|
 |
 |
 |
 |
Date :
2009-05-15 19:34:35 |
By :
pjgunner |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
ผมเองกะว่าจะใช้ OOP กับโปรเจกต์ที่กำลังวางแผนไว้ หลังจากศึกษา javascript library ตัวหนึ่ง
เห็นกระทู้นี้ ก็เลยมาชำเลืองดูก่อน
แต่ว่า OOP ใน php ยังไม่เป็น แบบ stable หรือ standard ซักเท่าไหร่ หลังจากลองอ่านดู OOP สำหรับ php 5
ซึ่งปัจจุบันผมใช้ php 2.2.3
As of PHP 5.3.0, it's possible to reference the class using a variable. Keywords like self, parent or static are not allowed in dynamic class references.
ตย.
Code (PHP)
<?php
// Copy from php manual ^^!
class Foo
{
public static $my_static = 'foo';
public function staticValue() {
return self::$my_static;
}
}
class Bar extends Foo
{
public function fooStatic() {
return parent::$my_static;
}
}
print Foo::$my_static . "\n";
$foo = new Foo();
print $foo->staticValue() . "\n";
print $foo->my_static . "\n"; // Undefined "Property" my_static
print $foo::$my_static . "\n"; // ตามที่เข้าใจ น่าจะบรรทัดนี้ ว่า ไม่ควร
$classname = 'Foo';
print $classname::$my_static . "\n"; // หรือว่าจะ บรรทัดนี้
print Bar::$my_static . "\n";
$bar = new Bar();
print $bar->fooStatic() . "\n";
?>

ดังนั้นควรใช้ Foo::$my_satatic; จะดีกว่านะคับ
ผมเองก็ยังไม่ได้ไปอ่านรายละเอียด OOP ที่น่าจะ stable ของ php6
|
 |
 |
 |
 |
Date :
2009-05-15 19:58:07 |
By :
pjgunner |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
โอ้ว เป็นประโยชน์มาก ขอบคุณคับ
สำหรับความรู้คับ
สำหรับ php 6 ผมอ่านคร่าวๆ (คร่าวมากๆ เพราะอ่านไม่ค่อยออก เหอๆ)

แต่ถ้ามีความรู้เกี่ยวกับ js lib ผมก็เอานะคับ
ตอนนี้ผมใช้ jquery เป็นแค่พื้นๆ นิดหน่อย แล้วก็ต้องไปหัดใช้ ext js อีกตัว
ตอนนี้ผมก็กำลังลองผิดลองถูกเหมือนกัน
ยังไงก็ share กันได้นะคับ ^^
(อันที่จริงต้องเรียกว่าผมมาขอความรู้ถึงจะถูก หุหุ)
|
 |
 |
 |
 |
Date :
2009-05-15 22:50:42 |
By :
nut_t02 |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
ext รู้สึกจะไม่ฟรีแล้วนะครับ
|
 |
 |
 |
 |
Date :
2009-05-15 23:22:34 |
By :
plakrim |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
กำลังหัดเหมือนกันครับ
ตอนแรกมีหนังสือ แล้วอ่านเห็นผ่านๆ
แต่ไม่ได้ลองศึกษาจริงๆ
เวลาเขียน ก็เขียนแค่
Ex. My Code
<?
class db
{
public function query ($cmd)
{
return @mysql_query ($cmd);
}
public function fetch ($cmd)
{
return @mysql_fetch_array ($cmd);
}
public function num ($cmd)
{
return @mysql_num_rows (self::query ($cmd) );
}
public function quickfetch ($cmd)
{
return self::fetch ( self::query ($cmd) );
}
public function connect ()
{
global $data;
$connect = @mysql_connect ($data['host'], $data['user'], $data['pass']);
@mysql_select_db ($data['db']);
return $connect;
}
public function close ($con = "")
{
@mysql_close ($con);
}
}
?>
ผมใช้แค่นี้เองครับ แถมใส่ $db = new db(); ไว้ในหน้าพวก config ที่จะต้องถูก include โดยหน้าอื่นๆ
สรุปคือ ทำไว้เท่ๆ ไปงั้น 
ตอนนี้เขียนเว็บบอร์ดเล่นๆ ตอนเริ่มก็ยังไม่เห็นกระทู้นี้ เลยอัด function ไปยาวเลย
พอมาเห็นกระทู้นี้เลยลองหยิบหนังสือ PHP มาอ่าน OOP ดู
ตอนนี้เพิ่งมาเปลี่ยนเป็น OOP ไป คลาส 2 คลาสเองครับ (คิดไม่ออกว่าจะใช้ยังไงดี)
เลยอยากให้ ท่านไหนใจดี มาช่วยเด็ก ม.4 คนนี้ คิดหน่อยครับ ว่าจะใช้ยังไงดี 
ใครอยากช่วยคิดก็แอดมาเลยครับ bank[at]th-gaming.com
ปล. ไม่ได้ใช้ในเชิงพาณิชย์แน่นอนครับ ลองเขียนเล่นๆ ไว้ใช้เอง ก่อนเปิดเทอม งุงิ
|
 |
 |
 |
 |
Date :
2009-05-15 23:37:36 |
By :
PoseidonX |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
รู้สึกว่าถ้าเพื่อการศึกษาจะยังฟรีอยู่นะคับ
แต่ถ้าเพื่อธุรกิจคงต้องซื้อ license อยู่

|
 |
 |
 |
 |
Date :
2009-05-15 23:43:10 |
By :
nut_t02 |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
เพื่อการศึกษา มันจะได้ใช้กี่ครั้งเนี้ย
|
 |
 |
 |
 |
Date :
2009-05-15 23:44:47 |
By :
plakrim |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
ผมก็กำลังเขียน database แบบ oop อยู่
อีกประมาณ 3 ปีก็เสร็จแล้วล่ะ (ล้อเล่นได้ประมาณ 90% แล้ว) เหลือ debug อีกหน่อย
|
 |
 |
 |
 |
Date :
2009-05-16 01:02:21 |
By :
num |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
นี่ก็เยี่ยมคับ ไว้เอามาแชร์กันนะคับ

หนับหนุนความคิดดีดี แหะๆ
|
 |
 |
 |
 |
Date :
2009-05-16 07:21:01 |
By :
nut_t02 |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
ขอโทษนะคับ ผมเพิ่งเข้าไปดูปฏิทิน rep No. 16 เยี่ยมมากคับ
ถ้าประยุกต์กะ ajax หน่อยคงสามารถเขียน note ลงไปได้ เหมือน google calendar เลย
ถ้าเขียนได้ แล้วก็คงมีแนวความคิดแล้วล่ะคับ ว่า google doc ทำงานยังไง
พอเป็น idea ไปทำอย่างอื่น
ปล ผมชอบนะที่คุณเขียน comment ด้วยใครที่อ่าน code ไม่ค่อยรู้เรื่องก็เดาๆ ได้จาก comment นี่แหละ
อันที่จริง comment ควรเขียนประมาณนี้อ่ะคับ เพราะ tool บางตัวสามารถนำ comment มาแสดงได้เช่น เขียนโคดแบบนี้
Code (PHP)
<?php
/**
* Enter description here...
*
*/
class test {
/**
* Enter description here...
*
* @param string $d (1-31)
* @param string $m (1-12)
* @param string $y
* @return integer
*/
public function getWeek($d = '', $m = '', $y = '')
{
$day = date('j');
$month = date('n');
$year = date('Y');
if ( is_numeric($d) && $d > 0 ) $day = $d;
if ( is_numeric($m) && $m > 0 ) $month = $m;
if ( is_numeric($y) && $y > 0 ) $year = $y;
$firstWeek = date('w', mktime( 0, 0, 0, $month, 1, $year));
return ceil( ( $day + $firstWeek ) / 7 );
}
}
?>
เวลา tool ที่ใช้เขียนจะแสดงแบบนี้คับ

จะเป็นประโยชน์มากสำหรับคนที่นำไปใช้ต่อ ลองนึกดูสิว่าถ้าเรามีโคดยาวๆ เยอะๆ หลายบรรทัด หรือบางทีแยกออกเป็นหลายไฟล์
คงจะไม่มีคนไปนั่งไล่หรอกคับ ว่า function นี้รับ parameter อะไร return อะไรยังไง
เค้าก็อาศัยดูไอ้ตรงนี้อ่ะแหละ อีกอย่างนะคับ comment ที่ผมเขียนให้ดูมาสามารถใช้ phpDocumentor gen
ออกมาเป็นรูปแบบ html สวยๆ ได้ เช่น ที่นี่คับ
อ่อ อีกเรื่องนึงคับ (หลายเรื่องจังแหะ )
programmer เราๆ ท่านๆ เนี่ยส่วนใหญ่ไม่ค่อย validate parameter ที่รับเข้ามากันคับ
อย่างน้อยก็ควรมีการดัก error ไว้ จะไม่ validate ก็ได้ถ้าใช้คนเดียว
หรืออย่างน้อยก็มีค่า default ให้ดูเป็นตัวอย่าง ซึ่งค่า default นี่อย่างน้อยก็ให้ program ทำงานต่อได้โดย
ไม่ error ออกมา php fatal error หรือ php warning คับ
แพร่มซะยาวเลยผม
เด๋วผมขอเอาไปใช้มั่งนะคับ ปฏิทินนี่ ^^
|
 |
 |
 |
 |
Date :
2009-05-16 08:02:13 |
By :
nut_t02 |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
rep 16. เขียน calendar ได้ขนาดนี้ไม่ใช่มนุษย์แล้วครับ (เหนือมนุษย์) อิๆ
|
 |
 |
 |
 |
Date :
2009-05-16 08:37:46 |
By :
num |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
ทดสอบใหม่อีกรอบ เพราะลืมเรื่อง dynamic paramiter ไป
Code (PHP)
<?php
interface DBConnect{
public static function connect($host ='', $user ='', $pass ='', $db_name ='', $flag ='');
public static function endConnection();
}
?>
Code (PHP)
<?php
class MySQLConnect implements DBConnect{
const DEF_HOST = 'localhost';
const DEF_USER = 'root';
const DEF_PASSWORD = '';
const DEF_DB = 'mysql';
//@implement inteface DBConnect::connect()
public static function connect($host = self::DEF_HOST, $user = self::DEF_USER, $pass = self::DEF_PASSWORD, $db_name = self::DEF_DB, $flag = false){
global $conn;
if($flag)
$conn = mysql_pconnect($host, $user, $pass); // persistent connection
else
$conn = mysql_connect($host, $user, $pass);
if(!$conn) exit( mysql_error() );
if( !mysql_select_db($db_name, $conn) ) exit('Cannot select database.');
mysql_query("SET NAMES UTF8");
return $conn;
}
//@implement interface DBConnect::endConnection()
public static function endConnection(){
return mysql_close($conn);
}
}//MySQLConnect class
?>
Code (PHP)
<?php
// ไม่เคยใช้ oracle แต่ลองมั่วๆ ตามแมนน่วนดู ไม่รู้ว่าจะทำงานป่าว
class OracleConnect implements DBConnect{
const DEF_USER = 'root';
const DEF_PASSWORD = '';
const DEF_DB = 'oracle';
//@implement interface DBConnect::connect()
public static function connect($host='', $user = self::DEF_USER, $pass = self::DEF_PASSWORD, $db_name = self::DEF_DB, $flag = ''){
global $conn;
if($flag) //if 1
if( is_array($flag) ){//if 2
foreach($flag as $key=>$val)
$$key = $val;
if($charset && $session_mode)
$conn = ocilogon($user, $pass, $db_name, constant($charset), constant($session_mode));
else if($charset)
$conn = ocilogon($user, $pass, $db_name, constant($charset));
else if($session_mode)
$conn = ocilogon($user, $pass, $db_name, NLS_LANG, constant($session_mode));
else
exit('พารามิเตอร์ไม่ถูกต้อง'); // หรือ trow Exception
}else{ // if 2
$conn = ocilogon($user, $pass, $db_name, constant($flag));
}
else //if 1
$conn = ocilogon($user, $pass, $db_name);
if(!$conn) exit('Error: connect to oracle.');
return $conn;
}
//@implement interface DBConnect::endConnect()
public static function endConnection(){
return oci_close($conn);
}
}//end OracleConnect
?>
ปล.ยังไม่สามารถทีละหลาย คอนเน็คชั่นได้ แค่ทดสอบเขียนดู
|
 |
 |
 |
 |
Date :
2009-05-16 09:52:37 |
By :
pjgunner |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
ลืมสร้าง Factory class ให้ด้วย - -!
Code (PHP)
<?php
//คลาสโรงาน ^^
class DBConnectFactory{
//to establish default connection
public static function createDefaultConnection($db_type ='MySQL'){
switch($db_type){
case 'MySQL':
return MySQLConnect::connect();
break;
case 'Oracle':
return OracleConnect::connect();
break;
default:
exit("Sory No Connection to '$db_type' database");
}
}
//to establish user connection
public static function createConnection($db_type = 'MySQL', $host='', $user ='', $pass ='', $db_name ='', $flag =''){
switch($db_type){
case 'MySQL':
return MySQLConnect::connect($host, $user, $pass, $db_name, $flag);
break;
case 'Oracle':
return OracleConnect::connect($host, $user, $pass, $db_name, $flag);
break;
default:
exit("Sory No Connection to '$db_type' database");
}
}
}// DbConnectFactory class
?>
|
 |
 |
 |
 |
Date :
2009-05-16 10:11:17 |
By :
pjgunner |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
มันช่างน่าปวดหัว... มากกว่าที่โรงเรียนอีก ฮ่าๆ
ปล. public function กับ public static function มันแสดงผลเหมือนกันหรือเปล่าครับ เห็นในหนังสือบอกว่าให้ผลเหมือนกัน แล้วก็ static ใช้กับตัวแปร แล้วเรียกแบบ function::$var; อะครับ หรือมันเปลี่ยนไปแล้วหว่า
|
 |
 |
 |
 |
Date :
2009-05-16 10:57:52 |
By :
PoseidonX |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
สักวันจะเขียนแบบ OOP ให้ได้ค่ะ
แต่ตอนนี้ขอเขียนแบบธรรมดาให้รอดก่อนดีกว่า แหะๆ
|
 |
 |
 |
 |
Date :
2009-05-16 11:15:52 |
By :
Avrill |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
อยากให้เขียน tutorail เรื่อง OOP ของ PHP5 ครับ จะได้มีคนเริ่มใช้จริงๆ เลยอิๆ 
|
 |
 |
 |
 |
Date :
2009-05-16 12:56:09 |
By :
num |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
ตอบ rep No 30 นะคับ
ขอตอบเรื่อง "static ใช้กับตัวแปร แล้วเรียกแบบ function::$var;"
ตอบว่า ผิดคับต้องเป็นแบบนี้คับ "class::$var;" ^^'
ขอตอบเรื่อง "public function กับ public static function มันแสดงผลเหมือนกันหรือเปล่าครับ"
ตอบว่า ถ้าเรื่องการแสดงผลก็แสดงผลเหมือนกันคับ แต่ที่ต่างกันคือวิธีการเรียกใช้งาน
สำหรับผม ผมว่าควรจะเรียกใช้งานให้ต่างกัน (แม้ว่าจะเรียกเหมือนกันก็ได้ แต่ php error จะไม่เหมือนกัน) คือ
สำหรับ static function ควรเรียกแบบ
<?php
class test {
public static function functionStatic(){
}
}
test::functionStatic();
?>
สำหรับที่ไม่ใช่ static function ควรเรียกแบบ
<?php
class test {
public function functionNonStatic(){
}
}
$test = new test();
$test->functionNonStatic();
?>
php สามารถเรียกแบบ ตัวอย่าง 1 และ 2 นี้ได้โดยไม่ error ใดๆ (ย้ำนะคับว่า เฉพาะ php ภาษาอื่นผมไม่แน่ใจคับ)
แต่ผมว่า ควรเรียกให้ต่างกัน เพื่อกันความสับสนคับ
ตัวอย่าง 1
<?php
class test {
public function functionNonStatic(){
}
}
// แบบ initiate object ก่อน
$test = new test();
$test->functionNonStatic();
// แบบ static
test::functionNonStatic();
?>
ตัวอย่าง 2
<?php
class test {
public static function functionNonStatic(){
}
}
// แบบ initiate object ก่อน
$test = new test();
$test->functionNonStatic();
// แบบ static
test::functionNonStatic();
?>
|
 |
 |
 |
 |
Date :
2009-05-17 07:58:53 |
By :
nut_t02 |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
factory class ที่ rep No. 28-29 ของคุณเอี่ยวคับ
จากตัวอย่างของคุณเอี่ยว พวกเราก็เริ่มมีแนวคิดที่คล้ายๆ กับ library ADOdb แล้วนะคับ
คือ concept ของ ADOdb สรุปออกมาง่ายๆ ว่า
ถ้าเราเปลี่ยน db ที่ใช้เช่นจาก MySQL ไปเป็น ORACLE เราต้องเปลี่ยน code แค่บรรทัดเดียวเท่านั้น
โดยที่ program ทั้งหมดที่เขียนมา 1000 กว่าไฟล์ (ยกตัวอย่างเพื่อให้เห็นภาพ) ต้องใช้งานได้ถูกต้องเหมือนเดิมทุกประการ
วิธีเรียกใช้งาน code ของคุณเอี่ยวคับ
<?php
$conn = DBConnectFactory::createConnection("MySQL", "localhost", "root", "mysql", "db_test1");
//หรือ
$conn = DBConnectFactory::createConnection("Oracle", "localhost", "root", "mysql", "db_test1");
?>
บางคนต้องลองเขียนก่อนลองใช้ ถึงจะเห็นภาพ
ส่วนบางคนต้องลองใช้ก่อนลองเขียน ถึงจะเห็นภาพ
ผมเลย แนบ link ของ ADOdb เป็นตัวอย่างที่ใช้ในชีวิตจริง ที่ใช้ factory class สำหรับให้พวกที่ 2 เห็นภาพนะคับ ^^
ส่วนพวกที่ 1 ดูตัวอย่างจาก code ของคุณเอี่ยวหรือ ของผม เป็นแนวทางไปก็ได้คับ
วิธีใช้งาน ADOdb สั้นๆ แบบภาษาไทยที่นี่
ส่วนตัว lib ADOdb download ได้ ที่นี่
ส่วน manual ตัวเต็มดูได้ ที่นี่
|
 |
 |
 |
 |
Date :
2009-05-17 08:36:46 |
By :
nut_t02 |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
public เรียกได้หมด
private เรียกได้เฉพาะภายในคลาสตัวเอง
protected เรียกได้เฉพาะใน ครอบครัว ก็คือคลาสลูกนะคับ
ตัวแปร static คือ ค่านั้นมีอยู่ตลอดเวลา เช่น
Code (PHP)
<?php
class Test{
protected static $abc = 0;
public function __construct(){
self::$abc++;
}
public function getABC(){
return self::$abc;
}
}
echo '<br><br>';
$t = new Test();
echo $t->getABC(), '<br><br>';
$t2 = new Test();
echo $t->getABC();
//echo TEST::$abc; //เรียกไม่ได้เพราะเป็น protected
?>
ส่วน static method คือเมธธอดที่สามารถเรียกโดยไม่ต้องมี reference แต่ในเมดธอดต้องไม่เรียก สิ่งที่ต้องใช้ reference '$this' เมธอด หรือ ตัวแปร แต่สามารถเรียก ใช้ static, constant ได้
( ปล. ผมชอบพิมพ์ void ไปเอง ชอบลืม $this, self, parent, function
หลักการที่บอกมานั้น มาจาก Java ทั้งหมด PHP ก็คงจะเหมือนกัน 
)
|
 |
 |
 |
 |
Date :
2009-05-17 14:56:57 |
By :
pjgunner |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
ลืมบอกไปตัวแปรแบบ static ก็คือใช้ร่วมกันได้หลาย instance นั่นเอง (จะมีก็อบปี้เดียว)
|
 |
 |
 |
 |
Date :
2009-05-17 15:06:32 |
By :
pjgunner |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
แจ๋มจริงๆ แต่ละคนเก่งๆ กันทั้งนั้น เห็น coding แต่ละคนแล้วผมก็แค่เด็กๆ คงต้องเขียน oop อย่างจริงๆ จังๆ กับเขาบ้างแล้ว
|
 |
 |
 |
 |
Date :
2009-05-17 16:08:38 |
By :
plakrim |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
คห.26 ขอบคุณสำหรับคำแน่ะนำครับ
ผมก็กำลังฝึกเขียน OOP ไปเรือยๆ
ปรกติแล้ว เวลาผมเขียน ผมจะเน้นดีไซน์ และจัดรูปแบบโปรแกรมให้สวยงามก่อนครับ 555+
|
 |
 |
 |
 |
Date :
2009-05-17 22:25:16 |
By :
danya |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
คห.27 สวัสดีครับพี่หนุ่ม 555+
|
 |
 |
 |
 |
Date :
2009-05-17 23:36:31 |
By :
danya |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
ประโยชน์ที่หลายคน ลืมนึกถึงหรือ อ่านไปไม่ถึง เพราะยังไม่ค่อยเข้าใจ OOP ที่ผมเขียนก็คือ
สังเกตดู interface DBConnect จะมี abstract method ถึงแม้ว่าคลาสนี้ จะไม่เป็น interface ก็ตามยังไง
ก็ตามคลาสที่สืบทอดคุณสมบัติ หรือ implement ไปก็ต้องมีเม็ดธอดที่ประกาศในคลาสนี้ ดังนั้นเราจึงเชื่อแน่ว่า คลาส
ลูกหรือ คลาสที่ implement ไป จะต้องมีเมธอดที่มีอยู่ในคลาสแม่แน่นอน
สมมติว่าเรา สร้างชนิดการติดต่ออีกอัน โดย implement DBConnect ชื่อว่า MySQLiConnect จึงเชื่อได้แน่ว่า คลาสนั้นย่อมมี connect() และ endConnection() และมีการเข้าถึงที่เท่าเทียมหรือมากกว่า
สำหรับผู้ใช้ หรือผู้ที่ implement แล้วเป็นการง่ายในการใช้งาน สะดวกเหมาะสม แต่มันก็ต้องแลกกับเวลาในออกแบบพอสมควร ยังมีการออกแบบอีกหลายรูปแบบ ที่แตกต่างกัน ตามแต่ละส่วน(ถ้าออกแบบผิด ในบางส่วน ก็จะทำให้ยากในการแก้ไขเป็นอย่างมาก)
|
 |
 |
 |
 |
Date :
2009-05-18 08:07:58 |
By :
pjgunner |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
เอ่อ
ขอถามอีกอย่างครับ
ถ้าคำสั่งนี้
Code (PHP)
<?php
class a{
private $a;
function __construct () {
self::$a = 1;
}
}
?>
กับ
Code (PHP)
<?php
class a{
private $a;
self::$a = 1;
?>
มันต่างกันอย่างไรครับ
|
 |
 |
 |
 |
Date :
2009-05-18 21:55:25 |
By :
PoseidonX |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
ตอบคุณ PoseidonX นะคับ
code แรก error เพราะ $a ไม่ใช่ static property จึงอ้างแบบ static ไม่ได้
ส่วน code อันที่สอง syntax ผิดนะคับ
ใน class จะต้องประกอบด้วย
- property ในที่นี้คือ private $a นั่นเอง
- method หรือ function ในที่นี้คือ __construct() ก็ได้คับ
เพราะฉะนั้นผมเลยตอบไม่ได้ว่า มันต่างกันยังไง ^^
ปล ผมใช้ php 5.2.7 test นะคับ
|
 |
 |
 |
 |
Date :
2009-05-18 22:32:11 |
By :
nut_t02 |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
คุณ nut_t02 ครับ
ขอโทษทีครับ เขียนโค้ดผิด
คืออยากถามแค่ว่า ใส่ตัวแปร $a ใน function __construct() กับ ไม่ใส่ใน __construct()
มันจะให้ผลต่างกันยังไงครับ เพราะว่าในหนังสือที่ผมอ่านเขาบอกว่า __construct() ก็คือกำหนดค่าก่อนเรียกใช้ฟังก์ชั่นต่างๆ เท่านั้นเอง
|
 |
 |
 |
 |
Date :
2009-05-19 19:59:10 |
By :
PoseidonX |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
ตอบคุณ PoseidonX คับ
ถูกต้องตามที่คุณอ่านมาแล้วคับ คือ ทุกอย่างที่อยู่ใน function __construct() จะถูกเรียกใช้งานโดยอัตโนมัติเมื่อ instance object คับ
(เมื่อ new Class(); เท่านั้น)
ส่วนที่บอกว่าไม่ใส่ไว้ใน __construct() นั่นหมายถึง ใส่ไว้ใน function อื่นคับไม่ใช่เขียนลอยๆ มาตามตัวอย่างที่คุณเขียนมาคับ
ซึ่งจะทำงานเมื่อ user มีการเรียกใช้งานเท่านั้นคับ

|
 |
 |
 |
 |
Date :
2009-05-19 22:53:18 |
By :
nut_t02 |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
ผมเข้าไปดู DragonHtmlDB ของคุณ num แล้วคับ
เขียนได้ดีจริงๆ ค่อนข้างครบทุกอย่างที่อยู่ในใจผมเลย
concept แนวนี้แหละคับที่ผมอยากจะเอามาเป็นตัวอย่างให้คนใช้กันเยอะๆ
แต่ว่าคุณ num น่าจะแยกออกจากกันไปเลยนะคับระหว่าง class db กับตัว pagination ที่ใช้ แสดงตาราง (บรรทัดที่ 670, 774)
บางทีคนอื่นเค้ามาอ่านแล้วอาจจะอยากเอาไปประยุกต์ใช้กับเรื่องอื่น แต่เจอ code ไปพันบรรทัดก็อึ้งเหมือนกัน แก้ไม่ถูก ^^'
ตัวอย่างการเรียกใช้งาน อาจดูยากไปนิดนึงนะคับ แหะๆ

ปล. ใครจะเอา code ของคุณ num ไปใช้กรุณาอ่านและทำตาม license ก่อนนะคับ
สัญญาอนุญาตของครีเอทีฟคอมมอนส์แบบ แสดงที่มา-ไม่ใช้เพื่อการค้า-อนุญาตแบบเดียวกัน
ถือว่าเป็นการให้เครดิตคนคิดค้นขึ้นมาคับ
ข้อดีของการดู code คนอื่นก็คือ
เราจะได้เทคนิคการเขียนโปรแกรมแบบใหม่ๆ ที่ตัวเองยังไม่รู้ ได้เห็นบางคำสั่งที่ไม่เคยเห็น
ตรงนี้แหละคับที่เราควรเอามาลองใช้ลองดู เพื่อให้เป็นประสบการณ์ของตัวเอง
เด๋วไปลองเขียน code มาแลกกันดูมั่งดีกว่าเผื่อของผมตกหล่นจะได้มีผู้ช่วยชี้แนะคับ

|
 |
 |
 |
 |
Date :
2009-05-19 23:37:15 |
By :
nut_t02 |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
ตั้งใจไว้ แต่พอรีบทีไรกลับมาเขียนแบบเดิมทุกทีครับ แบบว่า ชินอ่ะ
|
 |
 |
 |
 |
Date :
2009-05-20 14:30:41 |
By :
navico |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
ไม่ทราบว่าคุณ num ใช้ editor หรือ ide ตัวไหนพัฒนาคับ
แล้วไม่ทราบว่า ใช้หลักการใดในการ ป้องกัน sql injection ครับ จะเอาไปใช้มั่ง ไม่รู้โดนมั่งรึป่าว
ขอบคุณคับ 
|
 |
 |
 |
 |
Date :
2009-05-21 13:30:34 |
By :
pjgunner |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
ขอบคุณมากคับ prepare statement ดีๆ นี่เอง
รู้วิธีใช้ sql injection แล้ว 
|
 |
 |
 |
 |
Date :
2009-05-21 14:35:58 |
By :
pjgunner |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
ผมเองก็ไม่เคยใช้พวก mysql_real_escape_string(); มาก่อน หรือเมื่อก่อนเคยใช้ addslashes();
ตอนนี้ไม่ใช้แล้ว
ผมลอง ใช้ sql injection กับ เว็บตัวเอง แต่ก็ล็อคอินไม่ได้เหมือนว่ามันได้ escape string ไว้แล้ว
เอา sql เดียวกันนี้ ไปยิงที่ phpmyadmin กลับ แสดงเรคคอร์ดออกมา
ยัง งง อยู่เหมือนกัน สรุปว่าจำเป็นต้อง escape หรือ escape ให้อัติโนมัติกันแน่คับ

|
 |
 |
 |
 |
Date :
2009-05-21 15:13:31 |
By :
pjgunner |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
ลืมบอกไปการจะใช้ class ของผมได้จะต้องตั้ง magic_quotes_gpc เป็น off ครับ
|
 |
 |
 |
 |
Date :
2009-05-21 16:07:46 |
By :
num |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|

ขอบคุณ คุณ num มากคับ ทำให้เข้าใจ String ใน PHP เยอะมากขึ้นจริงๆ แต่ผมเองก็ยังงง อยู่บ้าง
ต้องช่วยตัวเองบ้างแล้ว
สำหรับเพื่อนๆ ที่อยากจะใช้ PHP 6 ก็คงจะต้องเตรียมตัวกัน 
ผมเองก็คงจะต้อง ปรับเป็น off บ้างแล้วเหมือนกัน(เพื่อ อนาคต )
|
 |
 |
 |
 |
Date :
2009-05-21 16:39:07 |
By :
pjgunner |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
ขอโทษเพื่อนๆ ที่นอกเรื่องไปหน่อย เรามาเข้าเรื่อง OOP กันต่อดีกว่าคับ(เดี๋ยวจะโดนแช่ง)
ว่าด้วยเรื่อง abstract class และ interface
abstract class และ interface โดยหลักแล้วถูกออกแบบมาเพื่อให้ เป็นโครงร่างของคลาสต่างๆที่สืบทอดคุณสมบัติคับ โดยตัวมันเองแล้ว ไม่สามารถที่จะสร้าง instance ได้
เมธอดใน interface นั้น จะเป็น abstract method โดยอัตโนมัติ(ไม่จำเป็นต้องใส่โมดิฟายเออ abstract)
ส่วน เมธอดใน abstract class นั้น ถ้าอยากให้เป็น abstract method จำเป็นต้องใส่โมดิฟายเออ abstract ด้วย
โดยที่ abstract class สามารถมีได้ทั้ง เมธอดธรรมดา และ abstract method
ใน abstract class
คำว่า abstract method นั่นก็คือ จะต้องมีคลาสในครอบครัว(ลูกหลาน) implement ให้ครบก่อน จึงจะกลายเป็นคลาสธรรมดา(สร้าง instance ได้) ถ้า implement ไม่ครบ ก็จะยังเป็น abstract class อยู่
ใน interface
ถ้า implement ไม่ครบ ก็จะต้อง ใส่โมดิฟายเออ interface ด้วย
ความจริงแล้วอีกเหตุผลที่ เขาสร้าง interface ขึ้นมาก็คือ ลดความสับสนในการพัฒนา เรื่อง multiple inheritance นั่นเอง
ยังคิดตัวอย่างที่ใช้อยู่ทั่วไปไม่ออก แปะไว้ก่อน ละกัน 
|
 |
 |
 |
 |
Date :
2009-05-21 18:36:22 |
By :
pjgunner |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
พี่หนุ่ม โชว์เทพแล้วเว้ยยย อิอิ
พี่หนุ่ม ของเขาดีจริงนะ 5555+ 
|
 |
 |
 |
 |
Date :
2009-05-22 15:22:00 |
By :
danya |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
เรื่อง magic_quotes_gpc เป็นเรื่องที่ทำให้ต้องแก้โปรแกรมมาหลายทีแล้วอะ เลยรู้ซึ้งเลยว่ามันทำให้เกิดปัญหาตามมามากมาย
|
 |
 |
 |
 |
Date :
2009-05-22 15:51:34 |
By :
num |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
ขอโทษนะคับ เพราะช่วงนี้ผมไม่ว่างเท่าไหร่(ก็ติดเกมอยู่คับ เพิ่งเล่นดู สนุกดี http://urd.astonia.com/)
คือเรื่องตัวอย่างน่ะคับ ผมเองก็มีความคิดได้แล้วว่าจะเอาเรื่องอะไรดี ที่สามารถนำประยุกต์ใช้ได้แต่ยังไม่มีเวลาเขียนเพราะ ประโยคข้างบน 
แต่เรื่องที่คิดนั้น ก็จะเอามาบอกให้คนที่สนใจและติดตามกระทู้นี้อยู่ นำไปคิดและพัฒนามามาแสดงให้เพื่อนๆดูก็ได้ จะได้แชร์กันถึงความหมาย ซึ่งแต่ละคนอาจคิดหรือวางแผนไม่เหมือนกัน แตกต่างกัน จะได้นำมาหา QED ร่วมกัน

สมมติว่า เราจะสร้าง เกมออนไลน์ประเภทเกมภาษา เกมหนึ่ง(เช่น Final fantasy, Dragon Wariror) ซึ่งมีรายละเอียดคร่าวๆ คือ เกมนี้เป็นเกมภาษา เป็นเกมเนื้อเรื่อง มีฮีโร่(ตัวเอก กับพักพวกที่เราใช้ได้ อาจหลายตัว) มีมอนสเตอร์หลากหลายชนิดหลายระดับหรือ อาจมีหลายธาตุ อาจมีสกิล เวทมนต์ ต่างๆ ก็ได้
แน่นอนว่า ที่ผมบอกไปในพารากราฟข้างบน หมายถึงเป้าหมายหลักของเรา แต่สมติว่าเรายังไม่ต้องคิดถึงเรื่องเนื้อเรื่องหรืออะไรอย่างอื่น สิ่งที่เราสนใจก็ตอนนี้ก็คือ การออก class ต่างๆให้ใช้ร่วมกันได้อย่างมีประสิทธิภาพมากที่สุด โดยใช้ OOP ซึ่งแน่นอนว่า OOP ในสถานการ์ณนี้ ย่อมเป็นประโยชน์อย่างยิ่ง(reusable, extensible) แน่นอนว่าเกี่ยวกับเรื่อง ตัวละคร ฮีโร่ มอนส์เตอร์ ต่างๆนั่นเอง โดยยังไม่ต้องไปรวมถึงการไป ดึง/บันทึก ข้อมูลจากฐานข้อมูล
ปล. นะครับ : เรื่องนี้ไม่จำกัดความคิด ไม่มีผิดถูก แต่มีเรื่องของประสิทธิภาพในการ reusable และ extensible โดยให้โปรแกรมไม่ต้องจำเป็นต้องไปแก้โค้ดเดิมในภายหลัง คืออยากให้ใช้ OOP ให้มีประสิทธิภาพกัน และเพื่อเป็นการหาทางออกร่วมกัน เราสามารถที่จะปรึกษาหาทางกันได้ โดยเอาโค้ดมาแปะกัน(ขอให้ 1 rep ต่อ ทุกคลาส เพื่อไม่ให้งง แต่แก้เอามาใหม่ หรือแลกเปลี่ยนกันได้ถ้ามีการแลกเปลี่ยนกัน มีคอมเมนต์ พอเข้าใจ)

|
 |
 |
 |
 |
Date :
2009-05-24 22:05:58 |
By :
pjgunner |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
มีเบื้องต้นประมาณนี้หรือเปล่าคับ เพื่อนๆ ช่วยดูให้ผมด้วย
ขาดไรตรงไหนมาช่วยกันนะคับ
เรียนรู้ไปพร้อมๆ กันคับ มี tutor นี่แล้วคับ
Code (PHP)
<?php
class ตัวละคร {
protected เลือด;
protected พลังเวท;
protected basic_skill;
protected level;
protected exp;
protected ธาตุ;
}
class hero extends ตัวละคร {
protected ชื่อ;
protected more_skill;
}
class monster extends ตัวละคร {
protected ชื่อ;
protected more_skill;
}
?>
มีคงมีอีกอ่ะแหละคับ
แต่ผมอยากให้คนอื่นช่วยๆ กันคิดคับ
|
 |
 |
 |
 |
Date :
2009-05-26 07:52:45 |
By :
nut_t02 |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
จากตัวอย่าง ของคุณ nut_t02 ผมคิว่าน่าจะใส่ operation ด้วยนะครับ
จาก rep.63 ผมก็ลองเอาไปสร้างได้ดังนี้
Code (PHP)
<?php
abstract class Character{//เป็น abstract เพื่อไม่ให้สร้าง instance
protected $name;
protected $picture;
protected $alive = true;
public final function getName(){ return $this->name; }
public final function setName($name){ $this->name = $name; }
public final function getStatus(){ return $this->alive; }
public final function setPicture($picture){ $this->picture = $picture; }
public final function getPicture(){ return $this->picture; }
}//Character
//ใช้เก็บสถานะ Character
abstract class CharacterStatus extends Character{
protected $character_exp;//ถ้าเป็น ฮีโร่ ก็เป็นฮีโร่ exp ถ้าเป็น มอนสเตอร์คือ exp ที่ได้รับเมื่อถูกกำจัด
protected $max_hp;
protected $max_mp;
protected $hp;
protected $mp;
}//CharacterStatus
//สามารถโจมตีได้
abstract class Attackable extends CharacterStatus{
protected $offence;
protected $defence;
protected $offence_element;
protected $defence_element;
public function attack(Attackable $dest){//overidable
if($dest instanceof Monster){
$hp_reduce = $this->calculate($this, $dest);
$dest->hp_reduce($hp_reduce);
}
}
public final function hp_reduce(Attackable $attacker, $amount =0){//เลือดลด เป็นพับบลิคเพราะ อาจติดพิษได้(จากข้างนอกคลาส)
if( $this->hp > $amount )
$this->hp -= $amount;
else
$this->death($attacker);
}
public final function hp_add($amount =0){//เลือดเพิ่ม
$this->hp += $amount;
if( $this->hp > $this->max_hp )
$this->hp = $this->max_hp;
$this->awake();
}
protected function death(Attackable $attacker){//ตาย
$this->alive = false;
$this->hp = 0;
setPicture("{$name}_death.png");
}
protected final function awake(){//ฟื้น
if( $this->hp > 0 )
$this->alive = true;
setPicture("{$name}.png");
}
//เป็น abstract เพราะ อาจมีสูตรการคำนวนต่างกันสำหรับ ฮีโร่ และ มอนสเตอร์
public abstract function calculate(Attackable $attacker, Attackable $dest);
public abstract function addExp($exp);
}//Attackable
class Hero extends CharacterStatus implements EquipableCharacter{
protected $hero_class;
public function __construct($name, HeroClass $class, $max_hp, $max_mp, $exp, $picture){
$this->setName($name);
$this->setclass($class);
$this->max_hp = $max_hp; $this->max_mp = $max_mp;
$this->character_exp = $exp;
$this->picture = $picture;
$this->hp = $this->max_hp; $this->mp = $this->max_mp;
}
//ตั้งอาชีพ มีผลต่อสกิล(แต่ยังไม่เขียน)
private function setClass(HeroClass $class){ $this->hero_class = $class; }
public function getClassName(){ return $hero_class->getName(); }
//@implement Attactable->calculate()
public function calculate(Attackable $attacker, Attackable $dest){
//อาจใช้สูตรอื่น และคำนวณ element ด้วย
return $attacker->offence - $dest->defence;
}
//@implement Attackable->addExp()
public function addExp($exp){
$this->character_exp += $exp;
//คำนวน level
}
//@implement Equipable->setEquipment()
public function setEquipment(Equipment $item, $insert = true){
if( $item instanceof Weapon )
$this->weapon = $insert ? $item : 'None';
else
$this->body = $insert ? $item : 'None';
}
//@implement Equipable->getWeapon()
public function getWeapon(){ return $this->weapon; }
//@implement Equipable->getBody()
public function getBody(){ return $this->body; }
}// Hero
class Monster extends CharacterStatus{
public function __construct($name, $max_hp, $max_mp, $exp, $picture){
$this->setName($name);
$this->setclass($class);
$this->max_hp = $max_hp; $this->max_mp = $max_mp;
$this->character_exp = $exp;
$this->picture = $picture;
}
//@overide Attackable->death()
protected function death(Attackable $attacker){
parent::death($attacker);
$attacker.addExp($this->character_exp);
}
//@implement Attackable->addExp
public function addExp(){}
}
/* Interface ต่างๆ */
interface EquipableCharacter{//ให้ Hero implement
public function setEquipment(Equipment $eq, $insert=true);
public function getWeapon();
public function getBody();
}
interface Item{}//ยังไม่เขียนข้างใน interface คือยังไม่เสร็จเอาไว้ให้ item อื่นๆ implement
interface Equipment{}//เพื่อเป็น reference ได้
class Weapon implements Item, Equipment{
public $name;
public $attack_value;
public $element;
public function __construct($name, $attack_value, Element $element){
$this->name = $name; $this->attack_value = $attack_value; $this->element = $element;
}
public function getName(){ return $this->name; }
public function getAttackValue(){ return $this->attack_value; }
public function getElement(){ return $this->element; }
public function __toString(){
return "Weapon name : {$this->name}\n Attack : {$this->attack_value}\n Element : {$this->element}";
}
}
class Body implements Item, Equipment{}//ยังไม่เขียน อาจคล้าย Weapon
abstract class HeroClass{
public $name;
public $skills = array();
public function getClassName(){ return $this->name; }
public function getSkills(){ return $this->skills; }
}
//ตัวอย่าง อาชีพ อีโร่ Novice
class Novice extends HeroClass{//มีได้แค่ instance เดียว (Sigleton)
private static $instance;
private function __construct(){//ไม่ให้สร้าง instance ด้วยตัวเอง
$skills[] = 'defend';
}
public function defend(){}
public static function singleton(){
if( !isset($instance) )
$this->instance = new Novice();
return $this->instance;
}
private function __clone(){}
}
class CharacterFactory{
public static function createHero($name = '', HeroClass $class, $max_hp =100, $max_mp =10, $exp =0, $picture ='default_hero.png'){
return new Hero($name, $class, $max_hp, $max_mp, $exp, $picture);
}
public static function createMonster($name, $max_hp, $max_mp, $exp, $picture='slime.png'){
return new Monster($name, $max_hp, $max_mp, $exp, $picture);
}
}
?>
ปล. ผมเองก็มึนอยู่ ผมก้ไม่ได้ช่ำชองเท่าไหร่ ไม่รู้ว่า อันไหนควรจะทำแบบไหนเท่าไหร่ อาจขาดๆ เกินๆ
ขอไปกินข้าวก่อนนะครับ โค้ดข้างบนต้องต้องสร้าง instance ของ HeroClass ไว้ใช้ก่อนนะครับโดยใช้ singleton() ส่วนการบันทึก ก็คงใช้ใช้ serialization ช่วยครับ
|
 |
 |
 |
 |
Date :
2009-05-28 11:08:42 |
By :
pjgunner |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
ขอแก้หน่อยนะครับ
เมธอด Attackable->attack() ยังเขียนไม่เสร็จครับ ผมลืม ตอนเขียนนึกอะไรขึ้นได้ก็ย้ายไปเขียนที่อื่น ความจริงมันน่าจะมีเรื่อง skill เข้ามาเกี่ยวอีกนะครับ
และ
class CharacterFactory ที่จริงควรเป็น abstract class CharacterFactory นะครับ
|
 |
 |
 |
 |
Date :
2009-05-28 18:00:25 |
By :
pjgunner |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
เพิ่มคลาส
Code (PHP)
<?php
interface NPC{
public function isSeller(){}
public function isQuest(){}
}
class NPCSeller extends Character implements NPC{
private $items;
public function __construct($items){
$this->items = $items;
}
//@implement NPC->isSeller()
public function isSeller(){ return true; }
//@implement NPC->isQuest()
public function isQuest(){ return false; }
}
class NPCQuest extends Character implements NPC{
private $quests;
public function __construct($quests){
$this->quests = $quests;
}
//@implement NPC->isSeller()
public function isSeller(){ return false; }
//@implement NPC->isQuest()
public function isQuest(){ return true; }
}
?>
สังเกตจากโค้ดที่แนบมา ผมคิดว่าผมคงจะออกแบบผิด ใช้ไม่ถูกหลักการซะแล้วหละครับ สังเกต เมธอดข้างบน ไม่ได้ใช้ประโยชน์ของ Polymorphism ความจริง Character ควรเป็น interface มากกว่าหละมั้ง(สับสนตัวเอง ) ยังไงคงจะต้องออกแบบใหม่ คราวนี้ ร่างโครง กะสะโคป ไว้ก่อนดีกว่า ไม่งั้นเหมือนเดิมอีก
ปล. กระทู้เงียบเลยครับ ยังไงก็คุยกันเรื่อง ที่เกี่ยวข้องกันต่อเถอะครับ ไม่ต้องสนใจผม ไม่ได้ตั้งใจให้กระทู้เงียบเลย เดี๋ยวมันจะจบแค่นี้เสียเปล่าๆ
ปลอ. ผมคงไม่ได้กลับมาอีกประมาณ 1 เดือน อยากให้เพื่อนๆ คุยถกกันต่อครับ
|
 |
 |
 |
 |
Date :
2009-05-29 22:09:43 |
By :
pjgunner |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
ขอบคุณครับ กำลังศึกษาพอดี 
|
 |
 |
 |
 |
Date :
2009-06-02 17:00:19 |
By :
HS4OSX |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
ขอบคุณค่ะที่บอกกล่าวกัน
|
 |
 |
 |
 |
Date :
2009-06-09 01:28:02 |
By :
tan311 |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
ตรง rep.65 (ความจริงใช้ dynamic attribute เอาก็ได้) ความจริงเราไม่ควรใช้นะครับ เพราะ จะเสียประโยชน์ของ Infomation Hiding ซึ่งถ้าเป็น dynamic property แล้ว(เปลี่ยน attribute เป็น property นะครับ )
มันจะกลายเป็น public หมด ตัวอย่าง
Code (PHP)
<?php
class Test{}
$t = new Test();
$t->abc = 'xxx';
echo $t->abc;
?>
ส่วนตอนนี้ ผมกำลัง ลองทำโจทย์ของผมใหม่โดยให้สโคปไม่เกิน ให้ฮีโร่และมอนสเตอร์โจมตีกันได้ มี สถานะต่างๆ
ใช้ item และ สกิล ได้ ไอเทมบางอย่างรวมกันได้(คือมีหลายอันใน instance เดียว) ซึ่งผมใช้วิธีเขียนแบบ จากล่างไปสู่ บน ซึ่งตอนนี้ถึงขั้นตอนการเขียนเกี่ยวกับ potion ต่างๆ ผมติดอยู่ว่า ถ้าเป็น hp potion ขนาดต่างกัน ควรเขียน แบบแยก หรือว่า เขียนคลาสเดียวดี
โค้ดทั้งหมดที่เพิ่งเขียนได้
clases/Picture.php
<?php
function __autoload($class_name){
require_once($class_name.'.php');
}
interface Picture(){
public function getPicture();
public function setPicture();
}
?>
classes/Item.php
<?php
function __autoload($class_name){
require_once($class_name.'.php');
}
abstract class Item implements Picture {
protected $name, $legend, $picture;
public function getName() {
return $this->name;
}
protected function setName() {
$this->name = $name;
}
public function getLegend() {
return $this->legend;
}
public function setLegend($legend) {
$this->legend = $legend;
}
//@implement Picture::setPicture()
public function setPicture($picture) {
$this->picture = $picture;
}
abstract public function getType();
}
?>
classes/Equipment.php
<?php
function __autoload($class_name){
require_once($class_name.'.php');
}
interface Equipment {
public function getStatus();
//for enchance item for future feature
protected function setStatus();
}
?>
classes/Body.php
<?php
function __autoload($class_name){
require_once($class_name.'.php');
}
class Body extends Item implements Equipment {
const PICTURE_DIR = 'items/bodies/';
protected $status;
public function __construct($name, EquipmentStatus &$status, $legend ='', $picture= 'default.png') {
$this->setName($name);
$this->setStatus($status);
$this->setLegend($legend);
$this->setPicture($picture);
}
public function getStatus() {
return $this->status;
}
//@Implements Item::getType()
public function getType() {
return 'Body';
}
//@Overide Item::getPicture()
public function getPicture(){
return Body::PICTURE_DIR.$this->picture;
}
protected function setStatus(EquipmentStatus &$status) {
$this->status =& $status;
}
public function __toString() {
$first = $this->getType().' : '.$this->getName().'\n';
$statuses = $this->getStatus();
foreach($statuses as $attr=> $value)
$status .= $attr.' : '.$value.'\n';
$last = 'Legend : '.($this->getLegend() ? $this->getLegend() : 'None').'\n';
return ( $first.$statuses.$last );
}
}
?>
classes/Weapon.php
<?php
function __autoload($class_name){
require_once($class_name.'.php');
}
class Weapon extends Item implements Equipment {
const PICTURE_DIR = 'items/weapons/';
protected $status;
public function __construct($name, EquipmentStatus &$status, $legend ='', $picture= 'default.png') {
$this->setName($name);
$this->setStatus($status);
$this->setLegend($legend);
$this->setPicture($picture);
}
public function getStatus() {
return $this->status;
}
//@Implements Item::getType()
public function getType() {
return 'Weapon';
}
//@Overide Item::getPicture()
public function getPicture(){
return Weapon::PICTURE_DIR.$this->picture;
}
protected function setStatus(EquipmentStatus &$status) {
$this->status =& $status;
}
public function __toString() {
$first = $this->getType().' : '.$this->getName().'\n';
$statuses = $this->getStatus();
foreach($statuses as $attr=> $value)
$status .= $attr.' : '.$value.'\n';
$last = 'Legend : '.($this->getLegend() ? $this->getLegend() : 'None').'\n';
return ( $first.$statuses.$last );
}
}
?>
classes/EquipmentStatus.php
<?php
function __autoload($class_name){
require_once($class_name.'.php');
}
class EquipmentStatus {
//I want to fix scope of Equipment attrbite
//and arrage sort it
public function __construct($attrs) {
//base status
$this->attrs['att'] = $attrs['att'] ? $attrs['att']: 0;
$this->attrs['def'] = $attrs['def'] ? $attrs['def'] : 0;
$this->attrs['mag_att'] = $attrs['mag_att'] ? $attrs['mage_att'] : 0;
$this->attrs['mag_def'] = $attrs['mage_def'] ? $attrs['mag_def'] : 0;
//other status for attack and defend
//attack think to percent
//defend think to 100 percent prevent from enemy attack
$this->attrs['blind'] = $attrs['blind'] ? $attrs['blind'] : 0;
$this->attrs['prevent_blind'] = $attrs['prevent_bind'] ? 100 : 0;
$this->attrs['curse'] = $attrs['curse'] ? $attrs['curse'] ? 0;
$this->attrs['prevent_curse'] = $attrs['prevent_curse'] ? 100 ? 0;
$this->attrs['poison'] = $attrs['poison'] ? $attrs['poison'] : 0;
$this->attrs['prevent_poison'] = $attrs['prevent_poison'] ? 100 : 0;
$this->attrs['sleep'] = $attrs['sleep'] ? $attrs['sleep'] ? 0;
$this->attrs['prevent_sleep'] = $attrs['prevent_sleep'] ? 100 ? 0;
}
public function getAttrs() {
return $this->attrs;
}
}
?>
classes/ItemGroupable
<?php
function __autoload($class_name){
require_once($class_name.'.php');
}
interface ItemGroupable {
const MAX_NUMBER = 100;
public function getNumber();
public function add($number);
public function reduce($number);
}
?>
classes/Potion.php
<?php
function __autoload($class_name){
require_once($class_name.'.php');
}
abstract class Potion extends Item implements ItemGroupable {
const PICTURE_DIR = 'items/potions/';
//@Implements Itemgroupable::getNumber()
public function getNumber() {
return $this->number;
}
//@Implements Itemgroupable::add()
public function add($number) {
$this->number += $number;
if($this->number > ItemGroupable::MAX_NUMBER) {
$remain_number = $this->number - ItemGroupable::MAX_NUMBER;
$this->number = ItemGroupable::MAX_NUMBER;
throw new MaxItemNumberException($remain_number);
}
}
//@Implements Itemgroupable::reduce()
public function reduce($number) {
if($this->number < $number)
throw new ReduceItemNumberException($this->number);
else
$this->number -= $number;
}
}
?>
^ตรงคลาสนี้แหละครับที่จะใช้เป็นคลาสแม่ของ Potion ชนิดต่างๆ แต่ยังไม่แน่ว่า hp potion จะให้เป็นหลายคลาสตามจำนวนการเติม หรือว่า จะให้เป็นคลาสเดียว เพราะมันมีผลตอน group กัน เวลาที่ได้ของมาถ้าแยก ก็จะสามารถเก็บข้อมูลได้ง่าย แต่อาจมีปัญหาที่จะมีคลาสจำนวนมากในระบบ ถ้ามี Potion ประเภทอื่นๆ เช่น เพิ่มทั้ง เลือดและ mp ไอเทมประเภท ฟื้นชีวิต หรืออื่นๆ ซึ่งยังคิดไม่ออก (คลาสนี้ยังไม่สมบูรณ์ลืมใส่ useTo())
ใครมีข้อคิด แนะนำ สอบถาม ถามมาได้คับ ผมก็ยังคิดไม่ออกเหมือนกัน 
|
 |
 |
 |
 |
Date :
2009-06-10 23:03:17 |
By :
pjgunner |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
เรพข้างบน ยังไม่เสร็จนะครับ ยังไม่มีคลาส exception และยัง ไม่ถึงส่วน character เลย ยังทดสอบไม่ได้ ต้องเขียนให้หมดก่อนถึงจะทดสอบได้นะครับ แน่นอนว่า มันคงต้องมี error และส่วนที่ยังไม่สมบูรณ์ที่ต้องเพิ่มเข้าไป
ปล.ผมยังไม่ค่อยได้เข้ามาตอบนะครับ ช่วงนี้ ยังไงก็ทิ้ง คำถาม ข้อแนะนำ ข้อคิดเห็น ไว้เลยนะครับ
|
 |
 |
 |
 |
Date :
2009-06-10 23:08:02 |
By :
pjgunner |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
อยากลองศึกษษบ้างจัง อยากได้ความรู้ค่ะ
|
 |
 |
 |
 |
Date :
2009-06-12 09:55:18 |
By :
kai9 |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
ผมก็อยาก จะลองเขียน แบบ OO อยู่เหมือนกัน
|
 |
 |
 |
 |
Date :
2009-06-12 14:54:36 |
By :
StepZaLung |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
อยากเขียนอยู่นะครับ แต่ยังมีเรื่องที่ไม่เข้าใจอีกมากมายมีหนังสือภาษาไทยแนะนำไม๊ครับ?
|
 |
 |
 |
 |
Date :
2009-06-15 14:06:35 |
By :
rukia |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
PHP 5 ขึ้น
สงไสยต้องไปอัพPHPของตัวเองซะละ
|
 |
 |
 |
 |
Date :
2009-06-16 15:17:35 |
By :
ahung |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
ใครอยากเริ่มศึกษา OOP ก็ลองใช้ PDO ดูก็ได้ครับ มันใช้ ฟีเจอร์ OOP ใน php 5 พอดีเลย
พีดีโอก็ใช้ประโยชน์จาก abstraction ซึ่ง ถ้ามีฐานข้อมูลชนิดใหม่เพิ่มในอนาคต ก็ไม่ต้องเรียนคำสั่ง php ตัวใหม่อีก(เรียนเฉพาะดาต้าเบสชนิดใหม่)
PDO Introduction
The PHP Data Objects (PDO) extension defines a lightweight, consistent interface for accessing databases in PHP. Each database driver that implements the PDO interface can expose database-specific features as regular extension functions. Note that you cannot perform any database functions using the PDO extension by itself; you must use a database-specific PDO driver to access a database server.
PDO provides a data-access abstraction layer, which means that, regardless of which database you're using, you use the same functions to issue queries and fetch data. PDO does not provide a database abstraction; it doesn't rewrite SQL or emulate missing features. You should use a full-blown abstraction layer if you need that facility.
PDO ships with PHP 5.1, and is available as a PECL extension for PHP 5.0; PDO requires the new OO features in the core of PHP 5, and so will not run with earlier versions of PHP.
From PHP manual
http://gunner.freetzi.com
|
 |
 |
 |
 |
Date :
2009-06-19 10:07:06 |
By :
pjgunner |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
ดีมากเลย
|
 |
 |
 |
 |
Date :
2009-06-20 00:42:28 |
By :
yuttn |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
OOP โปรแกรมแรกของโผ้มมมม ม่ะรู้ถูกป่ะ พอดีอ่านหนังสือจาวาแล้วเอามาเขียน php (ปนกันแหลกลาน)
เขียนตามความเข้าใจอ่ะ ผิดถูกม่ะรู้โพสไว้ก่อน 555+
เดี๋ยวจะอ่านหนังสือต่อถ้าผมเข้าใจถูกจะมาโพสใหม่
Code (PHP)
<html>
<head>
<title>ทดลองการสร้าง OOP</title>
</head>
<body>
<?php
class showText
{
var $text;
function setText($txt1) {
$this->text = $txt1;
//ถ้าต้องการเรียกใช้แอตทริบิวต์จากภายในคลาส ให้ใช้ว่า $this->ชื่อแอตทริบิวต์;
}
function showSet() {
echo $this->text;
//ถ้าต้องการเรียกใช้แอตทริบิวต์จากภายในคลาส ให้ใช้ว่า $this->ชื่อแอตทริบิวต์;
}
function display() {
echo "ทดลองการเขียนโปรแกรมในแบบ OOP" . "<br>";
}
}
$box1 = new showText();
//การประกาศตัวแปรออบเจ็ค $ชื่อตัวแปรออบเจ็ค = new ชื่อคลาส;
$box1->display();
//ถ้าต้องการเรียกใช้แอตทริบิวต์จากภายนอกคลาสให้ใช้ว่า $ชื่อตัวแปรออบเจ็ค->ชื่อแอตทริบิวต์;
$box1->setText("ไรว้า");
//ถ้าต้องการเรียกใช้แอตทริบิวต์จากภายนอกคลาสให้ใช้ว่า $ชื่อตัวแปรออบเจ็ค->ชื่อแอตทริบิวต("อาร์กิวเมนต์");
$box1->showSet();
?>
</body>
</html>
ผลรัน
ทดลองการเขียนโปรแกรมในแบบ OOP
ไรว้า
|
 |
 |
 |
 |
Date :
2009-06-20 16:03:51 |
By :
maibon |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
ผมเพิ่งหัดเขียนแบบ oop เหมือนกันคับกำลัง งง อยู่เลย ไงผู้รู้ลองเขียนให้ผมดูมั่งได้ป่าวคับ...
แบบว่า่...รับค่า่มาจาก text field อ่ะคับ พอกด submit ให้แสดงเลขคี่จากค่าที่รับเข้ามาไล่ลงมาจนถึง 1 นะคับ...
ผมยังไม่รู้จะเขียนไงเลย..
เคยเขียนแบบฟังฃั่นอ่ะคับพอจะเริ่มเรียนรู้แบบ oop งงมากเลย ลองผู้รู้สอนหน่อยนะครับ...
|
 |
 |
 |
 |
Date :
2009-06-21 18:59:29 |
By :
olezajung |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
ขอบคุณครับ เป็นแนวทางที่ดี
|
 |
 |
 |
 |
Date :
2009-06-23 10:44:51 |
By :
pklangkua |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
Code (PHP)
<?php
require_once 'DB.php';
$user = 'root';
$pass = ' ';
$host = 'localhost';
$db_name = 'test';
$dsn = "mysql://$user:$pass@$host/$db_name";
$db = DB::connect($dsn);
if(DB::isError($db)){
die($db -> getMassage());
}
$sql = "select * from stu";
$result = $db -> query($sql);
if(DB::isError($result)){
die($result -> getMassage());
}
while($result -> fetchInto($row)){
$id = $row[0];
$name = $row[1];
$gpa = $row[2];
echo "$id \t $name \t $gpa <br>";
}
$sql = "INSERT INTO stu VALUES(4,'AuA',1.8,3)";
$result = $db -> query($sql);
//$result = $db -> query("insert into stu(sid,sname,sgpa,cid)values($id,'$name',$gpa,$cid)");
if(DB::isError($reult)){
die("inser error".$sesult -> getMassage()."\n");
}
$sql = "delete from stu where sid = $del";
$result = $db -> query($sql);
if(DB::isError($reult)){
die($result -> getMassage());
}
|
 |
 |
 |
 |
Date :
2009-06-23 13:58:27 |
By :
tuanau |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
ไม่รู้ว่าจะมีคนสนใจบะ
|
 |
 |
 |
 |
Date :
2009-06-23 13:59:23 |
By :
tuanau |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
กำลังศึกษา ครับ
งงเรื่อง การประกาศ พวก
static
private static
const
protected
public
$this->
ฯลฯ
ว่าใช้ อย่างไร มี ที่ศึกษา เพิ่ม เติม มั้ย ครับ  
|
 |
 |
 |
 |
Date :
2009-06-30 03:12:32 |
By :
madlyaek |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
ดีจัง การเขียน oop แต่เราอยากเริ่มต้องทำไงดี
|
 |
 |
 |
 |
Date :
2009-07-02 07:56:58 |
By :
kai9 |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
มีหนังสือสำหรับเรียน oop ไหมค่ะ แนะนำด้วยค่ะ
|
 |
 |
 |
 |
Date :
2009-07-02 07:57:51 |
By :
kai9 |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
เยี่ยมครับ
|
 |
 |
 |
 |
Date :
2009-07-06 12:59:46 |
By :
TTiger |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
เป็นปัญหามากคับ เรื่อง magic quote ตามที่คุณ num ได้บอกไว้ โดยเฉพาะ การเขียน กับ oop ถ้าเราได้เก็บ state ของ ข้อมูลในฐานข้อมูล เพราะเราต้องเอา slash เข้าออก บ่อยๆ ซึ่งโอเวอร์เฮดจริงๆ
ซึ่ง object ควรเก็บข้อมูลปรกติ ที่ไม่ได้ addslashes ไว้ด้วยซึ่งการแก้ปัญหา คือต้องเพิ่มโค้ดในโปรแกรมจำนวนมาก
แต่ตอนนี้ถ้าจะไปเซต php ให้ ปิดไป โปรเจกต์ที่อยู่ในระบบ ก็จะมีปัญหา และโปรเจกต์ของลูกค้ามันก็ควรเป็นไปตามมาตรฐานด้วย ซึ่งถ้าจะเขียนด้วย oop ทั้งระบบ ก็จะเป็นการเพิ่มต้นทุนด้านเวลา และการตรวจสอบมากขึ้นด้วย
ซึ่งปัญหานี้ควรได้รับการแก้ไข ซึ่งเราไม่สามารถปิด magic_quote_gpc ในขณะรันไทม์ได้ซะด้วย
ส่วนเรื่อง PDO มันก็ไม่ได้วิเศษวิโสอะไรหรอกนะครับ ผมลองใช้แล้ว ก็ไม่ได้มีฟีเจอร์ตามแต่ละดาต้าเบส
เหมือนแพ็คเกจ java.sql ของ Java ซึ่งให้เจ้าของดาต้าเบสเป็นผู้ implement เองเพียงแต่มี prepare statement ให้ใช้เท่านั้นเอง และต้องโค้ดมากขึ้นเกินจำเป็น
|
 |
 |
 |
 |
Date :
2009-07-15 11:26:00 |
By :
pjgunner |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
สำหรับหนังสือ เกี่ยวกะ OOP ของ PHP
ผมแนะนำ Insight PHP ฉบับสมบูรณ์ ของ provision คับ (ราคาปก 299)
เพราะอ่านแล้วรู้สึกว่าเข้าในง่ายดี ผมก็อ่านๆ งมๆ เอาเองก็พอจะรู้เรื่องมากขึ้นเพราะหนังสือเล่มนี้แหละครับ
อีกเล่มที่แนะนำคือ คู่มือเขียนโปรแกรมด้วยภาษา Java ของ provision อีกเช่นเคย (ราคาปก 149)
เล่มนี้อธิบายแนวคิดเกี่ยวกับ OOP ให้คนที่ไม่มีพื้น OOP เลยให้เข้าใจ OOP ได้
โดยความเห็นส่วนตัวแล้ว ผู้ที่ศึกษาด้วยตัวเอง หนังสือสองเล่มนี้ คงจะช่วยให้ท่านได้ เข้าใจและไม่กลัว OOP แน่นอน
|
 |
 |
 |
 |
Date :
2009-07-31 10:08:24 |
By :
maibon |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
ชอบ oop เหมือนกันครับ เท่าที่เคยเขียน php ตั้งแต่ 4,5,6 ก็รองรับการเขียนโปรแกรมแบบ oop ทุกเวอร์ชั่น แตกต่างก็จะมีบางคุณสมบัติของ oop ที่บางเวอร์ชั่นทำไม่ได้ เช่น การกำหนดระดับการเข้าถึงข้อมูล ถ้าเวอร์ชั่น 4 ก็จะเป็น public หมด แต่ถ้า 5-6 ก็จะเป็นได้ทั้ง public private ฯลฯ สำหรับคนที่จะหัด oop ผมแนะนำ javascrip ครับ ไม่ต้องเครียมการอะไรมาก ฝึกง่าย แสดงผลลัพธ์ง่าย ถึงจะไม่รองรับคุณสมบัติของ oop ทั้งหมดแต่ก็ได้หลักการของ oop พอสมควรเลยครับ
|
 |
 |
 |
 |
Date :
2009-07-31 23:14:39 |
By :
oointhai |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
อ่านะ เข้ามาดู ขอบคุณมากๆ เลยครับ
|
 |
 |
 |
 |
Date :
2009-08-12 18:57:57 |
By :
Sirichut |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
ขอบคุณมากๆครับที่ให้ความรู้
|
 |
 |
 |
 |
Date :
2009-08-13 15:17:28 |
By :
badkung04 |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
นี้หรือ OOP เดียวเอาไว้ก่อนดีกว่า ศึกษา PHP เอาตัวแปรให้มันเต็มที่ก่อนดีกว่าแล้วค่อยมาศึกษาตัวนี้ต่อไป
คนเก่งก็เก่งจริงๆคนโง่ก็โง่ได้ใจ หุหุหุหุ(คนโง่นั้นคือผมเองนะคับ)
|
 |
 |
 |
 |
Date :
2009-08-13 15:28:30 |
By :
somparn |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
เขียนเองพอถูๆ ไถ ๆ แต่ใช้ถนัดมากครับ oop เนี่ย หุ หุ
oop code ที่ผมใช้บริการบ่อย www.phpclass.org
ยากได้อะไร ก็สมัครสมาชิก แล้ว search เอานะครับ
ตอนนี้ที่ผมเอามาใช้งาน อยู่มีสองตัว
คือ class split page =>kgpager
class ajaxtableedit
ใช้เวิร์คดีครับ
|
 |
 |
 |
 |
Date :
2009-08-14 23:19:18 |
By :
DownsStream |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
อยากทำเว็บให้เก่งกว่านี้ คงต้องฝึกอีกนานเรยนะเรา ฮ่าๆๆ
|
 |
 |
 |
 |
Date :
2009-08-24 20:45:54 |
By :
gangzaclub |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
กะลัง จะเขียน function เป็น oop ก็มาอีก เฮ้อ จะตามทันไหมน้อ..
|
 |
 |
 |
 |
Date :
2009-08-27 12:59:51 |
By :
peak_z |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
คับผม ผมก็ไม่ได้เรียน หรือศึกษา javascript มามากนัก เพราะตัวเองก็เพิ่งใช้เป็นได้ไม่นาน
ผมก็ชอบมันตรงที่เป็นไดนามิคดี และอาจทำให้บางฟีเจอร์
ไม่ทราบคุณ oointhai พอมีตัวอย่างการใช้ feature OOP ที่ได้เกริ่นมาซัก อย่างละ 1 ตัวอย่างบ้างมั้ยคับ
จะเป็นพระคุณอย่างมาก 
|
 |
 |
 |
 |
Date :
2009-08-29 07:57:11 |
By :
pjgunner |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
ผมขอยกตัวอย่าง Polymorphism นะครับ ตัดมาจากเว็บอ้างอิง
Code (PHP)
/* Polymorphism. */
/* Class. */
function Shape( ) {
this.getArea = function( ) {
};
}
/* Class inherit from Shape. */
function Circle( radius) {
this.radius = radius ;
}
Circle.prototype = new Shape( ) ;
/* Overriding. */
Circle.prototype.getArea = function( ) {
return 3.141 * this.radius * this.radius ;
}
/* Class inherit from Shape. */
function Rectangle( width , height ) {
this.width = width ;
this.height = height ;
}
Rectangle.prototype = new Shape( ) ;
/* Overriding. */
Rectangle.prototype.getArea = function( ) {
return this.width * this.height ;
}
/* new instance. */
var oCircle = new Circle( 2 ) ;
var oRectangle = new Rectangle( 2 , 2 ) ;
/* ทดสอบ object คนละชนิดใน array โดยเรียก getArea(). */
var list = new Array( ) ;
list[ 0 ] = oCircle ;
list[ 1 ] = oRectangle ;
for( var i = 0 ; i < list.length ; i++ ){
var oShape = list[ i ] ;
document.write( oShape.getArea( ) + '<br>') ;
}
// Result
12.564
4
ที่มา : http://www.oop-programming.net
|
 |
 |
 |
 |
Date :
2009-08-29 10:10:12 |
By :
oointhai |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
คับ language feature มันมีก็จริงแต่เราต้องมาทำเอง (ไม่ชอบ keyword 'function')
ถ้าจะให้ผมเรียน oop ผมก็ไม่เลือก javascript อยู่ดีคับ มีแค่บางฟีเจอร์ ลิงค์ที่เกี่ยวข้อง
ปล. ควรใช้ instanceof ด้วยนะครับ
แล้ว Encapsulation ล่ะครับ
|
 |
 |
 |
 |
Date :
2009-08-29 11:57:12 |
By :
pjgunner |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
encapsulation ตามที่ผมเข้าใจจากการเขียนโปรแกรม ก็คือกลไกของภาษาในการเก็บสารสนเทศที่เกี่ยวข้องกันเข้าไว้ด้วยกันใน object ซึ่งถ้ามองในเรื่องของ oop ก็คือกลไกของภาษาในการเก็บ property และ method ที่เกี่ยวข้องกันเข้าไว้ด้วยกันใน object ซึ่งถ้าตามความเข้าใจของผม ถ้าดูจาก code ที่ผ่านๆมา ก็จะสามารถมองเห็นการทำ encapsulation ของภาษา php ซึ่งทำการ encapsulate โดยใช้ class เช่นเดียวกับภาษาระดับสูงทั่วๆไปอย่าง java ,c++ ,c# ฯลฯ ส่วนภาษา javascript ก็ใช้ function หรืออีกภาษาที่หันมารองรับ oop อย่าง vb.net ก็ใช้ module หรือ class ก็ได้ โดยส่วนตัวผมสนใจ oop โดยไม่ได้ยึดติดกับภาษาใดภาษาหนึ่ง เพราะผมเองที่หากินกับการเขียนโปรแกรมคงไม่มีความสามารถไปเปลี่ยนแปลงกลไกของภาษาต่างๆที่รองรับ oop หากแต่ต้องก้มหน้าก้มตาศึกษาภาษาต่างๆตาม job ที่เข้ามา ตอนนี้ก็มี oop บน rubby มาอีกภาษาหนึ่ง ซึ่งมีรูปแบบการสืบทอดคลาสโดยใช้เครื่องหมาย < แทน extends ผมเองก็คงจะปฏิเสธรูปแบบของภาษาเค้าไม่ได้ เพราะไม่งั้นโปรแกรมก็คงทำงานไม่ได้
สุดท้ายผมก็ขอให้ทุกท่านใช้ oop กับภาษาที่ท่านถนัด แล้วก็สามารถใช้ concept ของ oop กับภาษาอื่นๆที่จะต้องใช้โดยหลีกเลี่ยงไม่ได้ครับ
|
 |
 |
 |
 |
Date :
2009-08-29 13:06:09 |
By :
oointhai |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
คับผม ผมก็มอง ruby อยู่ครับ ตัวภาษามันเป็น strong dynamic ดี ถึงแม้จะใช้เครื่องหมาย < มันก็มีความหมายเดียวกัน ความจริงแล้วผมก็ไม่เคยสร้างคลาสแบบ ใช้คีย์เวิร์ด function ใน js หรอกครับ ก็เพิ่งเคยเห็นเหมือนกัน
ปรกติก็ใช้ {} ตัวอย่าง ซึ่งมันก็เป็นคล้าย associative array ที่มี property เป็น method ได้ เวลาจะสืบทอดก็ใช้ jQuery.extend() เอาถึงแม้ว่าจะใช้ instanceof ไม่ได้
การใช้เพียงแค่ class ของภาษา oop ต่างๆ ตามความคิดเห็นของผมมันไม่ได้ถือว่าเป็น(หรือใช้ประโยชน์ได้เต็มที่) oop ครับเพราะมันไม่ได้มีประโยชน์มากนักในการพัฒนาโปรแกรม ผมว่า oop มันมีประโยชน์ในกรณีที่
1. สร้างเครื่องมือที่สามาถ เพิ่ม เปลี่ยนแปลงการทำงานในรายละเอียดภายหลังได้(ใช้กับงานได้หลายประเภท)
2. ทำระบบที่สามารถ เพิ่มเติม ถอดออก เปลี่ยนแปลง ได้ตามธุรกิจและผู้ใช้ได้ง่าย(สร้างซอฟต์แวร์ที่สามารถแข่งขัน ได้เร็วโดยไม่ต้องเริ่มพัฒนาใหม่)
3. สร้างต้นแบบ ให้คนอื่นไปพัฒนาต่อได้หลายคน และเอามาประกอบกันได้ง่าย
ความจริงแล้วการออกแบบโปรแกรมให้เป็น oop มีต้นทุนสูงคือ
1. ใช้เวลาศึกษาวิถีทางเขียนโปรแกรมแบบ oop นานกว่า แบบทั่วไป
2. ใช้เวลาในการออกแบบ นาน
3. ใช้เวลาในการศึกษารูปแบบ นาน สำหรับคนที่เอาไปพัฒนาต่อ(จึงมี pattern ยังไม่ได้เรียนเหมือนกัน)
4. ทำงานช้ากว่าการเขียนแบบทั่วไป
ดังนั้นถึงแม้ผมจะเขียนโปรแกรมแบบ oop ได้คล่อง ผมก็ยังจำเป็นต้องตัดสินใจว่าจะใช้ในโปรเจกต์ไหน หรือส่วนไหนของโปรเจกต์ เพราะว่ามันไม่ได้ทำให้ผลงานเป็นไปอย่างที่ผมต้องการเพียงแต่มันทำให้รูปแบบการพัฒนาและปรับปรุงเป็นไปอย่างที่ผมต้องการ โดยเฉพาะระบบที่ค่อนข้างใหญ่แล้ว แล้วต้องมีการแข่งขันตลอดผมก็ต้องใช้มันถึงแม้ว่ามันจะไม่ได้ช่วยเรื่อง GUI มากนักก็ตาม
อย่าไปใช้มันเพราะว่ามันเท่ห์ แต่ควรใช้กับงานที่จำเป็นต้องใช้มันจริงๆ
สำหรับคนที่อยากจะศึกษา "รู้ไว้ใช่ว่า"
แนะนำให้ศึกษาในภาษาที่มันค่อนข้างบังคับ ครับ เช่น Java
และ php ตอนนี้ก็มีฟีเจอร์ พอควรแก่การศึกษาเช่นกัน
ปล. ผมเพิ่งเขียน javascript เป็นเมื่อปีเศษนี้คับ
|
 |
 |
 |
 |
Date :
2009-08-29 17:59:56 |
By :
pjgunner |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
แง่มๆ เพิ่งลองเขียน javascript แบบ OOP ง่ะ
<script type="text/javascript">
//ref: http://amix.dk/blog/viewEntry/19038
var AJS = {
update: function(l1, l2) {
for(var i in l2)
l1[i] = l2[i];
return l1;
}
}
AJS.Class = function(members) {
var fn = function() {
if(arguments[0] != 'no_init') {
return this.init.apply(this, arguments);
}
}
fn.prototype = members;
AJS.update(fn, AJS.Class.prototype);
return fn;
}
AJS.Class.prototype = {
extend: function(members) {
var parent = new this('no_init');
for(k in members) {
var prev = parent[k];
var cur = members[k];
if (prev && prev != cur && typeof cur == 'function') {
cur = this._parentize(cur, prev);
}
parent[k] = cur;
}
return new AJS.Class(parent);
},
implement: function(members) {
AJS.update(this.prototype, members);
},
_parentize: function(cur, prev) {
return function(){
this.parent = prev;
return cur.apply(this, arguments);
}
}
}//end AJS.Class
Shape = AJS.Class({
name: 'Shape',
init: function(name){
if (typeof name == 'string'){
this.name = name;
}
},
getArea: function(){
return 0;
},
getAreaMessage: function(){
return this.name + ' area = ' + this.getArea();
}
});
Circle = Shape.extend({
init: function(radius){
this.parent('Circle');
this.radius = radius;
},
getArea: function(){
return Math.PI * this.radius * this.radius;
}
});
Rectangle = Shape.extend({
init: function(width,height){
this.parent('Rectangle');
this.width = width;
this.height = height;
},
getArea: function(){
return this.width * this.height;
}
});
window.onload = function(){
var p0 = new Shape();
var p1 = new Circle(10);
var p2 = new Rectangle(10,20);
alert(p0.getAreaMessage());
alert(p1.getAreaMessage());
alert(p2.getAreaMessage());
}
</script>
ref : เขียน Javascript แบบ OOP โดยใช้ AJS.Class
|
 |
 |
 |
 |
Date :
2009-10-05 12:05:06 |
By :
num |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
ว่าแต่ AJS นี่ย่อมาจากอะไรคับ อ่านดูคลาส AJS แล้วงงเต๊ก
แต่ตอนใช้ ก็ดูดีมาก เกือบสะดวกเหมือน OOP จากภาษาอื่นเลย และมีคอนสครัคเตอร์ให้ใช้ แถมเรียกคอนสตรัคเตอร์ของคลาสแม่ได้ด้วย 
ว่าแต่คุณสมบัติอื่นๆ มีอะไรขาดไปมั่งป่าวคับ
|
 |
 |
 |
 |
Date :
2009-10-05 13:15:52 |
By :
pjgunner |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
หุหุ ผมก็อยากเขียน แบบ OOP เหมือนกันครับ เพราะอนาคตการพัฒนาจะได้ง่ายและสะดวก ตอนนี้ก็เพิ่งจะลองหัดเขียนเว็บ php ครับ
กำลังศึกษาอยู่ครับ ก็ได้โค๊ดจากเว็บนี้ล่ะครับเป็นแนวทางให้ผลงานออกมาได้ ยังไงก็จะพยายามมาก ๆ ครับอยากเป็น pro 
|
 |
 |
 |
 |
Date :
2009-10-05 15:14:36 |
By :
cshunter |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
ผมชอบเข้ามาอ่านที่นี่ครับ
เด็กเยอะดีครับ ชอบดูเด็กโชว์ภูมิกันครับ
ไว้วันหน้าจะเอางานแบบที่เป็นผู้ใหญ่ๆมาให้ชมกันนะครับ
|
 |
 |
 |
 |
Date :
2009-10-07 14:00:24 |
By :
เอาใจช่วยเด็กๆ |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
ชอบ rep 106 ครับ
ผู้ใหญ่อะไรชอบแอบดูเด็ก สงสัยแอบดูมานานละ
ว่าแต่ว่าจะเอางานมาให้ชม อย่าไปก้อบของผู้ใหญ่ด้วยกันมาให้นะครับ เดี๋ยวเด็กจะนิสัยเหมือนผู้ใหญ่ บางคน
หรือว่าผู้ใหญ่จะนิสัยเหมือนเด็ก (ชอบโชว์ภูมิ)
|
 |
 |
 |
 |
Date :
2009-10-07 17:27:34 |
By :
pjgunner |
|
 |
 |
 |
 |
|
|
 |
 |
|
 |
 |
 |
|
|
 |
 |
|
55555555555
ผมชอบเลี้ยงเด็กก๊าบ
|
 |
 |
 |
 |
Date :
2009-10-07 22:30:10 |
By :
somparn |
|
 |
 |
 |
 |
|
|
 |
| | |