امروز پنجشنبه ۱۴۰۰/۰۱/۲۶

2021/04/15 GMT +4:30
دسته بندی
×

» دوباره نویسی آدرس های وب (URL Rewrite) در htaccess

web-url-rewrite

دوباره نویسی آدرس های وب یا URL Rewrite تکنیکی است که در دانش سئو (علم بهینه سازی برای موتورهای جستجو یا Search Engine Optimization) توصیه شده و امروزه در گستره شبکه جهانی اینترنت مورد استفاده قرار می گیرد، اغلب آدرس های وب به دلیل اینکه به صورت داینامیک ایجاد و به ردیف های پایگاه داده اشاره دارند پارامترها و مقادیر مربوط به ساختار برنامه نویسی و پرس و جوها را در خود نمایش می دهند، به طور مثال در بیشتر سیستم های مدیریت محتوایی که به زبان PHP یا ASP.NET نوشته می شوند برای تنظیم پارامترهای آدرس های URL باید از علامت ?، = و & استفاده شود که این حالت ضمن اینکه ساختار برنامه نویسی سایت را در معرض دید عموم قرار می دهد از نظر سئو و موتورهای جستجو نیز بهینه نیست، البته اینکه واقعا آدرس های داینامیک در مقابل آدرس های استاتیک (URL هایی که پارامتر متغیر ندارند و همواره ثابت هستند) تا چه میزان روی عملکرد صفحات وب از نظر سئو تاثیر گذار است خود جای بحث دارد، اما به دلایل دیگر شاید هنوز ضرورت استفاده از آدرس های استاتیک برای داشتن صفحات وب بهینه همچنان احساس شود، به هر صورت به جهت کاربردی بودن این تکنیک مطلب پیش رو را به آموزش نحوه دوباره نویسی آدرس های وب (URL Rewrite) در فایل htaccess اختصاص داده ایم.

ضرورت استفاده از آدرس های استاتیک


ممکن است این سوال در ذهن خیلی از برنامه نویسان و مدیران سایت های وب وجود داشته باشد که آیا حتما باید از آدرس های URL استاتیک استفاده کنیم؟
پاسخ به این پرسش بستگی زیادی به هدف و میزان تسلط و آشنایی ما با برنامه مدیریت محتوایی دارد که از آن برای سایت خود استفاده می کنیم (برنامه های مدیریت محتوا تحت عنوان CMS یا Content Management System شناخته می شوند)، دلایلی برای استفاده از آدرس های استاتیک ارائه می شود از جمله اینکه:
- حفظ امنیت و مخفی سازی ساختار برنامه نویسی
- کوتاهتر بودن URL و سهولت به حافظه سپاری
- کسب رتبه بهتر در موتورهای جستجو و کلیک بیشتر
به لحاظ حفظ امنیت و مخفی سازی ساختار برنامه نویسی CMS ها این گونه آدرس ها از ضریب اطمینان بالاتری برخوردارند، چرا که URL های داینامیک معمولا ساختار مشخص و در معرض دیدی دارند که نحوه قرارگیری دایرکتوری ها و عناوین واقعی ستون های دیتابیس را نمایان می کند اما با دوباره نویسی آدرس ها ساختار URL ها به نحو دلخواه پیچیده و نامفهوم می شود، مثال:
example.com/index.php?id=1&title=url-rewrite

example.com/1/url-rewrite
در این مثال پسوند php به راحتی زبان برنامه نویسی سایت را مشخص می کند و پارامترهای id و title احتمالا اشاره مستقیم به نام ستون های پایگاه داده دارند که در کل به لحاظ امنیت توصیه نمی شود، هرچند وجود پارامترها یا مشخص بودن زبان برنامه نویسی سایت به خودی خود مشکلی ایجاد نمی کند و به صرف این حالت امکان نفوذ به برنامه ما وجود ندارد اما در مقوله امنیت اصل کلی این است که کمترین اطلاعات از تکنولوژی به کار رفته نمایان باشد و پیچیده ترین ساختار را داشته باشیم.
دلیل دیگر توصیه به استفاده از این شیوه کوتاه و خواناتر شدن آدرس های URL و حذف علامت های ?، = و & از آن است، آدرس های استاتیک معمولا کوتاهترند و این در سئو یک مزیت محسوب می شود، البته این گفته بستگی زیادی به تعداد کاراکتر استفاده شده در آدرس URL دارد (هر چه کوتاهتر، بهتر)، آدرس های کوتاهتر و فاقد علامت های داینامیک با سهولت بیشتری به خاطر سپرده می شوند.
مزیت بعدی که در خصوص آدرس های بازنویسی شده گفته می شوند اینکه در لیست نتایج موتورهای جستجو معمولا آمار کلیک بهتری کسب می کنند و به اصطلاح کلیک خور بهتری دارند، دلیل این موضوع هم علاقه گوگل به این سبک آدرس ها و خواناتر بودن آنها به دلیل کوتاهی و وجود عبارات کلیدی در آدرس URL است، البته باید توجه کرد بین یک آدرس داینامیک با پارامترهای مناسب و کوتاه و آدرس استاتیک با شرایط مشابه از نظر کسب کلیک بیشتر شاید آنچنان فرق محسوسی ملموس نباشد.

تصورات اشتباه در خصوص آدرس های وب


هرچند دانش سئو بر ضرورت استفاده از آدرس های دوباره نویسی شده در وب تاکید دارد اما تصورات اشتباهی نیز در این خصوص شکل گرفته است، بعضا گفته می شود که موتورهای جستجو قادر به ایندکس صفحات ارجاعی از آدرس های داینامیک نیستند که این تصور کاملا اشتباه است، تمام موتورهای جستجوی معروف به خوبی آدرس های داینامیک را درک و محتوای آنها را ایندکس می کنند منتها URL های استاتیک به دلایلی که در بالا اشاره شد توصیه می شوند، تصور اشتباه دیگر اینکه می گویند آدرس بازنویسی شده نمی تواند هیچ پارامتر داینامیکی داشته باشد که این گفته نیز کاملا اشتباه است، هدف از دوباره نویسی می تواند بسته به نیاز متفاوت باشد، به فرض ممکن است به لحاظ فنی امکان حذف تمام یا بخشی از پارامترهای داینامیک وجود نداشته باشد (به فرض در موتورهای جستجو شاهد هستیم که این پارامترها همچنان در آدرس URL وجود دارند) و صرفا زبان برنامه نویسی سایت را مخفی می کنند، مثال:
example.com/index.php?id=1&title=url-rewrite

example.com/?id=1&title=url-rewrite
در این مثال صرفا قسمت index.php حذف شده است و به خودی خود اشکالی ایجاد نمی کند (هرچند در سئو هر چه آدرس URL پارامتر داینامیک کمتری داشته باشد بهتر است).

کدام شکل URL را انتخاب کنیم؟


همانطور که گفتیم این امر بستگی زیادی به هدفمان دارد، به فرض اگر نوع فعالیتمان در وب طوری است که رقابت تنگاتنگ با سایرین از لحاظ جذب بازدیدکننده اهمیت زیادی برایمان دارد و سایر اصول مربوط به بهینه سازی را نیز رعایت کرده ایم، توصیه می شود این مورد را هم فرا گرفته و در کنار دیگر اصول وب و مسائل فنی از آن استفاده کنیم، اما اگر به طور مثال سایتی اداری یا شخصی را مدیریت می کنیم و جوانب امنیتی پایگاه داده را هم رعایت کرده ایم دوباره نویسی آدرس ها چندان ضرورتی نخواهد داشت، کما اینکه بسیاری از سایت های موفق هستند که از لینک های داینامیک استفاده می کنند و مشکل خاصی نیز برای آنها از این لحاظ پیش نمی آید، از طرفی برای برخی برنامه های وب به دلیل تعداد زیاد پارامترها عملا امکان دوباره نویسی وجود ندارد به طور مثال موتورهای جستجو، سایت های خرید آنلاین و... بنابراین همه چیز بستگی به خودمان و نوع کار دارد.

نکات مهم دوباره نویسی آدرس های وب (URL Rewrite)


