Задать вопрос
  • Олимпиада по веб, пoмогите понять задание?

    @Vadim_Lasso
    Пример решения задачи:

    js.php
    <?php
    define('FILENAME_SEPARATOR', '@'); // разделитель для имени файла со статистикой показов, в виде: домен@ip_сервера
    define('COLUMN_SEPARATOR', ';'); // разделитель столбцов с данными в файлах 
    
    /**
     * Получает данные из файла и преобразует в массив
     */
    function getContentsFileInArray($fileName) 
    {
    	$arrayOfStrings = file($fileName, FILE_IGNORE_NEW_LINES);
    	$data = array();
    	foreach ($arrayOfStrings as $string) {
    		$row = explode(COLUMN_SEPARATOR, $string);
    		$data[$row[0]] = $row;
    	}
    	return $data; // формат: array('ID баннера' => array('элементы из строки'))
    }
    
    /**
     * Получает доступные для показа баннеры
     */
    function getAvailableBanners(
    	$arBanners,   // данные о всех баннерах
    	$arSiteStats  // статистика показов баннеров для одного сайта
    ) 
    {
    	foreach ($arBanners as $ID => $arBanner)
    		if (isset($arSiteStats[$ID]) && $arSiteStats[$ID][1] == $arBanner[3])
    			unset($arBanners[$ID]); // исключение баннера, если в статистике сайта у него закончились показы
    	return $arBanners;
    }
    
    /**
     * Обновляет/создает статистику показов для сайта
     */
    function updateSiteStats(
    	$fileName,    // путь к файлу статистики сайта
    	$arSiteStats, // статистика показов баннеров для одного сайта
    	$arBanner     // данные о показанном баннере
    ) 
    {
    	/* если в статистике сайта уже есть информация о показах баннера */
    	if (isset($arSiteStats[$arBanner[0]][1]))
    		$arSiteStats[$arBanner[0]][1]++; // то увеличивается на единицу
    	/* иначе в статистику добавляется баннер с одним показом */
    	else
    		$arSiteStats[$arBanner[0]] = array($arBanner[0], 1);
    	/* преобразование массива в текстовый формат */
    	$content = '';
    	foreach ($arSiteStats as $arItem)
    		$content .= implode(COLUMN_SEPARATOR, $arItem) . PHP_EOL;
    
    	$fileLock = __DIR__ . DIRECTORY_SEPARATOR . basename($fileName) . '.lock';
    	$fp = fopen($fileLock, "w");
    	flock($fp, LOCK_EX); // блокировка обновления статистики, если от сайта одновнеменно поступило более одного запроса
    	if (!file_put_contents($fileName, $content))
    		return false;
    	flock($fp, LOCK_UN);
    	fclose($fp);
    	unlink($fileLock);
    	return true;
    }
    
    /**
      * Формирует HTML баннера
      */
    function getBannerHTML($arBanner) 
    {
    	$dir = implode('/', array_slice(explode('/', $_SERVER['REQUEST_URI']), 0, -1));
    	$image = 'http://'.$_SERVER['HTTP_HOST']. $dir . '/' . $arBanner[1]; // формирование полного url адреса к изображению
    	$url = $arBanner[2]; // ссылка на сайт баннера
    	return sprintf('<a href="%1$s" target="_blank"><img src="%2$s" alt="%1$s" width="200" /></a>', $url, $image);
    }
    
    
    $remoteIP = $_SERVER['REMOTE_ADDR'];
    /* получение домена сайта, запросившего показ баннера */
    $remoteDomain = isset($_SERVER['HTTP_REFERER']) ? str_ireplace('www.', '', parse_url($_SERVER['HTTP_REFERER'], PHP_URL_HOST)) : die;
    
    /* путь к директории со статистикой показов баннеров для каждого сайта */
    $folder = __DIR__.DIRECTORY_SEPARATOR.'files';
    if (!is_dir($folder)) mkdir($folder, 0755, true);
    
    /* путь к файлу со статистикой показов баннеров для текущего сайта */
    $fileSiteStats = $folder.DIRECTORY_SEPARATOR.$remoteDomain.FILENAME_SEPARATOR.$remoteIP;
    /* путь к файлу с данными о всех баннерах */
    $fileBanners = __DIR__.DIRECTORY_SEPARATOR.'banners.txt';
    
    $arSiteStats = array();
    $arBanners = file_exists($fileBanners) ? getContentsFileInArray($fileBanners) : false;
    /* если существует файл статистики показов, то исключаются баннеры, которые уже были показаны нужное количество раз */
    if (file_exists($fileSiteStats)) {
    	$arSiteStats = getContentsFileInArray($fileSiteStats);
    	if (!$arBanners = getAvailableBanners($arBanners, $arSiteStats))
    		die;
    }
    $arBannerForShow = $arBanners[array_rand($arBanners)]; // получение случайного баннера
    ?>
    <? if (updateSiteStats($fileSiteStats, $arSiteStats, $arBannerForShow)): // обновление/создание статистики для сайта ?>
    	document.write('<?=getBannerHTML($arBannerForShow)?>');
    <? endif; ?>


    index.html
    <!DOCTYPE html>
    <html lang="ru">
    	<head><meta charset="utf-8"></head>
    	<body>
    		Баннер:<br/> <script type="text/javascript" src="js.php"></script>
    	</body>
    </html>


    Так же примеры решения остальных задач: vk.com/doc20505384_410265549
    Ответ написан
    Комментировать