วันพฤหัสบดีที่ 27 พฤศจิกายน พ.ศ. 2557

การทำงานไฟล์ และไดเรคทอรี

เมื่อทราบถึงไวยากรณ์เบื้องต้น การเข้าถึงและควบคุมข้อมูลภายในฟอร์ม HTML ต่อไปค้นหาวิธีการเก็บสารสนเทศเป็นไฟล์ข้อความ (text file) สำหรับการใช้ต่อไป โดยจะเป็นการเก็บและโหลดด้วยการเขียนลงไฟล์และอ่าน เมื่อมีปริมาณข้อมูลมากต้องใช้ระบบจัดการฐานข้อมูล เช่น MySQL

การเปิดและปิดไฟล์
การประมวลผลไฟล์เริ่มต้นและสิ้นสุดด้วยการเปิดไฟล์และปิดไฟล์

การเปิดไฟล์
การเปิดไฟล์ใน PHP ใช้ฟังก์ชัน fopen ไฟล์ที่เปิดต้องระบุลักษณะการเปิดหรือโหมดไฟล์ (file mode)

โหมดไฟล์
ระบบปฏิบัติการบนแม่ข่าย จำเป็นต้องทราบถึงการทำงานกับไฟล์ที่มีการเปิด โดยต้องทราบว่าถ้าไฟล์ได้รับการเปิดโดยอีกสคริปต์ ขณะที่มีการเปิดและทำงาน ถ้าผู้เปิด (เจ้าของสคริปต์) มีสิทธิในการทำงานนั้น
โดยเฉพาะอย่างยิ่ง โหมดไฟล์ไห้กลไกกับระบบปฏิบัติการในการหาวิธีควบคุมการเข้าตามคำขอจากบุคคล หรือสคริปต์และวิธีการตรวจสอบการเข้าถึงและสิทธิกับไฟล์เฉพาะเจาะจง
ทางเลือกในการทำงานเมื่อเปิดไฟล์มี 3 ทางเลือก
เปิดไฟล์สำหรับอ่านอย่างเดียว เขียนอย่างเดียว หรือทั้งการอ่านและการเขียน
ถ้าเขียนไฟล์ อาจจะมีการเขียนทับข้อมูลเดิมของไฟล์ หรือเพิ่มข้อมูลต่อท้ายไฟล์
ถ้ากำลังพยายามเขียนไฟล์บนระบบที่ต่างกันระหว่างไฟล์ไบนารีกับไฟล์ข้อความ ควรระบุ
ฟังก์ชัน fopen() สนับสนุนตัวเลือกทั้ง 3 แบบ

 fopen
