Archive for the ‘PHP’ Category

Internship, Day 32 (5 Jun 2012)

Posted on June 6th, 2012 in computer, in English, in Thai, personal, PHP, programming | No Comments »

เวลาเหลือน้อยลงไปทุกทีๆ สำหรับการฝึกงานที่ใกล้จะจบลง งานของผมที่ต้องมานั่งแก้บั๊กก็ยังไม่เสร็จ ตอนเช้าผมก็เลยบอกหัวหน้าฝ่ายไปตรงๆ ว่าไม่น่าจะทัน แม้ว่ามันจะไม่ยากแต่มันเยอะมาก และเป็นการแก้บั๊กจากงานที่ไม่ได้ทำเอกสารไว้ ทำให้ไม่รู้ว่าต้องเริ่มแก้ตรงไหนก่อน ต้องมาคอยไล่ดักเอาเองตลอด ที่สำคัญอย่างที่บอกไปในตอนก่อนๆ คือพี่ที่ทำแอพพลิเคชันตัวนี้มาก่อนใช้หน้าต่างแบบ pop-up เยอะมาก ทำให้ไล่โค้ดยากขึ้นไปอีก

เวลาที่เหลือส่วนใหญ่ก็ทำสไลด์เพื่อเตรียมนำเสนอในวันที่ 7 ต่อไป

Time’s running out and the end of internship draws near. I have to continue debugging the job but it’s not quite done so I met the boss and told him it’s not going to finish in time. It’s not that hard, but the code was not documented so I have no idea where the possible code defects are. Most importantly, I might have said this earlier, that this application uses a lot of JS pop-ups which makes it all harder.

Whatever time I have left, I spend them on working with the slide to present on 7th.

Internship, Day 28 (29 May 2012)

Posted on May 29th, 2012 in computer, CPE, in English, in Thai, personal, PHP, programming, SQL | No Comments »


(Photo: Guess where we had our lunch today!)

วันนี้กลายเป็นว่างานไม่ค่อยเดินเท่าไหร่ เนื่องจากผมพยายามสร้าง Task List ที่เอาไว้เก็บว่าลูกค้าแต่ละคนเข้ามาทำอะไรบ้าง ความซับซ้อนมันอยู่ที่การสร้างระบบฐานข้อมูลที่รองรับรายการหลายๆ ชนิดได้ ซึ่งตรงนี้ผมก็ทำโดยใช้ generalization และ specialization และหลังจากที่นั่งมั่วกับโค้ดเป็นเวลานาน ในที่สุดผมก็เริ่มเขียน PHP แบบ MVC เป็นขึ้นมาบ้าง แต่ก็ยังไม่ค่อยเข้าใจเท่าไหร่ ที่บอกว่างานไม่เดินเป็นเพราะว่าที่ทำลงไปจริงๆ ไม่ต้องทำก็ได้ เพราะโค้ดที่มีมามันก็มี Task List อยู่แล้ว แค่เก็บไว้อีกที่นึง อ้อ วันนี้พี่พาไปเลี้ยงมือเที่ยงด้วย ขอบพระคุณมากครับ (ถ้าพี่ตามมาอ่านในนี้นะ ^ ^”)

So I didn’t progress much today. I tried to build a Task List system which keeps track of what each customer does at a particular time. The complexity lies within the database code that needs to support multiple types of entries for the Task List, which can be accomplished using generalization and specialization techniques. After messing around for some time, I started to grasp the concepts of PHP and MVC and can now code a bit more properly. The lack of progress was due to the fact that there’s already a Task List system in place. I was reinventing the wheel all along. Finally, special thanks to the senior that treated me lunch!

The Wheel I did reinvent


Note: Tables authorized_on_customer and equipment and column data in temp_equipment shown here are simplified versions of the “real thing” on the live server.

Internship, Day 27 (28 May 2012)

Posted on May 29th, 2012 in computer, in English, in Thai, personal, PHP, programming, SQL | No Comments »