باید یادآور شویم دوباره نویسی آدرس های داینامیک وب (URL Rewrite) کار حساسی است و باید با دقت و تسلط کامل انجام شود، اشتباه در این مورد ممکن است باعث بروز مشکلاتی از جمله ایجاد محتوای تکراری (Duplicate Content) و یا اختلال در عملکرد سایت شود، البته در صورت گرفتن پشتیبان از دستورات موجود خوشبختانه تغییرات فایل htaccess به سرعت قابل بازگشت به حالت سابق است چون سرور در هر بار فراخوانی آدرس های URL، کدهای htaccess را مجددا اجرا کرده و برای نشست جاری آخرین دستورات را اعمال می کند اما با این وجود بازنویسی باید با در نظر گرفتن تمام احتمالات و آزمایش های لازم قبلی صورت گیرد تا جایی برای هیچگونه اشتباه ناخواسته باقی نماند، بعضا شاهد هستیم که یک قانون به خودی خود مشکلی ایجاد نکرده اما به جهت تداخل با سایر قوانین در نهایت موجب بروز اشکالاتی در عملکرد سایت یا برنامه های تحت وب شده است، اکثر این موارد در صورت تست و آزمایش و خطای قبلی قابل شناسایی و رفع هستند.

آشنایی با mod_rewrite در سرورهای Apache


دوباره نویسی یا Rewrite آدرس ها در سرورهای لینوکسی Apache با کمک ماژولی به نام mod_rewrite انجام می شود، این ماژول تقریبا یکی از محبوب ترین، قدرتمند ترین و پرکاربردی ترین ها در این نوع سرورها است و قدرت آن در حدی است که هر نوع دستکاری در ساختار لینک های سایت توسط mod_rewrite میسر می شود، اصول کار این ماژول بر اساس عبارات با قاعده یا Regular Expressions است که قوانین خاصی برای آن با این روش تعریف می شود که به آنها Rewrite Rule می گویند، اگرچه گستره قواعد و ویژگی های این ماژول بسیار زیاد است اما برای استفاده های معمول می توان با فراگیری چند تکنیک و دستور ساده نیازهای سرویس یا سایت تحت وب مد نظرمان را برطرف کنیم، این قابلیت در بیشتر سرورهای Apache به صورت پیش فرض فعال است اما اگر در هاستمان فعال نبود می توانیم موضوع را با پشتیبان فنی سرور خود مطرح کنیم، نصب و استفاده از این ماژول بسیار آسان و پرکاربرد است و معمولا پشتیبان فنی هاست آن را هنگام اعمال تنظیمات سرور فعال می کند.

URL Rewrite در سرورهای ویندوز


در سرورهای ویندوز ماژول mod_rewrite وجود ندارد اما با پلاگین های جایگزین دیگری می توانیم عملیات دوباره نویسی آدرس ها را با سرورهای لینوکس شبیه سازی کنیم، به طور مثال پلاگینی با نام ISAPI_Rewrite در سرورهای ویندوز می تواند رهگشا باشد.

نحوه دوباره نویسی آدرس های وب


برای دوباره نویسی آدرس های وب قبل از هر چیز به فایل متنی ساده بدون نام و با پسوند htaccess. در ریشه سایتمان (پوشه www یا public_html) نیاز خواهیم داشت، اگر فایل htaccess. به طور پیش فرض در سرور وجود ندارد می توانیم به راحتی آن را در برنامه مدیریت هاست مانند cPanel یا DirectAdmin ایجاد کنیم، با توجه به بی نام بودن این فایل در محیط ویندوز ساخت آن ممکن است به سادگی ممکن نباشد که با راه حل زیر می توانیم این مشکل را رفع کنیم:
برنامه Notepad را اجرا کرده و در صورت نیاز دستورات مورد نظرمان را درون آن درج می کنیم، سپس از گزینه File قسمت Save As را انتخاب کرده و زبانه Save as type را بر روی All files تنظیم می کنیم، نهایتا در قسمت File name عبارت htaccess. را تایپ و فایل را ذخیره می کنیم (دقت کنیم در هنگام تایپ نام فایل نقطه باید در ابتدا باشد!)، راه حل جایگزین اجرای برنامه Command Prompt ویندوز و درج دستور زیر در آن است:
copy con .htaccess
سپس دو بار دکمه Enter را بزنید، فایل در آدرس مورد نظر (معمولا دایرکتوری مربوط به User ویندوز) ایجاد می شود.
دقت کنیم که نقل و انتقال این فایل از سیستم عامل به سرور مخصوصا از طریق برنامه های پروتکل FTP باید به صورت ASCII انجام شود نه باینری (BINARY)، سپس مطابق نیازمان دستوراتی که در ادامه بررسی خواهیم کرد را در آن درج و تنظیم می کنیم.
شیوه نگارش (Syntax) کلی دستورات htaccess به شکل زیر است:
RewriteRule Pattern Target/Substitution [Flags] 
فرض کنیم آدرس زیر را می خواهیم دوباره نویسی کنیم:
http://example.com/index.php?q=home
هدف ما این است که آدرس بالا را به صورت زیر بازنویسی کنیم، یعنی با وارد کردن آدرس زیر در مرورگر سرور پارامترهای URL بالا را در پس زمینه دریافت کند:
http://example.com/home
بدین منظور ابتدا ماژول mod_rewrite را روشن می کنیم، سپس از قوانین آن استفاده کرده و با عبارات با قاعده (در ادامه در این خصوص بیشتر خواهیم گفت) یک قانون (Rewrite Rule) می نویسیم تا وقتی سرور آدرس درخواستی را با آن مطابقت داد قانون ما عمل کرده و پارامترهای اصلی در پس زمینه دریافت شوند:
RewriteEngine On
RewriteRule ^home /index.php?q=home [NC,L]
با کپی عبارت بالا در فایل htaccess. و قرار دادن آن در ریشه سایت، سرور آدرس دریافتی را با قسمت Pattern بررسی و اگر با الگوی قانون تعریف شده مطابقت داشته باشد آدرس اصلی (قسمت Target/Substitution - هدف/جایگزین) را بازنویسی می کند، در واقع پارامتر اول در قسمت الگو (home) منطبق بر ساختار URL استفاده شده در سایت و قسمت دوم قانون (index.php?q=home) همان آدرس نهایی بازنویسی شده برای استفاده در سرور و برنامه PHP است، به عبارتی قانون بالا از دو قسمت تشکیل شده است، در بخش اول آدرس درخواست شده از سرور بررسی می شود، اگر این آدرس با الگوی (Pattern) ما که در RewriteRule در نظر گرفته ایم مطابقت داشت آدرس استاتیک درخواستی به صورت پارامترهای داینامیک قسمت دوم هدف (Target) جانشین (Substitution) می شود، یعنی اگر در قسمت ابتدایی آدرس استاتیک بعد از دامنه سایت عبارت home وجود داشته باشد سرور آدرس را به صورت index.php?q=home شناسایی می کند، علامت هایی مانند ^ که در قانون نویسی به کار می روند معنی خاصی دارند که به آنها دستورات عبارات با قاعده یا Regular Expressions گفته می شود، حروف [NC,L] نیز معنی خاصی در زمینه نحوه پردازش قوانین دارند و با این روش منظورمان را به سرور تفهیم می کنیم، به طور مثال NC (nocase) به معنی Not Case-sensitive یا حساس نبودن به حروف بزرگ و کوچک است، یا حرف L به معنی Last و آخرین دستور است یعنی اگر این قانون اجرا شد بقیه قوانین بعد از آن نادیده گرفته می شوند، به این حروف نشانه گذاری در اصطلاح پرچم ها یا Flags می گویند، در ادامه دستورات باقاعده (Regular Expressions) و پرچم ها (Flags) در htaccess را بررسی می کنیم.
نکته: اگر قوانین را درست و کامل ننویسیم معمولا خطای داخلی سرور با کد 500 یا همان HTTP Error 500 Internal Server Error دریافت خواهیم کرد.

عبارات با قاعده (Regular Expressions) در htaccess


برای نوشتن و کاربرد صحیح قوانین دوباره نویسی باید حداقل آشنایی مختصری با عبارات با قاعده (Regular Expressions) داشته باشیم، عبارات باقاعده زبانی قراردادی جهت انتخاب یا بررسی قسمت خاصی از یک رشته متنی است، به طور مثال اگر در رشته متنی زیر که یک آدرس URL فرضی است:
http://example.com/find/?search=htaccess&page=23
بخواهیم صرفا اعداد را استخراج کنیم عبارت باقاعده آن می تواند به این شکل نوشته شود:
([0-9]+)
اگر در همین رشته بخواهیم مقادیر پارامتر search را از URL استخراج کنیم عبارت باقاعده آن به شکل زیر خواهد بود:
^search=([^&]*)
هر کاراکتر در RegExp معنی و کاربرد خاص خود را دارد که آموزش مفصل آن در آدرس زیر در دسترس است:
آموزش کاربردی عبارات با قاعده (Regular Expressions)
در ادامه صرفا جهت یادآوری چند نوع کاراکتر دستوری متداول از عبارت باقاعده را همراه با معنی آنها بررسی می کنیم:
Anchors یا لنگرها:
لنگرها شروع و پایان یک رشته را در الگو مشخص می کنند، به فرض الگوی زیر به معنی کلیه آدرس هایی است که بعد از دامنه سایت قسمت دوم آنها با اعداد (0 تا 9) شروع می شود:
^([0-9]+)$
الگوی بالا با URL فرضی زیر تطبیق دارد:
http://www.example.com/143231
علامت ^ ابتدای دامنه دستور را بعد از آدرس دامنه مشخص می کند و به معنی نقطه شروع الگو است، علامت $ انتهای دامنه دستور را مشخص می کند و به معنی نقطه پایان الگو است، با این توضیح قبل از علامت ^ و بعد از علامت $ نباید کاراکترهای متنی دیگری داشته باشیم در این صورت الگو با متن مطابقت نمی کند، به طور مثال الگوی بالا با URL های فرضی زیر تطبیق ندارد:
http://www.example.com/143231/dir

http://www.example.com/dir/143231
دسته بندی ها یا Character Classes:
نوع دیگر از دستورات باقاعده با حروف الفبای انگلیسی مانند w ،s ،W ،d و... (حساس به بزرگ یا کوچک بودن حروف) تعریف می شوند، به فرض کاراکتر d\ با اعداد (0 تا 9) مطابقت دارد، یا حرف w\ به معنی حروف و اعداد انگلیسی است، همچنین W\ شامل همه چیز به جزء حروف و اعداد انگلیسی می شود، کاراکتر s\ (با حروف کوچک) نیز به معنی فضای خالی و S\ به معنی هرچیزی به جز فضای خالی است.
نکته: برای تفهیم دستوری بودن کاراکترها به سیستم از یک بک اسلش (\) قبل از حروف الفبا استفاده می کنیم، جالب است که در برخی موارد (به طور مثال کاراکتر نقطه) این بک اسلش کاراکتر را از حالت دستوری خارج و به یک حرف متنی ساده تبدیل می کند، نقطه در دستورات عبارات باقاعده به معنی "هر کاراکتر" است اما با درج بک اسلش قبل از آن حالت دستوری خنثی می شود.
تاکیدات یا Assertions:
یک نوع دیگر از کاراکترهای دستوری عبارات با قاعده تاکیدات هستند، به اینصورت که اگر به فرض لینک دریافتی را برای وجود حرف a بررسی کرده و در عین حال بخواهیم بعد از حرف a کلمه فرضی book نیز نیامده باشد، خواهیم نوشت:
[^\S]*a(?!book)[^\S]*
قسمت مربوط به حرف S (با حروف بزرگ) و کاراکتر * (تعداد تکرار صفر یا بیشتر) در اینجا به معنی هر چیزی به جزء فاصله خالی در عبارت به تعداد تکرار صفر یا بیشتر است، به عبارتی وجود یا عدم وجود این قسمت اختیاری است، سپس وجود حرف a بررسی می شود و بعد از آن عدم وجود کلمه book و سپس نبودن فضای خالی، اگر آدرس URL درخواستی از این الگو پیروی کند قسمت دوم قانون اجرا می شود.
گروه و حدود:
یکی از پرکاربردترین نوع دستورات در عبارات با قاعده گروه ها و حدود هستند، به فرض اگر بخواهیم قسمت خاصی از یک رشته را انتخاب کنیم می توانیم دستورات را بین کاراکترهای () درج کنیم، مثال:
([\w]+)
این دستور حروف و اعداد انگلیسی را از رشته استخراج می کند، کاراکتر + نشان دهنده الزام به وجود حداقل یک حرف یا عدد است.
نکته: در htaccess می توانیم گروه های داخل () را به صورت شماره گذاری شده دریافت (Capture) کنیم، برای این منظور از کاراکتر $ (علامت دلار یا Dollar Sign) و شماره گروه مورد نظر استفاده می کنیم، مثال:
RewriteRule ([a-z0-9/-]+)-([a-z]+).html$ $1-$2.php [NC,L,QSA]
علاوه بر این اگر بخواهیم بررسی کنیم که در رشته متنی عباراتی خارج از محدوده اعداد 0 تا 9 و حروف a تا z قرار دارد یا خیر، با استفاده از کاراکترهای [] و بدون تعریف گروه خواهیم نوشت:
[^A-Za-z0-9]+
کاراکتر ^ داخل حدود [] حالت منفی می گیرد و به معنی "هر کاراکتری به جز" است.
کاراکتر | به معنی "یا":
کاراکتر دستوری "یا" با علامت | نیز در عبارات با قاعده کاربرد زیادی دارد، به فرض گروه زیر به معنی وجود حروف web یا goo در رشته متنی است:
(web|goo)
کاراکترهای دستوری عبارات با قاعده تنوع زیادی دارند و آموزش تمام آنها با جزئیات در این مطلب ممکن نیست، در اینجا بیشتر آشنایی اولیه با شیوه نگارش و هدف از به کارگیری آنها در نوشتن قوانین دوباره نویسی URL های وب مد نظر است.

پرچم ها (Flags) در htaccess


قسمت آخر در تعریف قوانین دوباره نویسی آدرس های وب استفاده از پرچم ها (Flags) است که به صورت [flag1,flag2,flag3] نوشته می شوند، با پرچم ها می توانیم نحوه پردازش دستورات را در فایل htaccess مدیریت کنیم، پرچم ها در دو شکل کوتاه یا کامل (به فرض L یا last) قابل استفاده هستند اما عمدتا شکل کوتاه آنها به کار می رود، این عبارات دستوری طیف های متنوعی دارند و هر کدام با هدف خاصی به کار می روند که در ادامه چند مورد از مهمترین ها را بررسی می کنیم:
- پرچم END
این پرچم اجرای دستورات htaccess را در نشست جاری به طور کامل متوقف می کند، البته تفاوت آن با L در این است که اگر چند فایل htaccess در دایرکتوری اصلی و دایرکتوری های زیرمجموعه داشته باشیم، با END اجرای تمام این فایل ها متوقف می شود اما با L صرفا فایل حاوی این دستور اجرایش متوقف می شود:
RewriteEngine On
RewriteRule ^index/([0-9]+)$ /index.php?page=$1[NC,END]
- پرچم F یا forbidden
در صورت استفاده از این پرچم و تطبیق الگو با آدرس URL درخواستی، سرور خطای وضعیت Forbidden 403 برمی گرداند:
RewriteRule "\.exe" "-" [F]
این قانون اجرای فایل های با پسوند exe از طریق فراخوانی آدرس URL را در سایت ممنوع می کند.
- پرچم L یا last
با اجرای قانون متناظر با این پرچم، مفسر دیگر قوانین را در فایل جاری نادیده می گیرد:
RewriteRule ^posts/([0-9]+)-(.*)\.html$ posts.php?id=$1 [NC,L]
تفاوت پرچم L با END در این است که با اجرای پرچم END تمام قوانین چه در فایل فعلی و چه در دیگر فایل هایی که ممکن است در دایرکتوری های زیرمجموعه ریشه سایت وجود داشته باشند خاتمه می یابند اما پرچم L صرفا اجرای ادامه قوانین را در فایل htaccess جاری متوقف می کند.
- پرچم NC یا nocase
در صورت درج این پرچم بزرگ یا کوچک بودن حروف اهمیتی ندارد و الگوی قانون در هر دو حالت تطبیق پیدا می کند:
RewriteRule "(.*\.(jpg|gif|png))$" "http://images.example.com$1" [NC]
در این مثال بزرگ یا کوچک بودن فرمت فایل ها مهم نیست و در صورت تطبیق با الگو قسمت دوم قانون برای سرور دریافت می شود.
- پرچم QSA یا qsappend
اگر آدرس درخواستی از سرور یک یا چند پارامتر داینامیک داشته باشد، به فرض:
http://example.com/news/123/?cat=2&title=this-is-easy
در حالت عادی پارامترهای داینامیک در قانون دوباره نویسی دخیل نمی شوند و قابل بررسی هم نیستند، به طور مثال اگر قانون زیر را داشته باشیم و کاربر آدرس بالا را از سرور درخواست کند:
RewriteRule ^news/(.*)$ news.php?url=$1 [NC,L]
در نهایت آدرس زیر برای استفاده در سرور دریافت می شود:
news.php?url=123
اما اگر قانون را با افزودن پرچم QSA به شکل زیر تغییر دهیم:
RewriteRule ^news/(.*)$ news.php?url=$1 [QSA,NC,L]
آدرس نهایی برای سرور به این صورت خواهد بود:
news.php?url=123/?cat=2&title=this-is-easy
- پرچم R یا redirect
برای انتقال کاربر از آدرس فعلی به آدرس مد نظرمان از پرچم R یا عبارت redirect استفاده می کنیم، این انتقال می تواند به همراه تنظیم کدهای وضعیت سری 300 الی 399 باشد، به طور مثال قانون زیر آدرس درخواستی را به صورت همیشگی (Permanently) به URL جدید منتقل می کند:
RewriteRule ^old-([0-9]+)$ new-$1 [R=301,NC,L]
برای تنظیم عدد متناظر با وضعیت HTTP از علامت = در مقابل R استفاده می کنیم.
نکته: پرچم R باید به همراه پرچم L استفاده شود، فلسفه این کار مشخص است، با ریدایرکت در واقع قصد اتمام بارگذاری آدرس درخواستی جاری و انتقال به آدرس جدید را داریم و لذا پردازش ادامه قوانین در نظر گرفته شده برای URL فعلی منطقی نیست و ممکن است با خطاهای ناخواسته مواجه شویم.
تعداد پرچم های قابل استفاده در هنگام نوشتن قوانین دوباره نویسی به موارد گفته شده ختم نمی شود، برای آشنایی بیشتر می توانیم به لینک زیر رجوع کنیم:
https://httpd.apache.org/docs/2.4/rewrite/flags.html

