|
|
|
อยากเขียนแบบ MVC โดยไม่ใช้เฟรมเวิร์คทำได้ไหมครับ ไม่รู้ว่าต้องออกแบบยังไงบ้างอ่ะครับ |
|
|
|
|
|
|
|
ถ้ามีความเข้าใจ ใน MVC และความสามารถในการเขียนแบบ OOP อยู่แล้ว ก้อไม่จำเป็นต้องใช้ Framework ก้อได้คับ
|
|
|
|
|
Date :
2010-06-03 00:35:26 |
By :
kerb |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ควรจะหัดเขียน framework ที่มีอยู่ทั่วไปสัก 2-3 framework ครับก่อนจะเขียนด้วยตัวเอง
จะได้ความรู้อีกมหาศาลเลยครับ
|
|
|
|
|
Date :
2010-06-03 08:25:31 |
By :
num |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ควรจะหัดเขียน framework ที่มีอยู่ทั่วไปสัก 2-3 framework ครับก่อนจะเขียนด้วยตัวเอง
จะได้ความรู้อีกมหาศาลเลยครับ
-อันนี้หมายถึงความรู้ของเฟรมเวิร์ค หรือความรู้อะไรเหรอคับ เพราะตอนนี้ผมรู้สึกสับสนมากกว่าจะออกแบบอย่างไรดี เพราะศึกษามาหลายเว็บเหลือเกิน อีกทั้งหนังสืออีก ผมว่าเขียนก็พอเขียนได้อยู่ แต่การออกแบบนี่สิครับ
|
|
|
|
|
Date :
2010-06-03 09:22:30 |
By :
bier |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ถ้ายังออกแบบไม่ได้ ให้ศึกษาจาก framework ที่มีอยู่แล้วดูก่อนก็ได้ครับ จะได้พอรู้แนวทาง
|
|
|
|
|
Date :
2010-06-03 09:33:59 |
By :
kerb |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
อยากเขียนเอง ก็เขียนไปตาม หลักการของ mvc ครับ
สร้าง rounter ขึ้นมาเพื่อ เลือกสรร controller
คอนโทรลเลอร์ ตรวจสอบข้อมูล และดึงข้อมูลจาก model
เอาข้อมูลที่ได้จาก model ส่งให้ view
controller ส่งวิว ไปที่ client
แค่นี้คับ วิธีการออกแบบก็ขึ้นอยู่กับคุณ มันไม่ตายตัวครับ แต่วิธีง่ายๆ ก็เขียนคล้ายในเฟรมเวอร์คคับ
ผมก็ใช้ mvc ในเว็บครั้งแรกเหมือนกัน รู้สึกสับสนตรงที่ไดเรคทอรี่กับชื่อไฟล์อ่ะ คราวหน้าคิดว่าจะหาวิธีมาแก้นะ ^^
ปัญหา เช่น (ไฟล์ใน directory)
controller/user.php
model/user.php
view/user.php
บางทีมัน ชื่อคล้ายกัน เวียนหัวฉิบเป๋ง เลย บางทีกดผิดกดถูก จะดูไฟล์คอนโทรลเลอร์ ต้องคลิกหลายทีเลย กรรมจริง
ทำเวียนหัว
แนะนำให้ใช้เฟรมเวอร์คคับ เพราะมันมีฟีเจอร์ดีๆ ที่มากกว่าแค่ mvc มีทั้ง router และ helper และ module ต่างๆ ให้เลือกใช้
ปล. ผมใช้ kohana นะ
ข้อดีของมันก็มีอยู่ เช่นการเขียนให้ strong มากขึ้น ปรกติ php ก็ทำได้ แต่เฟรมเวอร์คผมมันก็บังคับ
เช่น ตัวแปรที่ยังไม่มีค่า จะไม่สามารถใช้ได้ ต้องประกาศก่อน ช่วยให้ลดความเสี่ยงที่จะใช้ค่าเดิมที่มีอยู่ กรณีที่มีโค้ดเยอะ ช่วยให้เขียนโปรแกรมใหญ่ๆ ได้ง่ายขึ้น
และ scope variable ช่วยให้ตัวแปร ในไฟล์ไหน ก็อยู่ในไฟล์นั้น ไม่เหมือนกับ include เข้ามา ทำให้ตัวแปร อาจมีค่าที่ไม่ตรงกัน หรือเป็นอีกตัวแปรของอีกไฟล์
อืม ส่วน พวก dynamic language ที่ weak อย่าง php มักไม่เขียน getter, setter หรอกคับ โค้ดยาวเปล่าๆ ใช้ไปเลย
getter ex: $var = $ins->var1;
setter ex: $ins->var1 = $var;
ถ้ามัวแต่นั่งเขียน getter และ setter มันก็จะช้ามาก เหมือน java
ไม่เหมือนใน ruby ที่ใช้ getter,setter อย่างเดียวในการ access variable และโค้ดแค่บรรทัดเดียวจัดการได้ทั้งคลาส
ผมคิดว่า mvc ในเว็บที่ เว็บเฟรมเวอร์คทั่วๆไปใช้ มันเทียบไม่ได้กับ swing ใน java หรอกคับ ถ้าทำอย่างนั้น มันจะอืดและไม่มีความจำเป็นด้วยคับ
ปล. ผมว่าเขียนแบบธรรมดา งานเสร็จเร็วกว่าเยอะคับ แต่เขียนใช้เฟรมเวอร์คก็เน้น เมนเทรนยาวได้ดี
|
|
|
|
|
Date :
2010-06-03 09:46:06 |
By :
pjgunner |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
m
1) ระดับ escape ข้อมูลป้องกัน injection
2) ระดับ data abstract layer (เขียนแบบเดียวต่อได้หลาย dbms)
3) ระดับ orm เขียนในรูปเชิง object
4) มีการ validation แทรกข้อมูลการ validation ลงไปใน model หรือไม่
v
1) เน้นโปรแกรมแบบนำกลับมาใช้ใหม่กลุ่ม helper ช่วย render
หรือเน้น design เน้น view ดีไซน์ใน dream ได้ แต่อาจจะต้องเขียนใหม่
2) มีการแบ่งเป็น layout และ view หรือไม่
3) มีการแทรก sub view ได้หรือไม่
c
1) มีการ route url ไปยัง action แบบปกติ
2) มีการ route url ไปยัง action method ใน class
3) มีการป้องกันการเข้าถึง private method
4) มีการเปลี่ยนแปลง layout และ view ได้
5) สามารถแทรกคำสั่ง beforeAction, afterAction
concept ทั่วๆ ไปน่ะครับ ตอนแรกต้องวาง concept ให้แน่ชัดก่อนครับว่าต้องการอะไรบ้าง
ไม่งั้นเขียนนานและอาจจะต้องแก้ซ้ำครับ เลยอยากให้ไปดู framework ต่างๆ ก่อนน่ะครับ
ว่าเค้ามีโครงสร้างที่ช่วยเขียนโปรแกรมอะไรบ้าง เพื่อจะได้เลือกเอาอันที่สำคัญๆ มาออกแบบครับ
อีกอย่างหนึ่ง ทีมที่เขียน framework เค้าเขียนแบบเทพจริงๆ
จะได้ syntax และคำสั่งและวิธีการเขียนโปรแกรมใหม่ๆ เพิ่มขึ้นเยอะครับ
|
|
|
|
|
Date :
2010-06-03 09:57:57 |
By :
num |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ขอบคุณทุกความเห็นครับ แต่ที่ผมทำอยู่ตอนนี้คือเลียนแบบโปรเจค jsp ของรุ่นพี่เลยว่ามีไฟล์อะไรบ้าง แต่ละไฟล์ทำหน้าที่อะไร เพราะเห็นว่า jsp กฌ็เรียนกใช้คลาส servlet เหมือนกัน ผมก็เอา servlet นั้นมาแทนโดยเป็นไฟล์ controller ของผมไป ประมาณนั้นครับ
และปกติที่หันไปใช้เฟรมเวิร์คก็คือต้องการให้โปรเจคเสร็จเร็ว โค้ดดิ้งน้อย แ ต่ผมว่าผมพอจะมีเวลาที่จะคิด ออกแบบ และเขียนโค้ดด้วยตัวเอง เพราะในเมื่อผมลาออกจากที่ทำงานในวันข้างหน้า ก็จะมีคนเข้ามาแก้ของผมโดยที่ไม่ต้องมานั่งศึกษาเฟรมเวิร์คอีก
ปล ผมอยากรู้ว่าคนที่ใช้เฟรมเวิร์คจำเป็นต้องชำนาญในภาษานั้นๆทมาก่อนแล้วหรือไม่ครับ เพราะอีกความคิดนึงที่มันขัดแย้งกันก็คือ คนที่เขียนไม่เป็น แต่ต้องการศึกษาในระยะเวลาสั้นๆอ่ะครับ ก็เลยศึกษามันขึ้นมา
|
|
|
|
|
Date :
2010-06-03 10:04:11 |
By :
bier |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ขอบคุณคุณ num ครับ
ผมก็มีปัญหา ลองผิดลองถูก ไม่รู้ ว่าเอาไปไว้ไหนดี ในบางกรณี
เช่น validation นี่ ควรเอาไปไว้ใน model เหรอคับ(ตามที่ คุณ num บอก) แต่ผมเอาไปไว้ใน controller เพราะคิดว่ามันสะดวกกว่า ถ้าผิดก็ไม่ต้องส่งไปที่ model
และก็ยังมีปัญหา จิปาถะ ที่ยังหาวิธีแก้แบบว่า แก้ให้เข้าใจและเป็นมาตรฐาน(ในการเขียนต่อไป)อีก หลายอย่าง
ปล. เฟรมเวอร์ที่ผมใช้ตอนนี้เป็น HMVC แล้ว ^^ สุดหรู เฟรมเวอร์คผมก็เจ๋งตรงนี้
ปล. เฟรมเวอร์คดีนะคับ ยังมี controller template ให้ด้วย ประโยชน์และวิธีการใช้งาน เยี่ยมไปเลย
|
|
|
|
|
Date :
2010-06-03 10:15:50 |
By :
pjgunner |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ไม่ทราบว่าผมจะขอโค้ดเฟรมเวิร์คของคุณ pjgunner ได้ไหมครับ อยากเอามาศึกษาดูน่ะครับ
|
|
|
|
|
Date :
2010-06-03 10:21:29 |
By :
bier |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ตอบ No.7
ผมว่าการอ่านโค้ดคนอื่น ที่ง่ายที่สุดก็ โค้ดธรรมดาคับ(ไม่ใช้ oo) เพราะมันตรงไปตรงมาตามบรรทัด
ส่วนการอ่านโค้ด โดยที่โค้ดนั้นใช้หลักการและ oo ด้วยนั้น มันยากสำหรับคนทั่วไปคับ เพราะต้องรู้ ทฤษฎีการทำงาน และการออกแบบของผู้เขียนก่อน
สำหรับ ใช้เฟรมเวร์คแล้วโปรเจกต์เสร็จเร็วเหรอ อืม
ตอนนี้ผมยังไม่ชำนาญ คิดว่ามันช้ากว่าหลายเท่าคับ และยังคิดว่าอีก 5-6 โปรเจกต์ถัดไปที่ใช้เฟรมเวอร์คยังคงช้ากว่าเขียนแบบ simple คับ (ถึงจะเป็นโปรเจกต์ข้อนข้างใหญ่ ที่เฟรมเวิร์คได้เปรียบ) ทั้งนี้ขึ้นอยู่กับความง่ายของเฟรมเวิร์คตัวนั้นๆ เพราะเฟรมเวิร์คบางตัวก็ไม่ใช่ mvc คิดว่าอาจเขียนได้เร็วมากๆ
คำถามสุดท้ายอันนี้ผมก็ไม่แน่ใจ ผมว่าขึ้นอยู่กับเอกสาร ประกอบของเฟรมเวอร์คด้วยนะ ถ้าเอกสารดีๆ มือใหม่สำหรับภาษานั้นๆ ก็คงจะศึกษาได้ไม่ยากมากนัก
|
|
|
|
|
Date :
2010-06-03 10:31:00 |
By :
pjgunner |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ตอบ No. 9
โค้ดผมให้ไม่ได้หรอกคับ (โปรเจกต์แรกของผมที่ใช้เฟรมเวิร์ค เอาไปอ่านก็ไม่รู้เรื่องหรอก เพราะผมยังไม่ได้ใช้ความสามารถของมันได้เต็มที่ และยังมีปัญหาด้านวิธีการต่างๆ ที่ต้องหาวิธีแก้อีก) แต่ให้ตัวอย่างได้คับ(บางหน้าง่ายๆ หลักการ mvc ทั่วไป เอาหน้าหนึ่งในหลังร้านละกัน)
คอนโทรลเลอร์ เทมเพลต
<?php defined('SYSPATH') or die('No direct script access.');
class Controller_Manage_ManageTemplate extends Controller_Template
{
public $template = 'templates/manage';
public $head_data = array();
public function before()
{
parent::before();
if ( ! User::is_admin())
{
$this->request->redirect(URL::site('manage/hahaha'));
}
if ($this->auto_render)
{
$this->template->title = '';
$this->template->meta_keywords = '';
$this->template->meta_description = '';
$this->template->favicon = array(
'href' => URL::base().'assets/image/icon.ico',
'type' =>'image/png'
);
$this->template->body = '';
$this->template->styles = array();
$this->template->scripts = array();
}
}
public function after()
{
if ($this->auto_render)
{
$styles = array(
'assets/css/manage.css' => 'screen',
'assets/css/blueprint/ie.css' => 'screen',
'assets/css/blueprint/print.css' => 'print',
'assets/css/blueprint/screen.css' => 'screen',
);
$scripts = array(
'assets/js/default.js',
'assets/js/jquery-1.4.2.min.js',
);
$this->template->styles = array_reverse(array_merge($this->template->styles, $styles));
$this->template->scripts = array_reverse(array_merge($this->template->scripts, $scripts));
parent::after();
}
User::add_admin_cookie_time();
}
}
ตัวคอนโทรลเลอร์ จริง
<?php defined('SYSPATH') or die('No direct script access.');
class Controller_Manage_EmployContact extends Controller_Manage_ManageTemplate
{
public function action_index()
{
$this->template->title = 'PJGUNNER Management System: Employ & Contact';
$this->template->body = View::factory('manage/employcontact')
->set('employ_list', Request::factory('manage/employcontact/employlist')->execute()->response)
->set('contact_list', Request::factory('manage/employcontact/contactlist')->execute()->response);
}
public function action_employlist()
{
$model = new Model_Manage_EmployContact;
$this->request->response = View::factory('manage/employlist')
->set('employs', $model->get_employs());
$this->auto_render = FALSE;
}
public function action_contactlist()
{
$model = new Model_Manage_EmployContact;
$this->request->response = View::factory('manage/contactlist')
->set('contacts', $model->get_contacts());
$this->auto_render = FALSE;
}
public function action_employinfo($id)
{
$model = new Model_Manage_EmployContact;
$data = $model->get_employinfo($id);
if ( ! empty($data))
{
$this->request->response = View::factory('manage/employinfo', $data[0]);
$model->set_red_employ($id);
}
$this->auto_render = FALSE;
}
public function action_contactinfo($id)
{
$model = new Model_Manage_EmployContact;
$data = $model->get_contactinfo($id);
if ( ! empty($data))
{
$this->request->response = View::factory('manage/contactinfo', $data[0]);
$model->set_red_contact($id);
}
$this->auto_render = FALSE;
}
}
โมเดล
<?php defined('SYSPATH') or die('No direct script access.');
class Model_Manage_EmployContact extends Kohana_Model
{
public function get_employs()
{
$sql = "SELECT * FROM employ ORDER BY employ_id DESC";
return $this->_db->query(Database::SELECT, $sql, FALSE)
->as_array();
}
public function get_contacts()
{
$sql = "SELECT * FROM contact ORDER BY contact_id DESC";
return $this->_db->query(Database::SELECT, $sql, FALSE)
->as_array();
}
public function get_employinfo($id)
{
$sql = sprintf(
"SELECT * FROM employ ".
"WHERE ".
"employ_id = %d",
(int) $id
);
return $this->_db->query(Database::SELECT, $sql, FALSE)
->as_array();
}
public function set_red_employ($id)
{
$sql = sprintf(
"UPDATE employ ".
"SET ".
"employ_status = 1 ".
"WHERE ".
"employ_id = %d",
(int) $id
);
return ($this->_db->query(Database::UPDATE, $sql, FALSE) > 0)
? TRUE
: FALSE;
}
public function get_contactinfo($id)
{
$sql = sprintf(
"SELECT * FROM contact ".
"WHERE ".
"contact_id = %d",
(int) $id
);
return $this->_db->query(Database::SELECT, $sql, FALSE)
->as_array();
}
public function set_red_contact($id)
{
$sql = sprintf(
"UPDATE contact ".
"SET ".
"contact_status = 1 ".
"WHERE ".
"contact_id = %d",
(int) $id
);
return ($this->_db->query(Database::UPDATE, $sql, FALSE) > 0)
? TRUE
: FALSE;
}
}
วิว หลัก(มีวิวย่อยหลายอันเพราะเป็น ajax)
<div id="body-section">
<h3>Employ & Contact</h3>
<div class="span-7 colborder">
<div class="border-all round-border">
<div class="subhead">Employ</div>
<ul class="employ">
<?php echo $employ_list;?>
</ul>
</div>
<br />
<div class="border-all round-border">
<div class="subhead">Contact</div>
<ul class="contact">
<?php echo $contact_list;?>
</ul>
</div>
</div>
<div id="display-content" class="span-16 last">
<h3>Please select one.</h3>
</div>
</div>
<script type="text/javascript">
var loading = '<h3>loading..</h3>';
$(document).ready(function()
{
$('a[employ_id]').click(function()
{
var this_element = this;
var uri = '<?php echo URL::site('manage/employcontact/employinfo');?>' + '/' + $(this).attr('employ_id');
$('#display-content')
.html(loading)
.load(uri, function(text, text_status, xhr)
{
if (text_status == 'error')
{
$(this).html('<h3>Load error. Try again.</h3>' + 'Status: ' + xhr.status)
.css('cursor', 'pointer')
.click(function()
{
$(this_element).click();
});
}
});
});
$('a[contact_id]').click(function()
{
var this_element = this;
var uri = '<?php echo URL::site('manage/employcontact/contactinfo');?>' + '/' + $(this).attr('contact_id');
$('#display-content')
.html(loading)
.load(uri, function(text, text_status, xhr)
{
if (text_status == 'error')
{
$(this).html('<h3>Load error. Try again.</h3>' + 'Status: ' + xhr.status)
.css('cursor', 'pointer')
.click(function()
{
$(this_element).click();
});
}
});
});
});
</script>
ตย. วิวย่อย ที่ใช้ใน ajax เอามาให้ดูอันนึง
<h3>Employ Info: #<?php echo $employ_id;?></h3>
<p class="about-info">
<strong>Date</strong>: <?php echo $employ_datetime;?><br />
<strong>By</strong>: <?php echo $employ_name;?><br />
<strong>Contact</strong>: <?php echo Text::auto_link($employ_contact);?><br />
<strong>Type</strong>: <?php echo $employ_type;?><br />
<strong>Attach file</strong>: <?php echo is_null($employ_file) ? 'None' : HTML::anchor(URL::site('employ_file/'.$employ_file), 'Download');?>
</p>
<p><?php echo Text::auto_p(Text::auto_link($employ_detail));?></p>
ปล. ผมยังใช้ พวกโมดุลยังไม่เป็นเลย เลยเขียนง่ายๆ
นี่ครับเว็บเฟรมเวิร์ค http://kohanaframework.org/
นี่ ครับ เว็บเอกสาร(unofficial เพราะเป็นเวิร์ชั่นใหม่แกะกล่อง เขียนใหม่หมดไม่เอาของเก่ามาพัฒนา) http://kerkness.ca/wiki/doku.php
|
|
|
|
|
Date :
2010-06-03 10:49:36 |
By :
pjgunner |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ขอบคุณคุณ pjgunner ครับ ผมดูแล้วสงสัยมานานว่า บรรทัด Code (PHP)
<?php defined('SYSPATH') or die('No direct script access.');
มันคืออะไรเหรอครับ
|
|
|
|
|
Date :
2010-06-03 10:52:51 |
By :
bier |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
คือไม่ให้เข้าได้โดยตรงคับ (ถึงจะใช้รีไรท์โหมดแล้ว และไม่ใช้ไม่ได้) คือไฟล์จะถูก เรียกจาก auto_load() ก็คือมันถูก include ได้เท่านั้นครับ เพราะไฟล์หลักได้ ประกาศค่าคงที่ SYSPATH ไว้ครับ จริงๆ ไม่จำเป็นหรอกคับ มันเป็นเหตุผลด้านซีเคียวริตี้ เล็กน้อย กันโฮสไม่เปิด รีไรท์โหมดมั้ง
|
|
|
|
|
Date :
2010-06-03 11:01:19 |
By :
pjgunner |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
auto_load() นี่คือไรอ่ะคับ
|
|
|
|
|
Date :
2010-06-03 11:08:24 |
By :
bier |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
คือโหลดอัตโนมัติ ครับ จริงๆ เฟรมเวิร์คนี้ไม่ได้ใช้ __autoload() แต่ใช้ spl_autoload()
ลองหาโหลดโค้ดเฟรมเวิร์คมาดูได้คับ
จะพูดง่ายๆ มันก็คือ การค้นหาไฟล์ ที่มีคลาสนั้นอยู่คับ คือเราไม่ต้อง include แต่เฟรมเวิร์คมันจัดการค้นหาตำแหน่งไฟล์ให้เอง เพราะ ไฟล์คลาส มัน 1 คลาส ต่อ 1 ไฟล์ และมี convension การวางชื่อไฟล์กับไดเรคทอรี่ อ่านได้ในเอกสารที่บอกคับ
|
|
|
|
|
Date :
2010-06-03 11:16:24 |
By :
pjgunner |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
มีหนังสือ cackphp ที่เป็นไทย ขายไหมครับ
|
|
|
|
|
Date :
2010-06-03 11:19:02 |
By :
ความรู้เท่าหางอึ่ง |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
อืมน่าสนอ่ะครับ แล้วถ้าผมไม่ใช่เฟรมเวิร์คผมสามารถทำได้ไหมแบบไม่ต้อง include อะไรประมาณนี้อ่ะครับ ขอบคุณครับ
|
|
|
|
|
Date :
2010-06-03 11:22:29 |
By :
bier |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<?php
class xxx {
function x{
}
}
?>
ก้อเป็นเหมือน 1 C ที่มีฟังชั่นต่างอยู่ภายในใช่ป่ะคับ
|
|
|
|
|
Date :
2010-06-03 11:26:05 |
By :
ความรู้เท่าหางอึ่ง |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Load balance : Server 00
|