2012-04-02 41 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