2013-05-27 38 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; 
} 
?>