(Photo: What my friend eats for lunch. Not always like this, but always better than mine.)

เข้าสู่สองสัปดาห์สุดท้ายของการฝึกงานแล้ว ผมก็ยังไปทำงานชิ้นเดิมต่อ โดยวันนี้ผมไปขอพี่สร้างตารางใหม่ลงในฐานข้อมูลได้แล้ว โดยสร้างเป็นตารางขึ้นมาเพื่อใช้เก็บข้อมูลชั่วคราวของ Session ส่วนปัญหาเรื่องโค้ดที่ไม่มีการอธิบายนั้นตอนนี้ผมใช้วิธีสร้างไฟล์ติดต่อฐานข้อมูลแยกไว้ต่างหากออกมาจากตัว MVC ก่อน แต่ก็พยายามใช้ของเดิมเท่าที่ทำได้ ไม่สร้างใหม่ (ปัญหานอกจากการไม่มี document คือเขาเอาปลั๊กอิน JS มาใส่ ทำให้ไล่หน้าต่างๆ ไม่ถูก เพราะต้องมาไล่ทั้ง MVC ไล่ทั้ง JS call) ผลที่ได้วันนี้เลยไม่ก้าวหน้าเท่าที่ควร พี่ก็เร่งให้งานเสร็จ เพราะจะได้ไปทำงานอื่นอีกสองอัน

And now I’ve entered the last two weeks. I still work on the same piece today. I got permission to create new tables necessary to store temporary variables from sessions. The undocumented code problem forced me to build a new (hack) procedural code separate from the MVC architecture provided by CodeIgniter; I still attempted to preserve the old code however. Apart from lack of documentation, there are also JS plugins and they really throw me off balance because I spend too much time hunting each piece down, tracing both JS and MVC. In the end, I have not progressed much despite the expedition given by the senior because they wanted me to do two more pieces.

Internship, Day 26 (25 May 2012)

Posted on May 28th, 2012 in computer, in English, in Thai, personal, PHP, programming, SQL | No Comments »


(Photo: Handling two computers at once…)

สรุปว่าส่วนที่ต้องทำจริงๆ คือ การเก็บพวก session การใช้งานต่างๆ ลงไปพักไว้ในฐานข้อมูลก่อน โอเคครับ ไม่ยาก แต่นาน 555+ ที่ต้องเก็บลงฐานข้อมูลเป็นเพราะว่ามันนานเกินกว่าจะเก็บไว้ด้วย PHP session ครับ

So it’s just storing sessions into the database. It’s not that hard but will take some time to code. The reason for this is because the said session is a real-world session which is longer than a PHP session.

SQL: Insert with respect to reference table

Since there’s not much in the blog today, let’s write another knowledge scrap. A reference table is an enumerated table with IDs against “facts” in a one-to-one manner such as:

 
userclass(id INT, name VARCHAR(20));
+------+----------+
| id   | name     |
+------+----------+
|    1 | normal   |
|    2 | silver   |
|    3 | gold     |
|    4 | platinum |
+------+----------+

usertype(id INT, name VARCHAR(20));
+------+------------+
| id   | name       |
+------+------------+
|    1 | individual |
|    2 | sme        |
|    3 | corporate  |
+------+------------+
 

Say, if we want to insert a “silver sme” user into a table, rather than, with PHP variables, using

 
// Get the reference ID from two tables
$q1 = "SELECT id FROM userclass WHERE name='$class'";
$q2 = "SELECT id FROM usertype WHERE name='$type'";

$r1 = mysql_query($q1);
$r2 = mysql_query($q2);

$s1 = mysql_fetch_assoc($r1);
$s2 = mysql_fetch_assoc($r2);

$classid = $s1 ['id'] ;
$typeid = $s2 ['id'] ;

// Now insert into new table
$q3 = "INSERT INTO user (uname, uclass, utype) VALUES('$username', $classid, $typeid)";
$r3 = mysql_query($q3) or die(mysql_error());
 

