A-AA+then

โปรเจ็คท์ .::{เปรียว}::. ต่อ -->

1,149

หลังจากที่แก้ปัญหาเรื่อง %20 กลายเป็น _
ก็เจอปัญหาที่น่างุนงงอีกอย่าง

มันตรงกันทุกประการแต่ไม่ใช่ตามเงื่อนไข
แล้วมันยังไง ..............คืองี้

กำหนดให้ URL เป้าหมายปลายทางเท่ากับ
ค่าที่ได้มาจาก $_GET ที่มาตาม Address bar

$target=getUrlFromGet();

กรณีที่เข้าในครั้งแรกอาจจะไม่สามารถแสดง
หน้าเว็บเพจได้ เลยตั้งค่าไว้เท่ากับหน้าที่ต้องการ

if($target['URL']==null){
 $target['URL']=$config['start_page'
];
}

แล้วทำการดีไฟน์ _PAGE_ ขึ้นมาเพื่อนำไปใช้งาน

define('_PAGE_',$target['URL']);

จากนั้นก็ดีไฟน์ _CONTENT_ ขึ้นมาอีก

define('_CONTENT_',getContent(_PAGE_));

โค้ดเหล่านี้ไม่มีปัญหาอะไร
ปัญหาอยู่ตรงที่ if ที่อยู่ในฟังก์ชั่น getContent();
ซึ่งจะมีการเปรียบเทียบว่า

ถ้าหาก $page และ $data[0] มีค่าตรงกันก็จะให้
return $data[1]; ซึ่งก็คือข้อมูลของหน้าที่ต้องการนั่นเอง
แต่การตรวจสอบกลับพบว่าเป็นเท็จเสมอไม่ว่าข้อมูลจะ
ตรงกันหรือไม่

เลยลอง echo ค่าต่างๆ ออกมาดูผลเป็นแบบนี้

บรรทัดที่ ----->2
ข้อมูลทั้งหมดในบรรรทัดนี้ คือ -----> หน้าที่ 1|นี่คือข้อมูลที่จะแสดงในหน้าที่ 1
ข้อมูลของ $data[0] คือ ----->หน้าที่ 1
ข้อมูลของ $data[1] คือ ----->
นี่คือข้อมูลที่จะแสดงในหน้าที่ 1

$page ที่ส่งมาตรวจสอบ คือ ----->หน้าที่ 1

กรณีที่ $data[0] มีค่าไม่เท่ากับ $page ให้แสดงข้อมูลดังนี้

ข้อมูลของ $data[0] ที่ได้มาคือ ----->หน้าที่ 1 (อ้าว! แล้วมันไม่ตรงกันกับ $page ตรงไหนอ่ะ)
ข้อมูลของ $data[1] ที่ได้มาคือ ----->นี่คือข้อมูลที่จะแสดงในหน้าที่ 1

DATA TYPE ของ $page ----->string
DATA TYPE ของ $data[0] ----->string
DATA TYPE ของ $data[1] ----->
string

ดูแล้วงงๆ อ่ะ นะ ทั้งๆ ที่มันก็มีค่าเหมือนกัน แต่ทำไมเงื่อนไขเป็นเท็จ

ส่วนโค้ดเต็มๆ คือ

function getContent($page){
 $file =_DIR_DB_._LANGUAGE_.'_content.php';
 $GetLine = file($file);
 foreach($GetLine as $value){
  $data = explode("|",$value);

 
// มีปัญหาตรงนี้
  if(trim($data[0]) == $page){
   return $data[1];
   break
;
  }
  //-----------------

 }
}

9 ความคิดเห็น

เท่าที่ดู ก็ไม่ผิด

แต่ที่ผิดอาจจะที่อื่น

ความเป็นไปได้อาจอยู่ที่ content.php

ลอง echo $file ออกมาดู

ลอง echo $value แต่ละบรรทัด ออกมาดู

โค้ดไม่ผิด แต่ข้อมูลอาจผิด

เพิ่มเติม

1.การเขียน for ใน ฟังก์ชั่น ไม่จำเป็น ต้องมี break; ถ้ามี return เพราะ เมื่อพบ return มันจะออกจากฟังก์ชั่นทันที ไม่ทำบรรทัดต่อไป
2.การใช้งานฟังก์ชั่น หากไม่พบข้อมูลที่ต้องการ ควร return ค่าใดค่าหนึ่งกลับไป ไม่ควรปล่อยให้ผลลัพท์สุดท้าย (หากไม่พบ) ว่างเปล่า เพราะโดยทั่วไป เราอาจต้องตรวจสอบซ้ำอีกครั้ง เพื่อประกันความผิดพลาด

ยกตัวอย่างโค้ดด้านบน ลองเดาว่า ถ้ามันบังเอิญไม่พบข้อมูล มันจะ return อะไรกลับมา

function getContent($page){
 $file =_DIR_DB_._LANGUAGE_.'_content.php';
 $GetLine = file($file);
 foreach($GetLine as $value){
  $data = explode("|",$value);
  if(trim($data[0]) == $page){
   return $data[1];// พบข้อมูลที่ต้องการ
  }
 }
 return false; // ถ้าไม่พบข้อมูลที่ต้องการ
}


