วันอาทิตย์, กรกฎาคม ๒๙, ๒๕๕๐

PHP AJAX Autocomplete - จะใช้ของ ฝรั่งทำมายังงัย ก็ต้องเอามาปรับอยู่ดี

ไม่ใช่เซียนเว็บจ๋านะ แต่มันต้องใช้ฟังก์ชันนี้ เลยได้เล่มนี้มา

ปัญหาก็คือ บ้านเรามันใช้ภาษาไทย
คนเขียนซอร์สโค๊ดมาเค้าใช้ภาษาอังกฤษ
คนเขียนคอมไพล์ผ่าน result ขึ้น
เอามาใช้ กับเราก็ขึ้นเหมือนกัน ขึ้นแต่ภาษาอังกฤษนะ
ภาษาไทยใส่เข้าไป ไม่มีเอ๊าท์พุต ไม่เจอเรกคอร์ด ไม่มีข้อมูลที่เกี่ยวข้อง

อันนี้ก็เป็นอันนึงภาษาอังกฤษก็ผลออกมาถูกดี
แต่พอใส่ภาษาไทย ผลไม่ขึ้น ทั้งๆที่เช็คแล้ว ทุกขั้นตอน
ยิ่งงาน AJAX มีขั้นตอนให้ไล่เยอะ HTML <-> JavaScript <-> PHP
สืบไปสืบมา ก็เจอปัญหา เรื่องภาษานี่แหละ

คือมันมีปัญหา ตอน JavaScript ส่ง Parameter ไปใช้ PHP แบบ GET

พูดถึงส่งข้อมูลแบบ GET คือ ส่ง Parameterไปกับ URL เช่น
view.php?user=gunda

หรือ
thread.php?id=K122GSBPA8D72H2WJ

ส่งข้อมูลแบบนี้มันทำให้ Bookmark หน้านั้นได้ Bookmark หน้านั้น ก็คือ Bookmark ข้อมูลที่ส่งไปด้วย
ถ้า Bookmark ไว้ตอนสั่งซื้อของ กด Bookmark นี่ทีไร ก็เป็นอันว่าสั่งซื้อของทุกที

หรือข้อมูลที่ต้องให้ Bookmark ได้ ก็เช่น หน้าที่ไป Category เป็นต้น
view.php?category=0

ถ้า Bookmark หน้านี้ไว้ เปิดมาก็เป็นหน้าเดิม(แต่ข้อมูลอัพเดตขึ้น)ทุกที

เป็นที่มาของการส่งข้อมูลว่า ส่งข้อมูลที่ไม่ควรจำ ให้ไปส่งแบบ POST
แบบ POST จะส่งข้อมูลไม่ให้ผู้ใช้เห็น ข้อมูลก็ปลอดภัย

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

ไอ่อักขระพวกนี้ ก็รวมภาษาไทย ด้วย

ตามมาตรฐาน ASCII 1 ไบต์ เก็บได้ 256 แบบ
128 อักษร เก็บ ภาษาอังกฤษ
128 ที่เหลือ เก็บแต่ละภาษาแล้วแต่ที่มันอยู่ อยู่เมืองไทยมันก็ แปลให้เป็นภาษาไทย.. -> อักษร อันตราย

ภาษาไทย อันตราย มันเลย เข้ารหัส ให้เป็นภาษาอังกฤษซะ เช่น
พ เข้ารหัส เป็น %BE

BE เป็น เลขฐาน 16 คือ 190 ในฐานสิบ ตัวใหญ่เล็ก ไม่ต่าง

กลับมาเรื่องโปรแกรม..

ตอน JavaScript ส่ง Parameter ไปให้ PHP แบบ GET มันเข้ารหัส (encode) แบบ JavaScript ให้
ไม่ใช่แบบที่ PHP อ่านออก

ตัวอย่าง
PHP -> urlencode('พ') -> %BE
PHP -> urldecode('พ') -> พ
JavaScript -> escape('พ') -> %u0E1E
JavaScript -> unescape('พ') -> พ


PHP -> urlencode('p') -> p
PHP -> urldecode('p') -> p
JavaScript -> escape('p') -> p
JavaScript -> unescape('p') -> p


PHP -> urlencode('%BE') -> %25BE
PHP -> urldecode('%BE') -> พ
JavaScript -> escape('%BE') -> %25BE
JavaScript -> unescape('%BE') -> ¾