we have a “PHP-clean but more SQL-complex” way to do it:

 
$q = "INSERT INTO user (uname, uclass, utype)
       (SELECT '$username', userclass.id, usertype.id
        FROM userclass, usertype
        WHERE userclass.name = '$class'
          AND usertype.name = '$type'
       )";
$r = mysql_query($q) or die(mysql_error());
 

It does not hurt to study SQL. You can in fact extend this to as many reference tables as necessary. This is a generalized version of the SQL code:

 
INSERT INTO target_table (
  fixed_col_1, fixed_col_2, ..., fixed_col_m,
  ref_col_1, ref_col_2, ..., ref_col_n)
  (SELECT fixed_input_1, fixed_input_2, ..., fixed_input_m,
          ref_id_1, ref_id_2, ..., ref_id_n
   FROM ref_table_1, ref_table_2, ..., ref_table_n
   WHERE
     ref_table_1.ref_val_1 = ref_input_1 AND
     ref_table_2.ref_val_2 = ref_input_2 AND
     ... AND
     ref_table_n.ref_val_n = ref_input_n
  );
 

Where:

  • fixed_col_i are target columns you want your fixed inputs to go into
  • ref_col_j are target columns you want your inputs to be referenced into IDs and go into
  • fixed_input_i is the data itself. Usually a string or integer or something else.
  • ref_id_j is the id column from each table j. For brevity I’ll force this column to be int.
  • ref_table_j is the table itself. Each table is defined by ref_table_j (ref_id_j INT, ref_val_j SOME_DATA_TYPE)
  • ref_val_j is the value (or “name”) column from each table j.
  • ref_input_j is the user input, usually supplied from PHP or something else.

It will take some time to understand all this due to my bad English, but I think the code can be studied more easily due to the fact that the code does not belong to any human language — they are just symbols derived from English.

Internship, Day 25 (24 May 2012)

Posted on May 25th, 2012 in computer, in English, in Thai, personal, PHP, programming, SQL | No Comments »


(Photo: Finally got this bun!)

วันนี้ผมก็ทำงานต่อจากเมื่อวานเฉยๆ ครับ ไม่ค่อยมีอะไรมาก แต่สิ่งที่เป็นปัญหาอย่างหนักในการทำงานคือฐานข้อมูลที่ไม่มี Foreign Key เลย แม้ว่าเราจะหาความสัมพันธ์ได้จาก query ต่างๆ ที่มี แต่เป็นเรื่องยากพอสมควรเมื่อเทียบกับการทำฐานข้อมูลให้ชัดเจนตั้งแต่แรก และไม่ทราบว่าตรงไหนเป็นบั๊กเพราะไม่ทราบตั้งแต่แรกว่าโปรแกรมควรจะทำงานอย่างไร ทำให้ผมได้แต่จัดการกับ error message ที่ขึ้นมาชัดๆ เท่านั้น (เปิดจาก log ก็ไม่ได้เพราะเซิร์ฟเวอร์ไม่มีการเก็บ error_log ไว้เลย)

I continued on yesterday’s work and not much else. The big problem exists here again because there are no foreign keys at all in the tables I work with. Even though it’s possible to infer from the other queries, it’s still harder than reading a documented or properly FK’d database. Additionally, I didn’t know which part is bugged because I didn’t know how the program is supposed to work, so I could only fix the real, visible errors. (No logs because the server doesn’t have error_log configured.)

Bonus

By the way, this:

 SELECT x,y
FROM A,B
WHERE A.x = B.y; 

is as fast as:

 SELECT x,y
FROM A
  INNER JOIN B ON A.x = B.y; 

Reference: http://stackoverflow.com/questions/121631/inner-join-vs-where

Internship, Day 24 (23 May 2012)

Posted on May 24th, 2012 in cloud, computer, in English, in Thai, personal, PHP, programming | No Comments »


(Photo: I can has coffee?)

