2013-05-27 34 views
0

有人問之前......我不能使用MySQL數據庫爲這個項目)PHP - 創建UL嵌套列出了從Flatfile文件

使用PHP,我需要創建嵌套UL的從平面文件數據庫。我遇到的問題是我不想顯示重複項目。我可以進一步解釋,但如果你看看下面的代碼,你會看到數據和目標。謝謝。

FLATFILE DATA:

 
section|category|service 
Section One|Category One| 
Section One|Category Two|SC1 
Section One|Category Two|SC2 
Section One|Category Two|SC3 
Section One|Category Two|SC4 
Section One|Category Three| 
Section Two|Category Four|SC5 
Section Two|Category Four|SC6 
Section Three|Category Five|SC7 


HTML目標產量:

<ul class="section"> 
    <li>Section One 
     <ul class="category"> 
      <li>Category One</li> 
       <!-- no service --> 
     </ul> <!-- /category --> 
     <ul class="category"> 
      <li>Category Two</li> 
       <ul class="service"> 
        <li>SC1</li> 
        <li>SC2</li> 
        <li>SC3</li> 
        <li>SC4</li> 
       </ul> <!-- /service --> 
      </li> 
     </ul> <!-- /category --> 
     <ul class="category"> 
      <li>Category Three</li> 
       <!-- no service --> 
     </ul> <!-- /category --> 
    </li> 
</ul> <!-- /section --> 

<ul class="section"> 
    <li>Section Two 
     <ul class="category"> 
      <li>Category Four</li> 
       <ul class="service"> 
        <li>SC5</li> 
        <li>SC6</li> 
       </ul> <!-- /service --> 
      </li> 
     </ul> <!-- /category --> 
    </li> 
</ul> <!-- /section --> 

<ul class="section"> 
    <li>Section Three 
     <ul class="category"> 
      <li>Category Five</li> 
       <ul class="service"> 
        <li>SC7</li> 
       </ul> <!-- /service --> 
      </li> 
     </ul> <!-- /category --> 
    </li> 
</ul> <!-- /section --> 

我的第一次嘗試。考慮到我需要首先檢查「一節「存在,然後將當前」部分「分配給」section_last「以比較下一個」部分「與當前的「部分」值...並且如果不是,則打印「部分」...然後進入該類別。 我沒有對「服務」值部分進行編碼,因爲我沒有對&類別值取得任何成功。似乎我遇到了背後的'邏輯'問題,或者可能存在將循環中的過去值與PHP提供的下一個值進行比較的方法。

在看到@Kyle S的示例代碼後,我可能會在完全不正確的路徑上對此進行編碼。

<?php 
$section = ''; 
$category = ''; 
$service = ''; 
$section_last = ''; 
$category_last = ''; 
$service_last = ''; 

$x = 0; 

$file = fopen("categories_data.txt", "r"); 
if (!$file) { echo 'ERROR: Unable to open file: <strong>'.$file.'</strong>'; } 
fgets($file); // IGNORE FIRST LINE IN FLATFILE - column names 

while (!feof($file)) { 
    $lines = fgets($file); 
    $ele = explode('|', $lines); 

    $section = $ele[0]; 
    $category = $ele[1]; 
    $service = $ele[2]; 

    $service = str_replace(array("\n", "\r", "\r\n", "\n\r"), '',$service); 

    if(strlen($section)>0) { 
     if(!($section == $section_last)) { 
      echo ' 
    <ul> 
     <li>'.$section; 
      $section_last = $section; 
      $x++; 
     } 
    } 
    echo ' 
      <ul><li>'.$category.' > '.$service.'</li></ul> 
'; 
     if($x) { 
      if($section != $section_last) { 
       echo ' 
     </li> 
    </ul> 
'; 
     } 
    } 


} // end $data_file WHILE 

fclose($file); 
?> 
+0

您可以加入你寫的問題代碼,請?你有什麼嘗試,爲什麼它沒有工作? – andrewsi

回答

0

我會建議使用嵌套的數組,如果存在service項目使用PHP的in_array功能檢查。

例如,添加數據一行的價值,檢查是否該服務在這樣做之前先存在:

$data = explode("|", $line); 
$section = $data[0]; 
$category = $data[1]; 
$service = $data[2]; 

if (!array_key_exists($section, $tree)) { 
    $tree[$section] = array(); 
} 

if (!array_key_exists($category, $tree[$section])) { 
    $tree[$section][$category] = array(); 
} 

if (!in_array($service, $tree[$section][$category])) { 
    $tree[$section][$category][] = $service; 
} 
0

我不能居功此解決方案。我在另一個網站上被一位「專家」回答。不過,我真的覺得這個話題足夠重要,可以在這個'堆棧'網站上重新發布這個解決方案。

SOLUTION:

<?php 
define('TAB', "\t"); 
define('TAB2', "\t\t"); 

// Open the input file 
$file = fopen('lines.csv', 'rt'); 
// ignore the first line 
fgets($file); 
// Get the next line into an array splitting on the pipe 
$line = fgetcsv($file, 255, '|'); 

// set the initial section value 
$section = $line[0]; 
// Initialise batch array 
$current = array(); 
// Loop through all lines in the file 
do { 
// If this line contains a section that is not the same as the previous line then dump the last section 
    if ($section != $line[0]) { 
    dump_categories($current, $section); 
// Set our section flag to the next section  
    $section = $line[0]; 
// Clear the array of batched items to dump  
    $current = array(); 
    } 
// Add the line to the batch 
    $current[] = $line; 
} while($line = fgetcsv($file, 255, '|')); 
// Remember to dump batch that has built up 
dump_categories($current, $section); 
fclose($file); 

function dump_categories(& $lines, $section) 
{ 
// Set our category flag 
    $category = $lines[0][1]; 
// initialise batch array 
    $current = array(); 
// Start a new seection 
    echo '<ul class="section">' . PHP_EOL; 
    echo TAB . '<li>' . $section . PHP_EOL; 
// If there are categories in this section then process them - don't want empty bullets here 
    if (!empty($lines[0][1])) { 
    foreach($lines as $l) { 
// if this is a new category then dump category and services for this category  
     if ($category != $l[1]) { 
     dump_services($current, $category); 
// set our category flag   
     $category = $l[1]; 
// ... and clear the batch array   
     $current = array(); 
     } 
// add to batch  
     $current[] = $l; 
    } 
// and dump batched lines  
    dump_services($current, $category); 
    } 
    echo TAB . '</li>' . PHP_EOL; 
    echo '</ul>'; 
} 
// Services we assume is the end of the line so output the service if it exists. 
function dump_services(& $lines, $category) 
{ 
    echo TAB2 . '<ul class="category">' . PHP_EOL; 
    echo TAB . TAB2 . '<li>' . $category . PHP_EOL; 
    if (!empty($lines[0][2])) { 
    echo TAB2 . TAB2 . '<ul class="service">' . PHP_EOL; 
    foreach($lines as $l) { 
     if (!empty($l)) { 
     echo TAB . TAB2 . TAB2 . '<li>' . $l[2] . '</li>' . PHP_EOL; 
     } 
    } 
    echo TAB2 . TAB2 . '</ul>' . PHP_EOL; 
    } 
    echo TAB . TAB2 . '</li>' . PHP_EOL; 
    echo TAB2 . '</ul>' . PHP_EOL; 
} 
?>