-2

一段时间以来,我一直被以下问题困扰。

我不断收到以下错误:

Warning: Invalid argument supplied for foreach() in     
/home/content/50/10835750/html/dogdays/game/table.class.php on line 32

Warning: Cannot modify header information - headers already sent by (output started at    
/home/content/50/10835750/html/dogdays/game/table.class.php:32) in 
/home/content/50/10835750/html/dogdays/game/loadplayer.php on line 77
Redirecting to /game/locations/

我的代码如下:

<?php 
// First we execute our common code to connection to the database and start the session 
define('MyConst', TRUE);

include('database.class.php');
include('table.class.php'); 
include('user.class.php');
include('characters.class.php');
include('pc/player.class.php');
include('pc/human.class.php');
include('loginattempts.class.php');
include('timer.class.php'); 
include('functions.php'); 
include('loginf.php');


$dbo = database::getInstance();
$dbo -> connect("*****************", "***********", "*********", "********", 
array(PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8')); 

secSessionStart();

$_SESSION['page'] = "loadplayer.php";

// At the top of the page we check to see whether the user is logged in or not 
if(empty($_SESSION['user'])) 
{ 
    // If they are not, we redirect them to the login page. 
    header("Location: login.php"); 

    // Remember that this die statement is absolutely critical.  Without it, 
    // people can view your members-only content without logging in. 
    die("Redirecting to login.php"); 
} 

// Everything below this point in the file is secured by the login system 

// We can display the user's username to them by reading it from the session array.  
Remember that because 
// a username is user submitted content we must use htmlentities on it before     
displaying it to the user. 
?>
<?php
//    if(empty($_SESSION['playercharacter'])) {
    $character_id = "";
    $queryString = $_SERVER['QUERY_STRING'];
    $queryString = explode("&", $queryString);
    if(strcmp(substr($queryString[0],0,2),"c=") == 0) {
        $character_id = substr($queryString[0],2);
    }

    $c = new characters();
    $c -> load($character_id);
    $playercharacterobject = new human($c, null);
    $_SESSION['playercharacter'] = $playercharacterobject;

    try {
        $stmt = $dbo->getConnection()->prepare("SELECT * FROM location WHERE 
location_id = :location_id");
        $query_params = array(':location_id'=>$playercharacterobject->location_id);       
        // Execute the prepared query.
        $result = $stmt->execute($query_params);
    }
    catch(PDOException $ex) { 
        // Note: On a production website, you should not output $ex->getMessage(). 
        // It may provide an attacker with helpful information about your code.  
        die("Failed to run query1: " . $ex->getMessage()); 
    }

    $rows = $stmt->fetch(PDO::FETCH_ASSOC);

    $_SESSION['currentlocation'] = $rows['url'];
    $validAccess = array("babelfloor.php");
    $_SESSION['validAccess'] = $validAccess;
    $_SESSION['prevlocation'] = "loadplayer.php";
//    }


//     echo $_SESSION['currentlocation'];
//     echo $rows['url']; 
    // THIS IS LINE 77. THE ONE THAT IS CAUSING PROBLEMS 
    header("Location: /game/locations/".$_SESSION['currentlocation']);
    die("Redirecting to /game/locations/".$_SESSION['currentlocation']);
//      header("Location: combat.php");
//      die("Redirecting to combat.php"); 
?>

<?php
/**
* @author Alvin Tung
* @copyright 2013
*/

if(!defined('MyConst')) {
    die('Direct access not premitted');
}

class table {
    protected $id = null;
    protected $table = null;

    function __construct() {

    }

    function bind($data) {
        foreach ($data as $key=>$value) {
            $this -> $key = $value;
        }
    }

    function load($id) {
        $this->id = $id;

        $dbo = database::getInstance();
        $sql = $this->buildQuery('load');
        $row = $dbo->query($sql, array(':'.$this->table.'_id'=> $id));

            // THIS IS LINE 32
        foreach ($row as $key=>$value) {
            if($key == "user_id()") {
                continue;
            }

            $this->$key = $value;
        }

    }

    // write database object contents to database
    function store() {
        $dbo = database::getInstance();

        $array = array();
        $classVars = get_object_vars($this);

        if($this->id =="") {
            foreach ($classVars as $key=>$value) {
                if ($key == "id" || $key == "table") {
                    continue;
                }

                $array[":{$key}"] = $value;
            }
        }
        else {
            $array[':'.$this->table.'_id'] = $this->id;
        }     

        $sql = $this -> buildQuery('store');

        $dbo -> query($sql, $array);   
    }

    function buildQuery($task) {
        $sql = "";

        if ($task == "store") {
            // if no id value has been store in this object yet,
            //  add new record to the database, else just update the record.
            if ($this->id == "") {
                $keys = "";
                $values = "";
                $classVars = get_class_vars(get_class($this));
                $sql .= "INSERT INTO {$this->table}";

                foreach ($classVars as $key=>$value) {
                    if ($key == "id" || $key == "table") {
                        continue;
                    }

                    $keys .= "$key,";
                    $values .= ":$key,";
                }

                // NOTE: all substr($keys, 0, -1) does is gets rid of the comma
                // at the on the last array element.
                $sql .= "(".substr($keys, 0, -1).") Values (".substr($values, 0,   

-1).")";

            }
            else {

                $classVars = get_class_vars(get_class($this));
                $sql .= "UPDATE {$this->table} SET ";

                foreach ($classVars as $key=>$value) {
                    if ($key == "id" || $key == "table") {
                        continue;
                    }

                    $sql .= "{$key} = '{$this->$key}',";

                }
                $sql = substr($sql, 0, -1)." WHERE {$this->table}_id = :{$this-

>table}_id";

            }         
        }
        elseif ($task == "load") {
            $sql = "SELECT * FROM {$this->table} WHERE {$this->table}_id = :

{$this->table}_id";
        }

        return $sql;      
    }
}



?>

我已经尝试将 ob_start() 添加到 loadplayer.php 的顶部,正如这里大多数答案所建议的那样,但是它只是输出一个空白页。您的见解将不胜感激。

4

1 回答 1

1

错误消息Invalid argument supplied for foreach()表明foreach给定的东西既不是数组也不是Traversable对象。

鉴于这段代码:

$dbo = database::getInstance();
$sql = $this->buildQuery('load');
$row = $dbo->query($sql, array(':'.$this->table.'_id'=> $id));

// THIS IS LINE 32
foreach ($row as $key=>$value) {

很明显,这$row不是您所期望的。可能查询包含无效的 sql 或数据库中不存在 id。您应该进行更多的错误检查以正确处理这些情况。

消息headers already sent在这里并不重要。如果你解决了第一个问题,第二个问题也将消失。

于 2013-07-07T14:11:07.717 回答