انتقال فایل های هاست به هاست دیگر با PHP , Js ( استفاده از فناوری Ajax )

انتقال سریع فایل از هاست به هاست دیگر ، یکی از مهم ترین مشکلات اصلی مدیران سایت انتقال فایل ( داده ) از سرور قبلی به سرور جدید می باشد .به جز قالب و ماژول هایی روی هاست قبلی نصب است و نیاز به انتقال و نصب روی هاست جدید دارد 2 بخش اصلی از اطلاعات وبسایت مانند :1- داده های دیتابیس2- فایل و پرونده های دانلود روی هاست دانلود ( در این آموزش روی این موضوع متمرکز خواهیم شد )نیازمند انتقال است .index.php صفحه HTML برای دریافت لینک فایل هاصفحه ای با فرمی را خواهیم داشت که می تواند لینک های فایل ها را دریافت و پس از ارسال درخواست POST به آدرس داخلی file-transfer.php نتیجه در جدول خود نمایش دهد .<!DOCTYPE html> <html lang=&quotfa&quot> <head> <meta charset=&quotUTF-8&quot> <title>Rapidcode.iR - انتقال فایل بین 2 هاست مختلف</title> <link rel=&quotstylesheet&quot href=&quotstatic/css/main.css&quot> </head> <body> <div class=&quotcontainer&quot> <a id=&quotintroduce&quot href=&quothttps://rapidcode.ir&quot target=&quot_blank&quot>رپید کد • کتابخانه مجازی برنامه نویسان</a> <form dir=&quotltr&quot id=&quotform-host-info&quot> <textarea name=&quotremote-file&quot id=&quotremote-file&quot rows=&quot10&quot placeholder=&quotلینک فایلی که میخواهید انتقال دهید&quot></textarea> <input type=&quotbutton&quot id=&quotsend&quot value=&quotانتقال&quot> </form> <table id=&quotlogger&quot> <thead> <tr> <th>تاریخ و زمان</th> <th>پیغام</th> </tr> </thead> <tbody> </tbody> </table> </div> <script src=&quotstatic/js/lib/farvardin.min.js&quot> <script src=&quotstatic/js/app.js&quot> </body> </html><!DOCTYPE html>فایل main.css استایل برنامه.container { margin: 0 auto; width: 80%; text-align: center; direction: rtl; } #introduce { display: block; width: 100%; font-size: 35px; font-weight: bold; color: white; padding-bottom: 5px; background-color: #4CAF50; text-decoration: none; margin-bottom: 15px; } /* Page Style */ #logger { border-collapse: collapse; width: 100%; margin-top: 35px; } #logger th, #logger td { border: 1px solid green; padding: 5px 10px; } #logger td { direction: ltr; } #logger th:first-child { width: 35%; } #success { background-color: green; color: white; border-radius: 5px; display: inline-block; padding: 5px; }اسکریپت file-transfer.php برای دریافت فایل از سرور قدیمی و انتقال آن به سرور جدیدmax_execution_time حداکثر زمان برای اجرا اسکریپت php که default روی 30 ثانیه است ولی با قرار دادن عدد صفر آن را روی نامحدود تنظیم می کنیم یعنی تا زمانی که دانلود و انتقال پرونده زمان می برد اسکریپت اجرا شود .<?php ini_set(&quotmax_execution_time&quot, 0); # در صورتی که از محیط شل استفاده می کنید نیازی به این نیست class TransferFileHosts { private $transfer_rate = 8192; // max chunk size 8192 public $remote_link = &quot&quot public $path_to_save = &quot&quot public $file_basename = &quot&quot public $file_extension = &quot&quot public $filename = &quot&quot public $file_size = 0; public function __construct($remote_link = null, $path_to_save = null) { if (!$remote_link) return false; if (!is_dir($path_to_save)) mkdir($path_to_save); $this->remote_link = $remote_link; $this->path_to_save = $path_to_save; $fileinfo = pathinfo($this->remote_link); $this->file_basename = $fileinfo[&quotbasename&quot]; $this->file_extension = $fileinfo[&quotextension&quot]; $this->filename = $fileinfo[&quotfilename&quot]; $this->file_size = $this->get_remote_filesize($this->remote_link, false); } public function get_remote_filesize($remote_link = null, $convert_to_mb = true) { $tmp_remote_link = $remote_link; if (!$tmp_remote_link) $tmp_remote_link = $this->remote_link; $headers_data = get_headers($tmp_remote_link, true); $filesize = $headers_data['Content-Length']; $filesize = $convert_to_mb ? $this->convert_byte_to_mb($filesize) : $filesize; return $filesize; } public function convert_byte_to_mb(int $byte) { $mb = $byte / 1048576; $mb = round($mb, 2); return $mb; } public function download_file() { $progress_percent = 0; $filesize = $this->convert_byte_to_mb($this->file_size); $path_to_save = &quot{$this->path_to_save}{$this->file_basename}&quot echo &quot<p id=\&quotdownload\&quot>Downloading {$this->file_basename} with size : {$filesize} MB<p>&quot $fp_server = fopen($this->remote_link, &quotrb&quot); $fp_local = fopen($path_to_save, &quotwb&quot); while (!feof($fp_server) && $content = fread($fp_server, $this->transfer_rate)) { $progress_percent += strlen($content) / $this->file_size * 100; fwrite($fp_local, $content); } echo &quot<p id=\&quottransfer\&quot>file <strong id=\&quotfilename\&quot>{$this->file_basename} </strong><span id=\&quotsuccess\&quot> successfully</span> transferred to {$path_to_save}<p>&quot } } $save_path = __DIR__ . &quot/server/&quot $link = @$_POST['remote-file']; if (!$link) { die(&quot<p id=\&quoterror\&quot>no remote file passed !</p>&quot); } $transfer_agent = new TransferFileHosts($link, $save_path); $transfer_agent->download_file();توضیحات لازم برای کلاس TransferFileHostsدر ابتدا که ویژگی مورد نظر مان را با توجه به کاربرد و سطح دسترسی شان تعریف می کنیم :transfer_rate ← نرخ انتقال اطلاعات از آنجایی که تابع fread حداکثر تا 8192 بایت امکان دریافت داده دارد .remote_link ← لینک فایلی که می خواهیم دانلود و به هاست جدید انتقال داده شود .path_to_save ← مسیری که می خواهیم فایل دانلود شده روی آن ذخیره شود .file_basename ← نام فایل + پسوند ( این متغیر پس از وارد کردن لینک فایل مقدار دهی خواهد شد )file_extension ← پسوند فایل ( *.x )filename ← نام فایل ( x.* )file_size ← حجم فایل ( برحسب بایت )متد __constructپس از وارد کردن آدرس لینک فایل و مسیر ذخیره این متد شروع می کند به مقدار دهی .با کمک تابع pathinfo می توانیم کلی جزئیات از نام فایل داشته باشیم .متد get_remote_filesizeاین متد پس از وارد کردن لینک فایل حجم آن را با تابع get_headers با ما می دهد همچنین اگر دومین پارامتر آن true باشد حجم آن را به مگابایت تبدیل می کند .متد convert_byte_to_mbاز نام آن مشخص هست تبدیل واحد بایت به مگابایت .متد download_fileprogress_percent درصد دریافت اطلاعات را به ما می دهد در صورتی که این پروژه را بر روی shell اجرا می کنید به کارتان خواهد آمد .fp_server : فایل پوینتری هست برای دریافت اطلاعات از لینک داده شده . مود rb خواندن داده به صورت باینریfp_local : فایل پوینتری برای ذخیره فایل دانلود شده از هاست بر روی مسیر داده شده . مود wb ذخیره داده به صورت باینریتابع fread : آرگومان دوم این است که در هر درخواست چه میزان از داده را بخواند ( برحسب بایت ) که روی حداکثر 8192 تنظیم کردیم .تابع feof : بررسی می کند به پایان داده فایل رسیده است یا خیر .در آخر لینک فایل را که به صورت متد POST ارسال می گردد را دریافت و با مسیر ذخیره به کلاس TransferFileHosts می دهیم و با متد download_file انتقال و ذخیره سازی را آغاز می کند .اسکریپت app.js ارسال درخواست POSTjs بازها می دونند که دیگه کار های Dom manipulation و xhr رو با این فایل انجام می دیم ( کار های ساده )let url = location.href + &quotfile-transfer.php&quot var itemCounter = 0; let remoteFiles = []; const btnSend = document.getElementById(&quotsend&quot); const inpRemoteFileUrl = document.getElementById(&quotremote-file&quot); // Register Event Listener btnSend.addEventListener(&quotclick&quot , handlerSendTransferRequest); // functions function funcGetPersianDate(){ const date = new Date(); const fullDate = [date.getFullYear() , date.getMonth() , date.getDate()]; const persianDate = farvardin.gregorianToSolar(fullDate[0] , fullDate[1] , fullDate[2] , &quotstring&quot) + &quot # &quot + date.getHours() + &quot:&quot + date.getMinutes() + &quot:&quot + date.getSeconds(); return persianDate; } function funcInsertToTable(tableDom , domData){ tableDom.querySelector(&quottbody&quot) += domData; } function funcShowMessageResponse(response){ itemCounter++; const table = document.getElementById(&quotlogger&quot); const html = new DOMParser().parseFromString(response , &quottext/html&quot); let downloadDom = html.getElementById(&quotdownload&quot); let transferDom = html.getElementById(&quottransfer&quot); const persianDate = funcGetPersianDate(); const tableRowDom = `<tr><td>${persianDate}</td><td id=&quotdl-${itemCounter}&quot></td></tr><tr><td>${persianDate}</td><td id=&quottr-${itemCounter}&quot></td></tr>`; funcInsertToTable(table , tableRowDom); document.getElementById(&quotdl-&quot+itemCounter)(downloadDom); document.getElementById(&quottr-&quot+itemCounter)(transferDom); } function funcSendPostRequest(url){ if(!remoteFiles[0]) return false; btnSend.setAttribute(&quotdisabled&quot , &quottrue&quot); const xhr = new XMLHttpRequest(); xhr.open(&quotPOST&quot , url); const form = new FormData(); form.append(&quotremote-file&quot , remoteFiles[0]); xhr. = function(){ if(this.status === 200){ const response = this.response; funcShowMessageResponse(response); remoteFiles.shift(); if(remoteFiles[0]) funcSendPostRequest(url); else btnSend.removeAttribute(&quotdisabled&quot); }else{ alert(&quotخطایی از سمت سرور میزبان دریافت گردید&quot) } } xhr. = function(e){ alert(&quotخطای شبکه&quot); console.warn(e); } xhr.send(form); } // handler functions function handlerSendTransferRequest(wedontneedthiseventLoL){ const remoteFile = inpRemoteFileUrl.value.split(&quot\n&quot); if(!remoteFile) { alert(&quotیک آدرس معتبر برای انتقال فایل وارد کنید !&quot); return false; } remoteFiles = remoteFile; funcSendPostRequest(url); }دانلود سورس انتقال هاست به هاستمنبع : RaPiDcoDe.iRآموزش ویدیویی این مقاله