fopen() มีไวยากรณ์เป็น
$handle = fopen (filename, mode, [include_path]);
filename เป็นข้อความระบุพาร์ทของไฟล์ สามารถเป็นพาร์ทสมบูรณ์
'/home/book/orders/orders.txt'
หรือ พาร์ทสัมพัทธ์กับไดเรคทอรีปัจจุบัน
'../orders/orders.txt'
ตัวอย่างชุดนี้เรียกใบสั่งซื้อเป็น
$fp = fopen ("$DOCUMENT_ROOT/../../orders/orders.txt", "w");
ถ้าไม่ระบุพาร์ท ไฟล์จะได้รับการสร้างหรือค้นหาในไดเรคทอรีเดียวกับสคริปต์
พารามิเตอร์ที่ 2 ของ fopen () คือโหมดไฟล์ และต้องเป็นข้อความ การระบุนี้บอกถึงความต้องการทำงานกับไฟล์ ในกรณีที่ส่งผ่าน "w" ไปยัง fopen () หมายความว่า เปิดไฟล์สำหรับการเขียนการสรุปโหมดไฟล์ แสดงในตาราง 1.3.1
ตาราง 1.3.1 สรุปโหมดไฟล์สำหรับ fopen
โหมด     ความหมาย
r โหมดอ่าน เปิดไฟล์สำหรับการอ่าน เริ่มทำงานจากตอนต้นไฟล์
r+โหมดอ่าน เปิดไฟล์สำหรับการอ่านและเขียน เริ่มทำงานจากตอนต้นไฟล์
wโหมดเขียน เปิดไฟล์สำหรับการเขียน เริ่มทำงานจากตอนต้นไฟล์ ถ้าไฟล์มีอยู่แล้วจะลบข้อมูลที่มีอยู่ ถ้าไม่มีไฟล์จะสร้างขึ้นใหม่
w+โหมดเขียน เปิดไฟล์สำหรับการเขียนและอ่าน เริ่มทำงานจากตอนต้นไฟล์ ถ้าไฟล์มีอยู่แล้วจะลบข้อมูลที่มีอยู่ ถ้าไม่มีไฟล์จะสร้างขึ้นใหม่
aโหมดเพิ่ม เปิดไฟล์สำหรับการเพิ่ม (เขียน) เริ่มทำงานจากจุดสิ้นสุดของข้อมูลที่มีอยู่ ถ้าไม่มีไฟล์จะได้รับการสร้างขึ้นใหม่
a+โหมดเพิ่ม เปิดไฟล์สำหรับการเพิ่ม (เขียน) และอ่าน เริ่มทำงานจากจุดสิ้นสุดของข้อมูลที่มีอยู่ ถ้าไม่มีไฟล์จะได้รับการสร้างขึ้นใหม่
bโหมดไบนารี ใช้ร่วมกับโหมดอื่น โดยอาจจะจำเป็น ถ้าระบบไฟล์แยกระหว่างไฟล์ไบนารีและไฟล์ข้อความ ระบบ Windows มีการแยก แต่ระบบ Unix ไม่มีการแยก
ตามตัวอย่างมีการโหมด “w” ซึ่งจะยอมให้มีเพียง 1 ใบสั่งซื้อในไฟล์ แต่ละครั้งเมื่อมีใบสั่งซื้อใหม่จะ เขียนทับใบสั่งซื้อเก่า ดูเหมือนว่าจะไม่มีเหตุผล ดังนั้นควรระบุเป็นโหมดเพิ่ม
$fp = fopen ("../orders /orders.txt.", "a");
 พารามิเตอร์ที่ 3 ของ fopen() เป็นตัวเลือก สามารถใช้พารามิเตอร์นี้ ถ้าต้องการค้นหา include_path  ของไฟล์ ถ้าต้องการทำให้ตั้งค่าพารามิเตอร์เป็น 1 ถ้าบอก PHP ให้ค้นหา include_path จะไม่จำเป็นให้ชื่อไดเรคทอรีหรือพาร์ท
$fp = fopen ("orders.txt ", "a", 1);
ถ้า fopen() เปิดไฟล์สำเร็จ พอยเตอร์ของไฟล์ ได้รับการส่งออกและควรเก็บในตัวแปร ในกรณีที่นี้คือ $fp ตัวแปรนี้สามารถใช้เข้าถึงไฟล์ เมื่อต้องการอ่านหรือเขียน

เปิดไฟล์สำหรับ FTP หรือ HTTP
นอกจากการเปิดไฟล์สำหรับการอ่านและเขียนแล้ว สามารถเปิดไฟล์ผ่าน FTP และ HTTP ด้วยฟังก์ชัน fopen()
ถ้าชื่อไฟล์เริ่มต้นด้วย ftp:// การเชื่อมต่อ FTP ในโหมด Passive จะได้รับการเปิดด้วยแม่ข่ายตามการระบุและพอยเตอร์เพื่อเริ่มต้นไฟล์ที่ส่งออก
ถ้าชื่อไฟล์เริ่มต้นด้วย http:// การเชื่อมต่อ HTTP จะได้รับการเปิดด้วยแม่ข่ายตามการระบุและพอยเตอร์ที่ตอบสนองการส่งออก เมื่อใช้โหมด HTTP ต้องมี slash ต่อท้ายบนชื่อไดเรคทอรีดังนี้
http: //www.server.com/
ไม่ใช่
http://www.server.com
เมื่อระบุตามรูปแบบหลัง (ไม่มี slash) แม่ข่ายเว็บ จะใช้ HTTP redirect เพื่อส่งไปยัง address แรก (มี slash) เหมือนความพยายามของ browser
ฟังก์ชัน fopen() ไม่สนับสนุน HTTPredirect ดังนั้นต้องระบุ URL ที่อ้างถึงไดเรคทอรีกับ slash ท้าย
ชื่อโดเมนใน URL ไม่มีผลจากตัวพิมพ์ แต่พาร์ทและชื่อไฟล์มีผล