เหมือนอะไรๆ จะกลับเข้าสู่ภาวะปกติอีกครั้งเมื่อผมปิดงานโปรแกรมวิดีโอได้ซักที แต่สุดท้ายก็ไม่เป็นเช่นนั้น เพราะวันนี้ในขณะที่ผมกำลังอ่านเรื่อง Cloud ต่อพี่ก็เอางานใหม่มาให้ทันที งานนั้นคือระบบบันทึกการเข้าออกของลูกค้าที่เข้ามาใน data center

แน่นอน องค์กรมหาชนขนาดนี้เขามีใช้อยู่แต่แรกแล้วละ เพียงแค่ว่าเขาอยากให้ทำละเอียดลงไปอีกเท่านั้นเอง เพราะเดิมข้อมูลลูกค้าจะถูกแยกเป็นรายบริษัท คือเป็นความสัมพันธ์แบบ one-to-many จากบริษัทไปหาบุคคล (คือ บริษัทหนึ่งมีหลายคนที่เข้าออก data center ได้) แบบใหม่ต้องการแทรกรายละเอียดงานในระดับ project ลงไปด้วย ทำให้เป็น one-to-many-to-many จากบริษัทไปหาโปรเจคไปหาบุคคลแทน

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

Everything seemed to calm down when I close my video task, but it finally was not the case because while I was reading about Cloud the senior came and tasked me with a new job: visitor logging for data center.

Surely, this kind of public corporation already has one, but they want me to go a bit into deeper detail. Customer data relationship used to be one-to-many of company-to-person (one company may have many persons that can access the data center) but the new one will have “project” stuffed in the middle, giving a one-to-many-to-many of company-project-person.

Fortunately there already exists an application that does this and it is already being worked on. The problem is it bugs a lot and the seniors who worked on it no longer had time to continue this project. I have my own problem though: I have no experience with CodeIgniter MVC which this project uses.

Useful reads for vCloud:
http://www.yellow-bricks.com/2010/08/31/vmware-vcloud-director-vcd/
http://www.yellow-bricks.com/2010/09/07/vcd-networking-part-1-intro/
http://frankdenneman.nl/2010/09/provider-vdc-cluster-or-resource-pool/

Internship, Day 21 (18 May 2012)

Posted on May 19th, 2012 in cloud, computer, in English, in Thai, personal, PHP, programming | No Comments »


(Photo: We have SCB. Your argument is invalid. << Wait what?!)

วันนี้ผมเริ่มจากการทำระบบตรวจสอบและปรับไฟล์ก่อนเลย โดยคราวนี้มามาดใหม่ แทนที่จะเอาไฟล์มาไล่ทีละชื่อ (โคตรเชยเลย) ผมใช้คำสั่ง array_diff($a, $b) เพื่อหา A-B (เมื่อ A และ B เป็นเซตที่แทนด้วยอาร์เรย์ $a และ $b ตามลำดับ) แล้วลบหรือโหลดไฟล์ทีเดียวหมดเลย ง่ายดี ทำไมตอนนั้นคิดไม่ได้แบบนี้ก็ไม่รู้ จากนั้นผมก็เขียนคู่มือการใช้งานต่อจนจบ โดยเปลี่ยนจาก text เป็น HTML จะได้อ่านง่ายๆ หน่อย แล้วก็ใส่ spinner (ไอ้ตัวหมุนๆ เวลารอ ajax ทำงาน) ขณะมีการดาวน์โหลดไฟล์ที่ใช้เวลาค่อนข้างนานโดยใช้ spin.js ซึ่งใช้งานได้ง่ายและเป็น MIT License ด้วย จึงนำมาใช้กับชิ้นงานของบริษัทได้ทันที

