【问题标题】:Undefined offset error in PHP 2d arrayPHP 2d 数组中的未定义偏移错误
【发布时间】:2026-01-20 17:25:01
【问题描述】:

编辑:代码可在此处查看:http://codepad.org/28XT71AB

我已经搜索过了,但似乎没有什么能像我的问题一样出现。

开始之前:我已将所有可能出现问题的代码放在下面。这是大约200行代码,非常抱歉!但我完全被难住了。

我有一个二维数组$val,它由一个函数填充。

然后将数组传递给另一个函数,该函数使用数据填充表。

只有在我将一个函数一分为二时才会出现问题。

我有一个函数,它会获取大量数据,用它填充二维数组,然后为该数据创建显示。我决定拆分它 - 一个函数填充数组,另一个函数以所需格式显示此数据。

但是,由于将函数一分为二,即使仔细分析了代码,由于某种原因,数组要么没有被正确填充,要么没有被正确读取,或者出现了其他问题。

包括我的代码转储,因为显然我自己的眼睛无法发现问题。

抱歉,代码很多。但是我已经检查了每一行,无法找出问题所在 - 尤其是当它是一个功能时,它运行良好!

未定义的偏移误差在以下代码中指示的点处循环。

全局变量和第一个函数 - 从 CSV 中获取数据。

/*
  variables that work out current week
*/

$termstart = strtotime("03 October 2011"); //start of term, set manually every year, week 1 is first week after freshers.
$todaysdate = strtotime("now"); //todays date
$weekdif = ceil(($todaysdate-$termstart)/604800);//weeks between the two dates
//define global variables and arrays
$row = 0;
$col = 0;
$num = 0;


//this is the main timetable interface array
$val = array(array());

$ttdata = array();

$lecs = array();

tableinit($weekdif);


function tableinit($wkd)
{

$days = array("Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday");
$times = array("09:00", "10:00", "11:00", "12:00", "13:00", "14:00", "15:00", "16:00", "17:00");


//Check for appropriate CSV file and open it
if (($handle = fopen("timetable.csv", "r")) !== FALSE)
{
    //Check file for data and copy it into an array
    while (($data = fgetcsv($handle, 1000, ",")) !== FALSE)
    {
        //filter out blank lines in the file
        $fdata = array_filter($data);
        $num = count($fdata);

        //If line is not empty
        if ($num > 0)
        {
            //for every value in the array (the line)
            for ($c=0; $c<$num; $c++)
            {

                /*
                  This gets the module code, trims it of useless data,
                  then adds the name into an array of lectures for comparison later.
                  This is used to set up different colours for each different module
                */

                if ($c == 3)
                {
                    $lecture = substr($fdata[$c],0,8);

                    if (empty($lecs))
                    {
                        $lecs[] = $lecture;
                    }
                    else if (!(in_array($lecture,$lecs)))
                    {
                        $lecs[] = $lecture;
                    }

                    $ttdata[] = $lecture;
                }

                //if it's the 4th value or higher, then its data we want to display.
                if ($c >= 4)
                {
                    //add the data to an array. If no array exists, create it
                    $ttdata[] = $fdata[$c];
                }



                /*
                  if the value is a day of the week
                  set the value of the first timetable column as the appropriate day
                  with the corresponding row
                */

                switch ($fdata[$c])
                {
                    case $days[0]:
                        $row = 0;
                        $val[$row][0] = $fdata[$c];
                        break;
                    case $days[1]:
                        $row = 1;
                        $val[$row][0] = $fdata[$c];
                        break;
                    case $days[2]:
                        $row = 2;
                        $val[$row][0] = $fdata[$c];
                        break;
                    case $days[3]:
                        $row = 3;
                        $val[$row][0] = $fdata[$c];
                        break;
                    case $days[4]:
                        $row = 4;
                        $val[$row][0] = $fdata[$c];
                        break;
                    case $days[5]:
                        $row = 5;
                        $val[$row][0] = $fdata[$c];
                        break;
                    case $days[6]:
                        $row = 6;
                        $val[$row][0] = $fdata[$c];
                        break;
                }

                /*
                  this function compares the current week to the weeks in the timetable.
                  If there's a match, add a flag to the array for that lecture.
                  if not, do nothing.
                */

                if ($c == 6)
                {
                    $exp1 = explode(",", $fdata[$c]);

                    foreach ($exp1 as $i)
                    {
                        $i = trim($i);
                        $exp2 = explode("-", $i);

                        if (($wkd >= $exp2[0])&&($wkd <= $exp2[1]))
                        {
                            $ttdata[] = TRUE;
                        }
                    }
                }

                /*
                  if c the second value in the array,
                  check the value against the Time array
                  and set the column appropriately
                */
                if ($c==1)
                {
                    switch ($fdata[$c])
                    {
                        case $times[0]:
                            $col = 1;
                            break;
                        case $times[1]:
                            $col = 2;
                            break;
                        case $times[2]:
                            $col = 3;
                            break;
                        case $times[3]:
                            $col = 4;
                            break;
                        case $times[4]:
                            $col = 5;
                            break;
                        case $times[5]:
                            $col = 6;
                            break;
                        case $times[6]:
                            $col = 7;
                            break;
                        case $times[7]:
                            $col = 8;
                            break;
                        case $times[8]:
                            $col = 9;
                            break;
                    }
                }
            } //end line

            //fill the timetable with whitespace to preserve shape and empty slots
            for ($i=0;$i<=6;$i++)
            {
                for ($j=1;$j<=9;$j++)
                {
                    if (!isset($val[$i][$j]))
                    {
                        $val[$i][$j] = "&nbsp;";
                    }
                }
            }

            //if there's a flag to display data
            if (isset($ttdata[4]))
            {
                //remove the flag
                unset($ttdata[4]);
                //fill the current timetable position with the array of data to display
                $val[$row][$col] = $ttdata;
            }

            //delete the array of data to display
            unset($ttdata);
        }
    }
    fclose($handle);//close the file when finished
}

}