ปัญหาการเปิดไฟล์
ถ้าการเรียก fopen() ล้มเหลว ฟังก์ชันจะส่งออก FALSE ทำให้สามารถทำงานกับความผิดพลาด แบบผู้ใช้คุ้นเคย (user-friendly) โดยการปิดข่าวสารผิดพลาดของ PHP และกำหนดคำอธิบายที่สื่อความหมายเอง
@ $fp = fopen("$DOCUMENT_ROOT/../../orders/orders.txt ", "a");
if (!$fp)
{
echo "<p><strong> ใบสั่งซื้อของท่านไม่สามารถประมวลในขณะนี้  "
."โปรดทำคำสั่งซื้อใหม่ภายหลัง</strong></p></body></html>";
exit;
}
สัญลักษณ์ @ หน้าการเรียก fopen() บอก PHP ให้ปิดผลลัพธ์ความผิดพลาดจากฟังก์ชัน
หมายเหตุ   สัญลักษณ์ @ ต้องอยู่ที่จุดเริ่มต้นของบรรทัดที่อาจจะเกิดความผิดพลาด

การปิดไฟล์
เมื่อเสร็จสิ้นการใช้ไฟล์ ควรปิดไฟล์ด้วยฟังก์ชัน  fclose ()
fclose ($fp);
ฟังก์ชันนี้ส่งออก TRUE ถ้าปิดสำเร็จ หรือ FALSE ถ้าปิดไม่ได้ ความผิดพลาดโดยทั่วไปเกิดขึ้นน้อยกว่าการเปิดไฟล์ ดังนั้นในกรณีที่จึงเลือกไม่ทดสอบ

การเขียนลงไฟล์
การเขียนลงไฟล์ใน PHP ทำได้ง่าย โดยสามารถใช้ฟังก์ชัน fwrite() หรือ fputs การเรียก fwrite() เขียนดังนี้  fwrite ($fp , $outputstring);
นี่เป็นการบอก PHP ให้เขียนข้อความที่เก็บใน $outputstring ไปยังไฟล์ที่ชี้โดย $fp

พารามิเตอร์สำหรับ fwrite ()
ฟังก์ชัน fwrite () ใช้ 3 พารามิเตอร์ แต่ตัวที่ 3 เป็นตัวเลือก ไวยากรณ์สำหรับ fwrite() คือ
int fwrite (int fp, string str, int [length]);
พารามิเตอร์ที่ 3 length เป็น จำนวนไบต์มากที่สุดในการเขียน ถ้ากำหนดพารามิเตอร์นี้ fwrite () จะเขียนข้อความตามพารามิเตอร์ string ไปยังไฟล์ที่ชี้โดย fp จนกระทั่งจบ string หรือเท่ากับจำนวน length ไบต์ แล้วแต่ค่าใดมาถึงก่อน

รูปแบบไฟล์
เมื่อกำลังสร้างไฟล์ข้อมูล รูปแบบของข้อมูลจึงกับการออกแบบให้เหมาะสม อย่างไรก็ตาม ถ้าว่างแผนการใช้ไฟล์ข้อมูลกับโปรแกรมประยุกต์อื่น ต้องทำตามกฎของโปรแกรมประยุกต์นั้น
สมมติให้สร้างข้อความที่แสดง 1 เรคคอร์ดในไฟล์ข้อมูล สามารถทำได้ดังนี้
$outputstring = $date." \t แชมพู ".$shampooqty." ขวด \t ครีมนวดผม "
.$conditionerqty." ขวด \t"." สบู่ ".$soapqty." ก้อน \t ฿".$total
."\t ". $address."\n";
ในตัวอย่างได้เก็บแต่ละเรคคอร์ดแยกคนละบรรทัด การเลือกเขียนเรคคอร์ดต่อบรรทัด เพราะสามารถใช้ตัวแบ่งเรคคอร์ดอย่างง่ายด้วยตัวอักษรบรรทัดใหม่ เนื่องจากบรรทัดใหม่มองไม่เห็นจึงแสดงแทนด้วยตัวควบคุม "\n"
การเขียนฟิลด์ข้อมูลมีลำดับเดียวกันทุกครั้งและแบ่งฟิลด์ด้วย เช่นเดียวจากตัวอักษรมองไม่เห็น จึงแสดงแทนด้วยตัวควบคุม อาจจะเลือกตัวแบ่งที่เหมาะสมเพื่อให้ง่ายเมื่ออ่านกลับมา

