اگر وب سایت شما مقدار زیادی ترافیک در طول روز دریافت می کند و بارگذاری وبسایت شما کند شده است ، شما احتملا به دنبال روش هایی مبنی بر سیستم کش cache برای بالا بردن سرعت لود سایت خود هستنید.
همانطور که می دانید هر درخواست کلاینت-سرور شامل تعداد زیادی کویری ، حلقه ها ، محاسبات و دستورات دیتابیس است . همه این ها بر روی هم زمان لود سایت را بالا می برد. راهکار ساده برای جلوگیری از همه اینها ساخت کش فایل و ذخیره آنها در یک دایرکتری جدا است ، که بعدا برای بارگذاری صفحات استاتیک به جای صفحات زنده و داینامیک استفاده شود .
ساخت سیستم کش در php
انجین های مختلفی برای سیستم کش در php مانند APC , Xcache یا Opcache برای افزایش بازدهی اپلیکیشن شما وجود دارد ، اما همه آنها کاملا متفاوت از هم کار می کنند ،
اگر شما کنجکاو هستید در مورد آنها بیشتر بدانید با یک جستجوی ساده مقالات زیادی را در وب می توانید پیدا کنید ، اما در این آموزش شما ساخت یک سیستم کش در php را به سادگی با استفاده از output Buffer و Filesystem یاد می گیرید . ترکیب این دو تابع یک سیستم کش عالی را برای شما ایجاد می کند.
PHP output Buffer : این قابلیت به طور قابل توجهی بازدهی را افزایش و مقدار زمان نیاز برای دانلود را کاهش می دهد ، چونکه خروجی در قسمت های کوچک برای مرورگر فرستاده نمی شود بلکه کل صفحه HTML در یک متغییر ارسال می شود . این متد بسیار ساده است نگاهی به کد زیر می ندازیم :
1 2 3 4 5 6 7 |
<?php ob_start(); // start the output buffer /* the content */ ob_get_contents(); gets the contents of the output buffer ob_end_flush(); // Send the output and turn off output buffering ?> |
در خط اول ob_start()
، output buffering را فعال می کند یعنی اینکه بعد از این همه چیز در بافر ذخیره و محتویات بافر از طریق ob_get_contents()
در دسترس خواهد بود . ob_end_flush()
در اخر برای غیرفعال سازی بافرینگ استفاده شده است.
PHP filesystem : بخشی از هسته php است که به ما اجازی خواندن و تغییر محتویات فایل ها را می دهد
1 2 3 |
$fp = fopen('/path/to/file.txt', 'w'); //open file for writing fwrite($fp, 'I want to write this'); // fclose($fp); //Close file pointer |
همانطور که می بینید در خط اول fopen()
یک فایل را در مود رایت که با w مشخص شده است باز می کند (در صورتی که وجود نداشته باشد ، می سازد) . در خط دوم fwrite()
رشته تعریف شده را در فایل اضافه می کند و در اخر fclose()
با موفقیت فایل باز شده در ابتدای کد را می بندد.
پیاده سازی سیستم کش در php
حاله که شما به صورت واضح در مورد output buffer و filesystem اگاه شدید ، ما از هر دوی این متد ها برای ساخت سیستم کش در php استفاده خواهیم کرد. لطفا نگاهی به عکس زیر بیندازید ، فلوچارت زیر به شما ایده سیستم کش (cache) را می دهد.
زمانی که یک کاربر درخواست محتویات را میدهد ، اسکریپت به سادگی کش صفحه درخواستی را نشان می دهد ، اگر وجود نداشته باشید ، یک کپی جدید از آن ساخته و به مرورگر ارسال میکند.
در زیر یک مثال کامل از پیاده سازی سیستم کش در php را برای تست شما قرار دادیم ، می توانید این کد ها را در پروژه های خود استفاده کنید و انتظار کار کردن را به صورت کامل داشته باشید .می توانید زمان انقضا ، پسوند فایل کش (cache) و .. بنا به نیاز خود تغییر بدهید.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
<?php //settings $cache_ext = '.html'; //file extension $cache_time = 3600; //Cache file expires afere these seconds (1 hour = 3600 sec) $cache_folder = 'cache/'; //folder to store Cache files $ignore_pages = array('', ''); $dynamic_url = 'http://'.$_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] . $_SERVER['QUERY_STRING']; // requested dynamic page (full url) $cache_file = $cache_folder.md5($dynamic_url).$cache_ext; // construct a cache file $ignore = (in_array($dynamic_url,$ignore_pages))?true:false; //check if url is in ignore list if (!$ignore && file_exists($cache_file) && time() - $cache_time < filemtime($cache_file)) { //check Cache exist and it's not expired. ob_start('ob_gzhandler'); //Turn on output buffering, "ob_gzhandler" for the compressed page with gzip. readfile($cache_file); //read Cache file echo '<!-- cached page - '.date('l jS \of F Y h:i:s A', filemtime($cache_file)).', Page : '.$dynamic_url.' -->'; ob_end_flush(); //Flush and turn off output buffering exit(); //no need to proceed further, exit the flow. } //Turn on output buffering with gzip compression. ob_start('ob_gzhandler'); ######## Your Website Content Starts Below ######### ?> <!DOCTYPE html> <html> <head> <title>Page to Cache</title> </head> <body> Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer ut tellus libero. </body> </html> <?php ######## Your Website Content Ends here ######### if (!is_dir($cache_folder)) { //create a new folder if we need to mkdir($cache_folder); } if(!$ignore){ $fp = fopen($cache_file, 'w'); //open file for writing fwrite($fp, ob_get_contents()); //write contents of the output buffer in Cache file fclose($fp); //Close file pointer } ob_end_flush(); //Flush and turn off output buffering ?> |
یک راهنمایی کوچک برای درک کد سیستم کش در php :
- دریافت آدرس URL صفحه و تبدیل آن به md5 برای نامگذاری فایلو
- بررسی اینکه آدرس جز اسامی نادیده گرفته نباشد
- بررسی برای فایل های کش انقضا نشده و جروجی gzip بافر.
جمع بندی
امیدوارم این اسکریپت به شما کمک کند که سیستم کش اختصاصی خودتان را بسازید، اما شما باید از کش کردن صفحاتی مثل حساب کاربری(بعد از لاگین) ، صفحات جستجو یا صفحاتی که زود به زود آپدیت میشوند(صفحه اصلی) خودداری کنید ، کاربران شما ممکن از این موضوع ناخوشایند راضی نباشند .
و به یاد داشته باشید فقط کش کردن صفحات کافی نیست ، ترکیب و فشرده سازی فایل ها جاواسکریپت ، CSS برای افزایش بازدهی یا حتی چندین ترفند و نکته و استفاده از ابزارهای رایگان مثل PageSpeed ، Chrome DevTools برای بررسی بازهی و سرعت سایت شما بسیار کاربردی و تاثیرگذار خواهند بود .
همچنین روش دیگری برای کش کردن صفحات وب در PHP معرفی کردیم که حتما مطالعه بفرمایید.
موفق و پیروز باشید
سلام وقت بخیر ایا امکانش هست بخشی از کد رو به نحوی جلوگیری از کش شدنش کرد مثلا بگیم خط ۵۰ تا ۶۰ کش نشه و بقیه کش بشه با تشکر
سلام. ممنون
در اینصورت باید برای فایل موردنظر کش جداگانه بنویسید و کدهای مربوط به کش کردن رو در همان فایل بنویسید
سلام سینا هستم از ملبورن
من نیاز دارم یه فایل اکسل خیلی بزرگ با ۵۰ تا ۱۰۰ هزار ردیف رو تولید کنم تا کاستومر دانلود کنه.
با توجه به محدودیت تایم سرور(۹۰ ثانیه) نمی تونم منتظر شم که تمام اطلاعات از API بیاد بعد من فایل رو درست کنم.
چه جوری میتونم از بافرینگ استفاده کنم ممنون میشم کمکم کنید
سلام . از توابع fopen و ob_clean برای دریافت خروجی استفاده کنید . همچنین قبل از اجرا حتما با set_time_limit() محدودیت زمان اجرا را افزایش بدید .
https://netparadis.com/execution-time-limit-in-php
?php
define("CHUNK_SIZE", 1024*1024); // Size (in bytes) of tiles chunk
// Read a file and display its content chunk by chunk
function readfile_chunked($filename, $retbytes = TRUE) {
$buffer = "";
$cnt =0;
// $handle = fopen($filename, "rb");
$handle = fopen($filename, "rb");
if ($handle === false) {
return false;
}
while (!feof($handle)) {
$buffer = fread($handle, CHUNK_SIZE);
echo $buffer;
ob_flush();
flush();
if ($retbytes) {
$cnt += strlen($buffer);
}
}
$status = fclose($handle);
if ($retbytes && $status) {
return $cnt; // return num. bytes delivered like readfile() does.
}
return $status;
}
موفق باشید