<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Разработка &#187; header</title>
	<atom:link href="http://www.job-blog.bullgare.ru/tag/header/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.job-blog.bullgare.ru</link>
	<description>о программировании и работе</description>
	<lastBuildDate>Fri, 03 Feb 2012 09:42:30 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.4</generator>
		<item>
		<title>Заголовки на скачивание файла</title>
		<link>http://www.job-blog.bullgare.ru/2010/01/%d0%b7%d0%b0%d0%b3%d0%be%d0%bb%d0%be%d0%b2%d0%ba%d0%b8-%d0%bd%d0%b0-%d1%81%d0%ba%d0%b0%d1%87%d0%b8%d0%b2%d0%b0%d0%bd%d0%b8%d0%b5-%d1%84%d0%b0%d0%b9%d0%bb%d0%b0/</link>
		<comments>http://www.job-blog.bullgare.ru/2010/01/%d0%b7%d0%b0%d0%b3%d0%be%d0%bb%d0%be%d0%b2%d0%ba%d0%b8-%d0%bd%d0%b0-%d1%81%d0%ba%d0%b0%d1%87%d0%b8%d0%b2%d0%b0%d0%bd%d0%b8%d0%b5-%d1%84%d0%b0%d0%b9%d0%bb%d0%b0/#comments</comments>
		<pubDate>Mon, 18 Jan 2010 12:19:06 +0000</pubDate>
		<dc:creator>bullgare</dc:creator>
				<category><![CDATA[php]]></category>
		<category><![CDATA[header]]></category>

		<guid isPermaLink="false">http://www.job-blog.bullgare.ru/?p=614</guid>
		<description><![CDATA[Чтобы при обращении по данному урлу браузер выдавал запрос на сохранение файла, нужно передать заголовки. Для этого достаточно только одного заголовка &#171;Content-Disposition: attachment; filename=\&#187;myfile.csv\&#187;\r\n&#187; Но более полно код будет выглядеть так (взято из конкретного примера на php): header("Content-Description: File Transfer\r\n"); header("Pragma: public\r\n"); header("Expires: 0\r\n"); header("Cache-Control: must-revalidate, post-check=0, pre-check=0\r\n"); header("Cache-Control: public\r\n"); header("Content-Type: text/plain; charset=UTF-8\r\n"); header("Content-Disposition: attachment; [...]]]></description>
			<content:encoded><![CDATA[<p>Чтобы при обращении по данному урлу браузер выдавал запрос на сохранение файла, нужно передать заголовки.<br />
Для этого достаточно только одного заголовка<br />
<em>&laquo;Content-Disposition: attachment; filename=\&raquo;myfile.csv\&raquo;\r\n&raquo;</em><br />
<span id="more-614"></span><br />
Но более полно код будет выглядеть так (взято из конкретного примера на php):</p>
<pre class="code">
header("Content-Description: File Transfer\r\n");
header("Pragma: public\r\n");
header("Expires: 0\r\n");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0\r\n");
header("Cache-Control: public\r\n");
header("Content-Type: text/plain; charset=UTF-8\r\n");
header("Content-Disposition: attachment; filename=\"myfile.csv\"\r\n");
echo 123321;
</pre>
<p>В итоге будет предложено скачать файл с названием по умолчанию myfile.csv.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.job-blog.bullgare.ru/2010/01/%d0%b7%d0%b0%d0%b3%d0%be%d0%bb%d0%be%d0%b2%d0%ba%d0%b8-%d0%bd%d0%b0-%d1%81%d0%ba%d0%b0%d1%87%d0%b8%d0%b2%d0%b0%d0%bd%d0%b8%d0%b5-%d1%84%d0%b0%d0%b9%d0%bb%d0%b0/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Функция header в php</title>
		<link>http://www.job-blog.bullgare.ru/2009/09/%d1%84%d1%83%d0%bd%d0%ba%d1%86%d0%b8%d1%8f-header-%d0%b2-php/</link>
		<comments>http://www.job-blog.bullgare.ru/2009/09/%d1%84%d1%83%d0%bd%d0%ba%d1%86%d0%b8%d1%8f-header-%d0%b2-php/#comments</comments>
		<pubDate>Wed, 23 Sep 2009 09:47:28 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[php]]></category>
		<category><![CDATA[Программирование]]></category>
		<category><![CDATA[cache]]></category>
		<category><![CDATA[header]]></category>
		<category><![CDATA[http]]></category>

		<guid isPermaLink="false">http://www.job-blog.bullgare.ru/?p=287</guid>
		<description><![CDATA[Функция header в php используется для посылки HTTP-заголовков (почитать на w3.org). void header ( string $string [, bool $replace = true [, int $http_response_code ]] ) $string: сам заголовок. Бывает двух типов. Первый начинается с &#171;HTTP/&#187; (header(&#171;HTTP/1.0 404 Not Found&#187;);). Второй начинается не с &#171;HTTP/&#187;. Состоит из двух частей &#171;имя парметра: значение&#187; (например, &#171;Location: http://www.example.com/&#187; [...]]]></description>
			<content:encoded><![CDATA[<p>Функция <a href="http://ru2.php.net/manual/en/function.header.php">header</a> в php используется для посылки <a href="http://www.faqs.org/rfcs/rfc2616">HTTP-заголовков</a> (<a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html">почитать на w3.org</a>).<br />
<span id="more-287"></span></p>
<pre class="code">
void header  ( string $string  [, bool $replace = true  [, int $http_response_code  ]] )
</pre>
<p><strong>$string</strong>:<br />
сам заголовок. Бывает двух типов. Первый начинается с &laquo;HTTP/&raquo; (<em>header(&laquo;HTTP/1.0 404 Not Found&raquo;);</em>). Второй начинается не с &laquo;HTTP/&raquo;. Состоит из двух частей &laquo;<em>имя парметра</em>: <em>значение</em>&raquo; (например, <em>&laquo;Location: http://www.example.com/&raquo;</em> или <em>&laquo;Content-type: application/pdf&raquo;</em>).<br />
Второй параметр булевого типа. Если <em>true</em> (по умолчанию), то заголовок замещает предыдущий с таким же именем параметра, если <em>false</em>, то передаётся несколько параметров одного типа:</p>
<pre class="code">
&lt;?php
header('WWW-Authenticate: Negotiate');
header('WWW-Authenticate: NTLM', false);
?&gt;
</pre>
<p>Третий параметр, <em>$http_response_code</em>, можно использовать для передачи HTTP-заголовков ответа (200, 404 и т.п.):</p>
<pre class="code">
// 301 Moved Permanently
header("Location: /foo.php",TRUE,301);

// 302 Found
header("Location: /foo.php",TRUE,302); //это значение по умолчанию.
header("Location: /foo.php");//аналогично

// 303 See Other
header("Location: /foo.php",TRUE,303);

// 307 Temporary Redirect
header("Location: /foo.php",TRUE,307);
</pre>
<p>Функция <em>header</em> используется для простановки заголовков &laquo;вручную&raquo;, для кеширования, для внешнего перенаправления, для выставления правильного mime-типа и кодировки.</p>
<blockquote><p>Пример простановки заголовков &laquo;вручную&raquo;:</p></blockquote>
<pre class="code">
ob_start();
@header("HTTP/1.1 503 Service Temporarily Unavailable");
@header("Status: 503 Service Temporarily Unavailable");
@header("Retry-After: 120");
@header("Connection: Close");
?&gt;&lt;!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN"&gt;
&lt;html&gt;&lt;head&gt;
&lt;title&gt;503 Service Temporarily Unavailable&lt;/title&gt;
&lt;/head&gt;&lt;body&gt;
&lt;h1&gt;Service Temporarily Unavailable&lt;/h1&gt;
&lt;p&gt;The server is temporarily unable to service your
request due to maintenance downtime or capacity
problems. Please try again later.&lt;/p&gt;
&lt;/body&gt;&lt;/html&gt;&lt;?php
echo ob_get_clean();
exit();
</pre>
<blockquote><p>Пример внешнего перенаправления:</p></blockquote>
<pre class="code">
	public static function redirect($url = '/')
	{
		header('Location: ' . $url);
		die();
	}
</pre>
<blockquote><p>Пример реализации скачивания файлов по расширению (полезен перечислением mime-типов):</p></blockquote>
<pre class="code">
&lt;?php

function dl_file($file){

    //First, see if the file exists
    if (!is_file($file)) { die("404 File not found!"); }

    //Gather relevent info about file
    $len = filesize($file);
    $filename = basename($file);
    $file_extension = strtolower(substr(strrchr($filename,"."),1));

    //This will set the Content-Type to the appropriate setting for the file
    switch( $file_extension ) {
      case "pdf": $ctype="application/pdf"; break;
      case "exe": $ctype="application/octet-stream"; break;
      case "zip": $ctype="application/zip"; break;
      case "doc": $ctype="application/msword"; break;
      case "xls": $ctype="application/vnd.ms-excel"; break;
      case "ppt": $ctype="application/vnd.ms-powerpoint"; break;
      case "gif": $ctype="image/gif"; break;
      case "png": $ctype="image/png"; break;
      case "jpeg":
      case "jpg": $ctype="image/jpg"; break;
      case "mp3": $ctype="audio/mpeg"; break;
      case "wav": $ctype="audio/x-wav"; break;
      case "mpeg":
      case "mpg":
      case "mpe": $ctype="video/mpeg"; break;
      case "mov": $ctype="video/quicktime"; break;
      case "avi": $ctype="video/x-msvideo"; break;

      //The following are for extensions that shouldn't be downloaded (sensitive stuff, like php files)
      case "php":
      case "htm":
      case "html":
      case "txt": die("Cannot be used for ". $file_extension ." files!>"); break;

      default: $ctype="application/force-download";
    }

    //Begin writing headers
    header("Pragma: public");
    header("Expires: 0");
    header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
    header("Cache-Control: public");
    header("Content-Description: File Transfer");

    //Use the switch-generated Content-Type
    header("Content-Type: $ctype");

    //Force the download
    $header="Content-Disposition: attachment; filename=".$filename.";";
    header($header );
    header("Content-Transfer-Encoding: binary");
    header("Content-Length: ".$len);
    @readfile($file);
    exit;
}
?&gt;
</pre>
<p>*Mime-типы описываются <a href="http://www.faqs.org/rfcs/rfc2046.html">здесь</a>.</p>
<p>Заголовок <em>header(&laquo;Content-Transfer-Encoding: binary&raquo;);</em> очень важен для того, чтобы заставить браузер скачивать файл, а не отображать текстовое содержимое.</p>
<blockquote><p>Пример установки использумой кодировки:</p></blockquote>
<pre class="code">
	header('Content-type: text/html; charset=utf-8');
	header('Content-type: text/xml; charset=utf-8');
</pre>
<p>Самая интересная часть: <strong>кеширование</strong> (<a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9">w3.org</a>).<br />
Для начала надо заметить, что HTTP/1.0 моежт не поддерживать основную директиву (<em>Cache-Control</em>), поэтому в этом случае нужно использовать заголовок <em>Pragma: no-cache</em>. Хотя уже давно все поддерживают 1.1, поэтому особого смысла это делать нет.<br />
Заголовок <strong><em>Cache-Control</em></strong> может использоваться как для запроса, так и для ответа. Нас интересует только ответ.<br />
Синтаксис следующий:<br />
<em>&laquo;Cache-Control: значение&raquo;</em>.<br />
Значения:</p>
<pre class="code">
"public" //может кешироваться всеми (прокси-серверами тоже)
"private" //может кешироваться клиентом
"no-cache" //должен кешироваться клиентом (есть ещё доп. параметры)
"no-store" //не сохранять на диске
"no-transform" //для прокси-серверов запрещает изменять тип файла (для картинок, к примеру)
"must-revalidate" //все должны подтвердить наличие кеша
"proxy-revalidate" //прокси должен подтвердить наличие кеша
"max-age" "=" delta-seconds //закешировать на это время
"s-maxage" "=" delta-seconds //для общего кеша (не private) переопределяет значение "max-age" и заголовок "Expires:"
Например:
Cache-Control: max-age=значение
</pre>
<p>Заголовок <strong><em>Expires</em></strong> используется для задания даты, при которой кеш считается просроченным<br />
(<em>Expires: Thu, 01 Dec 1994 16:00:00 GMT</em>), можно задавать дату в прошлом (значит, кеш уже просрочен) или в будущем. При этом если используется заголовок <em>Cache-Control: max-age=значение</em>, то он переопределяет заголовок <em>Expires</em>.<br />
Заголовок <strong><em>ETag</em></strong> используется для создания &laquo;тегов&raquo;, по сравнению которых можно определить, актуален ли кеш в браузере/на прокси-сервере.<br />
Использование:<br />
<em>ETag: уникальный тег</em>.<br />
Обычно для создания тегов советуют использовать что-то вроде:</p>
<pre class="code">
$etag = md5_file($file);
header("Etag: $etag");
</pre>
<p>Думаю, для кеширования картинок вполне достаточно этого:</p>
<pre class="code">
$etag = filesize($file);
header("Etag: $etag");
</pre>
<p>Но только делать такие вещи в том же Nginx (возможно там такой механизм уже есть).<br />
Для запрета кеширования обычно используется связка</p>
<pre class="code">
header("Cache-Control: no-cache, must-revalidate"); // HTTP/1.1
header("Expires: Sat, 26 Jul 1997 05:00:00 GMT"); // Date in the past
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.job-blog.bullgare.ru/2009/09/%d1%84%d1%83%d0%bd%d0%ba%d1%86%d0%b8%d1%8f-header-%d0%b2-php/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