สุดท้ายผมก็เลยได้ทำงานชิ้นต่อไปคือการศึกษาเกี่ยวกับ vCloud Director อธิบายกันสั้นๆ จากผู้เริ่มต้น vCloud Director เป็นตัวที่มาครอบบน vCenter อีกที ก็หลักๆ ก็รู้แค่นี้แหละครับ (ยอมรับว่ารู้แค่นี้ เพราะตรงนี้เป็นรายงานประจำวัน ไม่ใช่บทความ) สำหรับลิงค์ที่อ่านไปจะไว้ท้ายเอนทรีนะครับ

Today I started from file consistency restorer, which I revised to use array_diff($a, $b) to find missing or extra files and take appropriate actions. Then, I finished the manual, which I converted into HTML format from plain text. Finally, I added spinner (that spinning thing when there are ajax calls) using spin.js , which uses MIT License and thereby is compatible with this work.

At the end of the day I started reading about vCloud Director. From a newbie, it’s something that runs on top of vCenter. That’s all I know. (And I’m going to admit my limits here because this is a daily report not an article).

References

http://www.yellow-bricks.com/2010/08/31/vmware-vcloud-director-vcd/
http://frankdenneman.nl/2010/09/provider-vdc-cluster-or-resource-pool/

Internship, Day 19 (16 May 2012)

Posted on May 17th, 2012 in computer, CPE, in English, in Thai, personal, PHP, programming | No Comments »

วันนี้ผมไปทำงานก็เจอดีแต่เช้าเลย เพราะหัวหน้าฝ่ายเรียกให้ไปคุยงานนิดหน่อย สรุปได้ใจความว่าผมต้องอ่านเรื่อง vCloud Director แล้วทำสไลด์ไปอธิบายให้ฟัง

ต่อมา ผมก็ทำงานต่อ แต่ไม่ทันไรพี่เลี้ยงก็มาคุยเรื่องการอัพโหลดไฟล์ขึ้น Aruba Captive Portal ซึ่งอัพไปแล้วมันใช้งานไม่ได้ด้วยเหตุผลบางประการ คือ พออัพไปแล้ว (หน้า video player ของผมเป็น iframe) มันพยายามที่จะเรียก iframe ขึ้นมาแต่ทำไม่ได้ โดยไม่ว่าจะ request ไปกี่ครั้งก็ได้ HTTP 302 กลับมาตลอด (ควรเป็น 200) และติดลูปอยู่อย่างนั้นจนเบราเซอร์หยุดการทำงานให้เอง อาการนี้ไม่รู้จะแก้ยังไง แถมไฟล์ที่จะเล่นอยู่บน YouTube ยิ่งยากเข้าไปใหญ่ เลยตัดสินใจเอาระบบโหลดไฟล์กลับมาอีกครั้ง แต่มาในร่างใหม่ที่บริหารในระดับ playlist แทน นั่นคือ ทั้ง playlist จะต้องเป็น YouTube หรือเป็น MP4 อย่างใดอย่างหนึ่ง (แต่ต้นกำเนิดมาจาก YouTube เหมือนกัน คือ สร้าง YouTube playlist ก่อน แล้วค่อยโหลดไฟล์มาลงเครื่องอีกทีด้วย youtube-dl)

เวลาที่เหลือทั้งวันของผมก็หมดไปกับการทำให้ตรงนี้มันใช้งานได้ครับ แต่ทำได้ไม่เท่าไหร่ เพราะผมต้องแก้โค้ดเก่าอยู่พอสมควร ตอนนี้มันกลับมาโหลดไฟล์ได้แล้ว แต่โหลดมาแล้วยังไม่เกิดประโยชน์อะไรเพราะไม่มีตัว player ที่จะเอาไว้เล่นไฟล์ที่โหลดมาครับ

Today I was summoned to the Department and he assigned me to read vCloud Director, then make a presentation to explain to him.

Then I continued my work for a bit before supervisor discussed uploading the file to Aruba Captive Portal, which failed. For some reasons after uploading (the video player which uses an iframe), the iframe (stored on “media server” separate from Aruba) cannot be loaded and the browser always gets HTTP 302, instead of 200, over and over until browser killed the tab. I don’t know how to fix it yet, but the fact that the files are on YouTube will make it all worse so we decided to bring back the file download system, in a new form that it is managed at playlist level instead, downloading entire playlists at a time. All or nothing. First, the user would create a YouTube playlist, then “convert” it to MP4.

