ความคืบหน้า PHP Hoffman Framework (3)

จากตอนที่แล้ว ความคืบหน้า PHP Hoffman Framework (2) ได้ปรับเปลี่ยนการ config จาก ini มาเป็น array ใน php แทนแล้ว ได้ทำการปรับ routing จากตั้งใน xml มาเป็น array ใน php เช่นกัน ทำให้ลดเวลาในการ parse ข้อมูลได้

เป็นแบบนี้ครับ

$Rounting['keywords'] = array(
    ':controller' => '[a-zA-Z][a-zA-Z0-9_\-]*', // Default
    ':action' => '[a-zA-Z][a-zA-Z0-9_\-]*' // Default
);

$Rounting['map'] = array(
    'login' => 'user/login',
    'userdetail' => 'user/detail',
    ':controller/:action' => null // Default
);

เหตุผลต่อมาในการทำแบบนี้เพราะ เราสามารถนำไปทำ cache ได้ง่ายขึ้นด้วยครับ

หลาย ๆ คนถามมาว่าทำไมเปลียนแปลงส่วน config ใหม่ ทั้ง ๆ ที่น่าจะดีอยู่แล้ว เหตุผลง่าย ๆ ก็คือลดการประมวลผลที่ไม่จำเป็นในการประมวลผลส่วนการตั้งค่าระบบไปซะ อีกอย่าง array ใน php ก็ทำความเข้าใจไม่ยากนัก ทำให้การปรับมาใช้ไม่ทำให้สวยความง่ายลงไปครับ

อาจจะทำ tools สำหรับ generate ตัว routing ด้วยก็ไม่ยากนักครับ

ความคืบหน้า PHP Hoffman Framework (2)

หลังจาก ความคืบหน้า PHP Hoffman Framework มีข้อเสนอแนะมาเกี่ยวกับ routing ที่เป็น xml กับ config ที่เป็น ini ทั้ง ทาง im และ comment (แต่ใน comment มีแค่ 4 คน)

จาก comment ของคุณ kaze เรื่อง config แบบ ini เมื่อเอามานั่งไล่ดู แล้วเห็นตรงกันกับคุณ kaze ตอนนี้เลยทำการปรับเปลี่ยนไปใช้ array และ convert ตัว array เป็น object แทน ซะ แต่ยังคงความสามารถ inherit ตัว config ไว้เพื่อความสะดวกในการขึ้น production app ได้ ตอนนี้เลยปรับเปลี่ยนจาก ini เป็น Array ใน php แทน

ตอนนี้เลยใช้เป็นแบบนี้ครับ

$Config['Production']['WebHost'] = 'http://localhost';
$Config['Production']['UseCleanUrl'] = true;
$Config['Production']['UseRoutesCache'] = false;
$Config['Production']['BaseUrl'] =  '/PHM2';
$Config['Production']['RenderViewDebugging'] = false;
$Config['Production']['RenderViewCompileCheck'] = false;
$Config['Production']['RenderViewCache'] = false;
$Config['Production']['ArgSeparator'] = ';';

$Config['Production']['Database']['Default'] = 'mysqli://root:1234@localhost:3007/production_album';
$Config['Production']['Database']['ReadServer'] = 'mysqli://root:1234@localhost:3008/production_album';
$Config['Development']['Database']['Default'] = 'mysqli://root:1234@localhost:3008/development_album';
$Config['Test']['Database']['Default'] = 'mysqli://root:1234@localhost/test_album';

โดน Dimension แรกเป็นตัวกำหนด config ว่าจะเป็น environment ไหน ส่วนตัวต่อมาก็เป็น dimension ของ ตัวที่เอาไปตั้งค่าจริง ๆ ส่วน ของ database จะเรื่องมากกว่าหน่อยตรงที่มีหลาย ๆ profile เผื่อในกรณีที่มีการใช้งานข้าม database หรือข้าม server กัน

อันนี้คือการเปลี่ยนส่วนของ config อีกรอบนึง แต่ดู ๆ แล้วน่าจะดีกว่าเดิมในแง่ของการไม่ต้อง parse ตัว ini ออกมา