تعیین شرط و پارامترهای آن در دستورات htaccess


یکی از قابلیت های کاربردی که ماژول mod_rewrite در اختیارمان قرار می دهد امکان تعیین شرط یا Rewrite Conditions با شیوه نگارش (Syntax) زیر است:
RewriteCond TestString CondPattern [Flags]
اما تعیین شرط چه کاربردی دارد؟
در هنگام نوشتن قوانین دوباره نویسی مواردی پیش می آید که بخواهیم اجرای یک قانون را منوط به وجود شرایطی کنیم، یعنی ابتدا بررسی کنیم اگر شرایط مد نظرمان محقق شده بود قانون بعد از آن اجرا شود، مثال:
RewriteCond "%{QUERY_STRING}" "hack" [NC]
RewriteRule "." "-" [F]
این دستور تمام آدرس هایی که قسمت بعد از علامت ? (Query String) در آنها شامل کلمه hack باشد را مسدود (403 Forbidden) می کند.
تعداد شروط برای یک قانون می تواند بیش از یک مورد باشد، به طور مثال اگر بخواهیم یک استثنا برای قانون بالا تعریف کنیم که به فرض اگر کوکی شامل عبارت debug از مرورگر دریافت نشد قانون اجرا شود، خواهیم نوشت:
RewriteCond "%{QUERY_STRING}" "hack" [NC]
RewriteCond %{HTTP_COOKIE} !debug [NC]
RewriteRule "." "-" [F]
هر دو شرط بالا باید برقرار باشند تا قانون اجرا شود، در واقع به صورت پیش فرض برای دو شرط پرچم AND استفاده می شود اگر نیاز است که صرفا با برقراری یک شرط قانون اجرا شود می توانیم از پرچم OR (ornext) استفاده کنیم:
RewriteCond "%{QUERY_STRING}" "hack" [NC,OR]
RewriteCond %{HTTP_COOKIE} !debug [NC]
RewriteRule "." "-" [F]
پرچم OR صرفا در قسمت شرط ها قابل استفاده است نه در قسمت قوانین که این به فلسفه تعریف این پرچم بر می گردد.
همان طور که در نمونه دستورات بالا مشخص است در قسمت اول هر شرط پارامترهایی به شکل 
 %{NAME_OF_VARIABLE}
مشاهده می شود که به آنها متغیرهای سرور می گوییم، این متغیرها بسته به مورد می توانند شامل اطلاعات مختلفی از مرورگر کاربر و امکانات سرور باشند که اسامی آنها در جدول زیر آمده است:
HTTP HeadersConnection & RequestServer Internals
HTTP_ACCEPT
HTTP_COOKIE
HTTP_FORWARDED
HTTP_HOST
HTTP_PROXY_CONNECTION
HTTP_REFERER
HTTP_USER_AGENT
AUTH_TYPE
CONN_REMOTE_ADDR
CONTEXT_PREFIX
CONTEXT_DOCUMENT_ROOT
IPV6
PATH_INFO
QUERY_STRING
REMOTE_ADDR
REMOTE_HOST
REMOTE_IDENT
REMOTE_PORT
REMOTE_USER
REQUEST_METHOD
SCRIPT_FILENAME
DOCUMENT_ROOT
SCRIPT_GROUP
SCRIPT_USER
SERVER_ADDR
SERVER_ADMIN
SERVER_NAME
SERVER_PORT
SERVER_PROTOCOL
SERVER_SOFTWARE
Date & TimeSpecials
TIME_YEAR
TIME_MON
TIME_DAY
TIME_HOUR
TIME_MIN
TIME_SEC
TIME_WDAY
TIME
API_VERSION
CONN_REMOTE_ADDR
HTTPS
IS_SUBREQ
REMOTE_ADDR
REQUEST_FILENAME
REQUEST_SCHEME
REQUEST_URI
THE_REQUEST
نکته: گروه هایی که در قسمت Rewrite Rule تعریف می کنیم با کاراکتر $ (دلار - Dollar) و عدد متناظر گروه قابل دریافت هستند، اما گروه های به کار رفته در قسمت Rewrite Conditions را با کاراکتر % (درصد - Percent) می توانیم در قانون خود داشته باشیم، به طور مثال:
RewriteCond "%{DOCUMENT_ROOT}" !-f
RewriteCond %{HTTP_HOST} ^(sub.example.com)$
RewriteRule ^/?([a-z]+)/([0-9]+)$ /panel.php?action=$1&page=$2&host=%1
به نظر این کاراکترها ($، %) بخشی از قوانین قراردادی در شیوه نگارش (Syntax) دستورات htaccess هستند و احتمالا فلسفه قابل ذکر دیگری ندارند.
در قسمت دوم RewriteCond بسته به هدف از نوشتن شرط موارد زیر به عنوان CondPattern قابل استفاده است:
- بررسی منفی (برابر نبودن) با علامت !، مثال:
RewriteCond %{REQUEST_FILENAME} !-d
این شرط بررسی می کند که نام فایل درخواستی با یک دایرکتوری در سرور برابر نباشد.
- مقایسه با علامت های <=> برای مقادیر رشته ای یا عدد، مثال:
RewriteCond %{HTTP_USER_AGENT} "=This Browser/Ver 28.0"
این مقایسه برابر بودن متغیر سرور HTTP_USER_AGENT که معمولا حاوی اطلاعاتی از مرورگر کاربر است را با رشته متنی در نظر گرفته شده در دابل کوتیشن بررسی می کند.
- مقایسه با حروف دستوری خاص برای مقادیر رشته ای یا عدد، مثال:
RewriteCond %{HTTP_HOST} eq "example.com"
این حروف شامل:
eq مشتق از واژه equal to یا برابر با.
ge مشتق از سرواژه های greater than  و equal to به معنی بزرگتر از یا برابر با.
gt مشتق از سرواژه های greater than به معنی بزرگتر از.
le مشتق از سرواژه های less than و equal to به معنی کوچکتر از یا برابر با.
lt مشتق از سرواژه های less than به معنی کوچکتر از.
ne مشتق از سرواژه های not equal to به معنی برابر نبودن با (حالت حروفی کاراکتر دستوری !).
- بررسی صفت های مربوط به فایل و دایرکتوری، مثال:
RewriteCond /old/page/%{REQUEST_URI} !-f
RewriteRule ^(.+) /other/archive/$1 [R=301]
در ادامه برخی از پر کاربردترین کاراکترهای مربوط به بررسی فایل و دایرکتوری در htaccess را بررسی می کنیم:
d مشتق از سرواژه directory جهت بررسی وضعیت وجود و دایرکتوری بودن (یا در حالت منفی نبودن) آدرس.
f مشتق از سرواژه file جهت بررسی وضعیت وجود و فایل بودن (یا در حالت منفی نبودن) آدرس.
l مشتق از سرواژه link جهت بررسی وضعیت نمایشی (symbolic) بودن یا نبودن آدرس، لینک های سمبلیک یا نمایشی آدرس های URL ای هستند که منبع واقعی برای آنها در سرور وجود ندارد (به فایل خاصی اشاره نمی کنند) و صرفا جنبه نمایشی دارند، معمولا این سبک آدرس ها با دوباره نویسی برای سرور قابل فهم می شوند.
- استفاده از دستورات باقاعده (Regular Expressions)، مثال:
RewriteCond expr "! %{HTTP_REFERER} -strmatch '*://%{HTTP_HOST}/*'"
RewriteRule "^/images" "-" [F]
دستور بالا در شرط آدرس ارجاعی (Referer) را با هاست (Host) بررسی می کند، برای استفاده از دستورات باقاعده (Regular Expressions) لازم است که قسمت expr و strmatch مطابق با نمونه بالا در دستور وجود داشته باشد.