I spent the rest of the day implementing all that, but did not progress much due to wrestling with the old code. It can now load files, but cannot play them yet.

[jQuery] … for MySQL Data Manipulation in PHP

Posted on May 16th, 2012 in computer, dedicated entry, in Thai, PHP, programming | No Comments »

<< อ่านบทที่แล้ว (jQuery for Beginners)

ก็กลับมาอีกครั้งกับหัวข้อ jQuery นะครับ วันนี้ผมจะมาเสนอเรื่องการใช้ jQuery ติดต่อกับฐานข้อมูลผ่าน PHP แบบง่ายๆ (ง่ายมากๆ) กัน

ก่อนที่เราจะทำอะไร เราต้องโหลด starter code กันก่อนครับ ถ้าโหลดแล้วก็ทำตามคำแนะนำที่ให้ไป จากนั้นก็เริ่มกันเลย

การอ่านค่าจากฟอร์ม

การอ่านค่าจาก form field ต่างๆ สามารถทำได้โดยใช้ .val() ยกตัวอย่างเช่น จากไฟล์ HTML ต่อไปนี้

 <form>
  <input type="text" id="name" name="name">
  <input type="button" id="btname" name="btname">
</form> 

เราสามารถเอาค่าออกมาจาก field “name” ได้โดยใช้คำสั่ง jQuery (บรรทัดบน) หรือ JS ธรรมดา (บรรทัดล่าง) ได้ดังนี้

 $("#name").val()
document.getElementById("name").value 

โจทย์: จาก starter code ที่ให้ไป ให้เปิดไฟล์ user.html ขึ้นมา ลองพิมพ์อะไรก็ได้ลงไปในช่องทั้งสอง ยังไม่ต้องทำอะไร จากนั้นให้ใช้คำสั่ง val ในการดึงค่าออกมา

การเรียกหน้า PHP จาก jQuery

เรามีไฟล์สองไฟล์ คือ signup.php กับ login.php ซึ่งเป็นไฟล์ที่สร้างผู้ใช้ใหม่กับทำการ login (แบบปลอมๆ) โดยไฟล์ทั้งสองนี้เป็นตัวแทนการ insert และการ select ตามลำดับ ให้ศึกษาไฟล์ให้เข้าใจก่อนที่จะอ่านต่อ …………………… หากอ่านจนพอเข้าใจ จะเห็นว่า ไฟล์ทั้งสองรับตัวแปรชื่อ user กับ pass แล้วเอาไปทำอะไรบางอย่างกับฐานข้อมูล จากนั้นมันจะ print ค่าออกมาหนึ่งในสองค่าคือ “OK” หรือ “FAILED” ขึ้นกับผลการทำงานที่ได้

เมื่อคราวที่แล้วผมสอนให้ผู้อ่านใช้คำสั่ง $.get ไป คราวนี้จะเปลี่ยนมาใช้คำสั่ง $.post บ้าง สำหรับ $.post ไม่ต่างอะไรจาก $.get เลยในแง่ของการใช้งาน ต่างกันแค่ความหมายนิดหน่อยเท่านั้น (สั้นๆ: GET ใช้ในการดึงข้อมูลออกมา โดยใส่ตัวแปรต่อจาก URL ในขณะที่ POST ใช้ในการส่งข้อมูลขึ้นระบบ โดยส่งตัวแปรด้วย HTTP Protocol ในส่วนที่ไม่ใช่ URL)

เช่น หากผมต้องการให้ส่งตัวแปร ‘ticket’ มีค่าเท่ากับ 814418 ไปยังหน้า ‘lottery.php’ โดยเมื่อ PHP ตอบกลับมาแล้วให้แสดงว่าได้รางวัลอะไร ก็จะมีโค้ดสองส่วน คือส่วนของ PHP ก่อน

 //LOTTERY PRIZE LOOKUP