ส่วน routing กำลังคิด ๆ อยู่ว่าจะเอาไงดี อาจจะปรับมาใช้แบบเดียวกันเลย เพื่อลดเวลาการ parse ข้อมูลลอง xml ด้วย

ส่วนเวลาเรียกใช้ก็ อ้างอิงแบบ Object ซะ โดยตัวอย่างด้านล่างก็ต้องเอาข้อมูล user ของ Database ที่เป็น Default ออกมา

echo $applicationConfigurations->Database->Default->user;

[Update 08/02/2007 00:21]

ตอนนี้ลดรูปลงมาให้ดูง่ายขึ้น (หรือเปล่า) มาเป็นแบบนี้ครับ

$Config['Production'] = array(
    'WebHost'=>'http://localhost',
    'UseCleanUrl'=>true,
    'UseRoutesCache'=>false,
    'BaseUrl'=>'/PHM2',
    'RenderViewDebugging'=>false,
    'RenderViewCompileCheck'=>false,
    'RenderViewCache'=>false,
    'ArgSeparator'=>';',
    'Database'=> array(
        'Default'=>'mysqli://root:1234@localhost:3007/production_album',
        'ReadServer'=>'mysqli://root:1234@localhost:3008/production_album'
    )
);

$Config['Development'] = array(
    'Database'=> array(
        'Default'=>'mysqli://root:1234@localhost:3007/development_album'
    )
);

$Config['Test'] = array(
    'Database'=> array(
        'Default'=>'mysqli://root:1234@localhost:3007/test_album'
    )
);

ความคืบหน้า PHP Hoffman Framework

  • ทำการ redesign ตัว clean url ใหม่อีกรอบ ด้วยการกลับมาใช้แบบเดิมเมื่อตอนออกแบบครั้งแรกคือ controller/action แทน ส่วนต้องการแก้ไข url ใหม่ ก็เพิ่มลงไปใน xml เอา โดย default คือ <map pattern=”:controller/:action” /> ถ้าต้องการใช้ user/login เป็น login เฉย ๆ ก็ <map pattern=”login” action=”user/login” /> แทนซะ หรือถ้าต้องการ rewrite ตัว url ที่มีการส่ง value ด้วยก็ <map pattern=”news” action=”page/show/1″ /> แทนก็ได้เช่นกัน โดยในรุ่นต่อไปจะมี plugin เสริมสำหรับการ hook ตัว xml ตัวนี้ให้ไปใช้ database ได้ แบบเดียวกับ drupal แทนช้าลงและโหลด db มากขึ้น กำลังจุดลงตัวในส่วนนี้ โดย clean url นี้มีประสิทธิภาพเพิ่มขึ้นเยอะกว่าเดิมมาก และลดความซับซ้อนในการตั้งค่าลงไปเยอะด้วย แต่ต้องแลกกับความยืดหยุ่นบางส่วนไป แต่ถ้าว่า ok กว่าเดิมมาก ๆ ในตอนนี้
  • หน้า error handler page นั้น ok แล้ว เพื่อดักข้อผิดพลาดในกรณีไฟล์ของ controller หรือ view ไม่มี รวมถึง arguments ไม่ครบเมื่อ controller ไป handle ตัว action
  • ตัว config ไฟล์ใน .ini file และสามารถทำ inherit config ได้ด้วย เช่น
[production]
database.default.type=mysql
database.default.hostname=localhost
database.default.username=root
database.default.password=1234
database.default.name=album