PHP -> urlencode('%u0E1E') -> %25u0E1E
PHP -> urldecode('%u0E1E') -> %u0E1E
JavaScript -> escape('%u0E1E') -> %25u0E1E
JavaScript -> unescape('%u0E1E') -> พ


ไม่มีฟังก์ชัน Javascript ที่เปลี่ยน "พ" เป็น "%BE"
เขียนใหม่ได้ว่า

function myEncode(input)
{
var output = "";
for(i=0;i {
if(input[i]>='ก')
{
output += '%'+(input[i].charCodeAt(0)-'ก'.charCodeAt(0)+161).toString(16);
}
else
{
output += input[i];
}
}
return output;
}

เปลี่ยนจาก
xmlHttpGetSuggestions.open("GET", getFunctionsUrl + encode(keyword), true);

เป็น
xmlHttpGetSuggestions.open("GET", getFunctionsUrl + myEncode(keyword), true);

เป็นอันเรียบร้อย

วันพุธ, กรกฎาคม ๒๕, ๒๕๕๐

Puzzle

Man#1 says:
พี่ๆ
Man#1 says:
ขอลองภูมิหน่อย
Man#2 says:
?
Man#1 says:
ภายในห้องห้องหนึ่ง เต็มไปด้วยมนุษย์ต่างดาวที่มาจากโลกอื่น และมีข้อมูลให้ดังนี้
1. มีมนุษย์ต่างดาวมากกว่าหนึ่งคนในห้อง
2. มนุษย์ต่างดาวแต่ละคนในห้องมีจำนวนนิ้วเท่ากันหมด
3. มนุษย์ต่างดาวแต่ละคนในห้องมีนิ้วอย่างน้อย 1 นิ้วบนมือแต่ละข้าง (มีมือมากกว่า 1)
4. ในห้องมีจำนวนนิ้วของมนุษย์ต่างดาวรวมทั้งหมดอยู่ระหว่าง 200 ถึง 300 นิ้ว
5. ถ้าคุณรู้จำนวนนิ้วทั้งหมดในห้อง คุณจะรู้จำนวนมนุษย์ต่างดาวที่มีอยู่ในห้อง
ขอถามว่า... มีมนุษย์ต่างดาวได้สูงสุดทั้งหมดกี่คนในห้อง? และ มนุษย์ต่างดาวแต่ละคนมีนิ้วได้สูงสุดกี่นิ้ว?

Man#1 says:
ผมมีคำตอบในใจแล้ว
Man#2 says:
มี x คน มี n นิ้ว
n > 1
200 =< nx <= 300
Man#2 says:
ข้อ 5 ถ้ารุ้จำนวนนิ้ว จะรุ้จำนวน มนุษย์ต่างดาวทั้งหมด
Man#2 says:
200/n <= x <= 300/n
Man#1 says:
hyperbola?
Man#2 says:
มันต้องเป็นจำนวนเต็มดิ
Man#2 says:
แป๊ปนะ
Man#2 says:
ถ้ารุ้จำนวนนิ่วทั้งหมด
Man#2 says:
ต้องรู้จำนวน มนุษย์ต่างดาว
Man#2 says:
ดังนั้น 200/n กับ 300/n จะต้อง เท่ากัน
Man#2 says:
หรือไม่ก็ห่างไม่เกิน 1
Man#2 says:
ไม่เกิน 2
Man#1 says:
OMG
Man#2 says:

Man#1 says:
คำตอบคือ?
Man#2 says:
ดังนั้น n = 100 ได้ เพราะได้ 2 <= x <= 3 พอดี
Man#2 says:
n = 300 ได้
Man#2 says:
100 ถึง 300 นิ้ว
Man#2 says:
100 ไม่ได้
Man#2 says:
ก็ต้อง 101 ถึง 300 นิ้ว
Man#2 says:
ดังนั้นมี คนได้สูงสุด 2 คน
Man#1 says:
101 * 2 = 202
Man#1 says:
คือ มี 2 คน หรือ 101 คน
Man#2 says:
2 คน
Man#2 says:
101 นั้นนิ้ว
Man#2 says:
n= นิ้ว
Man#2 says:
x = คน
Man#1 says:
แต่ given 202 นิ้ว ทั้งหมด ก็แปลได้ ว่า 2 คน หรือ 101 คนนะ ถูกป่าว
Man#1 says:
ยังงี้ violate ข้อ 5 ไม๊
Man#2 says:
101 นิ้ว
Man#2 says:
ไม่ใช่คน
Man#2 says:
n = นิ้ว
Man#1 says:
มนุษย์ต่างดาว
Man#1 says:
ไม่ใช่คน
Man#2 says:
200 <= nx <= 300
(200/n) <= x <= (300/n)
Man#2 says:
ต้องบังคับให้ได้ x เพียงค่าเดียว
Man#2 says:
ดังนั้น n เป็นได้แค่ 101 ถึง 300
Man#1 says:
101 102 103 ... 300
Man#1 says:
n:= 300
2/3 <=x<=1
Man#2 says:
แทนเข้าไป ได้ x ที่เป็นไปได้มากสุด คือ 2
Man#2 says:
n = 101 ได้ (200/101) = 1 กว่า ๆ (300/101) ได้ 2 กว่า ๆ
Man#2 says:
x ต้องเป็นจำนวนเต็ม
Man#2 says:
ดังนั้น พวกทศนิยมไม่เกี่ยว
Man#2 says:
ดังนั้นจะได้ค่าเดียว
Man#1 says:
อืม
Man#1 says:
คือ มันเป็น hyperbolic นะ
Man#2 says:
มันคืออะไร
Man#1 says:
คำตอบคือ ต้องหาช่วที่ upper bound กะ lower bound ห่างไม่เกิน หนึ่ง
Man#1 says:
xy = c
Man#1 says:

Man#2 says:
วิธีเดียวกันเลยนิ
Man#2 says:
ฮ่า ๆ
Man#1 says:
ม่ายช่ายยยย
Man#1 says:
ผม resay ที่พี่บอก
Man#2 says:
ไม่เหมือนกันยังไงอะ
Man#2 says:
พี่ก็ตั้ง สมการตามทุกข้อเลยนะ
Man#1 says:
งั้นดูนี้
Man#1 says:
ไม่ดิ
Man#1 says:
ผมไม่ได้ว่าของพี่ผิดไง
Man#1 says:
งงนิดนึง
Man#1 says:
กับข้อมห้าน่ะ
Man#1 says:
เค้าต้องการจะบอกไร
Man#2 says:
ก็ข้อห้า บอกว่า ถ้ารุ้จำนวน นิ้ว จะต้องรุ้จำนวนคน
Man#2 says:
จากสมการ 200 <= nx <= 300
Man#2 says:
แปลว่าถ้ารุ้ n แล้ว จะต้องทำให้ได้ x เป็นจำนวนเต็มอันเดียว
Man#2 says:
(200/n) <= x <= (300/n)
Man#2 says:
ดังนั้น n ที่ทำให้ได้ x เป็นจำนวนเต็มตัวเดียว
Man#2 says:
และ x >= 1
Man#2 says:
ก็คือ n อยู่ใน [101,300]
Man#1 says:
พี่คิดดูดิ
Man#1 says:
ถ้า n หรือ x ไม่ใช้ prime อะไรจะเกิดขึ้น?
Man#1 says:
http://siit.net/webboard/read.php?Topic_ID=41166
Man#2 says:
มันเกี่ยวอะไรกับ prime อะ
Man#2 says:
อ๋อ พี่แทนผิดนี่หว่า
Man#2 says:
ข้อ 5 บอกว่ารุ้จำนวน นิ้วทั้งหมดในห้อง
Man#2 says:
ไม่ใช่จำนวนนิ้วต่อคน
Man#2 says:
ดังนั้นก็เป็น ถ้ารู้ nx แล้ว ต้องรุ้ x
Man#2 says:
ดังนั้น nx ต้องเป็นเลข prime 2 ตัว คุณกันเท่านัน้
Man#2 says:
ไม่งั้น มันจะถ่ายไปมาได้
Man#2 says:
และต้องเป็นเลขที่เหมือนกันด้วย
Man#2 says:
ไม่งั้นสลับที่กันได้
Man#1 says:
เย้ๆ
Man#1 says:
(17,17) ป่าว
Man#2 says:
ใช่
Man#2 says:
ส่วน 19,17 อะผิด
Man#1 says:
เอา ที่คุยกันไปโพส ในบล๊อกผมได้ไม๊
Man#2 says:
ไปโพสดิ

วันจันทร์, กรกฎาคม ๒๓, ๒๕๕๐

ห๊ะ.. อะไรนะ Ubuntu ไม่มี พาสเวิร์ด root!!!

ufonik@ufo-base-ubuntu:~$ su
Password:
su: Authentication failure
หลังจากพาสเวิร์ดทุกตัวที่นึกออกและเคยใช้ถูกใส่ มาขอความช่วเหลือจากเพื่อนบ้านดีกว่า
ก่อนอื่นจะเล่าที่มาของ root ใน ลินุกซ์ และ คำสั่ง su เล็กๆ
root (ราก - นึกถึงต้นไม่กลับหัว รากจะอยู่บนสุด) เป็นยูเซอร์หนึ่ง ใน ลินุกซ์ ที่ทำได้ทุกอย่าง (ลบไฟล์ที่ชาวบ้านลบไม่ได้) เทียบได้คล้ายยูเซอร์ที่ชื่อว่า Administrator ใน Windows(tm) น่ะแหล่ะ
โดยปกติ เวลาล๊อกอินในลินุกซ์ จะให้ใช้ชื่ออื่นที่ไม่ใช่ root ล๊อกอินเข้ามา เพื่อที่จะใด้ไม่ทำไฟล์สำคัญๆในระบบเสียหายได้โดยบังเอิญ

แล้วทีนี้ พอจำทำงานที่ต้องแก้ไฟล์ที่สำคัญมากๆ เช่นสมมติลงโปรแกรมใหม่ ต้องได้รับสิทธิ เป็น root เท่านั้นถึงจะลงได้

วิธีหนึ่งจะทำได้ ก็คือ logout(คำสั่ง exit) ก่อนแล้ว login เข้ามาเป็น root แล้วทำงาน
วิธีก็ได้ แต่มันจะไม่สะดวก เหตุผลสั้นๆ ก็คือ เปิดงานไว้บนโต๊ะเยอะแยะ ต้องปิดงานหมด เพื่อจะเอาปฏิทินหใม่มาตั้งอย่างเดียว ก็ไม่คุ้ม

เลยมีคำสั่ง su (super user) ตามด้วย พาสเวิร์ด
จากนั้น ก็จะแปลงร่างเป็น root วางปฏิทินได้ทันที ไม่ต้องเก็บโต๊ะก่อน

ทีนี้ ในอูบุนตู เล็งเห็น ถึงความเป็นเสือกระดาษของ root ที่ใครๆ ก็มาขอใช้ชื่อไปทำนู่นทำนี้ แต่ตัวเองจริงๆแล้วก็ไม่ได้ทำอะไร
อูบุนตูเลยเอายูเซอร์ root ออกไปจากระบบซะ (ลินุกซ์ ทั่วไปจะต้องบังคับให้มี ยูเซอร์ root เสมอ ถ้าจะสร้าง ยูเซอร์อื่น ก็ค่อยเอายูเซอร์นี้ไปสร้างเอา) แต่ คำสั่ง su ยังอยู่ เอาไว้แปลงร่าง เป็น คนอื่นๆ ไม่จำเป็นว่า แปลงเป็น root อย่างเดียว

ทีนี้ เค้าเลยสร้างคำสั่งใหม่ คล้ายๆ su คือคำสั่ง sudo

sudo ไม่ได้แปลง ร่าง แต่ขอยืมมาแค่อำนาจในการทำงานเท่านั้น (ซึงมันก็ต้องใช้แค่อำนาจนั่นแหละ)

ฉะนั้น ถ้าเราต้องการแปลงร่างจริงๆ ก็ใช้สองคำสั่งคู่กัน
ufnik@ufo-base-ubuntu:~$ sudo su
root@ufo-base-ubuntu:/home/ufonik#
กลายเป็น root แล้ว สังเกตจาก $ เปลี่ยนเป็น #

ถ้าจะแปลงร่างเป็นคนอื่นก็ใส่ ยูเซอร์เนมไป

ufnik@ufo-base-ubuntu:~$ sudo su beckham
root@ufo-base-ubuntu:/home/ufonik#
เท่านี้ก็เป็น beckham ได้ โดยที่ไม่ต้อง logout จากระบบให้เสียเวลา