function prize($ticket){
  if($ticket==814418){
    return "First Prize!!"
  } else if (in_array($ticket%1000,Array(504,309,902,101)){
    return "..."
  } // ... (whatever)
}

print prize($_POST ['ticket'] ); 

สังเกตว่าเมื่อเราเรียกไฟล์จริงๆ ไฟล์ lottery จะ print ไม่ใช่ return ซึ่งถูกต้องแล้ว เพราะการเรียก jQuery หรือ ajax มันจะไม่รู้ว่า return อะไรออกมา มันจะเอาแต่สิ่งที่ print ออกมาเท่านั้น

จากนั้นเราไปดู jQuery กันต่อ

 //LOTTERY CHECKER
function checkPrize(ticket){
  $.post(
         'lottery.php',
         {'ticket': ticket},
         function(output){alert(output);}
        );
}

checkPrize(814418); 

อธิบาย: โค้ดนี้จะเรียก lottery.php โดยใช้วิธี POST ส่งตัวแปร ticket ไปหนึ่งตัวมีค่า 814418 ส่วนฟังก์ชันที่รับ output เราเรียกว่า “ฟังก์ชันนิรนาม” (anonymous function) ซึ่งถูกกำหนดขึ้นมาเฉพาะกิจ ใช้งานแค่ใน scope เท่านั้น เช่น ในกรณีนี้ ฟังก์ชันจะเอา output แสดงออกมาผ่าน alert เป็นต้น หากอธิบายคร่าวๆ (มากๆ) ก็จะได้อะไรที่คล้ายๆ กับรูปข้างล่าง

เอาเป็นว่าเราเอาไว้เท่านี้ก่อน สำหรับโจทย์ในวันนี้คือ “พยายาม hack ตัว login ของผมด้วย SQL Injection ให้ได้” สำหรับคราวหน้าหากผมมีแรงเหลือจะมาอธิบายว่าทำไม SQL Injection จะใช้ได้หรือไม่ได้กับชุดคำสั่ง JQ2 ของผมนะครับ :)

Internship, Day 13 (8 May 2012)

Posted on May 9th, 2012 in computer, CPE, in English, in Thai, personal, PHP, programming | No Comments »


(Photo: A report to be submitted to the company)

วันนี้ผมลืมบัตรพนักงานไว้ที่บ้าน ซึ่งแน่นอนว่าต้องกลับไปเอา ไม่เช่นนั้นจะเกิดความลำบากหลายอย่างมากตลอดทั้งวัน แต่กว่าจะกลับไปเอาบัตรแล้วกลับมาทำงานได้ก็เกือบสายเช่นกัน (ก็ยังดีที่ไม่สาย แต่ท่อนบนเปียกเหงื่อเต็มๆ ฮ่าๆ)

เข้าเรื่องกันดีกว่า ผมต้องการให้ระบบจัด playlist ของผมเรียงลำดับได้ด้วย (เช่น อยากสลับให้ไฟล์ 2 เล่นก่อนไฟล์ 1) แต่ไม่รู้ว่าจะสลับข้อมูลในฐานข้อมูลยังไงให้เหมาะสม ผมเลยใช้วิธีลบทั้งหมดแล้วสร้างใหม่เอาดื้อๆ เลย โดยใช้ความรู้เกี่ยวกับ transaction ในการรักษาสภาพฐานข้อมูล เพราะการลบสร้างใหม่จะมีหลายขั้นตอนมาก และหากมีปัญหาจะทำให้ข้อมูลที่เก็บไว้เสียหายได้ สำหรับการใช้ transaction ใน mysqli นั้นไม่ยาก แต่ขอเก็บไว้ทีหลังเหมือนเดิมครับ นอกจากนี้ เพื่อให้ได้ความเร็วในการทำงานมากขึ้น ผมจึงทดลองนำ prepared statements ออกมาใช้ด้วย

