บทที่ 7 สร้างไฟล์ sitemap.php
สร้างไฟล์ sitemap.php
เป็นบทรองสุดท้ายแล้วนะครับ สำหรับบทนี้จะพูดถึงเรื่องของการสร้าง sitemap.php เพื่อนำไปใช้งานอย่างอื่นต่อไปครับ หลายคนเอาไป ping หรือว่าเอาไป submit ก็ได้ครับแล้วแต่แผน
โดยทั่วไปแล้ว sitemap จะอัพเดทเมื่อมีกระทู้หรือว่าเนื้อหาใหม่ๆเสมอครับ ในเว็บ CMS หรือเว็บสำเร็จรูปอื่นๆ เช่น wordpress เป็นต้น แต่ด้วยสคริบของเราที่เราเขียนขึ้นมานี้ ด้วยความที่ว่าเราดึงข้อมูลมาจาก data.csv และเป็นข้อมูลตายตัว เราจะแก้ปัญหานี้อย่างไร
ส่วนตัวที่ผมทำนะครับ ผมจะทำในลักษณะที่ว่า จะให้มันแรนดอมมาซักจำนวนหนึ่ง 20-30 ชิ้น คร่าวๆ แล้วให้สลับไปเรื่อยๆ แต่ที่สำคัญอีกอย่างคือ ผมจะให้มัน random มาวันละครั้งพอครับ พูดง่ายๆ คือ ผมสร้าง sitemap มาวันละครั้งเท่านั้น และดึงสินค้ามาแค่ 20-30 ชิ้น
หลายๆคนอาจจะชินกับการ Gen Sitemap รอบเดียวเสร็จ แต่ ในส่วนนี้ผมจะทำให้ Gen หลายๆครั้งอย่างที่ผมกล่าวมานะครับ
เอาละครับ อันดับแรกต้องมาดูรูปแบบการสร้าง sitemap ก่อนว่าหน้าตาควรเป็นอย่างไร ผมยึดตามของ google นะครับ BUILD YOUR SITEMAP ที่นี่ครับ ลองเข้าไปอ่านกันได้ครับ
เอาละครับ อันดับแรกต้องมาดูรูปแบบการสร้าง sitemap ก่อนว่าหน้าตาควรเป็นอย่างไร ผมยึดตามของ google นะครับ BUILD YOUR SITEMAP ที่นี่ครับ ลองเข้าไปอ่านกันได้ครับ
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="https://www.sitemaps.org/schemas/sitemap/0.9">
<url>
<loc>https://www.example.com/foo.html</loc>
</url>
</urlset>
หลังจากที่ได้รูปแบบ แล้ว มาเริ่มเขียน php กันครับผม
เริ่มเขียน php sitemap
ผมต้องกำหนดชื่อไฟล์ก่อนครับว่าต้องเป็น sitemap.xml และจะกำหนดเวลาในการแคชแต่ละครั้งอยู่ที่ 1 วันครับ เป็นคอนเซ็บง่ายๆแหละครับ เมื่อรู้ว่าไฟล์ชื่อว่าอะไร ก็เช็คเวลาของไฟล์นั้นครับ ด้วย filemtime() ซึ่งจะเป็นการหาเวลาการแก้ไขไฟล์ครั้งหลังสุด
<?php
$max = 30;
$time_cache = 86400;
$cachefile = "sitemap.xml";
//Check Time Sitemap.xml
$chktime = time() - @filemtime($cachefile);
if($chktime > $time_cache || !file_exists($cachefile)) {
//Create new sitemap.xml
}else{
//Read sitemal.xml
}
?>
code สร้างไฟล์ sitemap |
อธิบายพอสังเขป
ผมตั้งค่าต่างๆไว้ โดยกำหนดค่า $max เป็นค่าที่กำหนดว่าจะดึงสินค้ามาทำ sitemap กี่ชิ้น $time_cache จะตั้งเวลาให้แคชหรือว่าสร้างไฟล์ใหม่เป็นเวลาเท่าไร โดยหน่วยจะเป็นวินาทีครับ ที่ผมตั้งไว้คือ 1 วัน 60x60x24 และ ตั้งชื่อไฟล์ $cachefile โดยจะตั้งเป็น sitemap.xml ครับ
มาถึงการเช็คเวลา $chktime ผมจะเช็คเวลาโดยการเอาเวลาปัจจุบัน time() ลบเวลาแก้ไขไฟล์ล่าสุด @filemtime($cachefile) จะได้ค่าส่วนต่างเวลามา หลังจากนั้นก้อเอามาเช็ค if กันนิดนึงครับ ว่าส่วนต่างเวลาที่หักลบมานั้น มันมากกว่าเวลา $time_cache หรือไม่ และผมยังเช็คว่าถ้าไม่มีไฟล์หรือไม่มีไฟล์ ชื่อว่า sitemap.xml ด้วยครับ โดยใช้ !file_exists($cachefile) ครับ เครื่องหมาย ! จะหมายถึงว่าไม่ครับ
ถ้าความต่างของเวลาเกิน เวลาที่ตั้งไว้ และยังไม่มีไฟล์ if($chktime > $time_cache || !file_exists($cachefile)) มันก็จะมาสร้างไฟล์ sitemap.xml ใหม่ครับ ถ้าไม่เข้าตามที่เราตั้งเกณฑ์ไว้ else มันก็จะอ่านไฟล์ sitemap.xml ครับผม
เอาลิงค์สินค้ามาวนได้แล้วครับทีนี้ แล้วเราจะวนในไหนละ
<url>
<loc>https://www.example.com/foo1.html</loc>
</url>
<url>
<loc>https://www.example.com/foo2.html</loc>
</url>
<url>
<loc>https://www.example.com/foo3.html</loc>
</url>
ประมานนี้เลยครับผม
ดูของจริงที่สคริบนะครับ Loop For จะวนจนกว่าจะครบค่า $max ที่เรากำหนดครับ วนไป random สินค้าไป
ผมดึง include 'app.php'; มาด้วยนะครับ ลืมบอกไปเพราะว่าจะใช้ function() บางตัว
//Create new sitemap.xml
$xml = '<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="https://www.sitemaps.org/schemas/sitemap/0.9">';
//Product Data from data.csv
$file = file(setting('file'));
$date = date('Y-m-d');
for ($i=0; $i < $max; $i++) {
$id = randid();
$data = explode(',', $file[$id]);
$title = trim($data['0'], '"');
$xml .= '
<url>
<loc>https://127.0.0.1/tempkaew/'.$id.'-'.cleantitle($title).'.html</loc>
<lastmod>'.$date.'</lastmod>
<changefreq>daily</changefreq>
<priority>0.5</priority>
</url>';
}
$xml .= '
</urlset>';
$createxml = fopen($cachefile, 'w');
fwrite($createxml, $xml);
fclose($createxml);
อธิบายพอสังเขป
ตัวสร้าง sitemap ตัวนี้ ผมจะ random สินค้ามาแสดงครับ ซึ่งไม่ให้เกินค่า $max ที่ตั้งไว้ และจะวนไปเรื่อยพร้อมสร้างและแปลงลิงค์ครับซึ่งเหมือนกับที่เราสร้างหน้าแรกให้เชื่อมกับหน้าสินค้าครับ
จากด้านบนนะครับผมจะประกาศค่าตัวแปร $xml ไว้ ซึ่ง จะกำหนดส่วนหัวของ sitemap xml ก่อนครับ คือส่วนนี้
$xml = '<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="https://www.sitemaps.org/schemas/sitemap/0.9">';
หลังจากนั้นผมจะมา Loop For วนและ random สินค้าจนกว่าจะถึงค่า $max ครับ(ย้ำหน่อย) ซึ่งผมกำหนดไว้ที่ 30 ครับ และจะดึงข้อมูลเหมือนการดึงสินค้าทั้งหมดครับ แต่จะดึงมาเฉพาะ Title ครับ ใช้เท่านี้ เพราะว่าเอามาแปลงเป็นลิงค์ให้เข้าเว็บเราเฉยๆครับ หรือว่าให้มันลิงค์ไปที่หน้าสินค้าเราให้ถูกนั่นเองครับ ลิงค์ไม่ถูกน่าฮาเลยนะครับ (Gen sitmap แล้วอย่าลืมลอง) for ($i=0; $i < $max; $i++) {
$id = randid();
$data = explode(',', $file[$id]);
$title = trim($data['0'], '"');
$xml .= '
<url>
<loc>https://127.0.0.1/tempkaew/'.$id.'-'.cleantitle($title).'.html</loc>
<lastmod>'.$date.'</lastmod>
<changefreq>daily</changefreq>
<priority>0.5</priority>
</url>';
}
โดยต้องกำหนด path และเป้าหมายให้ถูกต้องนะครับ <loc>https://127.0.0.1/tempkaew/'.$id.'-'.cleantitle($title).'.html</loc> ตามนี้ครับ ลิงค์ข้อมูลให้ถูก เดี๋ยว Bot ตามไปไม่เจอ งงหัวแตกเอา (ระบุลิงค์เต็มนะ)
และผมจะแทนค่าเจ้าพวกนี้ด้วย $xml .= ''; ทำไมต้อง $xml .= ทำไมไม่ $xml = เลยละ ถ้าหากเรา $xml = จะเป็นการกำหนดค่าใหม่ครับ แต่ถ้าเป็น $xml .= จะเป็นการเติมค่าเข้าไป เปรียบเทียบได้กับวางกล่องทับๆกันเรื่อยๆครับผม
เช่น
$xml = '1'; $xml = '2'; $xml = '3'; echo $xml; ผลลัพธ์ คือ 3
แต่ถ้า
$xml = '1'; $xml .= '2'; $xml .= '3'; echo $xml; ผลลัพธ์ คือ 123
แต่ตัวแรกต้อง $xml = ''; ไว้ก่อนนะครับ
หลังจากนั้นผมจะเอาค่า $xml มาสร้างไฟล์ sitemap.xml ครับ โดยใช้คำสั่งเจ้า fopen fwrite fclose นี่แหละครับ เทียบได้คือ เปิด เขียน ปิด (เปิดไฟล์แล้วอย่าลืมปิดไฟล์นะครับ)
ผมใช้คำสั่ง fopen($cachefile, 'w'); ซึ่ง w คือการ เขียนอย่างเดียวครับ ตัวแปรเหล่านี้ต้องเข้าศึกษาเพิ่มเติมที่ https://www.w3schools.com/php/func_filesystem_fopen.asp ครับ
ต่อจากนั้น
eles ไม่ตรงตามที่เรากำหนด |
ถ้ามันไม่ตรงตามี่เรากำหนด คือ มีไฟล์อยู่แล้ว และ ไฟล์ยังไม่เกินเวลาที่เรากำหนด else ให้มันอ่านค่า $cachefile หรือว่า ไฟล์ sitemap.xml นั่นเองครับ
ผลลัพธ์ที่ได้
ผลที่ได้ไม่ได้เรียงสวยงาม |
header("Content-Type: text/xml;charset=iso-8859-1");
เอาไว้หลัง <?php ครับ บรรทัดเดียวก็สวยได้แล้วครับ
เพิ่มเพียงบรรทัดเดียว |
sitemap ที่คุ้นตาหลายๆคน |
RewriteRule ^sitemap.xml$ sitemap.php [L]
บรรทัดเดียวก็พอครับ ประมาณว่า เราเรียกไฟล์ sitemap.xml มันจะทำงานโดยจะไปเช็คที่ไฟล์ sitemap.php ก่อนครับ เท่านั้นแหละการทำงานของมันครับ ที่เหลือก็ขึ้นอยู่กับ sitemap.php ที่เราเขียนมาแล้วแหละครับ
ไฟล์ sitemap.php
<?php
header("Content-Type: text/xml;charset=iso-8859-1");
//Include Function File
include 'app.php';
$max = 30;
$time_cache = 86400;
$cachefile = "sitemap.xml";
//Check Time Sitemap.xml
$chktime = time() - @filemtime($cachefile);
if($chktime > $time_cache || !file_exists($cachefile)) {
//Create new sitemap.xml
$xml = '<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="https://www.sitemaps.org/schemas/sitemap/0.9">';
//Product Data from data.csv
$file = file(setting('file'));
$date = date('Y-m-d');
for ($i=0; $i < $max; $i++) {
$id = randid();
$data = explode(',', $file[$id]);
$title = trim($data['0'], '"');
$xml .= '
<url>
<loc>https://127.0.0.1/tempkaew/'.$id.'-'.cleantitle($title).'.html</loc>
<lastmod>'.$date.'</lastmod>
<changefreq>daily</changefreq>
<priority>0.5</priority>
</url>';
}
$xml .= '
</urlset>';
$createxml = fopen($cachefile, 'w');
fwrite($createxml, $xml);
fclose($createxml);
}else{
//Read sitemal.xml
echo file_get_contents($cachefile);
}
?>
ไฟล์ .htaccess
RewriteEngine On
RewriteRule ^([^/]*)-([^/]*)\.html$ product.php?id=$1 [L]
RewriteRule ^contact$ page-contact.php [L]
RewriteRule ^sitemap.xml$ sitemap.php [L]
หากติดข้อสงสัยสอบถามได้ครับผม
17 ความคิดเห็น
$createxml = fopen($cachefile, 'w');
fwrite($createxml, $xml);
fclose($createxml);
ตรงบรรทัดนี้เลยครับผม
ผมเช็คเรื่องอายุไฟล์แล้วก้อแคชไฟล์ครับ ตามอธิบายด้านบนเลยครับ
คร่าวๆ คือว่า สร้างโฟล์เดอร์ขึ้นมา 1 อัน สำหรับไฟลแคช
แล้ว ต้องรู้ว่าไฟล์นั้นชื่อว่า อะไร อย่างในสคริบตัวนี้ ผมเอา title ไป แปลงเป็นลิงค์
ผมก็จะเช็คว่า ไฟล์ id-title.html นี้ มีหรือยัง มีในโฟล์เดอร์ที่เราตังยัง
คล้ายกับวิธี sitemap เลยครับ แต่ว่าหน้าสินค้า ตอนนี้ เราจะ echo ให้โชว์ใช่ไหมครับ
เราก็เปลี่ยนมา ให้มันเขียนเป็นข้อมูล ลงไฟล์ html (เหมือนเขียน xml ของ sitemap)
คล้ายๆกันครับ ลองดูนะครับ
This page contains the following errors:
error on line 1 at column 6: XML declaration allowed only at the start of the document
Below is a rendering of the page up to the first error.
ห้ามเว้นว่าง หรือว่ากด enter
$xml = '
ให้มันชิด ' เลยครับ
http://127.0.0.1/tempkaew/80-Herschel-Supply-Co-Parker-Backpack.html
2014-09-16
daily
0.5
---------
ถามครับว่า ถ้า ผมจะเปลี่ยน http://127.0.0.1/tempkaew/ ให้มันเป็น domain ของผม จะต้องทำงัย
คือ ผมได้กำหนดตัวแปรเพิ่มมา ครับ อยู่ใน app.php เพื่อให้มันอ่าน domain name แบบ auto โดยคำสั่ง ที่กำหนดมีดังนี้ครับ $urlwebsite =$_SERVER['SERVER_NAME']; แล้วผมก็อ้างค่า $urlwebsite ใน sitemap.php ดังนี้ครับ
$xml .= '
http://'.$urlwebsite.'/'.$id.'-'.cleantitle($title).'.html
'.$date.'
daily
0.5
';
แต่มันไม่ work ครับ , คุณจะพอมีแนวทางป่าวครับ
$mysite = 'http://'.$_SERVER['HTTP_HOST'].'/';
และ
'.$mysite.$id.'-'.cleantitle($title).'.html
ดูครับผม
$time_cache || !file_exists($cachefile)) {
//Create new sitemap.xml
$xml = '
';
//Product Data from data.csv
$url = file(setting('url'));
$file = file(setting('file'));
$date = date('Y-m-d');
for ($i=0; $i < $max; $i++) {
$id = randid();
$data = explode(',', $file[$id]);
$title = trim($data['0'], '"');
$xml .= '
'.$mysite.$id.'-'.cleantitle($title).'.html
'.$date.'
daily
0.5
';
}
$xml .= '
';
$createxml = fopen($cachefile, 'w');
fwrite($createxml, $xml);
fclose($createxml);
}else{
//Read sitemal.xml
echo file_get_contents($cachefile);
}
?>
Sitemap.php in Google Doc
"http://127.0.0.1/tempkaew/71-Tumi-Alpha-Bravo---Kingsville-Deluxe-BriefPack.html"
ผมก็ไม่รู้ว่า ตัวนี้ "127.0.0.1/tempkaew" มันโผล่มาได้ยังงัย
แล้ว ตรง
'.$mysite.$id.'-'.cleantitle($title).'.html
บรรทัด 36 อะครับ
เป็น อย่างนี้ ไหมครับ
?loc?'.$mysite.$id.'-'.cleantitle($title).'.html?/loc?
สรุปแล้วผม ตายน้ำตื้นครับ
ตามที่ admin แนะนำ คือให้ลบ sitemap.xml ไปก่อน แล้วลองใหม่ ก็ได้เลย ครับ
ขอบคุณมากครับ ต่อไปก็คงจะหัดเขียน หน้า template และ css file ครับ