آموزش ساخت نقشه XML سایت (Sitemap) با PHP و MySQL

یکی از ملزومات مورد نیاز مدیران وب معرفی اطلاعات آدرس های URL وبسایت، وبلاگ و... به صورت دستی بندی شده و دقیق به موتورهای جستجو است تا این موتورها به راحتی و با دقت بیشتر بتوانند کل صفحات موجود در یک آدرس اینترنتی را پیدا کرده و پوشش دهند، بدین منظور پروتکلی تعریف شده تحت عنوان Sitemap که در آدرس رسمی sitemaps.org با جزئیات در دسترس است، این پروتکل به وبمسترها اجازه می دهد تا آدرس های URL خود را در یک فایل XML قرار داده و به تناوب محتوای آن را به روزرسانی نمایند، با توجه به اینکه معمولا تعداد صفحات یک پایگاه اینترنتی همواره در حال تغییر و به روزرسانی است، ثبت دستی این تغییرات در فایل XML عملا گزینه مناسبی نبوده و بسیار وقتگیر و خسته کننده خواهد بود، ضمن اینکه احتمال بروز اشتباه نیز بالا خواهد رفت، از این رو در آموزش پیش رو ضمن ارائه اطلاعاتی در خصوص نقشه XML سایت، نحوه ساخت و به روزرسانی داینامیک آن با کدهای PHP و پرس و جوی MySQL را نیز به صورت نمونه توضیح خواهیم داد.
XML چیست و چرا در نقشه سایت استفاده می شود؟
XML (مخفف eXtensible Markup Language) زبان نشانه گذاری برای انتقال اطلاعات بین دستگاه های مختلف و یک استاندارد فراگیر است، XML قابل استفاده برای ماشین و قابل خواندن و درک توسط انسان است و این قابلیت وجود دارد تا با ساده ترین متد ممکن در تگ های مختلف نقشه XML سایت مواردی مانند آدرس صفحه، دوره به روزرسانی، تاریخ آخرین تغییرات، اولویت آدرس ها و... را برای هر URL به صورت جداگانه مشخص کنیم، لذا پروتکل Sitemap این زبان را برای ایجاد نقشه سایت مناسب دیده و در نظر گرفته است.
شیوه نگارش (Syntax) نقشه XML سایت
شیوه نگارش (Syntax) یک نقشه XML سایت در حالت کلی و برای نمونه به شکل زیر است:
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url>
<loc>http://www.example.com</loc>
</url>
<url>
<loc>http://www.example.com/?link=2</loc>
</url>
</urlset>
توضیح:- رمزگذاری (encoding) نقشه XML سایت باید به صورت UTF-8 باشد که در خط اول دستورات آن را تنظیم می کنیم.
- sitemaps.org آدرس سایت رسمی پروتکل نقشه XML سایت است، در شروع تگ urlset آن را به عنوان پروتکل مرجع قرار می دهیم.
- هر نقشه XML سایت باید با یک تگ urlset شروع و پایان یابد، در واقع تگ urlset برای هر نقشه سایت، تنها یک بار تکرار می شود.
- لینک ها و اطلاعات آنها در تگ url و به تعداد مورد نیاز قرار می گیرند، ترجیحا لینک ها را از بالاترین سطح تا پائین ترین سطح در تگ های url مرتب کنید، به طور مثال بخش ها را ابتدا و زیرمجموعه ها را در سطح های پائین تر قرار دهید.
- برای آدرس هایی که در سایت شما به اسلش (/) ختم می شوند، در نقشه سایت نیز باید حتما اسلش را در پایان آدرس URL قرار دهید، در غیر اینصورت نیازی به این کار نیست و توصیه نیز نمی شود، در واقع باید آدرس ها را به همان شکلی وارد کنید که در سایتتان استفاده می کنید.
- از به کار بردن کاراکترهای &, ', ", > و < در آدرس لینک ها خودداری کنید و به جای آنها از جایگزین HTML استفاده نمائید، در PHP با توابعی مانند htmlspecialchars می توان کاراکترهای خاص را به مقادیر HTML آنها تبدیل کرد.
ایجاد نقشه XML سایت به صورت داینامیک با PHP و MySQL
معمولا تعداد لینک های سایت های امروزی به چند مورد محدود نیست و همواره با تغییراتی افزایشی همراه است، از این جهت به روزرسانی دستی فایل XML امری بسیار زمانبر و با ضریب بروز اشتباه بالا خواهد بود و به همین جهت برای مدیریت و به روزرسانی نقشه XML سایتمان باید از زبان های سمت سرور و از جمله PHP و سیستم مدیریت پایگاه داده MySQL استفاده کنیم، در کد زیر ما اطلاعات فرضی را از پایگاه داده فراخوانی کرده و برای هر مطلب، لینک آن را به نقشه سایتمان اضافه و در پایان لینک ها را در یک فایل با نام sitemap.xml کپی می کنیم:
<?php
//ابتدا یک فایل با نام sitemap.xml بسازید.
//فایل را دریافت کرده و یک بار محتویات آن را پاک می کنیم
$file = "sitemap.xml";
//تنظیم مجوز های ویرایش
chmod($file, 0755);
//استفاده از متد w+
$file_handle = fopen($file, 'w+')
or die("خطا: سطح دسترسی برای ویرایش فایل در سرور تنظیم نیست!");
//متغیر با مقادیر خالی
$empty = "";
//نوشتن در فایل
$string_data = $empty;
fwrite($file_handle, $string_data);
fclose($file_handle);
//باز کردن مجدد فایل
$file = "sitemap.xml";
chmod($file, 0755);
//این بار با متد a
$file_handle = fopen($file, 'a') or die("خطا: سطح دسترسی برای ویرایش فایل در سرور تنظیم نیست!");
$start = "<?xml version='1.0' encoding='UTF-8'?>
<urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\">\n";
//نوشتن فایل با متد a
$string_data = $start;
fwrite($file_handle, $string_data);
//صفحه نخست
$home = "<url><loc>http://example.com</loc></url>\n";
//نوشتن
$string_data = $home;
fwrite($file_handle, $string_data);
//قبل از اتصال به پایگاه داده باید اطلاعات اتصال را تعریف کنید
$conn = mysqli_connect("localhost", "db_user", "db_pass", "db_name");
if(!$conn){
echo "Error!: " . mysqli_connect_errno() . ' - ' . mysqli_connect_error();
} else{
//دریافت اطلاعات پست ها از دیتابیس و تبدیل به لینک
$result = mysqli_query($conn, "SELECT * FROM posts ORDER BY rank ASC") or die(mysqli_error($conn));
while($row = mysqli_fetch_array($result)){
$id = $row['id'];
$url = "<url><loc>http://example.com/?id=$id</loc></url>\n";
//نوشتن
$string_data = $url;
fwrite($file_handle, $string_data);
}
}
//بستن نقشه سایت
$end = "</urlset>";
//نوشتن
$string_data = $end;
fwrite($file_handle, $string_data);
fclose($file_handle);
//پایان اتصال
mysqli_close($conn);
?>
توضیح:- فایلی با نام sitemap.xml ترجیحا در ریشه سایت بسازید.
- در کد بالا ابتدا بعد از فراخوانی فایل یک بار با متد +w محتویات آن را پاک سازی می کنیم (این کار برای جلوگیری از تکرار لینک ها در هر بار به روزرسانی نقشه XML سایتمان است).
- مجدد فایل را این بار با متد a فراخوانی کرده و اطلاعات جدید را در آن می نویسیم (فرق متد a و +w در این است که متد a به محتویات کنونی فایل خللی وارد نمی کند و در انتهای مقادیر موجود، مقادیر جدید را اضافه می کند اما متد +w فایل را خالی کرده و مجدد می نویسد).
- در نمونه کد بالا اطلاعات را از جدولی فرضی به نام posts دریافت کرده و برای هر مطلب یک لینک به خروجی می دهیم، توجه داشته باشید که اکستنشن استفاده شده در کد mysqli است که قاعدتا می تواند بر اساس نیاز خود از PDO نیز استفاده کنید.
- لینک های ما باید استاندارد HTML باشند و لذا استفاده از کارکترهای خاص &, ', ", > و < در آدرس لینک ها مجاز نمی باشد، توابعی مانند htmlspecialchars در PHP در این مورد کاربرد دارند.
- برای آپدیت مرتب نقشه XML سایت می توانیم به عنوان مثال آن را به کدهای صفحه ای که مطالبمان را از آن ارسال می کنیم اضافه کرده تا با هر بار ارسال مطلب جدید، اطلاعات فایل sitemap.xml نیز به روز رسانی شود، قاعدتا برای اعمال این حالت باید کمی برنامه نویسی سمت سرور (مانند PHP) مرتبط با CMS مورد استفاده بلد باشیم.
استفاده از نقشه XML سایت به لینک های معمول محدود نمی شود، محتویات دیگر صفحات وب از جمله تصاویر، ویدئوها، اخبار و... را نیز می توان در Sitemap گنجاند:
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
xmlns:image="http://www.sitemaps.org/schemas/sitemap-image/1.1"
xmlns:video="http://www.sitemaps.org/schemas/sitemap-video/1.1">
<url>
<loc>http://www.example.com/</loc>
<image:image>
<image:loc>http://example.com/imagename.jpg</image:loc>
</image:image>
<video:video>
<video:content_loc>http://www.example.com/videofilename.flv</video:content_loc>
<video:player_loc allow_embed="yes" autoplay="ap=1">http://www.example.com/videoplayer.swf?video=videofilename</video:player_loc>
<video:thumbnail_loc>http://www.example.com/thumbs/videofilename.jpg</video:thumbnail_loc>
<video:title>عنوان ویدئو</video:title>
<video:description>توصیف ویدئو</video:description>
</video:video>
</url>
<url>
<loc>http://www.example.com/?link=2</loc>
</url>
</urlset>
افزودن تاریخ و اطلاعات بیشتر به Sitemap
علاوه بر تگ <loc> که آدرس لینک ها را در آن قرار می دهیم، از چند تگ (اختیاری) دیگر نیز می توانیم در نقشه XML سایت خود استفاده کنیم، از جمله <lastmod> برای نمایش تاریخ ایجاد یا به روز رسانی لینک، <changefreq> که دوره تغییر یک لینک را مشخص می کند و <priority> که میزان اهمیت آن را نسبت به سایر لینک ها نشان می دهد.
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url>
<loc>http://www.example.com</loc>
<lastmod>2012-03-20</lastmod>
<changefreq>monthly</changefreq>
<priority>0.8</priority>
</url>
<url>
<loc>http://www.example.com/?link=2</loc>
<lastmod>2012-02-18T21:45:19+03:30</lastmod>
<changefreq>weekly</changefreq>
<priority>1</priority>
</url>
</urlset>
توضیح:- فرمت مقادیر تگ <lastmod> می تواند به صورت تاریخ ساده یا تاریخ همراه زمان و اختلاف زمانی باشد (در مثال بالا از هر دو روش استفاده کرده ایم).
- تگ <changefreq> می تواند مقادیری مانند ماهیانه (monthly)، هفتگی (weekly)، ساعت به ساعت (hourly)، روزانه (daily)، سالیانه (yearly)، همیشگی (always) و یا هرگز (never) داشته باشد که نشان دهنده چرخه حدودی تغییرات آن لینک است.
- تگ <priority> میزان اهمیت لینک را مشخص می کند، این مقدار می تواند به ترتیب از کم اهمیت ترین (0.0) تا پراهمیت ترین (1.0) در نوسان باشد.
اطلاعات تکمیلی در خصوص نقشه XML سایت را می توانید در سایت رسمی آن مشاهده کنید:
sitemaps.org