การอ่านไฟล์
สคริปต์นี้ทำตามลำดับปกติ คือ เปิดไฟล์, อ่านไฟล์ และ ปิดไฟล์ โดยอ่านชื่อ order.txt ที่เก็บในไดเรคทอรี order ภายนอกโครงสร้างเอกสาร
<?php
@ $fp = fopen("$DOCUMENT_ROOT/../../orders/orders.txt", "r");
if (!$fp)
{
echo "<p><strong>ไม่มีใบสั่งซื้อค้าง"
."พยายามอีกครั้งภายหลัง</strong></p></body></html>";
exit;
}
while (!feof($fp))
{
$order= fgets($fp, 100);
echo $order."<br/>";
}
fclose($fp);
?>
ต่อไปดูรายละเอียดฟังก์ชันในสคริปต์

เปิดไฟล์สำหรับการอ่าน
การเปิดไฟล์ใช้ fopen ในกรณีนี้ เปิดไฟล์สำหรับการอ่านอย่างเดียว ดังนั้นใช้โหมดไฟล์ “a”
$fp = fopen ("$DOCUMENT_ROOT/../../orders/orders.txt", "a");

รับรู้การสิ้นสุด
ตัวอย่างนี้ ใช้ while loop อ่านไฟล์จนกระทั่งสิ้นสุดไฟล์ การทดสอบไฟล์สิ้นสุดใน ใช้ฟังก์ชัน feof()
while (!feof ($fp))
ฟังก์ชัน feof ใช้พอยเตอร์ไฟล์เพียงพารามิเตอร์เดียว โดยจะส่งออก TRUE ถ้าพอยเตอร์ไฟล์อยู่ที่ จุดสิ้นสุดไฟล์ feof ย่อมาจาก File End of File