چند مثال کاربردی دوباره نویسی آدرس های وب (URL Rewrite)


جزئیات امکانات htaccess برای دوباره نویسی آدرس های وب به مواردی که بررسی کردیم ختم نمی شود، البته یادگیری تمام مباحث نه لازم است و نه مقدور، به هر صورت در نهایت هدف از طرح مباحث این است که بتوانیم نیازه های متنوع وبسایت ها و برنامه های تحت وب را در زمینه های مختلف پوشش دهیم، در ادامه با چند مثال کاربردی در خصوص نحوه استفاده کاربردی از دستورات htaccess در دوباره نویسی آدرس های وب (URL Rewrite) آموزش را به پایان می بریم.

انتقال آدرس از index.html به index.php


در این مثال آدرس صفحه اصلی را از index.html به index.php دوباره نویسی می کنیم:
RewriteEngine On
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /index\.html
RewriteRule ^index\.html$ http://example.com/index.php [R=301,L]
تفسیر دستور بالا:
اگر مقدار بازگشتی از متغیر سرور THE_REQUEST با حروف بزرگ انگلیسی به تعداد حداقل 3 و حداکثر 9 کاراکتر شروع و در این مقدار عبارت index.html نیز وجود داشت قانون بعدی اجرا شده و در صورتی که آدرس URL درخواستی با الگوی قانون مطابقت کند با پرچم R=301 که به معنی ریدایرکت همیشگی (Moved Permanently) است، کاربر از حالت index.html به آدرس http://example.com/index.php منتقل می شود.
نکته: متغیر THE_REQUEST شامل نمونه اطلاعات زیر است:
"GET /index.html HTTP/1.1"
انتقال از index.html به index.php را می توانیم بدون شرط نیز بنویسیم:
RewriteEngine on
RewriteRule ^index\.htm$ index.php [NC,R=301]

دوباره نویسی آدرس داینامیک با یک پارامتر متنی


در این مثال آدرس داینامیک با یک متغیر متنی را دوباره نویسی می کنیم:
RewriteEngine On
RewriteRule ^category/([^/]+) /?category=$1 [NC,L]
به فرض آدرس نمایشی http//example.com/category/learn در سرور به صورت http//example.com/?category=learn دریافت می شود، همانطور که گفتیم گروه های تعریف شده بین کاراکترهای () در قسمت RewriteRule با علامت $ و شماره متناظر آن مشخص می شوند، در این نمونه دستور نیز عبارت learn به این شیوه برای سرور بازنویسی شده است.

دوباره نویسی آدرس داینامیک با یک پارامتر عددی


در این مثال آدرس داینامیک با یک متغیر عددی را دوباره نویسی می کنیم:
RewriteEngine On
RewriteRule ^category/([0-9]+) /?category=$1 [NC,L]
به فرض آدرس نمایشی http//example.com/category/5 به صورت http//example.com/?category=5 دریافت می شود.

دوباره نویسی آدرس داینامیک با دو پارامتر متنی و عددی


در این مثال آدرس داینامیک با دو پارامتر متنی و عددی را دوباره نویسی می کنیم:
RewriteEngine On
RewriteRule ^category/([0-9]+)/([^/]+) /?category=$1&title=$2 [NC,L]
دستور بالا آدرس نمایشی http//example.com/category/5/learn-web را به صورت http//example.com/?category=5&title=learn-web دوباره نویسی خواهد کرد.

انتقال از آدرس بدون www به آدرس با www و برعکس


در مثال زیر دستوری تنظیم کرده ایم که اگر در آدرس درخواستی ورودی عبارت www تایپ نشده بود کاربر به آدرس با www هدایت شود:
RewriteEngine On
RewriteCond %{HTTP_HOST} !^www\.example\.com$ [NC]
RewriteRule .? http://www.example.com%{REQUEST_URI} [R=301,L]
برعکس این حالت یعنی انتقال از آدرس با www به آدرس بدون www (به اصطلاح non-www) را نیز با دستور زیر می توانیم تعریف کنیم:
RewriteEngine On
RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
RewriteRule ^(.*)$ http://%1/$1 [R=301,L]
متغیر سرور HTTP_HOST معمولا شامل آدرس اصلی سایت است که از مرورگر دریافت می شود، به طور مثال example.com و REQUEST_URI قسمت بعد از آدرس سایت را شامل می شود.

دانلود غیر مستقیم فایل های PDF


یکی از کاربردهای جالب دوباره نویسی آدرس های وب در htaccess امکان ایجاد قابلیت دانلود غیر مستقیم فایل ها و پردازش ابتدایی آنها با دستورات PHP به فرض جهت بررسی مجاز بودن دسترسی کاربر است، به طور مثال:
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^(.+)\.pdf$  /include/pdf.php?file=$1 [L,NC,QSA]
در این مثال در صورتی که کاربر فایلی با پسوند pdf را از سرور درخواست کند قبل از بارگذاری فایل در مرورگر (روند عادی) ابتدا در فایل pdf.php دریافت و پردازش مورد نظر اعمال می شود، به فرض اگر کاربر وارد سایت شده و مجاز به دانلود بود در نهایت با دستورات PHP فایل جهت دانلود به سمت مرورگر ارسال می شود.

حذف index.php از آدرس URL


از جمله کاربردهای استفاده از تکنیک دوباره نویسی آدرس های وب مخفی سازی تکنولوژی و زبان برنامه نویسی به کار رفته در ایجاد صفحات سایت و در عین حال داشتن آدرس های کوتاهتر و خواناتر است، به طور مثال می توانیم با نمونه دستور زیر عبارت index.php را از آدرس URL (با یک پارامتر) حذف کنیم:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !^/(favicon\.ico|apple-touch-icon.*\.png)$ [NC]
RewriteRule (.+) index.php?id=$1 [QSA,L]
طبق این دستور آدرس فرضی example.com/index.php?id=1 را می توانیم به صورت example.com/1 در سایت داشته باشیم.
نکته: با توجه به ساختار آدرس های سایت الگوی این سبک قوانین می تواند دامنه وسیعی از URL ها را شامل شود یا باعث ایجاد تداخل در قانون ها گردد، به همین دلیل و به صورت نمونه آیکن های ریشه سایت را با تعیین شرط از این قاعده مستثناء کرده ایم.

یادآوری مهم