[development : production]
database.default.hostname = localhost
database.default.username = root
database.default.password = 1234
  • เมื่อเราเลือก production เป็น environment มันจะไปดึงตัว config มาของ production มา แต่ถ้าใช้  development ก็จะไปดึงส่วนของ development ที่ override ตัว production มาใช้เท่านั้น ทำให้ลดการตั้งค่าลงไปเยอะ
  • ในส่วนของ Model layer มี 3 ทางเลือกให้ extends มาใช้งานได้ คือ Zend_Db, Doctrine หรือ LogicModel (ตัวนี้ผมเขียนเอง สนับสนุนแค่ MySQL เท่านั้น) โดยใครถนัดแบบไหนก็ใช้แบบนั้นได้เลย เพียงแค่ตั้งค่าใน Model แต่ละตัวว่าจะใช้แบบไหน กำลังหาจุดลงตัวเพื่อให้เราสามารถใช้ Model ได้หลากหลายรูปแบบการ extends จาก 3 ทางเลือก บางครั้ง Model บางตัวอาจจะเหมาะกับ Doctrine มากกว่า 2 ตัวที่เหลืออะไรแบบนั้น และอาจจะรองรับการเขียนด้วย function mysql(i) เดิม ๆ ได้ด้วย โดยผมมองว่า Model นั้นเป็น Business logic ซึ่งควรมี performance สูงที่สุดในการเขียนและนำไปใช้งานครับ
  • การส่งข้อมูลจาก controller ไปหา view นั้นใช้การ return ของ action ใน controller นั้น โดยการส่งข้อมูลแบบตัวแปรเดียวก็ได้ หรือส่งเป็น array ออกไปก็ได้ โดยส่งเป็น array จะทำการ fetch ข้อมูลให้ชั้นนึงเพื่อส่งผ่านเป็นตัวแปรนึงใน view ให้เลย โดยใช้การ map key เป็นชื่อตัวแปรใน dimension ที่ 1 ของ array ซะ
  • พยายามเอา ORM หลาย ๆ ตัวมาใช้ร่วมกันใน Model เพื่อลดการยึดติดของระบบกับรูปแบบ ORM ของตัวใดตัวหนึ่ง
  • ยังคงใช้ Zend แบบหลักในการพัฒนาระบบภายในเช่นเดิม

ตอนนี้โดยรวมพยายาปั้นตัวแรกออกมาให้ได้ก่อน เพื่อเอามารับคำติของทุกท่านครับ เพื่อเอามาพัฒนาต่อไปครับผม

กำลังเตรียมตัวไปงาน BarCamp Bangkok Winter 2008

image

งาน BarCamp Bangkok Winter 2008

จัดในวันที่ 26 มกราคม 2551 โดยจัดที่ร้านอาหาร Indus แถวสุขุมวิท บรรยากาศดีเยี่ยม งานเริ่มตั้งแต่ 10 โมงเช้าจนถึง 6 โมงเย็น แล้วมีปาร์ตี้ข้าวเย็นกันต่อตอนช่วงค่ำ

ตอนนี้กำลังปั่นตัว slide ที่จะเอาไปพูดในงาน 2 ตัว (ในรอบเดียว)

  1. MySQL Tuning นี่คงเอาเนื้อหาเดียวกับที่เคยได้โพสใน entry เก่าไปแล้ว แต่เพิ่มเติมและใส่ประสบการณ์ตรงของตัวเองลงไป
  2. PHP Framework ผมคงไม่พูดถึงตัวอื่นมาก เอาแค่ intro พอนิด ๆ แต่เอา PHP Hoffman Framework (HMF) ไปแสดงก่อน

ซึ่งตัว PHP Framework ของผมเนี่ย ตอนนี้ก็ปั่นตัว implementation code อยู่ ไม่รู้จะทันหรือเปล่า แค่ทำ Routing URL กับพวก Standard Code ต่าง ๆ ใหม่หมดก็เล่นซะหลายวัน รวมถึง Directory structure ก็เพิ่งจะลงตัวไป น่าจะเข้ารูปเข้ารอยในไม่ช้านี้ หลาย ๆ ภายใน Framework ยังไม่นิ่งพอจะเป็น Alpha version ได้ด้วยซ้ำ แถมหลายอย่างที่อยู่ใน 0.1a (ตัวใหม่ผมเรียกมันว่า Rv2 หรือ revolution version 2) ไม่ได้โอนถ่ายมาใส่อีกด้วย เพราะซ้ำซ้อน กับ Zend Components ที่จะเอามาใช้อยู่หลายตัวอย่าง ACL ที่ทำเองใน 0.1a พอมาตัวใหม่นี้ ใช้ Zend_Acl ของ Zend Framework แทน และหลาย ๆ ตัวที่โยกมาใช้ Zend แทนหลายตัวเลย รวมถึงตัว Model ที่ใช้ความสามารถของ Doctrine และ Zend_Db แทนที่ตัว Components ของผมเอง แต่ว่าตัวที่ผมใช้อยู่ก่อนหน้านั้นก็ยังคงมีอยู่ เหมือนเดิม เพียงแต่ไม่ได้เปิดใช้เท่านั้นเอง ส่วน Controller นี่เขียนเองหมดเลย Flow ตัว Controller ต่าง ๆ จัดการเองหมด รวมถึง Standard Structure และ Code ต่าง ๆ ส่วนของ View ก็ใช้ Smarty เข้ามาแทนของเก่าของผมเองทั้งหมดเลย

