Архив за Февраль 28th, 2008

Скачивание файлов с докачкой

Многие интернет-проекты (неважно, что это: движки форумов, фотогалереи или что-то ещё) позволяют пользователям загружать файлы на сайт и скачивать их оттуда.

С закачкой проблем не возникает никогда.

А вот со скачиванием закачанных файлов зачастую бывает одна маленькая проблема: многие вебмастера хотят знать, сколько раз был скачан тот или иной файл. Что же они делают? Очень просто: дают ссылку не на собственно файл, а на некоторый скрипт, который выглядит примерно так:
<?php
// тут подсчёт скачиваний, разные действия
// а дальше: просто выдача всего содержимого файла, примерно так:
readfile ($filename);
?>

И всё бы ничего, но:
Файлы порой бывают очень большими,
а связь — очень некачественной.

Ну и что? А очень просто: выданный таким образом файл нельзя скачивать порциями. То есть ни один менеджер скачиваний (например, ReGet, FlashGet или Download Master и прочие) не смогут:
Скачивать файл в несколько потоков;
Приостановить скачивание в любой момент, а через некоторый промежуток времени начать скачивать файл с места остановки (а ведь в этом и суть докачки).

Что делать?

Вот и меня посетила такая мысль. Полчаса экспериментов — и у меня получилась очень хорошая функция. Отдаю её Вам:
function downloadFile($filename, $mimetype=’application/octet-stream’) {
if (!file_exists($filename)) die(’Файл не найден’);

$from=$to=0; $cr=NULL;

if (isset($_SERVER[’HTTP_RANGE’])) {
$range=substr($_SERVER[’HTTP_RANGE’], strpos($_SERVER[’HTTP_RANGE’], ‘=’)+1);
$from=strtok($range, ‘-’);
$to=strtok(’/'); if ($to>0) $to++;
if ($to) $to-=$from;
header(’HTTP/1.1 206 Partial Content’);
$cr=’Content-Range: bytes ‘ . $from . ‘-’ . (($to)?($to . ‘/’ . $to+1):filesize($filename));
} else header(’HTTP/1.1 200 Ok’);

$etag=md5($filename);
$etag=substr($etag, 0, 8) . ‘-’ . substr($etag, 8, 7) . ‘-’ . substr($etag, 15, 8);
header(’ETag: “‘ . $etag . ‘”‘);

header(’Accept-Ranges: bytes’);
header(’Content-Length: ‘ . (filesize($filename)-$to+$from));
if ($cr) header($cr);

header(’Connection: close’);
header(’Content-Type: ‘ . $mimetype);
header(’Last-Modified: ‘ . gmdate(’r', filemtime($filename)));
$f=fopen($filename, ‘r’);
header(’Content-Disposition: attachment; filename=”‘ . basename($filename) . ‘”;’);
if ($from) fseek($f, $from, SEEK_SET);
if (!isset($to) or empty($to)) {
$size=filesize($filename)-$from;
} else {
$size=$to;
}
$downloaded=0;
while(!feof($f) and !connection_status() and ($downloaded<$size)) {
echo fread($f, 512000);
$downloaded+=512000;
flush();
}
fclose($f);
}

Функция принимает два параметра: $filename — полный путь до файла, $mimetype — MIME-тип файла (если не знаете, что это такое — не указывайте второй параметр при вызове функции).

Вызов функции может быть например таким:
downloadFile(’file/archive.zip’, ‘application/zip’);
// Выдаём пользователю файл “file/archive.zip” и указываем MIME-тип

Или таким:
downloadFile(’i_want_to_break_free.mp3′, ‘audio/mpeg’);
// Выдаём файл “i_want_to_break_free.mp3″ и снова указываем MIME-тип

А можно и вот так:
downloadFile(’somefile.ext’);
// Здесь пользователю отдаётся файл “somefile.ext”, но MIME-тип не указывается.
// Впрочем, ничего страшного в этом нет.

Однако не забудьте вот о чём: функция посылает заголовки header. Значит до вызова функции не должен выводиться никакой текст.

После вызова функции лучше тоже ничего не выводить — некоторые менеджеры закачек не смотрят на то, что необходимые размеры скачаны и качают пока не закончится поток данных. А это приведёт к тому, что в нормальный файл попадёт всякий бред.

Я бы посоветовал сразу после вызова downloadFile() сделать вызов die();

Глупо было бы думать, что я один такой умный (хотя и хотелось бы) . Но Вы можете (вместо моей функции) использовать PEAR-библиотеку HTTP_Download, которая реализует всё то, что и моя функция, и много других возможностей (как-то: кэширование, сжатие данных «на лету» и прочее).

Автор:Евгений Неверов http://evgeny.neverov.name

Tags: Mime, Pear, php, докачка, файл

Добавить комментарий Февраль 28, 2008

Что такое CSS

Страшно подумать, но в июле этого года исполнилось всего 10 лет стандарту HTML 1.0 (который, кстати, так никогда и не был “официально” принят и остался в виде черновика для “внутреннего употребления”). За эти 10 лет HTML прошел очень большой путь, завоевал практически все компьютеры в мире и стал одним из самых известных “компьютерных языков” (все-таки отнести его к языкам программирования рука не поднимается)… И одним из весьма заметных этапов развития HTML стало появление CSS - Cascading Style Sheets или, говоря по-русски, каскадных таблиц стилей.

Идея CSS очень проста. Если в HTML вы прямо в документе ставили указание на то, как должен выглядеть тот или иной элемент, то при использовании CSS такие указания выносятся в отдельный блок (который может либо включаться в документ, либо читаться из внешнего файла).

Такой простой ход стразу дает массу преимуществ вебмастеру. Прежде всего, значительно облегчается изменение внешнего вида сайта или отдельных его элементов - достаточно изменить определение соответствующего стиля в единственном CSS-файле, и эти изменения распространятся на весь сайт. Второе преимущество - сокращение размеров документов, которое особенно заметно на “красивых” страницах.

Первая версия CSS - CSS level 1 - принятая в 1996 и пересмотренная в 1999 году, позволяла оперировать только цветами, шрифтами, отступами и им подобными относительно простыми и частоиспользуемыми элементами. Принятая в 1998 году, спецификация CSS level 2 добавила возможность абсолютного позиционирования элементов, создания стилей для разных типов устройств, использования собственных курсоров, расширила возможности по выбору элементов, к которым должен применяться тот или иной стиль и многое другое. Естественно, что CSS level 2 поддерживает и таблицы стилей, созданные в CSS level 1. В настоящее время консорциум W3C активно ведет разработку стандарта CSS level 3 и CSS level 2 revision 1, которые должны учесть все возрастающие потребности вебмастеров и вебдизайнеров, по созданию современных и удобных сайтов.

Следует учитывать, что каскадные таблицы стилей не полностью абстрагируют визуальное представление документа от его содержания - они только позволяет более компактно описать правила визуального представления. И если вы захотите изменить дизайн сайта, то вам все-равно придется переписывать HTML код (правда, сделать это будет проще чем при отсутствии CSS). Значительно больший уровень абстракции можно получить, используя связку языков XML + XSL (из которых, в частности, можно генерировать HTML + CSS), но это намного сложнее, и несколько выпадает из темы данной статьи.

Но хватит теории! Давайте попробуем практикой заняться…

Есть три способа описать стиль элемента в HTML документе. Самый простой и, практически, не использующий преимуществ CSS способ - это указать стиль внутри тега HTML. Например, написать
<H2 STYLE=”COLOR: #AADDAA; FONT-WEIGHT: BOLD; FONT-SIZE:11pt;”>заголовок второго уровня</H2>
Единственное преимущество, которое можно получить таким образом - это задание некоторых атрибутов текста, которые не поддерживаются тегами HTML. Зато сохраняются все недостатки HTML - указанный стиль относится только к одному тегу и для изменения внешнего вида документа вам придется изменить описание стиля в каждом теге.

Второй способ несколько лучше: надо описания стилей заключить внутри тегов <STYLE TYPE=”text/css”> и </STYLE>. Например, если вы напишете
<STYLE TYPE=”text/css”>
H2 {COLOR: #AADDAA; FONT-WEIGHT: BOLD; FONT-SIZE:11pt;}
</STYLE>
а в тексте документа укажете <H2>заголовок второго уровня</H2>, то получите тот же эффект. Однако, в отличие от предыдущего способа, свойства отображения применятся ко всем тегам H2 в документе. И если, скажем, вам потребуется изменить размер шрифта или цвет всех заголовков второго уровня, то изменить потребуется всего одну строчку. Согласитесь, что это намного удобнее!

Однако, у предыдущего способа тоже есть свой недостаток: блок STYLE вам придется скопировать в каждую страницу своего сайта. А если страниц там несколько сотен? И вам понадобится что-то поменять? Неудобно… Но можно победить и эту проблему - с помощью тега LINK. Описав требуемые стили в отдельном текстовом файле (теги STYLE указывать не требуется), вы затем можете написать в секции HEAD документа
<LINK REL=”stylesheet” TYPE=”text/css” HREF=”style.css”>
Эта команда укажет, что таблица стилей находится во внешнем файле. Таким образом, даже для очень большого сайта может использоваться всего один файл со стилями, что очень сильно облегчает редактирование. Есть еще один “хитрый” необязательный параметр тега LINK: MEDIA. Он может указывать для какого типа устройств таблица стилей предназначена и иметь значения, например, “all” (используется по умолчанию), “handheld”, “print” и некоторые другие. Следует только учесть, что (пока еще?) не все браузеры понимают таблицы стилей, подключаемые с использованием этого параметра.

В некоторых случаях бывает полезно объединить два предыдущих метода - например, если разные секции должны иметь частично разные стили (скажем, отличаться цветом фона). Внутри тега STYLE можно указать
@import url(style.css)
и тогда к стилям, описанным внутри STYLE присоединятся стили из внешнего файла.

Но у внешних файлов тоже есть недостаток: если соединение с сервером не очень хорошее (что не редкость у модемных пользователей), то файл со стилями может и не скачаться… А страничка без стилей обычно выглядит преотвратнейше… Поэтому тут уж вам придется выбирать как лучше поступить.

Практика показывает, что таблицы стилей редко бывают больше 2-3 Кб, даже для очень “раскрашенных” страниц. И если ваш веб-сервер умеет “на лету” сжимать страницы (в Apache, например, этим занимается mod_gzip), то такой объем будет для пользователя практически незаметен. Ну а дальше - дело техники: пишется какая-нибудь команда, которая на сервере читает таблицу стилей из внешнего файла (все-таки один файл намного легче редактировать!) и встраивает ее содержимое в страницу, отдаваемую посетителю. В простейшем случае это может быть инструкция SSI, вроде
<!–#include file=”style.css” –>
а если ваш сайт написан на php, то можно написать, например,
<?php readfile(”style.css”); ?>

Источник: http://www.listsoft.ru/

Tags: CSS, html, style

Добавить комментарий Февраль 28, 2008


Календарь

Февраль 2008
Пн Вт Ср Чт Пт Сб Вс
    Март »
 123
45678910
11121314151617
18192021222324
2526272829  

Записи по месяцам

Записи по рубрикам

Бегун