1

อ้างจากคำตอบที่ #1ลอง echo $file ออกมาดู
ลอง echo $value แต่ละบรรทัด ออกมาดู


พยามลองแล้วเหมือนกันฮ่ะ จากด้านบนเป็นส่วนหนึ่งจากหลายๆ
การทดสอบพยามหาข้อผิดพลาด

และที่น่าแปลกใจมา คือ

กรณีที่ $data[0] มีค่าไม่เท่ากับ $page ให้แสดงข้อมูลดังนี้
ข้อมูลของ $data[0] ที่ได้มาคือ ----->หน้าที่ 1 (อ้าว! แล้วมันไม่ตรงกันกับ $page ตรงไหนอ่ะ)


ส่วนภายใน content.php
ไม่ได้มีอะไรมากมายเลย มีข้อมูลเพียงว่า


<?php exit;?>
หน้าที่ 1|นี่คือข้อมูลที่จะแสดงในหน้าที่ 1
หน้าที่ 2|นี่คือข้อมูลที่จะแสดงในหน้าที่ 2
หน้าที่ 3|นี่คือข้อมูลที่จะแสดงในหน้าที่ 3
หน้าที่ 4|นี่คือข้อมูลที่จะแสดงในหน้าที่ 4
หน้าที่ 5|นี่คือข้อมูลที่จะแสดงในหน้าที่ 5
หน้าที่ 6|นี่คือข้อมูลที่จะแสดงในหน้าที่ 6
หน้าที่ 7|นี่คือข้อมูลที่จะแสดงในหน้าที่ 7
หน้าที่ 8|นี่คือข้อมูลที่จะแสดงในหน้าที่ 8
หน้าที่ 9|นี่คือข้อมูลที่จะแสดงในหน้าที่ 9

ภายหลังเจอปัญหาที่ว่าในตอนต้นก็ลองเอา
<?php exit;?>
ออกไป


ทีนี้ก็เหลือแต่

หน้าที่ 1|นี่คือข้อมูลที่จะแสดงในหน้าที่ 1
หน้าที่ 2|นี่คือข้อมูลที่จะแสดงในหน้าที่ 2
หน้าที่ 3|นี่คือข้อมูลที่จะแสดงในหน้าที่ 3
หน้าที่ 4|นี่คือข้อมูลที่จะแสดงในหน้าที่ 4
หน้าที่ 5|นี่คือข้อมูลที่จะแสดงในหน้าที่ 5
หน้าที่ 6|นี่คือข้อมูลที่จะแสดงในหน้าที่ 6
หน้าที่ 7|นี่คือข้อมูลที่จะแสดงในหน้าที่ 7
หน้าที่ 8|นี่คือข้อมูลที่จะแสดงในหน้าที่ 8
หน้าที่ 9|นี่คือข้อมูลที่จะแสดงในหน้าที่ 9

แล้วก็พยามทดสอบเหมือนที่ผ่านๆ มา
if ก็ยังเป็นเท็จอยู่เช่นเดิม
จนกระทั่งนำมาโพสเพื่อขอคำปรึกษานี่แหล่ะฮะ

อ้างจากคำตอบที่ #11.การเขียน for ใน ฟังก์ชั่น ไม่จำเป็น ต้องมี break; ถ้ามี return เพราะ เมื่อพบ return มันจะออกจากฟังก์ชั่นทันที ไม่ทำบรรทัดต่อไป


จะแก้ไขและจำใส่ใจทันทีฮะ

อ้างจากคำตอบที่ #12.การใช้งานฟังก์ชั่น หากไม่พบข้อมูลที่ต้องการ ควร return ค่าใดค่าหนึ่งกลับไป ไม่ควรปล่อยให้ผลลัพท์สุดท้าย (หากไม่พบ) ว่างเปล่า เพราะโดยทั่วไป เราอาจต้องตรวจสอบซ้ำอีกครั้ง เพื่อประกันความผิดพลาด

ก่อนหน้านี้ก็มีอยู่ แต่เป็น
return;
และ
return $data[1];

ตามลำดับ
อันหลังนี้อยากรู้ว่าถ้ามันได้ข้อมูลมาไม่ตรงเลย ใน $data[1] มันมีอะไรอยู่ในนั้น
ยิ่งทำยิ่งงง

เพราะอย่าง

$target=getUrlFromGet();
if($target['URL']==null){
 $target['URL']=$config['start_page'
];
}

ก็ไม่เห็นเป็นปัญหา

หรือคุณอาพอจะมีวิธีไหนช่วยหาข้อผิดพลาดเพิ่มเติมมากกว่านี้รึป่าว
จะส่งโค้ดไปให้ดูก็เกรงจะเป็นการรบกวนคุณอาเกินไป

2

คำแนะนำที่น่าจะลองดู คือ

if($target['URL']==null){

ผมไม่แนะนำให้ใช้

จากที่ผมบอก ถ้าไม่พบจะ return false กลับไป อันนี้จะตรวจได้ชัวร์กว่า null

if($target['URL']==false){

ถ้ายังไม่ได้ ลองตรวจสอบก่อนว่า มันวนลูปถึงบรรทัดสุดท้ายของข้อมูลหรือไม่
3

เจอตัวปัญหาแล้วฮะ
มันอยูใน content.php จริงๆ

หากข้อมูลในไฟล์ที่นำมาเปรียบเทียบเป็น.......

อักษรภาษาอังกฤษ............ใช้ตรวจสอบได้ if เป็น true หากข้อมูลตรงกัน
ตัวเลข............ใช้ตรวจสอบได้ if เป็น true หากข้อมูลตรงกัน

อักษรภาษาไทย............ใช้ตรวจสอบไม่ได้ if เป็น false เสมอ
ไม่ว่าอักษรภาษาใดก็ตามหากมีช่องว่างหรืออักขระพิเศษรวมอยู่ด้วย............ใช้ตรวจสอบไม่ได้ if เป็น false เสมอ


กว่าจะหาเจอ........เล่นเอาไมเกรนขึ้นสมอง
รบกวนคุณอา  gOragod อธิบายเสริมตรงส่วนนี้ได้มั๊ยฮะว่าทำไมถึงมีข้อจำกัดแบบนี้ สำหรับท่านอื่นเป็นแบบนี้ด้วยอ๊ะป่าว
4

เข้าใจว่าคงเป็นที่ ภาษานะ ที่ทำให้มันไม่สามารถทำงานได้ถูกต้อง
5

 5555++
อ้างจากคำตอบที่ #5เข้าใจว่าคงเป็นที่ ภาษานะ ที่ทำให้มันไม่สามารถทำงานได้ถูกต้อง

บางทีเรื่องใกล้ตัวแค่นี้ก็ทำให้งงเป็นไก่ตาแตกได้เหมือนกันนะฮะคุณอา
อ้างจากคำตอบที่ #4อักษรภาษาไทย............ใช้ตรวจสอบไม่ได้ if เป็น false เสมอ

ตรงนี้พลาดไป
หลังจากตรวจสอบดูจนแน่ใจแล้วพบว่า อักษรภาษาไทย ก็ใช้ได้ฮะ
ก่อนหน้านี้ที่ว่ามันใช้ไม่ได้เพราะว่ามีช่องว่างรวมอยู่ด้วย

อันนี้เปรียวขออภัยในความผิดพลาดจริงๆ

แล้วก็ขอบพระคุณ คุณอา  gOragod ที่ใส่ใจดูแลให้คำปรึกษาเป็นอย่างดีเสมอมาฮะ
6

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

ลองตรวจสอบไฟล์ที่บันทึกไว้ ว่าเป็น ansi หรือ utf-8

ทั้งไฟล์ที่ใช้อ่าน และ ไฟล์ที่บันทึก ต้องตรงกัน

การที่ไฟล์ที่บันทึกไม่เป็น UTF-8 อาจมาจาก 2 สาเหตุ คือ
1.ไฟล์ที่ใช้เขียนไฟล์ข้อมูลไม่เป็น UTF-8 หรือไม่มีการกำหนด header ไว้
2. default charset ของ server ไม่ได้เป็น UTF-8

ทางออกสุดท้ายในกรณีที่ไม่สามารถแก้ปัญหาได้ คือ เข้ารหัสข้อความด้วยตัวเอง ก่อนมันจะถูกอะไรเข้ารหัส และ ถอดรหัสเมื่อต้องการแสดงผล เช่น
ใช้ rawurlencode() ตอนเขียนไฟล์นี้ และ ใช้ rawurldecode() เมื่อต้องการแสดงกลับเป็นข้อความปกติ
หรือ อาจเลือกวิธีอื่นๆ ตามถนัดก็ได้
7

อ้างจากคำตอบที่ #7ใช้ rawurlencode() ตอนเขียนไฟล์นี้ และ ใช้ rawurldecode() เมื่อต้องการแสดงกลับเป็นข้อความปกติ
หรือ อาจเลือกวิธีอื่นๆ ตามถนัดก็ได้

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



ที่แน่ๆ คือ หากมีช่องว่าง(เว้นวรรค)เข้ามาเกี่ยวข้องแล้วมันทำให้ if มีปัญหาทันที
เปรียวลองพยามหาช่องว่าง(เว้นวรรค)นี้อยู่แต่หาไม่พบ

ไม่ว่าจะหาด้วย
' '
หรือ
'&nbsp;'
หรือแม้กระทั่ง
'\s'

ก็ยังไม่พบ
ยังมีวิธีอื่นที่ใช้หาได้หรือเปล่าฮะ
8

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

จริงๆแล้วยังมีวิธีแก้ปัญหาอื่นๆ อีกนะ เช่น

เก็บเป็น CSV เช่น
"เมนู 1";ข้อความ 1"
"เมนู 2";ข้อความ 2"

หรือ XML

<item>
<menu>เมนู 1</menu>
<description>ข้อความ 1</description>
</item>

JSON....หรือ อื่นๆ อีกหลายรูปแบบ ที่ไม่ใช่ text ปกติ

เทคนิค มี เพียบเลย....
9
^