در پایان این آموزش مجددا یادآور می شویم دوباره نویسی آدرس های وب باید با دقت بالا انجام شود، اشتباه در نحوه چینش قانون ها مخصوصا در مورد قوانین مشابه ممکن است موجب بروز اختلال در عملکرد عادی سایت شده یا سبب ایجاد مشکلاتی نظیر مطالب تکراری (Duplicate Content) گردد، بهتر است با سربرگ های HTTP آشنا و بر تکنیک ریدایرکت 301 (Moved Permanently) نیز تسلط کافی داشته باشیم و قبل از اعمال تغییرات در ساختار URL های سایت حتما همه ی جوانب را تست و از کدهای فعلی پشتیبان تهیه کنیم.
دسته بندی: مهارتهای وب » بهینه سازی
related مطالب بیشتر:
» حل مشکل محتوای تکراری (Duplicate Content) در سایت
» مقایسه خطای 404 و کد 301 ریدایرکت (Redirect)
» مشکلات رایج در کدنویسی معتبر و رفع آنها
» چگونه سایت یا وبلاگ را برای موتورهای جستجو بهینه سازی کنیم؟
» چرا برخی سایت ها و وبلاگ ها رتبه الکسای بهتری دارند؟
commentنظرات (۱۷۳ یادداشت برای این مطلب ارسال شده است)
more یادداشت های جدید بر اساس تاریخ ارسال در انتهای یادداشت های موجود نمایش داده می شوند.
نویسنده: مهران
۱۵:۳۱ ۱۳۹۲/۱۱/۲۹
سلام خسته نباشید.
من هر کاری می کنم نمیشه
http://ariaandishan.com/index.html
را به
http://ariaandishan.com/home
تبدیل کنم .
لطفا کمکم کنید..
پاسخ: 
از الگوی نمونه زیر استفاده کنید:
RewriteEngine On
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /index\.html
RewriteRule ^index\.html$ http://yoursite.com/home [R=301,L]
نویسنده: مازیار
۱۵:۴۰ ۱۳۹۳/۰۲/۰۱
سلام
من می خوام بعد از ادرس سایت هرچی وارد می شه اول برسی کنه اگه کلمه های مثل home, message و غیره نبود اون صفحه رو باز کنه که مثلا پروفایل کاربری هست
RewriteEngine On
RewriteRule ^([^/]+) /a.php?a=$14 [NC,L]
از این کد استفاده کردم ولی ارور 500 داد میشه منو راهنمایی کنید؟
ممنون از سایت خوبتون
پاسخ: 
نکته اول عدد 14 است که باید 1 باشد!
نکته دوم اینکه کد استفاده شده برای هدف شما کاربرد ندارد، معنی کد شما این است که هر چیزی به جز علامت / بعد از آدرس سایت قرار گرفت، به عنوان پارامتر برای قسمت دوم در نظر گرفته شود و لذا شرطی وجود ندارد، نمونه روش صحیح (تست نشده):
RewriteEngine On
RewriteCond %{REQUEST_URI} !^/home|message
RewriteRule ^([^/]+) /a.php?a=$1 [NC,L]
نویسنده: مازیار
۰۰:۱۴ ۱۳۹۳/۰۲/۰۳
سلام
شرمنده نکته 1 اشتباه چاپی بود
همچنان با ارور 500 مواجه هستم و نمی دونم مشکل از کجای کار می تونه باشه
میشه از شما تقاضا کنم این مورد را بررسی نمایید.
واقعا شرمنده شما هستم.
تشکر از پیگیری شما
پاسخ: 
فایل htaccess را به صورت ZIP شده به آدرس ایمیل ما (درج شده در بخش تماس با ما) ارسال کنید تا بررسی کنیم، نتیجه را نیز از طریق ایمیل پیگیر باشید.
نویسنده: مازیار
۱۹:۰۱ ۱۳۹۳/۰۲/۰۵
سلام
اقا ممنون از لطف شما.
مشکل حل شد
کد باید به این صورت در بیاد تا کار بده
RewriteEngine On
|RewriteCond %{REQUEST_URI} !^/home|message|a
RewriteRule ^([^/]+) /a.php?a=$1 [NC,L]
یعنی باید خود صفحه مذکور به شرط لود نشدن اضافه بشه
پاسخ: 
خواهش می کنیم.
به نظر مشکل کد قرار گرفتن در یک حلقه بی پایان بود (یعنی سرور مدام فایل a.php را بارگذاری می کرد)، نکته ای که از قلم افتاده بود!
نویسنده: hesam
۰۱:۴۲ ۱۳۹۳/۰۲/۲۴
بسیار زیبا ممنون از لطف شما
نویسنده: yaghob
۱۲:۰۴ ۱۳۹۳/۰۳/۰۵
سلام خسته نباشید دوست عزیز
من این کدهای بالا رو انجام دادم ولی فقط وقتی در ادرس بار تایپ میکنم انجام میشه ولی وقتی که بر روی لینک کلیک میکنم دوباره ادرس تغییر میکنه به شکل اولیه
مثلا
ادرس
www.nabdownload.com/index.php?do=reg
رو تبدیل کردم به
www.nabdownload.com/reg
فقط زمانی که در ادرس بار تایپ میکنم درست کار میکنه
ولی وقتی بر روی لینک مربوط کلید کنی دوباره ادرس برمیگرده به
www.nabdownload.com/index.php?do=reg
لطفا راهنمایم کنید
اگه بخوام ادرس زیر تبدیل کنم
www.nabdownload.com/index.php?do=news&nid=66
چطوری تبدیل کنم
ممنون میشم اگه راهنمایم کنید
پاسخ: 
دستورات فایل htaccess. و ساختار سایت شما باید به صورت آنلاین بررسی شود، بدون آزمایش و خطا نمی توان گفت که مشکل از کجا است، شاید یک مورد خیلی جزئی باعث بروز مشکل شود، در مورد بخش دوم سوال نیز با ذکر نمونه در مطلب آموزش داده شده.
نویسنده: داوود
۱۱:۲۹ ۱۳۹۳/۰۳/۲۷
سلام.
من میخوام آدرس :
http://localhost/taranweb/Articles//Article/20
رو به
http://localhost/taranweb/Articles/?Article=20
تبدیل کنم.
چجوری میشه این کار رو کرد؟
پاسخ: 
به نظر یک / در آدرس اول شما اضافه است؟!
RewriteEngine On
RewriteRule ^taranweb/Articles//Article/([0-9]+) /taranweb/Articles/?Article=$1 [NC,L]
نویسنده: ehsan
۱۱:۰۶ ۱۳۹۳/۰۴/۰۱
سلام به خاطر مطلب خیلی خوبتون ممنون
میشه برا کاراکترهای فارسی بگین به چه صورت در rewrite باید قرار بدم
با تشکر
پاسخ: 
اصولا استفاده از حروف فارسی در آدرس URL توصیه نمی شود، بهتر است از استاندارد یونیکد UTF-8 استفاده کنید که در آن حروف فارسی تبدیل به کاراکترهای خاص می شوند (اما در نوار آدرس مرورگر به صورت کلمات قابل خوانا هستند)، این کار در PHP با توابعی مانند rawurlencode انجام می شود، به هر حال اگر لینک فارسی است، هم می توانید به همان طور فارسی استفاده کنید، هم مانند کاراکترهای انگلیسی از عبارت باقاعده
([^/]+) 
استفاده کنید.
نویسنده: میثم
۱۶:۰۵ ۱۳۹۳/۰۴/۰۸
سلام
ببخشید من با کل موضوع یه مشکلی دارم!
من با EasyPHP کار میکنم.
فایل httpd.conf رو ویرایش کردم و علامت # رو از این گزینه ها برداشتم
LoadModule rewrite_module modules/mod_rewrite.so
LoadModule headers_module modules/mod_headers.so
و بعد Easyphp رو restart کردم
سایت من به این شکله
http://localhost/site/index.php?p=2
حالا میخوام به این شکل در بیاد:
http://localhost/site/index/2
فایل httacces. رو با محتوای زیر ساختم و در ریشه قرار دادم
RewriteEngine On
RewriteRule ^site/index/([0-9]+) /site/index.php?p=$1 [NC,L]
قاعدتا الان نباید مشکلی باشه
ولی وقتی تو آدرس بار میزنم
http://localhost/site/2
ارور میده که
The requested URL /site/index/2 was not found on this server.
میشه بفرمایید کجای کار رو دارم اشتباه میرم یا کجا رو انجام ندادم؟
مرسی.
پاسخ: 
حل مشکل نیاز به تست دارد اما به نظر به هر دلیل mod_rewrite به درستی در برنامه شما فعال نشده، تا جایی که اطلاع داریم در برنامه EasyPHP باید علاوه بر اقدامات بالا، پارامتر دیگری به نام
AllowOverride None
را به
AllowOverride All
تغییر دهید، علت بعدی می تواند از تنظیم اشتباه دستورات htaccess با توجه به موقعیت فایل ها و آدرس درخواستی باشد.
نویسنده: میثم
۰۴:۴۰ ۱۳۹۳/۰۴/۰۹
سلام مجدد
مرسی ، بله باید این رو تغییر میدادم.
الان این رو که در آدرس بار می زنم درست میاد
http://localhost/site/index/2
ولی این رو میزنم
http://localhost/site/index.php?p=2
دیگه چیزی نمیاد ،
روالش به همین صورته؟ یعنی وقتی تبدیل میشه دیگه لینک های اول کار نمیکنن؟
=====
سوال دوم
چطور میشه لینک های آدرس بار رو در یک string ذخیره کرد؟
یعنی مثلا وارد یه صفحه ای میشیم بتونیم آدرس کامل (یا بخشی از آدرس) اون صفحه رو هم تو یه متغیر داشته باشیم؟
مرسی.
پاسخ: 
- خیر! اگر دستورات را به نحو صحیحی نوشته باشید، چه در حالت داینامیک و چه در حالت استاتیک، سرور متناسب با آدرس درخواستی نتیجه را نمایش می دهد، باید توجه کنید که حتی لینک های داینامیک نیز ابتدا با الگوی نوشته شده در فایل htaccess تطبیق داده می شوند، به عبارتی تمام آدرس های درخواستی با الگوهای فایل htaccess تطبیق داده می شوند و در صورت عدم تطبیق، در نهایت به صورتی که درخواست شده پردازش می شوند (رفع مشکل نیاز به تست دارد).
- برای دریافت آدرس لینک درخواستی از سرور می توانید از تابع زیر استفاده کنید:
function pageURL(){
$pageURL = 'http';
if($_SERVER["HTTPS"] == "on"){
$pageURL .= "s";
}
$pageURL .= "://";
if($_SERVER["SERVER_PORT"] != "80"){
$pageURL .= $_SERVER["SERVER_NAME"].":".$_SERVER["SERVER_PORT"].$_SERVER["REQUEST_URI"];
}
else{
$pageURL .= $_SERVER["SERVER_NAME"].$_SERVER["REQUEST_URI"];
}

return $pageURL;
}
$page_url = pageURL();
نویسنده: میثم
۰۴:۴۷ ۱۳۹۳/۰۴/۰۹
راستی خیلی ممنون میشم یه مقاله ای هم در رابطه با MVC در PHP ارائه بدید.
یا یه منبع مناسب انگلیسی یا فارسی معرفی کنید برای یادگیری چون هرچی سرچ کردم اصلا آموزش ها کامل نبودن.
====
اینم الان یادم افتاد ، چطور میشه مثل گوگل وقتی سرچ میکنیم ، زمان سرچ رو هم داشته باشیم. ( زمانی که طول کشیده تا سایت مورد نظر رو پیدا کنه)
البته سایت شما هم داره این مورد رو.
مرسی
پاسخ: 
- همان طور که می دانید مبحث MVC یا Model View Controller یک شیوه یا الگو (pattern) جهت خلق نظامند برنامه های کاربردی وب است که خود مبتنی بر مباحث شی گرایی است، به همین دلیل ارائه آموزش های خاص برای آن تا زمان طرح مباحث برنامه نویسی شی گراء ممکن نیست، در وب آموزش های نسبتا قابل فهمی (عموما به زبان انگلیسی) وجود دارد، البته می توانید الگوی خاص خود را داشته باشید و اجباری به رعایت اصول MVC نیست (هرچند درک مبانی آن مفید خواهد بود).
- برای محاسبه زمان پردازش دستورات PHP می توانید از نمونه کد آماده زیر استفاده کنید.
تکه کد زیر را در ابتدای صفحات PHP قرار دهید:
<?php
$time = microtime();
$time = explode(' ', $time);
$time = $time[1] + $time[0];
$start = $time;
?>
سپس در همان صفحه تکه کد زیر را در انتهای دستورات قرار دهید:
<?php
$time = microtime();
$time = explode(' ', $time);
$time = $time[1] + $time[0];
$finish = $time;
$total_time = round(($finish - $start), 4);
echo 'Page generated in '.$total_time.' seconds.';
?>
مبنای کد ساده و به راحتی قابل سفارشی سازی است.
نویسنده: علی
۰۹:۳۴ ۱۳۹۳/۰۴/۲۰
سلام خسته نباشی
من یه بخش تو سایتم دارم که به کاربرا پروفایل اختصاص میده آدرس پروفایل هر کاربر به این شکل هستش
http://localhost/?user=admin
آدرس رو به این صورت تغییر دادم
RewriteRule ^$ z.p.php
که به این شکل در اومد
?user=admin
من میخوام آدرس به این شکل تغییر پیدا بکنه
http://localhost/admin
تو فایل z.p.php هم که صفحه پروفایل رو نشون میده
کدها به این صورت هستش
ستاره دار رو توجه کن
require_once('tools/profile/db.php');
@ $user=$_GET['user']; ***
$conn = db_connect();
$result = $conn->query("select * from aliresalat_users where username = '$user'"); ***
$num_results = $result->num_rows;
for ($i=0; $i <$num_results; $i++)
{
$row = $result->fetch_assoc();

$userfullname=$row['userfullname'];
$email=$row['email'];
$usertel=$row['usertel'];
$userwebsite=$row['userwebsite'];
$ostan=$row['ostan'];
$keshvar=$row['keshvar'];
$shahr=$row['shahr'];
$jensiyat=$row['jensiyat'];
$tavalod=$row['tavalod'];
$alaghe=$row['alaghe'];
$avatar=$row['avatar'];
$laghab=$row['laghab'];
$usertel=$row['usertel'];
$useronline=$row['useronline'];
$username=$row['username'];
$userid=$row['userid'];
$chkProfile=$row['chkProfile'];
}
if($num_results)
{
اینجا هم فکر کنم باید یه تغییراتی داده بشه
چون ادرس به این شکل هستش
?user=admin
و همون طور که گفتم میخوام این شکلی بشه
http://localhost/admin
منتظر پاسخ هستم سپاس
پاسخ: 
- برای تبدیل آدرس های داینامیک به استاتیک نیازی به دستکاری کدهای PHP نیست، چون تفاوت خاصی بین حالت داینامیک و استاتیک نیست (در واقع لینک استاتیک اگر به درستی برای آن RewriteRule نوشته شود، معادل لینک داینامیک است و همان پارامترها را ارسال می کند)
- در اینجا نوشتن یک RewriteRule مناسب در htaccess نقش کلیدی دارد، می توانید برای حالت
http://localhost/admin
به صورت زیر دستور بنویسید:
RewriteEngine On
RewriteRule ^([^/]+) /z.p.php?user=$1 [NC,L]
این روش چون هیچ کلید واژه ای در لینک شما نیست، توصیه نمی شود و ممکن است در حالت های دیگر موجب بروز اختلال شود، بهتر است لینک به صورت زیر باشد:
http://localhost/user/admin
و به صورت نمونه زیر دریافت شود:
RewriteEngine On
RewriteRule ^user/([^/]+) /z.p.php?user=$1 [NC,L]
در این حالت عبارت کلیدی user باعث می شود تا تنها آدرس هایی که به دایرکتوری فرضی user ختم می شوند شامل دستور RewriteRule شوند.
نویسنده: علی
۱۰:۳۹ ۱۳۹۳/۰۴/۲۰
روش اول رو امتحان کردم
RewriteRule ^([^/]+) /z.p.php?user=$1 [NC,L]
http://localhost/admin
بعد از ورود به این شکل در میاد
http://localhost/admin/?user=admin
و خطای 500 میده روش دوم مشکلی نداشت ولی پیشنهادتون چیه واسه مشکل روش اول چون به هر حال پروفایل به نظر من که اصولا باید به صورت روش اول نشون داده بشه
ممنون بابت جواب سریع
نویسنده: علی
۱۱:۱۶ ۱۳۹۳/۰۴/۲۰
خوب مشکل رو حل کردم rule به این شکل در میاد
RewriteRule ^([^/.]+)(\/)?$ z.p.php?user=$1
نتیجه شد :
http://localhost/admin
میشه یه توضیح هم در مورد این rule بدید
RewriteRule ^([^/.]+)/([^/.]+)/followers?$ followers.php?uname=$1&bname=$2&%{QUERY_STRING}
پاسخ: 
به جزء دستور
%{QUERY_STRING}
سایر موارد مشخص هستند، این دستور نیز معرف پارامترهای درخواست شده از سرور است (یعنی تمام عبارتی که بعد از علامت ? در آدرس URL درخواستی وجود دارد)، به طور مثال Query String برای آدرس
http://localhost/admin/index.php?token=e8euhd64hdn3&id=33
مقدار زیر است:
token=e8euhd64hdn3&id=33
نویسنده: یحیی
۱۱:۱۴ ۱۳۹۳/۰۵/۲۲
میخواستم بدونم نظرتون راجع به این موضوع چیه
جایی خوندم که برای دوباره نویسی آدرس ها ابتدا همه آدرسها به یک فایل php فرستاده بشه و سپس در اون فایل میتوان فایل مورد نظز را فراخوانی کرد
مثلا همه فایل ها به فایل main.php ازسال بشه و سپس در این فایل متعاقب درخواست صفحه مورد نظر فراخوانی بشه
پاسخ: 
این بحث با حالت دوباره نویسی لینک های داینامیک متفاوت است، حالت مد نظر شما در هنگام طراحی ساختار یک برنامه کاربرد دارد که به فرض مطابق با پارامتر دریافتی از لینک یک کلاس یا کد PHP خاص در هسته برنامه پردازش می شود، اما بحث URL Rewrite به هسته برنامه مرتبط نیست و صرفا لینک های سایت را به صورت استاتیک تبدیل می کند.
more لطفا پیش از ارسال یادداشت نکات زیر را مد نظر داشته باشید:
- موارد غیرمرتبط با مباحث آموزش ها را در فرم منوی "تماس با ما" مطرح و پاسخ را از طریق ایمیل دریافت کنید.
- به سوالات کلی، مبهم و مشکلاتی که تلاشی برای رفع آن نکرده باشید پاسخ مختصر داده خواهد شد.
- کدها و اسکریپت های طولانی را ترجیحا در یک صفحه وب آنلاین قرار دهید تا امکان تست و بررسی وجود داشته باشد.
- از درج عناوین تبلیغاتی در فیلدها خودداری کنید، در صورتی که یادداشت تبلیغاتی تشخیص داده شود حذف خواهد شد.
- تمام یادداشت ها بررسی و زمانی جهت پاسخگویی در نظر گرفته می شود، لطفا از طرح سوالات متعدد خودداری کنید.





6 × 5
 refresh

آخرین دیدگاه ها
more برای دسترسی سریع به یادداشت مربوطه می توانید از لینک مطلب در کادر زیر استفاده کنید.
form شریفی
در:
سلام مجدد. من یه سوال خیلی تخصصی دارم. ممنون میشم پاسخ بدین. برای پروژه پایان نامه. دارم روی موتورهای جستجوگر تحقیق میکنم. فرض...
۱۴۰۰/۰۱/۲۵

form شریفی
در:
سلام استاد. من از متد file_get_contents استفاده می کنم برای دریافت اطلاعات از سایت های مختلف. بعضی وقتها سایت ها دیر لود میشه. آیا...
۱۴۰۰/۰۱/۲۵

form hh
در:
سلام خدمت شما بنده یه سوال داشتم تمام مراحل شما رو انجام دادم و نتیجه گرفتم و لازمه یه تشکرم بکنم. وبسایت من،...
۱۴۰۰/۰۱/۲۵

form erfan
در:
سلام من واسه یه دکمه یه محتوایی تعریف کردم که وقتی کلیک شد محتوا رو نشون بده اما تو دوجاش موندم یک اینکه چیکار کنم...
۱۴۰۰/۰۱/۲۱

form mahdi
در:
سلام استاد عزیز ، بازم معذرت میخوام سوالام زیاد شد ولی همشون در یک موضوع هستن ، تونستم که با این روش برای هر اسلایدر...
۱۴۰۰/۰۱/۱۸

form mahdi
در:
سلام استاد عزیز عذر میخوام بار سومه پیام میزارم ، مشکلش از ست اینترول بود که قطع نمیشد و با هم تداخل داشتند ولی بدون...
۱۴۰۰/۰۱/۱۸

form mahdi
در:
سلام وقت بخیر استاد عزیز ، یک تابع رو چطور میشه در جاوا اسکریپت اورراید کرد؟ که مثلا با هر فراخوانی مجدد ، قبلی ها...
۱۴۰۰/۰۱/۱۸

form متین
در:
سلام چجوری برای خود صفحه ادرس بسازیم که سایتی که رو ساختیم رو با دستگاه دیگه پیداش کنیم
۱۴۰۰/۰۱/۱۶

form امیرحسین برزویی
در:
من یک وبلاگ دارم و 9 سالمه من در وبلاگم مداحی می گذارم ولی وقتی قاب گذاشتم از این سایت من دیگه فیلم...
۱۴۰۰/۰۱/۱۶

form بنده خدا
در:
سلام خسته نباشین، خدا قوت. یه سوال دارم. چرا در بخش نظردهی وبلاگ به جای عنوان پست می نویسه مطلب مورد نظر یافت نشد؟!...
۱۴۰۰/۰۱/۱۵

form روح الله
در:
موقعی میخواهم وارد سایت ایران خودرو بشم پیام میده از Ip داخلی استفاده کنید دلیلش چیست
۱۴۰۰/۰۱/۱۴

form غریب
در:
تشکر از شما مشکلم حل شد امیدوارم موفق و پیروز باشید هر جا که هستید
۱۴۰۰/۰۱/۱۱

form غریب
در:
سلام مجدد ممنون و تشکر از کمکتون کد به خوبی کار میکنه اما همچنان من مشکلی دارم که حل نتونستم کنم...
۱۴۰۰/۰۱/۱۰

form غریب
در:
سلام مجدد این کدی که دادید خوب هست ولی من بد و ناقص توضیح دادم توجه کنید کد این هست تقریبا ممنون...
۱۴۰۰/۰۱/۱۰

form غریب
در:
سلام خسته نباشید من کدی دارم که میخوام داخل یه بخشیش نتیجه یه رویداد رو فراخوانی کنم و راهش و نمیدونم اگر میشه کمک...
۱۴۰۰/۰۱/۱۰

form محسن
در:
سلام ، سوال من مربوط به پنل کارگزاری هاست ، وقتی اسم یک سهم (نماد) را در قسمت جست و جو سرچ میکنم...
۱۴۰۰/۰۱/۰۸

form ترجمه
در:
باسلام همه صفحات من دارای دو url می باشد که یکی با حروف کوچک است و دیگری با حروف بزرگ چجوری این مشکل را...
۱۴۰۰/۰۱/۰۸

form سهیل ملکی
در:
سلام خسته نباشید ببخشید من میخوام از تابع navigator.online توی جاوا اسکریپت استفاده کنم تا باهاش بفهمم کاربر آنلاین هست یا نه و اگه بود...
۱۴۰۰/۰۱/۰۴

form Rabbiten
در:
سلام. من چند ماه است که دنبال کد استایل تصویر مثل تبلیغات بالای سایت شما هستم. اما هیچ جا پیدایش نمی کنم. لطف می...
۱۴۰۰/۰۱/۰۱

form mahdi
در:
سلام استاد عزیز سال نو رو تبریک میگم بهتون ، امیدوارم که خودتون و خانوادتون همیشه سالم و سلامت باشید و امسال پر از...
۱۳۹۹/۱۲/۳۰

form korosh abbasy
در:
سلام وقت بخیر ببخشید در مورد این مطلب سوالی پرسیدم شما در مورد output buffering توضیح دادید کد کار نمیکنه میخواستم ببینم نیازی هست من...
۱۳۹۹/۱۲/۲۹

form احمد
در:
سلام مجدد عذرخواهی میکنم یه موردی دیگه بود فراموش کردم در مورد سوال هدر بگم اینکه روی لوکال به هدر ارسال میشه ولی روی هاست...
۱۳۹۹/۱۲/۲۸

form احمد
در:
با سلام خسته نباشید ببخشید قبلا یه سری دستورات جی کوری رو از خودتون گرفتم وقتی فیلدهای فرمم تکمیل شده است توسط هدر بره به...
۱۳۹۹/۱۲/۲۸

form korosh abbasy
در:
سلام دم شما گرم این دستور برای خوندن فایل هم استفاده میشه؟ من میخوام دسترسی تعیین کنم که اگر یک متغییر true...
۱۳۹۹/۱۲/۲۷
  در انتظار بررسی: ۱
 پاسخگویی به سوالات ممکن است تا 24 ساعت زمان ببرد.