第二个功能(绘制表格)

drawtable($weekdif, $val);

function drawtable($wkd, $val)
{

$days = array("Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday");
$times = array("09:00", "10:00", "11:00", "12:00", "13:00", "14:00", "15:00", "16:00", "17:00");


//this sets up any days with no lectures, so there's not just a blank line
for ($m=0;$m<5;$m++)
{
    $row=$m;
    $val[$row][0] = $days[$m];
}

//create the table for the data from the main array
$table = "<table class='main' align='center'>\n<tr><td>Week $wkd</td>";

//create the line of different lecture times in the first row of the table
foreach ($times as $t)
{
    $table .= "<td class='dt'> ". $t . "</td>";
}
$table .= "</tr>\n"; //end first row

//for every weekday
for ($i=0;$i<5;$i++)
{
    //create a new row
    $table .= "<tr>";

    //for every time slot on that day
    for ($j=0;$j<=9;$j++)
    {
        //if there's an array present
        if (is_array($val[$i][$j]) == TRUE) //LOOP IS HERE
        {
            //copy the array to a temporary one
            $temp = $val[$i][$j];

            /*
              Switch statement to ensure that each module is always shown as a different colour.
              the same module will always be the same colour. Different modules will always be different colours.
            */

            switch ($temp[0])
            {
                case $lecs[0]:
                    $table .= "<td class='lecture1'>";
                    break;
                case $lecs[1]:
                    $table .= "<td class='lecture2'>";
                    break;
                case $lecs[2]:
                    $table .= "<td class='lecture3'>";
                    break;
                case $lecs[3]:
                    $table .= "<td class='lecture4'>";
                    break;
                case $lecs[4]:
                    $table .= "<td class='lecture5'>";
                    break;
                case $lecs[5]:
                    $table .= "<td class='lecture6'>";
                    break;
            }
            //for each value in the array
            foreach ($temp as $datum)
            {
                //print it and create a new line
                $table .= " ". $datum . " <br />";
            }
            $table .= "</td>";
        }
        //otherwise if a Day is present
        elseif ($j==0)
        {
            //print it
            $table .= "<td class='dt'>";
            $table .= $val[$i][$j]; //LOOP IS HERE
            $table .= "</td>";
        }
        //otherwise
        else
        {
            //print the whitespace
            $table .= "<td class='tt'>";
            $table .= $val[$i][$j];
            $table .= "</td>";
        }

    }
    //end row
    $table .= "</tr>\n";
}
//end table
$table .= "</table>";

//print the entire table
echo $table;

}

最后,看看实际的错误:

http://oliverlea.com/3yp/tt.php

【问题讨论】:

  • 这段代码是否构成了你的整个 tt.php,因为我没有得到 319 行?
  • 你应该把代码放到一些键盘上,比如codepad.org
  • 啊,不。上面有 23 行我开始引用我的代码,它设置页面 doctype,导入 jquery 和我自己的 js 文件,设置 css 等。然而,php 代码就在那里。我确实记下了在我的大量代码 sn-ps 中出现错误的两行(如//LOOP IS HERE
  • 你可以添加完整的代码吗

标签: php multidimensional-array


【解决方案1】:

您需要使用global 关键字授予tableinit$val 变量的访问权限:

  function tableinit($wkd) {
        global $val;

请参阅 PHP 的变量范围手册页:http://php.net/manual/en/language.variables.scope.php。如果没有 global 关键字,您的函数将创建 $val 的本地版本并对其进行操作,但您在页面顶部定义的 $val 保持不变。

【讨论】:

  • ...我真的永远不会知道这一点。谢谢!现在我只需要全局化一些其他变量。 =)
  • @omicronlyrae:global 只会消除症状,但不会治愈病因。而是开始将代码分组为函数并通过参数传递值。如果参数变得复杂,请使用结构。
最近更新 更多