ساخت فید خوان آر اس اس (RSS Feed Reader) با PHP
تبدیل تاریخ میلادی، شمسی با مبدل JDF در PHP
نمایش آمار بازدیدها با PHP بدون استفاده از دیتابیس
محدود کردن لینک دانلود مستقیم فایل ها با PHP و htaccess
ارسال پارامتر به URL و دریافت مقادیر با PHP


مثلا
sitemap.php?shoroo=0&payan=2000
که بعد از این خروجی به این صورت بگیرمsitemap0-2000.xml
داینامیک یعنی ایجاد سیستمی پویا که متناسب با نیاز شما به صورت خودکار رفتاری پویا داشته باشد، به عبارت ساده تر باید برنامه نویسی PHP کار کرده باشید و بتوانید با توجه به هدفتان برنامه پویا بنویسید (الگوریتم تعریف کنید)، به فرض برنامه شما باید تشخیص دهد که از ردیف 2000 به بعد یک فایل جدید بسازد و...
اول یه تشکر کنم بابت مطالب سایتتون که خیلی به دردم خورده.
سوالم اینه که مثلا اگه ما بخواهیم سایت مپ به صورت خودکار به چند تا سایت مپ تبدیل بشه باید چکار کنیم !
مثلا ما 100 هزار تا پست داریم و طبیعتا اگه بخواهیم همش رو یکجا نشون بدیم فشار زیادی به سرور میاره.
اگه بخواهیم مثلا هر 2000 تا پست یه سایت مپ ایجاد کنه به صورت خودکار و شماره بندی کنه.
postmap1.xml
postmap2.xml
.
.
.
ممنون میشم راهنمائی کنید.
وقتی تو گوگل عبارتی رو سرچ میکنیم، صفحاتی معرفی میشن که آدرس هرکدوم با رنگ سبز مشخص میشه. بعضی از این آدرس ها خیلی منظم و بصورت سلسله مراتبی هستند مثلا به این لینک برید:
https://www.google.com/webhp?hl=fa&gws_rd=ssl#hl=fa&q=%D8%A2%D9%85%D9%88%D8%B2%D8%B4+%D8%B3%D8%A7%D8%AE%D8%AA+%D9%86%D9%82%D8%B4%D9%87+%D8%B3%D8%A7%DB%8C%D8%AA+(Sitemap)+%D8%A8%D8%A7+php+%D9%88+xml
آیا گوگل از روی همین نقشه سایت به ساختار درختی محتوای سایت ها پی میبره؟ممنون میشم جواب بدین
گوگل حتی قادر به شناسایی و حذف عبارات اضافه در لینک ها است، به طور مثال عبارت "section" چون صرفا برای ساختار بندی سایت استفاده شده و هیچ لینکی در صفحات به آن ختم نمی شود، نادیده گرفته می شود.
چندتا سوال فنی!!؟
اول اینکه : مشکلی نداره اگه محتوای یه xml sitemap فقط حاوی لینک های اصلی و ثابت سایت باشه؟ مثل لینک های navigation و category که همیشه ثابتند ....
دوم اینکه: وقتی من یه صفحه ای دارم که یک pagination داره و دارای 500 و یا بیشتر دارای صفحه است page 1 page 2 page 3 ...... وقتی داخل هر صفحه تعدادی زیادی پست article موجود هست نحوه ی sitemap xml این شکل صفحات به شکله؟
و اینکه آیا sitemap یه سایت همیشه باید ثابت باشه یا هر یک ماه یه بار باید آپدیت کرد؟
ممنون میشم کامل با جزییات راهنمایی کنید... با تشکر از webgoo
- در مورد صفحه بندی باید بین کاربران عادی و موتورهای جستجو تفکیک قائل شد، صقحه بندی برای راحتی کاربران استفاده می شود، در مورد ربات های جستجوگر می توان آن را نادیده گرفت، در هر حال هم می توانید لینک صفحات را در فایل XML داشته باشید، هم لینک صفحات + مطالب و هم صرفا لینک مطالب.
- به روزرسانی نقشه سایت اجباری نیست، البته در صورتی که بخش ها و لینک های اصلی جدیدی به سایتتان اضافه یا مواردی حذف شده باشد، بهتر است که فایل XML را مطابق با آخرین تغییرات به روزرسانی کنید.
من میخوام برای یک سایت که از نیوک استفاده میکنه یک نقشه سایت داینامیک درست کنم. چه کدی باید استفاده کنم؟ توابعی که لینک پست ها رو میگیره نمیدونم.
با تشکر از زحمات شما
بازم بابت پاسخ هایی که میدین ممنونم یه سوالی که خیلی ذهنم رو مشغول کرده
تابع count
چیکار میکنه؟
if(count($_POST)>0){
//...........
}
هرچی تایپ میکنی در فیلد فقط 1 را نمایش میدهد یعنی چه چیزهایی را میشمارد این تابع؟اگه میشه درباره اون موضوع چت رومی که گفتم چگونه میشه همچین کدی را نوشت که هر کاربری پیام داد واسه همه ی کاربران نمایش بده من خودم نوشتم که فقط برای خود کاربر نمایش میده اگه امکانش هست با کد های بیشتر به صورت کامل توضیح بدید خیلی لازمه بخواین هزینه شو هم پرداخت میکنم
میشه در مورد نحوه تنظیم مجوزهای ویرایش بیشتر توضیح بدید؟
من یه سوال داشتم خارج از مطالب سایت هست و نمیدانم کجا سوالم را بپرسم لطفا همینجا پاسخ مرا بدهید:
من یک چت روم درست کردم با پی اچ پی و ایجکس وقتی که خودم تایپ می کنم ارسال می کنم پیام هام نمایش داده میشه ولی وقتی که کسی دیگری پیام بده و ارسال کنه پیام های اون را من نمیتوانم ببینم و فقط خود شخص میتواند ببیند
کد ها رو اینطوری تعریف کردم
دستور ایجکس این است که وقتی متن را در کادر نوشت و ارسال را زد با دستوران ایجکس آن متن را در فیلد بالا سلکت و چاپ کند و فقط برای خود کاربری که دکمه ی ارسال میزند چاپ می کند نه کسی دیگری این مشکل را چگونه حل کنم لطفا راهنماییم کنید بعضی ها میگن باید با جیکوری حل بشه
اطلاعات کاربر باید در دیتابیس ذخیره شده و برای آن یک گیرنده متناظر تعریف شود، سپس گیرنده پیام توسط درخواست ای جکس آخرین ارسال کاربر مقابل را دریافت کند، البته این تنها یک الگوی ساده است، در یک برنامه کاربردی قواعد زیادی باید رعایت و حالت های مختلف در نظر گرفته شود.
به فرض مثلا ما می خواهیم تعداد فایلها با فرمت xml در پوشه folder نمایش داده شود ممنون میشم راهنمایی نمایید
<?php
$folder = dirname(__FILE__).'/folder';
//echo $folder;
$handel = opendir($folder);
$count = 0;
while((($name = readdir($handel)) != false)){
$format = preg_match('/([\xml]+$)/', $name);
if($format){
//echo $name.'<br>';
$count++;
}
}
echo $count;
?>
نکته: آدرس فولدر به صورت کامل و صحیح باید تنظیم شود، در نمونه کد، فولدر با فایل PHP در یک دایرکتوری قرار دارند.
- به سوالات کلی، زمانبر، مبهم و مشکلاتی که تلاشی برای رفع آنها نکرده باشید پاسخ مختصر داده شده یا به بخش برنامه نویسی اختصاصی ارجاع داده می شوند.
- کدها و اسکریپت های طولانی را ترجیحا در یک صفحه وب آنلاین یا به صورت حساب موقت و آزمایشی قرار دهید تا امکان بررسی دقیق مشکل و خطایابی میسر باشد.
- تمام دیدگاه های ارسالی خوانده شده و برای هر کاربر مدت زمان لازم جهت پاسخگویی در نظر گرفته می شود، لطفا از طرح سوالات متعدد در بازه زمانی کوتاه خودداری کنید.