Задать вопрос
@andreyabc

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

Решаю олимпиадные задачи, но у этой даже условие понять не могу, поясните пожалуйста, непонятно откуда берется нужное количество показов баннера, и зачем даны их id?
Понимаю что лучше такие вопросы задавать организаторам, но внятного ответа от них я так и не получил.

Веб-аналитика показа баннеров на стороннем сайте.
Имеются баннеры: папка с изображениями и текстовый файл banners.txt, где построчно указаны ID баннера, имя файла с изображением, URL и количество показов баннера.
Необходимо разработать PHP-скрипт, который будет возвращать JS для показа одного баннера из списка. Если баннер уже был показан нужное количество раз, то он больше не показывается.
Входные данные: Папка /banners/, файл banners.txt c id, imgurl, href и количеством показов через “;”
0;/4/banners/1.png;ya.ru/;10
1;/4/banners/2.png;bitrix.ru/;2
  • Вопрос задан
  • 2680 просмотров
Подписаться 2 Оценить Комментировать
Решения вопроса 1
Tark
@Tark
Pyramid'альный мир
> непонятно откуда берется нужное количество показов баннера
Оно берётся из файла; "10" в конце первой строки, например. Дело в том, что обычно покупают показы баннеров, а не время их размещения: если показывать один и тот же баннер постоянно, то он сильно примелькается, поэтому продают тысячи показов и чередуют баннеры в случайном порядке.

> зачем даны их id
Этакий primary key. Возможно, тут - для облегчения выдачи случайного баннера. Можно просто выбрать случайное число от 0 до последнего и выдать баннер, который ему соответствует.

Вам остаётся лишь как-то сохранять данные о том, сколько раз какой из баннеров показан, и проверять это при выдаче.
Ответ написан
Пригласить эксперта
Ответы на вопрос 3
@fr33zy
> Имеются баннеры: папка с изображениями и текстовый файл banners.txt, где построчно указаны ID баннера, имя файла с изображением, URL и количество показов баннера.
Невнимательность погубит вас :)

Зачем нужны id? А как вы собираетесь увеличивать количество показов баннера, не идентифицируя его?
Ответ написан
Rema1ns
@Rema1ns
и так сойдет
довольно банальная задача для веб разработчика, могли бы и поинтереснее что нибудь придумать
Ответ написан
Комментировать
@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
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы