2012-04-02 43 views
0

编辑:代码是可以查看这里:http://codepad.org/28XT71AB未定义的偏移误差在PHP二维数组

我已经搜查,但似乎没有拿出很喜欢我的问题。

在我开始之前:我已经把所有可能成为问题的代码放在下面。这是大约200行代码,我非常抱歉!但我完全难倒了。

我有一个2D数组,$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

+0

这段代码是否构成了你的整个tt.php,因为我没有得到319行? – 2012-04-02 16:06:44

+0

你应该把代码放到一些代码上,比如http://codepad.org/ – hakre 2012-04-02 16:09:42

+0

啊,不。有23行以上的地方,我开始引用我的代码,其中设置页面doctype,导入jquery和我自己的js文件,设置CSS等,但PHP代码都在那里。我确实记录了我的海量代码片段中出现的两行错误(如'// LOOP is HERE') – omicronlyrae 2012-04-02 16:11:30

回答

2

你需要给tableinit访问与$val变量global关键字:

function tableinit($wkd) { 
     global $val; 

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

+0

...我从字面上不会知道这一点。谢谢!现在,我只需要全球化一些其他变量。 =) – omicronlyrae 2012-04-02 16:20:49

+0

@omicronlyrae:'全球'只会消除症状,但不会治愈原因。而是开始将代码分组到功能中,并通过参数传递值。如果参数变得复杂,则使用结构。 – hakre 2012-04-05 07:14:27