ตอนนี้ที่ตัดสินใจไว้ทั้ง 3 components หลัก ๆ ก็คือ

LogicModel ใช้ความสามารถต่าง ๆ จาก Doctrine และ Zend_Db และพวก tools ด้าน Business Logic ทั้งหมด
FlowController อันนี้เขียนเองทั้งหมดเพราะหาตัวที่มันโดนใจไม่ได้ ฮา …
RenderView ใช้ความสามารถต่าง ๆ ของ Smarty มาช่วยในส่วนนี้

เพราะเท่าที่หาข้อมูลและ defend กับตัวเองแล้วหลาย ๆ อย่างน่าจะใช้สิ่งที่มีอยู่และนำมาปรับให้เข้ากับแนวทางของ Framwork ของเราเองหลาย ๆ ตัวน่าจะทำให้มันง่าย ๆ เข้าไว้ด้วย Framework บางตัวทำเรื่องง่าย ๆ ให้เป็นเรื่องยากไปซะงั้น บางตัวทำงานไม่ยืดหยุ่นอะไรแบบนั้นอีก เลยทำเองซะ แล้วให้คนอื่นมา defend กับเราว่าควรปรับอะไรอีกบาง

หลาย ๆ อย่าง หลาย ๆ idea มาจากหลาย ๆ Framework มาปรับใช้เข้าด้วยกันบางอย่าง idea ดีมาก ๆ น่าจะทำให้มันทำงานได้ง่าย ขึ้นพอสมควร

แล้วเจอกันที BarCamp ครับ

AJAX on PHP @ NU

ได้รับเชิญจากอาจารย์ที่มหาวิทยาลัยให้ไปสอนเรื่องนี้ มีเวลาเตรียมตัวร่วมเดือน แต่ประกอบกับงานที่เพิ่งเริ่มทำ และมีงานที่เข้ามาตลอดทำให้หลาย ๆ อย่างในการสอนเมื่อวันหยุดช่วงวันแม่ที่ผ่านมาดูไม่พร้อมเท่าไหร่ slide สำหรับสอนนั้นเสร็จสด ๆ ก่อนสอนทั้ง 3 วันตลอด ซึ่งถึงแม้ว่าจะเสร็จทันเวลา แต่โดยส่วนตัวแล้วถือว่าเราจัดการเวลาในการทำสื่อการสอนไม่ดี เพราะน่าจะทำให้มันเสร็จก่อนสอนทั้งหมดเสียด้วยซ้ำ โดยการสอนนี่ก็มีเนื้อหาได้แก่

  • XHTML, DOM, CSS and JavaScript in Basic
  • PHP Basic Concept (OOP, Zend Certification), PHP Manual และ PEAR Package/Frameworks
  • Hypertext Transfer Protocol (HTTP)
  • AJAX in Basic และ Debug AJAX
  • XAJAX Framework

