Всем доброй ночи. Недавно начал изучать PHP и при решении задачи столкнулся с проблемой насчёт header. Вопрос в следующем: Форма для закачки фото скачивает картинки в папку 'img' и записывает данные в БД. После чего перенаправляет на эту же страницу. Если не делать перенаправление то при перезагрузке страницы F5 данные из формы повторно загружаются в БД. Проблема в том что header ("Location: index.php/") не срабатывает. Мануал читал но без работающего примера так и не смог понять что делать с этим header_ом где он должен размещаться чтобы после после перезагрузки страницы старые данные снова НЕ отправлялись в БД. Код (Text): <?php header("Content-type: text/html; charset=utf-8"); include_once ("php/start.php"); start_up(); function up_file($ft) {if(isset($ft) && isset($_POST['lod'])) { $a=$ft['name']; $x='img/'.$ft['name']; copy($ft['tmp_name'], $x); mysql_query ("INSERT INTO fot (id_ft, name, view) VALUES ('', '$a', '')"); header ('Location: index.php') } elseif (!isset($ft)) { $arr=scandir('img'); for($i=2; $arr[$i] != null ;$i++) {echo "<a href=foto.php?size=$arr[$i]><img src=img/$arr[$i] /></a>";} } } собственно форма: Код (Text): <body> <form method="post" enctype="multipart/form-data"> <input type="file" name="foto"/> <input type="submit" name="lod" value="Загрузить" /> </form> <br> <?php up_file($_FILES['foto']);?> </body>
1) Слэш долой из хедера. 2) В самом начале кода поставьте ob_start(); 3) В точке, где заканчивается выполнение, поставьте ob_end_flush(); 4)... 5)Летс мэджик бегинс!!!!
Раскрываю секрет фокуса: 1) Слэш означает директорию. Если указать "file.php/", это значит, что вы указываете путь к папке с именем "file.php". Есть такая папка? Ноуп. Редирект не сработает. 2) ob_start() говорит, что с момента вызова этой функции, php включит сбор всей исходящей инфы в буфер вывода, а не будет сразу отдавать клиенту. Соль в том, что это помогает избежать ошибку, при которой хедеры, отправленные после любого текста, вызывают ошибку. Буфер вывода сортирует входящие данные, и все хедеры ставит в начало ответа. Таким образом, мы можем отдавать заголовки ситуационно, по ходу пьесы, не парясь, что они идут не в начале вывода. И это как раз ваша ситуация. 3) Буфер открыли, он собирает все в память, а, чтобы он отдал, мы его просим это сделать, через вызов функции ob_end_flush(); Это значит, что пхп должен перестать писать в буфер и отдать его содержимое клиенту. На самом деле, если у вас используется всего один буфер вывода, то ob_end_flush() писать не обязательно. ПХП сам догадается, что по окончании работы скрипта, надо бы отдать результаты. Да, как можно понять из пункта 3, буферов может быть несколько. Они могут быть вложены один в другой как матрешки. И для работы с ними предусмотрено больше двух функций. Советую почитать отдельно.
Вродебы по стандартам в header Location должен быть абсолютный путь, хотя браузеры терпят всякое. http://en.wikipedia.org/wiki/HTTP_location но если внимательно почитать доки, то даже там где упоминается "относительный" путь, это protocol-relative URL. то есть типа //domain.com/path/to/page вобщем писать 'Location: index.php' это искать приключений на свою задницу. как с любым недокументированным поведением. безопасно делать Код (PHP): header('Location: http://example.com/site-root/index.php'); exit(); не забываем про exit(), мать его так!
Эт да. Вообще в плане работы со ссылками всегда лучше юзать абсолютные пути. Мороки с ними никакой нет, а профита вагон. мне больше нравится die, хоть это одно и то же. Но ставить его надо только если переадресация подразумевает точку остановки работы скрипта. А то автор подумает, что так всегда надо делать. Когда работаешь через буфер вывода, отправка такого хедера не подразумевает прерывание и "вся остальная работа пойдет вхолостую". Если логика подразумевает какие-то действия, пусть они делаются.
exit или die — так всегда надо делать! ))) а то автор подумает, что header location это команда по которой управление передается на другую страницу.
Нет, не надо так делать всегда. И пренебрегать не надо. Надо сделать то, что сделал я - объяснить автору причину подобного решения в коде. А что ему нужно - пусть сам решает. Если не глупый, то или прочитает, или уже знает о том, что делает функция header(), и как эти хедеры работают.
Fell-x27, ты молодец. автор, читай внимательно что он пишет! и, между прочим, не забывай ставить exit.