2013-05-08 98 views
2

我正在嘗試學習PHP,並不斷遇到PHP錯誤。這是一個鏈接到站點http://projects.jeremyohmann.com/homework。有人可以看看我的代碼,看看我做錯了什麼嗎?我認爲這個錯誤是在head.php中的某個地方,但它也可能在Login.php中。用戶在頁面刷新後不斷註銷,所以我認爲它與php會話有關。

,我得到確切的錯誤是:

Warning: session_start() [function.session-start]: Cannot send session cookie - headers already sent by (output started at /home/jeremyohmann/www/projects/homework/head.php:2) in /home/jeremyohmann/www/projects/homework/classes/Login.php on line 30 

Warning: session_start() [function.session-start]: Cannot send session cache limiter - headers already sent (output started at /home/jeremyohmann/www/projects/homework/head.php:2) in /home/jeremyohmann/www/projects/homework/classes/Login.php on line 30 

head.php

<html> 
<?php 
require_once ('config/config.php'); 
require_once ('config/db.php'); 
require_once ('classes/Login.php'); 
$login = new Login(); ?> 
<head> 
<title>Homework Managment Project</title> 
<link rel="stylesheet" type="text/css" href="reset.css"> 
<link rel="stylesheet" type="text/css" href="style.css"> 
</head> 
<div id="wrapper"> 
<div id="header"><h1>Homework Management Project</h1></div> 
<div id="nav"> 
<ul id="nav"> 
    <li><a href="index.php">Home</a></li> 
    <li><a href="register.php">Register</a></li> 
    <li><a href="about.php">About</a></li> 
    <li><a href="classes.php">Classes</a></li> 
    <?php 
    //ask is user is logged in. 
    if($login->isUserLoggedIn()==true){ 
    //show this if the user is logged in. 
    include('views/show-username.php');} 
    else{ 
    //show this if the user isn't logged in. 
    include('views/nav-login-form.php');} 
    ?> 
</ul> 
</div> 
<div id="content"> 

的login.php

<?php 

/** 
* class Login 
* handles the user login/logout/session 
* 
* @author Panique <[email protected]> 
* @version 1.2 
*/ 
class Login { 

    private  $db_connection    = null;      // database connection 

    private  $user_name     = "";      // user's name 
    private  $user_email     = "";      // user's email 
    private  $user_password_hash   = "";      // user's hashed and salted password 
    private  $user_is_logged_in   = false;     // status of login 

    public  $errors      = array();     // collection of error messages 
    public  $messages     = array();     // collection of success/neutral messages 


    /** 
    * the function "__construct()" automatically starts whenever an object of this class is created, 
    * you know, when you do "$login = new Login();" 
    */  
    public function __construct() { 

     // create/read session 
     session_start();           

     // check the possible login actions: 
     // 1. logout (happen when user clicks logout button) 
     // 2. login via session data (happens each time user opens a page on your php project AFTER he has sucessfully logged in via the login form) 
     // 3. login via post data, which means simply logging in via the login form. after the user has submit his login/password successfully, his 
     // logged-in-status is written into his session data on the server. this is the typical behaviour of common login scripts. 

     // if user tried to log out 
     if (isset($_GET["logout"])) { 

      $this->doLogout(); 

     } 
     // if user has an active session on the server 
     elseif (!empty($_SESSION['user_name']) && ($_SESSION['user_logged_in'] == 1)) { 

      $this->loginWithSessionData();     

     // if user just submitted a login form 
     } elseif (isset($_POST["login"])) { 

       $this->loginWithPostData(); 

     }   
    }  


    private function loginWithSessionData() { 

     // set logged in status to true, because we just checked for this: 
     // !empty($_SESSION['user_name']) && ($_SESSION['user_logged_in'] == 1) 
     // when we called this method (in the constructor) 
     $this->user_is_logged_in = true; 

    } 


