ФорумПрограммированиеPHP для идиотов → авторизации или Warning: Cannot modify header information

авторизации или Warning: Cannot modify header information

  • ISP

    Сообщения: 5 Репутация: N Группа: Кто попало

    Spritz 16 мая 2008 г. 6:01

    прочитал статью
    http://pyha.ru/articles/php/auth/
    и вроде все сделал как там написано и работало все нормально, но
    вот когда начал изменять… :(
    проблема в следующем, есть каркас страницы, где включаются с помощью require_once определенные блоки, и вот когда я вызываю блок с авторизацие и сохранинием в куки(или же делаю выход уже зарегистрированным пользователем) то появляется ошибка (приведу пример для выхода уже зарегистрованного пользователя)

    Warning: Cannot modify header information - headers already sent by (output started at Z:\home\aa.ru\www\index.php:84) in Z:\home\aa.ru\www\users\logdo.php on line 12

    Warning: Cannot modify header information - headers already sent by (output started at Z:\home\aa.ru\www\index.php:84) in Z:\home\aa.ru\www\users\logdo.php on line 13


    файл index.php который является каркасом

    <?php

    session_start();

    require_once('admin/config.php');


    // если пользователь не авторизован

    if (!isset($_SESSION['id']))
    {
    // то проверяем его куки
    // вдруг там есть логин и пароль к нашему скрипту

    if (isset($_COOKIE['login']) && isset($_COOKIE['password']))
    {
    // если же такие имеются
    // то пробуем авторизовать пользователя по этим логину и паролю
    $login = mysql_escape_string($_COOKIE['login']);
    $password = mysql_escape_string($_COOKIE['password']);

    // и по аналогии с авторизацией через форму:

    // делаем запрос к БД
    // и ищем юзера с таким логином и паролем

    $query = "SELECT `id`
    FROM `users`
    WHERE `login`='{$login}' AND `password`='{$password}'
    LIMIT 1";
    $sql = mysql_query($query) or die(mysql_error());

    // если такой пользователь нашелся
    if (mysql_num_rows($sql) == 1)
    {
    // то мы ставим об этом метку в сессии (допустим мы будем ставить ID пользователя)

    $row = mysql_fetch_assoc($sql);
    $_SESSION['user_id'] = $row['id'];

    // не забываем, что для работы с сессионными данными, у нас в каждом скрипте должно присутствовать session_start();
    }
    }
    }



    if (isset($_SESSION['user_id']))
    {
    $query = "SELECT `login`
    FROM `users`
    WHERE `id`='{$_SESSION['user_id']}'
    LIMIT 1";
    $sql = mysql_query($query) or die(mysql_error());

    // если нету такой записи с пользователем
    // ну вдруг удалили его пока он лазил по сайту.. =)
    // то надо ему убить ID, установленный в сессии, чтобы он был гостем
    if (mysql_num_rows($sql) != 1)
    {
    header('Location: login.php?logout');
    exit;
    }

    $row = mysql_fetch_assoc($sql);

    $welcome = $row['login'];
    }
    else
    {
    $welcome = 'гость';
    }
    ?>


    <html>
    <head>
    <title>PHP</title>
    <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=windows-1251">
    <META NAME="description" CONTENT="Описание информации на страничке, что содержит">
    <META NAME="keywords" CONTENT="Ключевые слова для поисковых систем">

    <!–эффект прозрачного закрытия окна и плавного перехода на новую страницу–>
    <!–<META http-equiv=Page-Exit  content=progid:DXImageTransform.Microsoft.Fade(Duration=1)>–>

    </HEAD>

    </head>
    <LINK rel="stylesheet" type="text/css" href="styles/style.css">

    <body bgcolor=white>


    <table width=95%  align=center bgcolor=#87CEFA CELLPADDING=0  CELLSPACING=0 BORDERCOLOR=blue>
    <tr>
    <td height=100 >
    logotip
    </td>
    </tr>
    </table>

    <table width=95%  align=center bgcolor=#87CEFA CELLPADDING=0  CELLSPACING=0 BORDERCOLOR=blue>
    <tr>
    <td align=center bgcolor=#3399ff>
    <?php
    require_once ("topmenu.php");
    ?>
    </td>
    </tr>



    <tr>
    <td>
    <table  align=center width=100% CELLPADDING=2  CELLSPACING=0 BORDERCOLOR=blue>

    <td width=150   valign=top>
    <?php
    require_once ("leftblock.php");
    ?>
    </td>

    <td width=* valign=top>

    <?php
    $page=$_GET['page'];
    if (!$page) $page="main";
    if (file_exists($page . ".php")==FALSE) $page="404";
    include ($page . '.php');


    // require_once ("main.php");
    ?>

    </td>

    <td width=150 valign=top>
    <?php
    require_once ("rightblock.php");
    ?>


    </td>
    </table>
    </td>
    </tr>


    <tr>
    <td height=80 bgcolor=#3399ff>

    "footer.php";

    </td>
    </tr>

    </table>

    <p align="center"><font size="2"><br>
    <strong>Created by
    <A href="mailto:фываыфва">ыфваыфва</A></strong> </font><br>
    </p>

    </body>
    </html>



    файл logdo.php

    <?php

    session_start();

    require_once('admin/config.php');

    if (isset($_GET['logout']))
    {
    if (isset($_SESSION['user_id']))
    unset($_SESSION['user_id']);

    setcookie('login', '', 0, "/");
    setcookie('password', '', 0, "/");
    // и переносим его на главную
    $return="index.php";
    echo "<html><head><meta http-equiv='refresh' content='0; url=$return'>
    </head></html>";
    // header('Location: ../index.php');
    exit;
    }

    if (isset($_SESSION['user_id']))
    {
    // юзер уже залогинен, перекидываем его отсюда на закрытую страницу
    $return="index.php";
    echo "<html><head><meta http-equiv='refresh' content='0; url=$return'>
    </head></html>";
    // header('Location: ../index.php');
    exit;

    }



    if (!empty($_POST))
    {
    $login = (isset($_POST['login'])) ? mysql_real_escape_string($_POST['login']) : '';

    $query = "SELECT `salt`
    FROM `users`
    WHERE `login`='{$login}'
    LIMIT 1";
    $sql = mysql_query($query) or die(mysql_error());

    if (mysql_num_rows($sql) == 1)
    {
    $row = mysql_fetch_assoc($sql);

    // итак, вот она соль, соответствующая этому логину:
    $salt = $row['salt'];

    // теперь хешируем введенный пароль как надо и повторям шаги, которые были описаны выше:
    $password = md5(md5($_POST['password']) . $salt);

    // и пошло поехало…

    // делаем запрос к БД
    // и ищем юзера с таким логином и паролем

    $query = "SELECT `id`
    FROM `users`
    WHERE `login`='{$login}' AND `password`='{$password}'
    LIMIT 1";
    $sql = mysql_query($query) or die(mysql_error());

    // если такой пользователь нашелся
    if (mysql_num_rows($sql) == 1)
    {
    // то мы ставим об этом метку в сессии (допустим мы будем ставить ID пользователя)

    $row = mysql_fetch_assoc($sql);
    $_SESSION['user_id'] = $row['id'];


    // если пользователь решил "запомнить себя"
    // то ставим ему в куку логин с хешем пароля

    $time = 86400; // ставим куку на 24 часа

    if (isset($_POST['remember']))
    {
    setcookie('login', $login, time()+$time, "/");
    setcookie('password', $password, time()+$time, "/");
    }

    // и перекидываем его на закрытую страницу
    $return="index.php";
    echo "<html><head><meta http-equiv='refresh' content='0; url=$return'>
    </head></html>";
    // header('Location: ../index.php');
    exit;

    // не забываем, что для работы с сессионными данными, у нас в каждом скрипте должно присутствовать session_start();
    }
    else
    {
    echo ('Такой логин с паролем не найдены в базе данных.  авотризуйтесь  — <a href="index.php?page=users/login">Авторизоваться</a>');
    }
    }
    else
    {
    echo('пользователь с таким логином не найден, авотризуйтесь — <a href="index.php?page=users/login">Авторизоваться</a>');
    }
    }
    ?>



    прошу не отсылать на http://phpfaq.ru/headers
    я там почитал, но к сожалению не понял, как исправить данную ошибку в моем примере, выше я не могу уже переносить, я ведь включаю данный год в коркас
    в пхп новичек, не судите строго=)
  • md5

    Сообщения: 11949 Репутация: N Группа: в ухо

    Spritz 16 мая 2008 г. 6:07, спустя 5 минут 45 секунд

    давайте код оформим, чтобы посмотреть, где 84 строка
    все умрут, а я изумруд
  • md5

    Сообщения: 11949 Репутация: N Группа: в ухо

    Spritz 16 мая 2008 г. 6:09, спустя 1 минуту 32 секунды

    <!–эффект прозрачного закрытия окна и плавного перехода на новую страницу–>
    <!–<META http-equiv=Page-Exit content=progid:DXImageTransform.Microsoft.Fade(Duration=1)>–>

    O_o
    все умрут, а я изумруд
  • ISP

    Сообщения: 5 Репутация: N Группа: Кто попало

    Spritz 16 мая 2008 г. 6:13, спустя 4 минуты 8 секунд

    чтоб с большим кодом не возится, приведу маленький) (извиняюсь что сразу код не подсветил)
    файл-группый каркас, в которм что то выводим, потом подключаем блок через require который должен динамически менятся, и дальше снова чтото статическое


    <?php
    session_start();
    include ('admin/config.inc');
    include ('users/func.inc');

    $welcome=enterusers();

    print '<h3>Здрасте, ' . $welcome . '.</h3>

    <a href="users/closed.php">Закрытая страница</a><br />';

    require_once ("users/login.php");

    if (!isset($_SESSION['user_id']))
    {
    print '<a href="users/login.php">Авторизация</a><br />';
    print '<a href="users/register.php">Регистрация</a><br />';
    }
    else
    {
    print '<a href="users/login.php?logout">Выход</a><br />';
    }

    print '<p><small>* Для авторизации использовать логин: <b>md5</b> и пароль: <b>password</b></small></p>';


    ?>



    получаю ошибку


    Здрасте, user2.
    Закрытая страница

    Warning: Cannot modify header information - headers already sent by (output started at
    Z:\home\SmallCmsV1\www\index2.php:10) in Z:\home\SmallCmsV1\www\users\login.php on line 19



    ну и сам логин пхп


    <?php

    if (isset($_GET['logout']))
    {
    if (isset($_SESSION['user_id']))
    unset($_SESSION['user_id']);

    setcookie('login', '', 0, "/");
    setcookie('password', '', 0, "/");
    // и переносим его на главную
    header('Location: ../index.php');
    exit;
    }

    if (isset($_SESSION['user_id']))
    {
    // юзер уже залогинен, перекидываем его отсюда на закрытую страницу

    header('Location: closed.php');
    exit;

    }



    if (!empty($_POST))
    {
    $login = (isset($_POST['login'])) ? mysql_real_escape_string($_POST['login']) : '';

    $query = "SELECT `salt`
    FROM `users`
    WHERE `login`='{$login}'
    LIMIT 1";
    $sql = mysql_query($query) or die(mysql_error());

    if (mysql_num_rows($sql) == 1)
    {
    $row = mysql_fetch_assoc($sql);

    // итак, вот она соль, соответствующая этому логину:
    $salt = $row['salt'];

    // теперь хешируем введенный пароль как надо и повторям шаги, которые были описаны выше:
    $password = md5(md5($_POST['password']) . $salt);

    // и пошло поехало…

    // делаем запрос к БД
    // и ищем юзера с таким логином и паролем

    $query = "SELECT `id`
    FROM `users`
    WHERE `login`='{$login}' AND `password`='{$password}'
    LIMIT 1";
    $sql = mysql_query($query) or die(mysql_error());

    // если такой пользователь нашелся
    if (mysql_num_rows($sql) == 1)
    {
    // то мы ставим об этом метку в сессии (допустим мы будем ставить ID пользователя)

    $row = mysql_fetch_assoc($sql);
    $_SESSION['user_id'] = $row['id'];


    // если пользователь решил "запомнить себя"
    // то ставим ему в куку логин с хешем пароля

    $time = 86400; // ставим куку на 24 часа

    if (isset($_POST['remember']))
    {
    setcookie('login', $login, time()+$time, "/");
    setcookie('password', $password, time()+$time, "/");
    }

    // и перекидываем его на закрытую страницу
    header('Location: closed.php');
    exit;

    // не забываем, что для работы с сессионными данными, у нас в каждом скрипте должно присутствовать session_start();
    }
    else
    {
    die('Такой логин с паролем не найдены в базе данных. И даём ссылку на повторную авторизацию. — <a href="login.php">Авторизоваться</a>');
    }
    }
    else
    {
    die('пользователь с таким логином не найден, даём ссылку на повторную авторизацию. — <a href="login.php">Авторизоваться</a>');
    }
    }

    print '
    <form action="login.php" method="post">
    <table>
    <tr>
    <td>Логин:</td>
    <td><input type="text" name="login" /></td>
    </tr>
    <tr>
    <td>Пароль:</td>
    <td><input type="password" name="password" /></td>
    </tr>
    <tr>
    <td>Запомнить:</td>
    <td><input type="checkbox" name="remember" /></td>
    </tr>
    <tr>
    <td></td>
    <td><input type="submit" value="Авторизоваться" /></td>
    </tr>
    </table>
    </form>
    ';

    ?>
  • megabit

    Сообщения: 367 Репутация: N Группа: Кто попало

    Spritz 16 мая 2008 г. 6:14, спустя 1 минуту 5 секунд

    надо буферизацию использовать ob_start  =)
  • ISP

    Сообщения: 5 Репутация: N Группа: Кто попало

    Spritz 16 мая 2008 г. 6:20, спустя 6 минут 30 секунд

    большое спасибо!!! замечательные функции)
  • megabit

    Сообщения: 367 Репутация: N Группа: Кто попало

    Spritz 16 мая 2008 г. 6:23, спустя 2 минуты 26 секунд

    чет я не вижу своего второго поста (куда пропал, а был) вобщем понял ты =)
  • AlexB

    Сообщения: 4290 Репутация: N Группа: в ухо

    Spritz 16 мая 2008 г. 7:46, спустя 1 час 23 минуты 22 секунды


    надо буферизацию использовать ob_start  =)

    Мля, надо приложение правильно проектировать, а не костыли подставлять и заплатки ставить.
  • megabit

    Сообщения: 367 Репутация: N Группа: Кто попало

    Spritz 16 мая 2008 г. 7:49, спустя 3 минуты 10 секунд

    ему нужен был ответ я ему ответил, =), а замена Header? что-то изи JavaScript-ов?
  • megabit

    Сообщения: 367 Репутация: N Группа: Кто попало

    Spritz 16 мая 2008 г. 7:50, спустя 1 минуту 1 секунду

    во втором посте было написано что Header использовать надо до вывода чего либо echo, а хз куда оно исчезло
  • AlexB

    Сообщения: 4290 Репутация: N Группа: в ухо

    Spritz 16 мая 2008 г. 7:55, спустя 5 минут 6 секунд


    ему нужен был ответ я ему ответил
    Офигительную любезность оказал. Теперь он будет везде пихать ob_start, так и не поняв отчего у него на самом деле проблема.


    во втором посте было написано что Header использовать надо до вывода чего либо echo
    Я не знаю куда оно исчезло, но это куда более вменяемый ответ на данный вопрос.
  • megabit

    Сообщения: 367 Репутация: N Группа: Кто попало

    Spritz 16 мая 2008 г. 8:07, спустя 11 минут 58 секунд

    Ну даже из самой ошибки было понятно что "заголовки уже отосланы"
  • ISP

    Сообщения: 5 Репутация: N Группа: Кто попало

    Spritz 16 мая 2008 г. 8:10, спустя 2 минуты 10 секунд

    ну в принципе я и начал уже везде пордяд пихать ob_start
    хотелось бы понять, как по умному сделать следующее…
    грубо говоря есть файл каркас-index.php в котор запихнут дизайн, к примеру 3 блока
    (шапка, основная часть, подвал), хочет сделать, чтоб весь дизайн содержался в ооднном файле, и в нем изменялся, а распространялся на все страницы.
    я нашел только один способ, как сделать это, более или менее…
    при помощи require_once подгружаю эти блоки, в результате

    require_once('shapka');

    $page=$_GET['page'];
    if (!$page) $page="main";
    if (file_exists($page . ".php")==FALSE) $page="404";
    include ($page . '.php');

    require_once('podval');


    из 3х частей меняется только main
    вот у меня и возникла труднасть с Header когад я так делал, я понял что его нужно делать до любого вывода
    но как в моем случае это сделать, когда у меня перед основной частью уже шапка выведена…

    подскажите более универсальный способ если такой есть, чтобы не пихать ob_start
    в заранее благодарен
  • AlexB

    Сообщения: 4290 Репутация: N Группа: в ухо

    Spritz 16 мая 2008 г. 11:51, спустя 3 часа 41 минуту 42 секунды


    хотелось бы понять, как по умному сделать следующее…

    Во кстати, я много тут распинался о шаблонах.
    Вот еще один аргумент в их пользу. Их использование, подталкивает более правильно структурировать код.
    Во всяком случае с шаблонами такая ошибка практически исключена, ибо echo в скрипте всего одно и всегда в самом конце.


  • megabit

    Сообщения: 367 Репутация: N Группа: Кто попало

    Spritz 16 мая 2008 г. 12:03, спустя 11 минут 47 секунд

    а какой вариант с шаблонами?, писать свой шаблонизатор и хранить каждый шаблон страницы в файле типа registration.tpl или как ? вот  я задумался над этим и не могу придумать чет

Пожалуйста, авторизуйтесь, чтобы написать комментарий!