Я использую вызванную загрузку для загрузки главным образом zip и mp3s на сайте, который я сделал (http://pr1pad.kissyour.net) - чтобы отследить загрузки в аналитике Google в базе данных и скрыть реальный путь загрузки:
Это - это:
extending CI model
... - bunch of code
function _fullread ($sd, $len) {
$ret = '';
$read = 0;
while ($read < $len && ($buf = fread($sd, $len - $read))) {
$read += strlen($buf);
$ret .= $buf;
}
return $ret;
}
function download(){
/* DOWNLOAD ITSELF */
ini_set('memory_limit', '160M');
apache_setenv('no-gzip', '1');
ob_end_flush();
header("Pragma: public");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Cache-Control: public",FALSE);
header("Content-Description: File Transfer");
header("Content-type: application/octet-stream");
if (isset($_SERVER['HTTP_USER_AGENT']) &&
(strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE') !== false))
header('Content-Type: application/force-download'); //IE HEADER
header("Accept-Ranges: bytes");
header("Content-Disposition: attachment; filename=\"" . basename("dir-with- files/".$filename) . "\";");
header("Content-Transfer-Encoding: binary");
header("Content-Length: " . filesize("dir-with-files/".$filename));
// Send file for download
if ($stream = fopen("dir-with-files/$filename", 'rb')){
while(!feof($stream) && connection_status() == 0){
//reset time limit for big files
set_time_limit(0);
print($this->_fullread($stream,1024*16));
flush();
}
fclose($stream);
}
}
Это находится на ЛАМПЕ с CI 1.7.2 - Это - мой собственный метод, соединенный из различных практических руководств на всем протяжении Интернета, потому что во время разработки, эти проблемы подошли: - предел сервера. ini_set
не помогли, таким образом, я использовал буферизованный _fullread
вместо этого нормальный fread
, который использовался insted @readonly
- ob_end_flush (), потому что сайт, сделал в CI1.7.2, и я должен был убрать буфер
Теперь... Это не работает. Это сделало, затем это прекратило показывать ожидаемое время размера/загрузки - я пытался очистить его и в то время как я очищал код, что-то произошло, я не знаю то, что и в любой предыдущей версии - это не работало (никакое изменение в настройках вообще) - редактирование: не работайте =, производит все в окно браузера.
Таким образом, я сказал, завинтите его, я посмотрю здесь.
Так, я в основном ищу сценарий или функцию, которую я могу поместить в свою выходную модель и сделаю:
Заранее спасибо.
Править: Теперь я чувствую себя более завинченным затем когда-либо/прежде чем, так как я пытался вызвать загрузку с .htaccess - в то время как это работало, это имело немногих незначительных/главных (выберите Ваш), проблемы
Теперь, хотя я удалил .htaccess, он все еще ожидает, пока загрузка не завершена (так же, как если бы он загружал для кэширования сначала), и это просто get's connected
и шоу открывается/сохраняет диалоговое окно.
Это зависит от того, кто пишет код клиента. Если вы пишете клиент и сервер, то это не имеет большого значения. Вы либо испытаете боль при создании URL-адресов на клиенте или на сервере.
Однако если вы создаете сервер и ожидаете, что другие люди напишут клиентский код, то они будут любить вас гораздо больше, если вы предоставите полные URI. Разрешение относительных URI может быть немного сложным. Сначала способ их разрешения зависит от возвращенного типа носителя. Html имеет базовый тег, Xml может иметь xml: базовые теги в каждом вложенном элементе, каналы Atom могут иметь базу в канале и другую базу в содержимом. Если вы не предоставляете клиенту явную информацию о базовом URI, то они должны получить базовый URI из URI запроса или, возможно, из заголовка Content-Location! И берегись этой следящей косой черты. Базовый URI определяется путем игнорирования всех символов справа от последней косой черты. Это означает, что завершающая косая черта теперь очень важна при разрешении относительных URI.
Единственным вопросом, требующим небольшого упоминания, является размер документа. Если вы возвращаете большой список элементов, где каждый элемент может иметь несколько ссылок, использование абсолютных URL-адресов может добавить значительное количество байтов в вашу сущность, если вы не сжимаете сущность. Это проблема perf, и вы должны решить, является ли она значимой в каждом конкретном случае.
-121--849623-Программы Android могут взаимодействовать с другими пользователями с помощью своих намерений. Интенты немного похожи на удаленные вызовы процедур: вы запрашиваете у другой программы определенное действие (например, сканировать штрих-код), и другая программа выполнит эту задачу для вас. Результат возвращается по завершении задачи.
Если пользователь установил сканер штрих-кодов ZXing, можно просто использовать функцию сканирования штрих-кода. После этого запускается сканер штрих-кодов, который позволяет пользователю отсканировать код и вернуть результат.
Более подробную информацию об этом сканере можно найти на странице Google Code этого проекта: http://code.google.com/p/zxing/wiki/ScanningViaIntent
-121--1305052-Таким образом, я использовал этот код (это измененная версия возобновления загрузки HTTP найдена в Интернете)
function _output_file($file, $path)
{
$size = filesize($path.$file);
@ob_end_clean(); //turn off output buffering to decrease cpu usage
// required for IE, otherwise Content-Disposition may be ignored
if(ini_get('zlib.output_compression'))
ini_set('zlib.output_compression', 'Off');
header('Content-Type: application/force-download');
header('Content-Disposition: attachment; filename="'.basename($file).'"');
header("Content-Transfer-Encoding: binary");
header('Accept-Ranges: bytes');
/* The three lines below basically make the
download non-cacheable */
header("Cache-control: no-cache, pre-check=0, post-check=0");
header("Cache-control: private");
header('Pragma: private');
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
// multipart-download and download resuming support
if(isset($_SERVER['HTTP_RANGE']))
{
list($a, $range) = explode("=",$_SERVER['HTTP_RANGE'],2);
list($range) = explode(",",$range,2);
list($range, $range_end) = explode("-", $range);
$range=intval($range);
if(!$range_end) {
$range_end=$size-1;
} else {
$range_end=intval($range_end);
}
$new_length = $range_end-$range+1;
header("HTTP/1.1 206 Partial Content");
header("Content-Length: $new_length");
header("Content-Range: bytes $range-$range_end/$size");
} else {
$new_length=$size;
header("Content-Length: ".$size);
}
/* output the file itself */
$chunksize = 1*(1024*1024); //you may want to change this
$bytes_send = 0;
if ($file = fopen($path.$file, 'rb'))
{
if(isset($_SERVER['HTTP_RANGE']))
fseek($file, $range);
while
(!feof($file) &&
(!connection_aborted()) &&
($bytes_send<$new_length) )
{
$buffer = fread($file, $chunksize);
print($buffer); //echo($buffer); // is also possible
flush();
$bytes_send += strlen($buffer);
}
fclose($file);
} else die('Error - can not open file.');
die();
}
, а затем в модели:
function download_file($filename){
/*
DOWNLOAD
*/
$path = "datadirwithmyfiles/"; //directory
//track analytics
include('includes/Galvanize.php'); //great plugin
$GA = new Galvanize('UA-XXXXXXX-7');
$GA->trackPageView();
$this->_output_file($filename, $path);
}
Он работает, как и ожидалось во всех упомянутых браузерах на Win/MAC - до сих пор
Есть одна странная вещь: вы вызываете ob_end_flush ()
в начале функции. Это фактически очищает выходной буфер, но также сначала выводит все на клиент (я предполагаю, включая Content-Headers, установленные CodeIgniter). Измените вызов на ob_end_clean ()
, он очищает буфер и отбрасывает его. Это даст вам чистый старт для создания ваших собственных заголовков.
Другой совет:
Вместо того, чтобы читать файл как поток и передавать его по блокам, вы можете попробовать эту функцию:
// ...
if (file_exists("dir-with-files/$filename")) {
readfile($file);
}
Она позаботится почти обо всем.
print ($ this -> _ fullread ($ stream, 1024 * 16));
Я полагаю, _fullread находится внутри класса? Если код выглядит так, как показано выше, то $ this ->
работать не будет.
Выводит ли он содержимое файла на экран, если вы закомментировали весь материал заголовка?
Просто выстрел в темноте... каждый заголовок, который я посылаю в своем коде 'принудительной загрузки' (который не так хорошо протестирован, как ваш), тот же самый, что и ваш, за исключением того, что я звоню: header("Cache-Control: private",false);
вместо него: header("Cache-Control: public",FALSE);
Не знаю, поможет это или нет.
Если вы собираетесь использовать такой метод «Вывести эхо с помощью php», то вы не сможете показать оставшееся время или ожидаемый размер для ваших пользователей. Почему? Потому что, если браузер попытается возобновить загрузку в середине, у вас не будет возможности обработать этот случай в PHP.
Если у вас есть обычная загрузка файла, Apache может поддерживать возобновленную загрузку через HTTP, но в случае, если загрузка приостановлена, Apache не имеет возможности выяснить, где в вашем скрипте выполнялись какие-либо объекты, когда клиент запрашивает следующий кусок.
По сути, когда браузер приостанавливает загрузку, он полностью разрывает соединение с веб-сервером. Когда вы возобновляете загрузку, соединение снова открывается, и запрос содержит флаг, говорящий «Начать с байта номер X». Но для веб-сервера, смотрящего на ваш PHP выше, откуда берется байт X?
Хотя теоретически сервер может определить, где возобновить ваш скрипт в случае прерывания загрузки, Apache не пытается выяснить, где возобновить. В результате заголовок, отправленный в браузер, сообщает, что сервер не поддерживает возобновление, что отключает ожидаемый размер файла и элементы ограничения по времени в большинстве основных браузеров.
РЕДАКТИРОВАТЬ: Кажется, вы сможете справиться с этим случаем, но с вашей стороны потребуется МНОГО кода. См. http://www.php.net/manual/en/function.fread.php # 84115 .