    private function loginWithPostData() { 

     // if POST data (from login form) contain non-empty user_name and non-empty user_password 
     if (!empty($_POST['user_name']) && !empty($_POST['user_password'])) { 

      // create a database connection, using the constants from config/db.php (which we loaded in index.php) 
      $this->db_connection = new mysqli(DB_HOST, DB_USER, DB_PASS, DB_NAME); 

      // if no connection errors (= working database connection) 
      if (!$this->db_connection->connect_errno) { 

       // escape the POST stuff 
       $this->user_name = $this->db_connection->real_escape_string($_POST['user_name']);    
       // database query, getting all the info of the selected user 
       $checklogin = $this->db_connection->query("SELECT user_id,user_name, user_email, user_password_hash, first_name, last_name FROM users WHERE user_name = '".$this->user_name."';"); 

       // if this user exists 
       if ($checklogin->num_rows == 1) { 

        // get result row (as an object) 
        $result_row = $checklogin->fetch_object(); 

        // using PHP's crypt function to 
        // this is currently (afaik) the best way to check passwords in login processes with PHP/SQL 
        if (crypt($_POST['user_password'], $result_row->user_password_hash) == $result_row->user_password_hash) { 

         // write user data into PHP SESSION [a file on your server] 
         $_SESSION['user_id'] = $result_row->user_id; 
         $_SESSION['user_name'] = $result_row->user_name; 
         $_SESSION['user_email'] = $result_row->user_email; 
         $_SESSION['first_name'] = $result_row->first_name; 
         $_SESSION['last_name'] = $result_row->last_name; 
         $_SESSION['user_logged_in'] = 1; 

         // set the login status to true 
         $this->user_is_logged_in = true; 

        } else { 

         $this->errors[] = "Wrong password. Try again."; 

        }     

       } else { 

        $this->errors[] = "This user does not exist."; 
       } 

      } else { 

       $this->errors[] = "Database connection problem."; 
      } 

     } elseif (empty($_POST['user_name'])) { 

      $this->errors[] = "Username field was empty."; 

     } elseif (empty($_POST['user_password'])) { 

      $this->errors[] = "Password field was empty."; 
     }   

    } 

    /** 
    * perform the logout 
    */ 
    public function doLogout() { 

      $_SESSION = array(); 
      session_destroy(); 
      $this->user_is_logged_in = false; 
      $this->messages[] = "You have been logged out.";  

    } 

    /** 
    * simply return the current state of the user's login 
    * @return boolean user's login status 
    */ 
    public function isUserLoggedIn() { 

     return $this->user_is_logged_in; 

    } 

} 

的index.php

<?php include('head.php') ?> 
<p>This is the test site for the Homework Grade Checker... Please check back soon to see if more progress has been made.</p> 
<?php include('foot.php') ?> 
+1

使用Google搜索得到的錯誤提供了大量優秀的信息......'不能發送會話cookie-已經由'發送的頭部'。這就是爲什麼我投票結束這個問題。 – Jasper 2013-05-08 16:55:31

+0

因爲session_start();已經開始。檢查你的其他文件config.php和db.php – tonoslfx 2013-05-08 16:56:36

回答

5

將輸出發送到瀏覽器後,您無法啓動會話。將<html>標記放在<head>標記上方。由任何輸出到瀏覽器之前

<?php 
require_once ('config/config.php'); 
require_once ('config/db.php'); 
require_once ('classes/Login.php'); 
$login = new Login(); ?> 
<html> 
<head> 
+0

感謝您的快速回答。它正在工作。 – user2363217 2013-05-08 17:00:28

1

功能是發送/修改HTTP標頭必須被調用,否則你會得到錯誤:

Warning: Cannot modify header information - headers already sent (output started at file:line)

這個錯誤會告訴你哪些文件引起的問題和線路上。

您在<html>標記後開始會話。所以做出以下改變,你會沒事的。

<?php 
require_once ('config/config.php'); 
require_once ('config/db.php'); 
require_once ('classes/Login.php'); 
$login = new Login(); 
?> 
<html> 
<head>