ต่อมา ผมก็ทำระบบดึง playlist กลับออกมา อันนี้ไม่ค่อยยากแล้ว แค่ใช้ SELECT ด้วย SQL จากนั้นจึง print ผ่าน json_encode เพื่อให้เรียกผ่าน jQuery ได้ง่ายๆ

พี่มาบอกว่า iPad ใช้งานตัวนี้ไม่ได้ ผมก็ไม่ค่อยแน่ใจว่าเกิดอะไรขึ้น (ยกเว้นว่าผมจะมี iPad ใช้ซักตัว 555+) แต่ก็ลง jQuery UI Touch Punch ไปแล้ว น่าจะใช้ได้ดีขึ้นเพราะผมทดลองใช้งานดูก็ไม่มีปัญหาแล้ว แต่ถ้าจะทำใช้บนมือถือคงต้องลดขนาดภาพลงอีก (ลองดูแล้วเต็มจอมากๆ)

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

I forgot the staff ID at home, so I had to go back and get it to avert further complications. As a result, I was almost late for work, sweating all over.

On point. I wanted the playlist manager to support “sorting” playing order, but I don’t know the optimal method so I just wiped the playlist and create it anew, using what I learned about transactions. I used transactions because it needed many steps to complete and I can’t risk any problem. Using transactions in mysqli is not very hard, so is “prepared statements” feature.

Then, I created the playlist loader that pulls data back from the database. I already got the hang of it, and a simple SELECT + json_encode did it all very well.

Senior staff came and told me it’s not working on iPad. I’m not sure how it looked like (unless I had, of course, an iPad!) but I installed jQuery UI Touch Punch and it partially works now. (Partial because there’s no screen real estate on my phone!!)

Finally, I don’t want to list every single playlist when user wants to find one so I used AutoComplete. It’s a bit tricky, but I’ll try to keep it easy. The end product is a text field with, of course, AutoComplete. If user enters something not already in the list, it will be added after the playlist is saved.

mysqli transactions with prepared statements

(I’m using procedural style here, and I assume that you’ve already created a connection.)

 // Disable autocommit (we're doing it manually here)
mysqli_autocommit($db, false);

// Your query here
// Replace potential variables with question marks
$q = "INSERT INTO files (fileName, fileAuthor) VALUES (?, ?)";

$stmt = mysqli_prepare($db, $q) or die('Prepare Failed');

// If we have an array, we can foreach over it
foreach ($newData as $row){
  $bind = mysqli_stmt_bind_param($stmt,'ss',$row ['Name'] ,$row ['Author'] );
  if (!$bind){
    mysqli_rollback($db);
    die('Bind Failed');
  }

  $result = mysqli_stmt_execute($stmt);
  if (!$result) {
    mysqli_rollback($db);
    die('Insert Failed');
  }
}

// All done, we can now commit and re-enable autocommit
mysqli_commit($db);
print('OK! All done!');

mysqli_autocommit($db, true); 

jQuery UI AutoComplete

HTML Part: Interface

 <div id="menu-container" style="position:absolute; width: 20px;"></div>
<input type="text" name="searchq" id="searchq"> 

JS Part: Just one function

 $(function(){
  $("#searchq").autocomplete({
    source:'get_data.php',
    minLength: 1,
    delay: 100,
    appendTo: '#menu-container'
  });
}); 

PHP Part is the trickiest. You will need to accept a GET variable, $_GET ['term'] , which are supplied as the user types into the text box. Yes, you will need to perform filtering here. The following is the easiest method, displaying every candidate alphabetically without limit.

 function filter_result($term){
  $r = mysqli_query("SELECT fileName FROM files WHERE fileName LIKE '%$term%'");
  $result = Array();
  while($row = mysqli_fetch_assoc($r)){
    $result []  = $row ['fileName'] ;
  }
  return $result;
}
print json_encode(playlist_list($_GET ['term'] )); 

Reference: [StackOverflow]