โดยเนื้อหามันอาจจะมีสลับบ้าง นิดหน่อย แต่ประมาณนี้แหละ ได้สอนส่วน OOP ซึ่งก็ intro เรื่อง concept ไปเลย ที่หนักสุดน่าจะเป็น HTTP Protocol มากกว่า เพราะส่วนใหญ่ที่เจอ ๆ ใน outline ตามที่ต่าง ๆ ไม่ค่อยได้สอนเท่าไหร่ แต่มันสำคัญมาก ๆ ในเวลาที่เราต้อง Debug ตัว AJAX มันต้อง Filter การส่งข้อมูลเข้าออกด้วย โดยใช้ 2 ตัวคือ FireBug กับ Proxomitron ในบางครั้งตัว FireBug จะจับข้อมูลที่ถูกส่งผ่าน iframe ไม่ได้ อย่างในกรณีของ google maps เป็นต้น แต่ Proxomitron จะดักได้ เพราะตัว Proxomitron มันดักแบบ Proxy Server ซึ่งข้อมูลทุกอย่างต้องวิ่งผ่านทั้งหมด ทำให้การ Filter ทำได้ง่ายกว่า แถมแก้ไขตัว header และ data ภายในก่อนส่งได้ด้วย เป็นโปรแกรมสำหรับทำมิดีมิร้ายได้เป็นอย่างดี ซึ่งก็ได้สอนเบื้องต้นในการใช้งานเท่านั้น จริงๆ สอนไปหน่อยเดี่ยว เพราะมันมีปัญหากับ ISA Server ของมหาวิทยาลัย ทำให้ Proxomitron ใช้งานไม่ค่อยได้ จะใช้ได้ก็ FireBug ที่พอทำให้เห็นภาพเท่านั้น

ส่วนต่อมาที่น่าจะเป็นก่อนมาเรียนพวก AJAX เลยคือพวก XHTML, CSS, HTML event tag, แนวคิดด้าน DOM แล้วก็ JavaScript อย่างน้อย ๆ ก็เขียนเองได้บ้างก่อน ไม่งั้นนึกภาพไม่ออกแน่ว่ามันเชื่อมโยงกันยังไง แล้วจะทำให้เราไปต่อไม่ได้ ถึงแม้ว่า XAJAX Framework จะทำให้เราไม่ต้องไป focus ที่ตัว JavaScript มาก แต่ว่าในระดับที่มีความซับซ้อนสูงๆ ก็จำเป็นเหมือนเดิม แต่บอกตามตรง XAJAX ทำให้เขียน AJAX เพื่อทำงานกับ PHP ได้ง่ายขึ้นเยอะมาก ๆ ลดเวลาการเขียนลงได้ 3-4 เท่า (วัดจากการที่ได้ใช้เอง) จริง ๆ ยังมี Framework อีกหลายตัวที่น่าสนใจ เอาไว้ว่าง ๆ จะลองเล่นดู

ส่วนที่เป็นพื้นฐานมาก ๆ อย่างเรื่อง path file และ page/data encoding นี่ก็ต้องพูด เพราะในมหาวิทยาลัยไม่ค่อยมีคนสนใจเรื่องนี้เท่าไหร่ ก็ต้องเสริม ๆ ลงไป แถมพูดเรื่อง Unicode ในส่วนของ UTF-8 ไปด้วยว่าในปัจจุบันทำเว็บใช้ UTF-8 น่าจะดีกว่า

จริง ๆ ใน outline กะว่าจะเสริม MySQL in Basic แต่ ไป ๆ มา ๆ ไม่ได้สอน เพราะท่าทางจะหนักเกินไป T_T จริง ๆ ต้องเป็นการสอนระยะยาวมากกว่า เพราะในระดับที่สอนอยู่นี้เนี่ย เป็นระดับปูพื้นฐานและให้ไอเดียว่ามันคืออะไร, การทำงานอย่างไร แล้วถ้ามีข้อผิดพลาดแล้วจะเริ่มไล่ปัญหาจากตรงไหนไปตรงไหนก่อน เพราะถ้าไม่สอนเรื่องพวกนี้ที่เป็นเรื่อง Basic ก่อน ทำงานระดับสูง ๆ ที่ซับซ้อนมาก ๆ พอเจอปัญหา จะเกิดเหตุการณ์แก้ปัญหาแบบมั่ว ๆ ได้

<?php ?> on AJAX

Slide Keynote

Powerpoint 2007 | 2003 | PDF

Example

http://www.fordantitrust.com/download/democode.zip
http://www.fordantitrust.com/download/ajax1.zip
http://www.fordantitrust.com/download/xajaxexam.zip