อ่าน 1 บรรทัดต่อครั้ง
ในตัวอย่างนี้ ใช้ฟังก์ชัน fgets() ในการอ่านจากไฟล์
$order = fgets($fp, 100);
ฟังก์ชันนี้ใช้อ่าน 1 บรรทัดต่อครั้งจากไฟล์ ในกรณีนี้จะอ่านจนกระทั่งพบตัวอักษรบรรทัดใหม่ (\n) พบกับ EOF หรืออ่าน 99 ไบต์จากไฟล์ ความยาวการอ่านมากที่สุดคือ ความยาวกำหนดลบด้วย 1 ไบต์
fgetss เป็นอนุพันธ์ที่น่าสนใจของ fgets และมีไวยากรณ์ดังนี้
string fgetss (int fp, int length, string [allawable_tags]);
ฟังก์ชันที่คล้ายกับ fgets() ยกเว้น การตัด tag ของ PHP และ HTML ที่พบในข้อความ ถ้าต้องการเก็บ tag เฉพาะ สามารถระบุใน allawable_tags
fgetcsv () เป็นอีกอนุพันธ์ของ fgets และมีไวยากรณ์ดังนี้
array fgetcsv (int fp, int length, string [delimiter];
ฟังก์ชันนี้ใช้กับการแบ่งบรรทัดของไฟล์ด้วยตัวแบ่ง เช่น ตัวอักษร tab หรือจุลภาค
พารามิเตอร์ length ควรยาวกว่าความยาวตัวอักษรของบรรทัดยาวที่สุดในไฟล์ที่กำลังอ่าน

อ่านทั้งไฟล์
แทนที่จะอ่านไฟล์ที่ละบรรทัด สามารถอ่านไฟล์ทั้งหมดใน 1 ครั้ง มีวิธีการอ่าน 3 วิธี
วิธีที่ 1 ใช้ readfile ()  สามารถแทนที่สคริปต์ข้างบนด้วยคำสั่ง 1 บรรทัด
readfile ("$DOCUMENT_ROOT/../../orders/orders.txt");
การเรียนฟังก์ชัน readfile() เปิดไฟล์ จะส่งข้อมูลตามผลลัพธ์มาตรฐาน browser จากนั้นปิดไฟล์ ไวยากรณ์ของ readfile() คือ int readfile (string filename, int  [use_include_path]);
พารามิเตอร์ที่ 2 เปิดตัวเลือกระบุให้ PHP มองหาไฟล์ใน include_path และทำงานเหมือนกับ fopen () ฟังก์ชันที่ส่งออกจำนวนไบต์ที่อ่านจากไฟล์
วิธีที่ 2 ใช้ fpassthru วิธีนี้ต้องเปิดไฟล์ด้วยการใช้ fopen() ก่อน จากนั้นส่งผ่านพอยเตอร์ไฟล์เป็นอากิวเมนต์ไปยัง fpassthru() ซึ่งจะเทกองข้อมูลจากตำแหน่งพอยเตอร์ตามผลลัพธ์มาตรฐาน ไฟล์ได้รับการปิดเมื่อเสร็จสิ้น
สคริปต์ข้างต้นสามารถแทนที่ด้วย fpassthru ได้ดังนี้
$fp = fopen ("$DOCUMENT_ROOT/../../orders/orders.txt", "a");
fpassthru ($fp);
ฟังก์ชัน fpassthru ()  ส่งออก TRUE ถ้าอ่านสำเร็จ และ FALSE ถ้าไม่สำเร็จ
วิธีที่ 3 เป็นการอ่านทั้งไฟล์ด้วยฟังก์ชัน file() ฟังก์ชันนี้เหมือนกับ readfile() ยกเว้น ส่งออกเป็น array แทนที่ส่งข้อมูลตามผลลัพธ์มาตรฐาน การเรียกเป็นการอ้างอิง
$filearray = file ($fp);
คำสั่งที่อ่านทั้งไฟล์เข้าสู่ array ชื่อ $filrarray แต่ละบรรทัดของไฟล์เก็บในแต่ละหน่วยข้อมูลของ array

การอ่านตัวอักษร
อีกวิธีในการประมวลผลคือ การอ่านที่ละตัวอักษรจากไฟล์ โดยการใช้ฟังก์ชัน fgetc() ฟังก์ชันที่ใช้พอยเตอร์ไฟล์เพียงพารามิเตอร์เดียว และส่งออกตัวอักษรต่อไปในไฟล์ while loop ในตัวอย่างสามารถใช้ fgetc() ได้ดังนี้
while (!feof($fp))
{
$char= fgetc($fp, 100);
if (!feof($fp))
echo ($char=="\n" ? "<br/>: $char);
}
คำสั่งที่อ่าน 1 ตัวอักษรจากไฟล์ต่อครั้งด้วย fgetc() และเก็บใน $char จนกระทั่งสิ้นสุดไฟล์ จากนั้นทำการประมวลผลเล็กน้อยเพื่อแทนที่ตัวอักษร สิ้นสุดแถวด้วยตัวแบ่งแถว HTML ที่เป็นการจัดรูปแบบ เนื่องจาก browser ไม่จัดบรรทัดใหม่ใน HTML เป็นบรรทัดใหม่ ถ้าปราศจากคำสั่งนี้ ไฟล์ทั้งหมดจะพิมพ์ออกมาเป็น 1 บรรทัด

การอ่านด้วยความยาวตามต้องการ
วิธีสุดท้ายในการอ่านจากไฟล์คือการใช้ฟังก์ชัน fread เพื่ออ่านด้วยจำนวนไบต์ตามความต้องการ ฟังก์ชันนี้มีไวยากรณ์ดังนี้
string fread (int fp, int length);
วิธีที่ทำการอ่านตาม length ไบต์ หรือ สิ้นสุดไฟล์ แล้วแต่ว่ากรณีใดมาถึงก่อน

ภาพรวมการประมวลผลไฟล์
การเขียนข้อมูลลงสู่ไฟล์มี 3 ขั้นตอน คือ
1. เปิดไฟล์ ถ้าไฟล์ไม่มีอยู่จริง ต้องมีการสร้างขึ้นมา
2. เขียนข้อมูลลงสู่ไฟล์
3. ปิดไฟล์

การอ่านข้อมูลจากไฟล์มี 3 ขั้นตอนเช่นกัน คือ
1. เปิดไฟล์ ถ้าไม่สามารถเปิดได้ เช่น ไม่มีไฟล์อยู่จริง จะต้องรับทราบและออก
2. อ่านข้อมูลจากไฟล์

3. ปิดไฟล์

ไม่มีความคิดเห็น:

แสดงความคิดเห็น