Archive for the ‘php’ Category
รู้จัก symfony framework เบื้องต้น
What is symfony?
บทนี้เราจะมารู้จักกับ symfony หรือ เรียกเต็มๆ ว่า symfony framework ซึ่งถ้าคนที่หาข้อมูลมาจะอยู่รู้แล้วว่าเป็น framework ที่ถูกเขียนขึ้นด้วย ภาษา PHP
ทีนี้เรามาดูความหมายจริงๆของ symfony กันเลย ทางทีมงานของ symfony ได้ให้ความหมายของ symfony ไว้ว่า
Symfony is a web application framework for PHP projects.
เป็นความมหายที่ตรงตัวสุดๆ คือ web application framework แต่หลายๆคนที่อ่านอยู่ไม่รู้แน่ๆว่ามันคืออะไร นิยามให้ง่ายๆ คือ library สำหรับสร้าง application นั้นเอง (คำพูดนี้คิดเอง อาจจะไม่ถูกซะทีเดียว หรือ ครอบคุมความมหายทั้งหมด ละไว้ในความเข้าใจของภาษาไทย)
สิ่งที่ symfony framework อยากจะทำออกมา คือทำให้เราเขียน application ได้ง่าย เร็ว ติดตั้งง่าย โดยได้ใจความพวกนี้มาจาก
The very small number of prerequisites make symfony easy to install on any configuration; you just need Unix or Windows with a web server and PHP installed. It is compatible with almost every database system. In addition, it has a very small overhead, so the benefits of the framework don’t come at the cost of an increase of hosting costs.
Using symfony is so natural and easy for people used to PHP and the design patterns of Internet applications that the learning curve is reduced to less than a day. The clean design and code readability will keep your delays short. Developers can apply agile development principles (such as DRY, KISS or the XP philosophy) and focus on applicative logic without losing time to write endless XML configuration files.
Symfony is aimed at building robust applications in an enterprise context. This means that you have full control over the configuration: from the directory structure to the foreign libraries, almost everything can be customized. To match your enterprise’s development guidelines, symfony is bundled with additional tools helping you to test, debug and document your project.
Last but not least, by choosing symfony you get the benefits of an active open-source community. It is entirely free and published under the MIT license.
จะเห็นว่าตัวหนาๆ คือสิ่งที่ symfony จะมีให้กับเราในการเขียน application หนึ่งตัวด้วย symfony framework
ในบทต่อๆไป เราจะรู้กันว่า ทำไมมันถึงง่าย ทำไมมันถึง easy to install ทำไมมันถึง small overhead และ clean design. การที่จะมีรูปแบบการเขียน code ที่ ดีและมีคุณภาพนั้น ส่วนใหญ่แล้วจะมาจากประสบการณ์ของ programmer ที่ดี มีความเป็นระเบียบเรียบร้อย ก็จะทำให้แก้ไข code ได้ง่าย. symfony จะช่วยเราได้อย่างไร?
setup pear after install apperve
หลังจากที่เราลง apperve ไปแล้ว ซึ่งเป็น package ที่นักพฒนาเว็บรู้จักกันดี เพราะมี apache + php + mysql + phpMyAdmin สำเร็จรูปออกมาอย่างดี กด install แล้วใช้งานได้เลย
เมื่อต้องการใช้งาน pear ก็ง่ายแสนง่าย เพราะมี script สำหรับ setup pear อยู่แล้ว โดยให้เข้าไปที่
C:\AppServ\php5
จากนั้นก็ รัน go-pear เลย มันก็หา path อะไรให้เองหมดอ่ะนะ ถ้าลงไปแบบ default ก็กด Enter ไปจากนั้นเราก็จะได้ใช้ pear
ลองทดสอบดูง่ายๆ ก็ เข้า command แล้วรัน pear ขึ้นมาดูว่ามันหาคำสั่งนี้เจอหรือเปล่าแค่นั้น
การทำ Mod Rewrite (url friendly)
Mod_Rewrite คืออะไร?
Mod_Rewrite คือการแปลง URL ที่ดูยากให้อยู่ในรูปแบบที่เราต้องการ เพื่อประโยชน์หลายด้าน (ซึ่งจะกล่าวถึงต่อไป) และการแปลงเพื่อประโยชน์ด้าน SEO ก็เป็นอีกอันนึงที่มีการนำเอา Mod_Rewrite มาใช้ เพราะเรารู้กันดีว่า Search Engine ไม่ค่อยชอบ pages ที่เป็น dynamic ที่มี query string ยาวเฟื๊อย
อ้างถึง
ตัวอย่าง URL ที่ยาว และซับซ้อน
โค้ด:
http://www.site.com/viewcatalog.asp?category=hats&prodID=53
เมื่อผ่านการแปลง เราสามารถทำให้สั้นลงได้ดังนี้
โค้ด:
http://www.site.com/catalog/hats/53/
เริ่มทำ Mod_Rewrite
บาง Server ไม่สามารถจะทำ Mod_Rewrite ได้เนื่องจากไม่ได้ติดตั้ง Module Mod_Rewrite ดังนั้นถ้าเราจำเป็นต้องใช้ Mod_Rewrite ก็ต้องตรวจสอบดีๆก่อนเช่า host
.htaccess ไฟล์สำคัญในการทำ Mod_Rewrite
เราจะใช้ไฟล์นี้ในการกำหนด Rule ของการทำ Mod_Rewrite
เริ่มต้นด้วยคำสั่ง
RewriteEngine on
เพื่อเปิดการทำงาน เขียนไว้ในบรรทัดแรกสุดของไฟล์
ต่อไปจะเป็นการนำเอา Mod_Rewrite ไปให้งาน ซึ่งผมจะเริ่มด้วยตัวอย่างง่ายๆ และเขียน Rewrite Rule ง่ายก่อน แล้วก็ยกตัวอย่างต่อไปเรื่อยๆนะครับ
ใช้ Mod_Rewrite ในการทำ Redirects
ถ้าเราต้องการเปลี่ยน location เก่า ไปที่ Location ใหม่แบบถาวร
RewriteEngine on
RewriteRule ^old\.html$ new.html
ถ้าเราเขียนแบบนี้ เมื่อมีการใส่ url เป็น old.html มันก็จะถูกส่งไปที่ไพล์ new.html แต่ผู้เยี่ยมชมยังเห็น URL บน browser เป็น old.html อยู่เหมือนเดิม
อาจจะดูงงๆ อธิบายเพิ่มเติมดังนี้ RewriteRule จะประกอบด้วยกัน 3 ส่วน
1. Call to action RewriteRule ขึ้นต้นบรรทัด กำหนดว่าบรรทัดนี้เป็น Rewrite Rule
2. Pattern ^old\.html$ เป็นการตรวจสอบ URL ที่ใส่เข้ามาทาง Location Bar ของ Browser ซึ่งจะใช้ regex (Regular Expression) ในการตรวจสอบ (จะอธิบายเพิ่มเติมต่อไป)
3. Rewrite new.html เป็น URL ที่เราต้องการให้แปลงเป็นอันใหม่
หมายเหตุ: จริงๆมี 4 ส่วน แต่ในตัวอย่างเราใช้ 3 ส่วน
ขออธิบายในส่วนที่ 2 (Pattern) เพิ่มเติมดังนี้ ในส่วนนี้ประกอบด้วยเครื่องหมายสำคัญ 3 อย่างคือ
^old\.html$
- เครื่องหมาย The caret หรือ ^ เป็นการกำหนดจุดเริ่มต้น URL ที่อยู่ภายใต้ direcory ปัจจุบันที่เราจะตรวจสอบ ซึ่งก็คือ directory เดียวกับไฟล์ .htaccess
- เครื่องหมาย The dollar sign หรือ $ ซึ่งบอกจุดสิ้นสุดของการตรวจสอบ Pattern
- อีกเครื่องหมายนึงก็คือ The period หรือ . จุด ที่อยู่ข้างหน้านามสกุล html ซึ่งเครื่องหมาย จุด นั้นเป็นอักขระพิเศษ ใน regular expressions ซึ่งจะมีความหมายว่า แทนด้วยตัวอักษรใดๆ 1 ตัว (ดูเพิ่มเติมใน regular expressions ต่อจากนี้) แต่ในนี้เราจะตรวจสอบว่า ถ้า Pattern เป็น old.html หรือไม่ เราจึงต้องใส่ \ ซึ่งเป็น escape charactor ไว้ด้วย
เมื่อเราเขียนตามนี้ เมื่อผู้เยี่ยมชมเว็บกรอกมาเป็น old.html server ก็จะทำ transparently redirect ไปที่ new.html โดยที่ผู้เยี่ยมชมเว็บไม่รู้ตัวว่าเป็นข้อมูลอันใหม่แล้ว เพราะ URL บน browser เป็น old.html อยู่เหมือนเดิม
แต่ถ้าเราต้องการให้ URL ที่ปรากฏบน browser เป็น new.html ด้วย เราก็เพียงแต่เติม [R] เข้าไปต่อท้ายบรรทัด ดังนี้
RewriteRule ^old\.html$ new.html [R]
ซึ่ง [R] ก็คือ ส่วนที่ 4 ที่ผมบอกไว้ข้างบน
4. Command Flag [R] ซึ่งจะเป็นคำสั่งพิเศษกำหนดเงื่อนไขไว้ มีหลายคำสั่งซึ่งจะบอกไว้ตอนท้าย
การใช้ Regular Expressions
จะบอกว่า เป็นส่วนสำคัญที่สุดในการทำ Rewrite และมันก็ทำความความเข้าใจได้ยากพอควร ไม่ต้องห่วงครับ เดี๋ยวผมจะอธิบายเป็นขั้นตอน และยกตัวอย่างประกอบไปเรื่อยๆนะครับ
ตัวอย่างแรก
RewriteRule ^products/([0-9][0-9])/$ productinfo.php?prodID=$1
จะเปลี่ยนจาก
productinfo.php?prodID=11 หรือ productinfo.php?prodID=99
ให้เป็น
products/11/ หรือ products/99/
ดูที่ Pattern จะมีส่วนของที่อยู่ในปีกกาเหลี่ยม [ ] เราเรียกว่า ranges
ในตัวอย่างจะเป็น [0-9] ซึ่งจะใช้ตรวจสอบว่าเป็นตัวอักษรที่อยู่ในช่วง 0-9 ใดๆ
เราสามารถตรวจสอบ ranges อื่นได้ เช่น [A-Z] ตรวจสอบว่าเป็นตัวอักษรตัวใหญ่ตั้งแต่ A-Z
[a-z] ก็เป็นการตรวสอบตัวเล็ก, ถ้า [A-Za-z] ก็ตรวจสอบว่าเป็นทั้งตัวใหญ่และตัวเล็ก เป็นต้น
และใน Pattern ก็จะมีส่วนที่อยู่ในวงเล็บ ( ) เป็นการเก็บค่าที่เราตรวจสอบพบ และตรงตามเงื่อนไข ซึ่งเราสามารถเอาค่านี้ ส่งไปให้ PHP ในส่วนของ Query String ได้ เราเรียกค่าที่ได้จากวงเล็บนี่ว่า back-reference
เราสามารถตรวจสอบและแยก back-reference ออกได้หลายๆอันใน URL อันเดียว (ดูตัวอย่างต่อๆไป) ซึ่ง back-reference ในวงเล็บแรก เวลาเราอ้างถึงเราก็จะใช้ $1 ส่วนลำดับต่อๆไป ก็จะเป็น $2, $3 ไปเรื่อยๆ
ดังนั้นผู้เยี่ยมชมเว็บ(หรือ bot ก็ได้)ก็จะเห็น url เป็น products/11/ หรือ products/99/ ซึ่ง สั้นและกระชับ โดยหารู้ไม่ว่า เราได้ซ่อน URL ที่ไม่ค่อยสวยงามและอ่านยากไว้เบื้องหลัง
ใส่ / ต่อท้าย
บางครั้งผู้เยี่ยมชมเว็บ อาจจะพิมพ์ URL แค่ products/12 ซึ่งเมื่อเข้าไปตรวจสอบใน Pattern ด้านบน ก็จะไม่ตรง เพราะ Pattern ด้านบนจะต้องมี / ต่อท้ายด้วย มันจึงไม่ทำ transparently redirect ให้เรา
เราก็มีวิธีแก้เหตุการณ์แบบนี้ ซึ่งเราก็จะเขียน Rule ใหม่เพิ่มเข้าไปดังนี้
RewriteRule ^products/([0-9][0-9])$ products/$1/ [R]
RewriteRule ^products/([0-9][0-9])/$ productinfo.php?prodID=$1
ดังนั้น เมื่อ Server ตรวจเจอ products/12 ก็จะเปลี่ยน URL เป็น products/12/ และแสดง URL ให้บน Browser ด้วย เพราะเราใส่ [R] ไว้ด้วย เมื่อเจอเงื่อนไขบรรทัดที่ 2 ก็เลยไม่มีปัญหาใดๆ ซึ่งมันก็จะส่งเป็น transparently redirect ไปที่ productinfo.php?prodID=12 ตามความต้องการของเรา
การใช้ Match Quantifiers
จะเป็นว่าตัวอย่างข้างบน เรากำหนดเป็น ^products/([0-9][0-9])$ นั่นหมายความว่า ตัวเลขที่ตามหลัง products/xx ต้องมี 2 ตัวเท่านั้น ซึ่งก็จะเป็นไปได้สูงสุดแค่ 99 แล้วกรณี productinfo.php?prodID=100 ล่ะจะทำอย่างไร?
ในกรณีนี้ เราสามารถใช้ Quantifiers เป็นตัวกำหนดได้ (Quantifiers มีหลายตัว จะอธิบายต่อไปเรื่อยๆ) ดังตัวอย่าง
RewriteRule ^products/([0-9]+)$ products/$1/ [R]
เครื่องหมายบวก + แทนอักษรตั้งแต่ 1 ตัว ถึง n ตัว (ตั้งแต่ 1 ตัวขึ้นไป) ดังนั้น [0-9]+ ก็หมายความว่า เป็นตัวเลข 0-9 ตั้งแต่ 1 หลักขึ้นไป ถ้าเราใส่ products/1 หรือ products/1000 ก็สามารถ Match case นี้ได้แล้วครับ
ข้อมูลเพิ่มเติมของ Rewrite Rule
RewriteRule
Regular expressions
Some hints about the syntax of regular expressions:
Text:
. Any single character
[chars] One of chars
[^chars] None of chars
text1|text2 text1 or text2Quantifiers:
? 0 or 1 of the preceding text
* 0 or N of the preceding text (N > 0)
+ 1 or N of the preceding text (N > 1)Grouping:
(text) Grouping of textAnchors:
^ Start of line anchor
$ End of line anchorEscaping:
\ char escape that particular charPattern Matching metacharacter Definitions
\ Use before any of the following characters to escape or null the meaning or it. \* \. \$ \+ \[ \]
^ Start matching at this point
$ End point of the match
. Any character
[] Starts a range
| Starts alternative match this|that would mean match this or that
() starts a back reference point
? match 0 or 1 time Quantifier
+ match atleast 1 or more times Quantifier
* match 0 to infinite times Quantifier
{} match minimum to maximum Quantifier {0,3} match up to 3 timesRange Definitions []
^ Negates the class. [^A-Z]+ means don?t match any uppercases
\ Use before any of the following characters to escape or null the meaning or it. [\+]+
- Range for matching [0-9]+ [a-zA-Z]+Command Flag
[R] Redirect you can add an =301 or =302 to change the type.
[F] Forces the url to be forbidden. 403 header
[G] Forces the url to be gone 401 header
[L] Last rule. (You should use this on all your rules that don?t link together)
[N] Next round. Rerun the rules again from the start
[C] Chains a rewrite rule together with the next rule.
[T] use T=MIME-type to force the file to be a mime type
[NS] Use if no sub request is requested
[NC] Makes the rule case INsensitive
[QSA] Query String Append use to add to an existing query string
[NE] Turns of normal escapes that are default in the rewriterule
[PT] Pass through to the handler (together with mod alias)
Skip the next rule S=3 skips the next 3 rules
[E] E=var sets an enviromental variable that can be called by other rules?
LINK:
http://www.askapache.com/htaccess/mod_rewrite-tips-and-tricks.html#default-mod-rewrite-hint
เข้าใจ sphinx full text search engine
จากที่เคยเกริ่นเรื่องเกี่ยวกับ sphinx full text search ไปแล้วทีนึง คราวนี้เรามาดูวิธีและหลักการทำงานของ full text search กัน
full text search engine นั้นจะทำงานในลักษณะของการทำ data ที่มาจากที่เรา config ไว้ มาทำเป็น index เฉพาะแบบของ fulltext search นั้นๆ ซึ่งแต่ละตัวก็จะไม่เหมือนกัน บางที่อาจจะไม่ได้ใช้แนวคิดนี้ แต่เห็นหลายๆ ที่จะเป็นแบบนี้ เพื่อให้สามารถ ค้นหาข้อมูลในรูปแบบของตัวเองได้
sphinx ก็เช่นเดียวกัน เราจะต้อง config ว่าให้ seletct ส่วนใด มาทำเป็น เนื้อความสำหรับ search ได้บ้าง หลังจากนั้นเราก็ตั้งใช้คำสั่งสร้าง index ขึ้นมา sphinx ก็จะสร้าง index ของตนเองขึ้นมา ให้สามารถทำการ search ได้ง่ายตามรูปแบบที่ตั่งไว้
การใช้งาน search นั่นเวลาจะใช้งานจึงต้องเขียนออกมาเป็นอีกส่วน ในส่วนใหญ่แล้วโปรแกรมพวกนี้ก็จะเปิด port อีก port ไว้เลยเป็นของตนเองอย่าง sphinx เองก็เปิด port ไว้เหมือนกัน ซึ่งตอนที่รัน เราก็สามารถ config ลงไปได้ด้วยว่าอยากจะเปิด port อะไีร เวลาสร้าง connection ก็ต่อมาที่ port นั้นๆที่ตั้งไว้
Sphinx เองเปิด port 3312 เป็น default ดูได้จาก sphinx.conf
# IP address to bind on
# optional, default is 0.0.0.0 (ie. listen on all interfaces)
#
# address = 127.0.0.1
# address = 192.168.0.1# searchd TCP port number
# mandatory, default is 3312
port = 3312
full text search engine ส่วนใหญ่จะมี library สำหรับติดต่อกับตัวเองพร้อมทั้ง reference มาให้อยู่แล้วเพื่อความสะดวกในการใช้งาน sphix ก็มีเช่นกัน คือ folder api ที่มาพร้อมๆ กับตัวที่ download มาติดตั้งแหละ มีทั้ง ภาษา PHP, ptyhon, ruby และ java เลยทีเดียว
รวมทั้งยังมี reference การใช้งานอีกด้วยที่ http://www.sphinxsearch.com/docs/current.html#api-reference
จากการที่เราทำ index ครั้งนึงเราก็จะ search ได้เพียงสิ่งที่เรานั่นสร้าง index ไป ดังนั้นเราก็ต้องทำ index เรื่อยๆ เช่นการทำ cronjob ของ indexer เป็นต้น
แต่การทำ cron ก็จะได้ ข้อมูลในการ search ไม่เป็นปัจจุบันเสมอ แต่จะ search ไปตามช่วงเวลาแทน sphinx เองก็มี mode ในการทำทั้ง merge index หรือการสร้าง index เสมอทุกๆ การใช้งาน ก็เอาไว้ต่อกันทีหลังแล้วกันนะ
sphinx full text search engine
วันนี้ทำงานสบายๆ ก็เลยมาเขียนซะหน่อย ห่างหายไปจาก blog นานๆ แล้ว ที่จะพูดถึงวันนี้ก็คือ fulltext search
ช่างเป็นอะไรที่ กิน performance เครื่องสุดๆ ลองคิดถึง algorithm ง่ายของ LIKE ใน SQL นะ
1 record ก็จะมีั text เช่น ‘some text’
แล้วเราก็หาคำว่า ‘me’ ใน text นี้ มันก็ต้องหา so, om, me แล้วก็เจอ ลองคิดดูว่ามันจะหาไปกี่ที
แน่นอนว่า วิธีนี้มันโง่และทึ่มมาก เพราะทำงานธรรมดาสุดๆ คือ เทียบกันไปเรื่อยๆ การทำงานจึงเป็น loop ไป เรื่อยๆ แต่ปัจจุบันนั้นก็มีคนศึกษาเรื่องนี้และได้คิด algorithm ออกมาเพื่อที่จะจัดการกับ full text search อีกมาก บาง algorithm ก็ได้รับความนิยม จนไปสู่การนำมาใช้งานจริง
.
sphinx ก็เป็นอีก 1 ตัวที่ได้รับความนิยมอยู่ในขณะนี้ เพราะด้วย performance และการใช้งานนั้นง่าย รวมทั้งยังเป็น Open Source อีกด้วย ทำให้เปิดโลกกว้างการการเพิ่มเติมและการนำไปใช้ด้วย
sphinx search นั้นมี feature หลักคือ
- high indexing speed (upto 10 MB/sec on modern CPUs)
- high search speed (avg query is under 0.1 sec on 2-4 GB text collections)
- high scalability (upto 100 GB of text, upto 100 M documents on a single CPU)
- supports distributed searching (since v.0.9.6)
- supports MySQL natively (MyISAM and InnoDB tables are both supported)
- supports phrase searching
- supports phrase proximity ranking, providing good relevance
- supports English and Russian stemming
- supports any number of document fields (weights can be changed on the fly)
- supports document groups
- supports stopwords
- supports different search modes (“match all”, “match phrase” and “match any” as of v.0.9.5)
- generic XML interface which greatly simplifies custom integration
- pure-PHP (ie. NO module compiling etc) search client API
ซึ่งถ้าอ่านดีๆ แล้วก็จะเห็น performance นั้นสูงทีเดียวและสามารถใช้งานได้ง่ายด้วย API และยัง support กับ Mysql และ postgresql ซึ่งเป็นฐานข้อมูล แบบ open source ที่ได้รับความนิยมทั่วโลก
จากที่ได้ลองติดตั้งดู ไม่มีอะไรยากเกินไปกว่า แตก tarball -> ./configure -> make -> make install แล้วก็ config อีกนิดหน่อย แค่ ใส่ user pass และ db name ของ database server ลงไปก็เสร็จแล้ว
ข้างใน config ก็มีให้เลือก database server อยู่แล้ว สามารถเลือกรูปแบบให้เหมาะสมได้เลย
ใน tutorial นั้นก็ได้มีการเขียนติดต่อกับ PHP ได้เลย เพียงนำ lib include ไปเท่านั้น
สามารถ compile ร่วมไปกับ mysql ให้เป็น engine ของ mysql ได้
วันนี้มาเกริ่นๆ เท่านั้น เกี่ยวกับ sphinx search ต่อไปก็จะมาพูดถึงการเขียนกัน แล้วก็รายละเอียด ลึกๆ แล้วกัน