В этой статье я хочу рассказать о том, как можно сделать загрузчик файлов на компьютер, а также счетчик обращений к файлу.
Мне часто бывает интересно узнать, сколько человек читают мои статьи, а так же интересно узнать скачивают ли мои файлы, и если скачивают, то как часто. Узнать статистику просмотра статей можно воспользовавшись каким-нибудь счетчиком, а вот посчитать количество скачиваний файла счетчиков я не видел. И поэтому решил сам написать скрипт, который будет считать количество обращений к файлу.
Помимо подсчёта статистики, скрипт можно оборудовать возможностью передавать браузеру файл таким образом, чтобы файл не открывался в браузере, а начал скачиваться на компьютер.
Скрипт будет состоять условно из двух этапов, передача файла браузеру для скачки и записи статистики. Для написания первой части скрипта, мне пришлось немного «погуглить» в поисках описания HTTP заголовков, поскольку на них все и завязано при работе с браузером. Я не буду вдаваться в подробности, все что нужно я описал в комментариях к коду, но если кому интересно подробнее можно почитать тут.
Вторая часть скрипта, как я уже и сказал, будет отвечать за ведение статистики по обращениям к файлам. Для того, чтобы вести статистику ее нужно куда-нибудь записывать. Тут предстает выбор: либо записывать все в базу данных, либо в файл. Работать с базой данных удобней, но для такой простой задачи использовать бд, как-то не рационально, поэтому я решил делать запись в файл.
Дальше описывать я ни чего не буду, просто приведу код. Я старался описывать каждую строку, поэтому надеюсь, что всем будет понятно.
<?php /* * Скачивание файла * Имя файла попадает в скрипт через get запрос ?file_name */ $fileName = $_GET['file_name']; // Получаем имя файла $folderFiles = "files"; // папка, где лежат файлы header("HTTP/1.1 200 OK"); // задаем заголовок, в котором сообщаем состояние http протокола. 200 ОК - значит все хорошо header("Content-type: application/octet-stream"); // объясняем браузеру, что нужно сохранить то что он получит header('Expires: ' . gmdate('D, d M Y H:i:s') . ' GMT'); // дата истечения срока актуальности файла. Можно не задавать $ua = (isset($_SERVER['HTTP_USER_AGENT']))?$_SERVER['HTTP_USER_AGENT']:''; // получаем информацию о браузере $isMSIE = preg_match('@MSIE ([0-9].[0-9]{1,2})@', $ua); // проверяем, вдруг это Internet EXplorer if ($isMSIE){ // если ie, то задаем несколько параметров, понятных только ие :) header("Content-disposition: attachment; filename=".$fileName); header('Cache-Control: must-revalidate, post-check=0, pre-check=0'); header('Pragma: public'); }else{ // если браузер адекватный header('Content-Disposition: attachment; filename="'.$fileName.'"'); // указываем имя файла, как он будет сохранен header('Pragma: no-cache'); // чтоб не кешил файл } readfile($folderFiles.'/'.$fileName); // передаем браузеру сам файл /* * Сохранение статистики * после того как файл отдали браузеру, запишем в файл количество скачиваний * писать будем все в один файл - stata.txt * поскольку файлов может быть люьое количество разделять статистику будем по строкам */ $arrayRows = file("stata.txt"); // открываем файл для чтения, тут каждая строка будет элементом массива $arrayFileName = array(); // массив для храниения имен файлов, полученных их файла foreach($arrayRows as $k=>$oneRow){ $a = explode('::', $oneRow); // разбираем строку на массив $arrayFileName[$k] = $a[0]; // получаем имя файла из строки } if(in_array($fileName, $arrayFileName)){ // проверяем есть ли среди уже записанных файлов, наш файл // если есть такой файл, то получаем количество его скачавний и увеличиваем на 1 $pos = 0; foreach($arrayFileName as $one){ if($one == $fileName){ $oldStr = $arrayRows[$pos]; // получаем старую строку $exp = explode('::', $arrayRows[$pos]); $countDownload = $exp[1]; // получаем количесво скачиваний файла $arrayRows[$pos] = $fileName.'::'.($countDownload+1); // увеличиваем кол-во скачиваний и записываем в массив со всей статистикой } $pos++; } }else{ // если файл скачивали первый раз $arrayRows[count($arrayRows)] = $fileName.'::1'; } $file = fopen ("stata.txt","r+"); // открываем файл для записи foreach($arrayRows as $one){ // перебераем весь массив fputs ($file, trim($one)); // и записваем статистику fputs ($file, "\n"); // после каждого файла делаем перевод каретки на новую строку } fclose ($file); ?>