使用PHP在页面上显示项目


Using PHP to display items on page

我有一个文档名为subjects.txt,格式如下:

DateCreated、主题链接

18.10.2015,"数学",http://address.html

17.10.2015,"英语",http://address.html

18.10.2015,"英语",http://address.html

"科学",

19.10.2015 http://address.html

17.10.2015,"数学",http://address.html

该文件包含基于学校主题创建的网站的url。一个主题可以有多个站点。

目标是使用PHP以以下格式打开、读取和显示文件的内容:
数学

   Link 1
   Link 2
英语

   Link 1
   Link 2

Science(因为只有一个链接,所以主题的名称是链接)

到目前为止,我已经能够打开并读取文件:

$file = "./subjects.txt";
$subjects = file_get_contents($file);

我在试图确定如何以指定格式编写文件时遇到了麻烦。

我试过使用爆炸来分离元素与","-但我不知道从那里去哪里。

您的输入文件看起来是逗号分隔值(CSV)格式。PHP有一个内置的fgetcsv函数,旨在使从文件中读取CSV数据变得容易。

<?php
$file = './subjects.txt';
$fh = fopen($file, 'r');
if ($fh === false) {
    die("Can not read {$file}");
}
$data = array();
while (($row = fgetcsv($fh, 1000, ',')) !== false) {
    if ($row[0] === 'DateCreated') {
        // Ignore the column header row
        continue;
    }
    list($date, $subject, $link) = $row;
    if (!isset($data[$subject])) {
        $data[$subject] = array();
    }
    $data[$subject][] = $link;
}
fclose($fh);
foreach ($data as $subject => $links) {
    // TODO: output each subject here
}

这是另一个版本

<?php 
$file = "./subjects.txt";
$h = fopen($file, "r");
if($h !== false) {
    $subjects = [];
    $data = [];
    while(!feof($h)) {
        if($line = trim(fgets($h))) {
            $line = explode(",", $line);
            if(!in_array("DateCreated",$line)) {
                array_push($subjects, $line);
            }
        }   
    }
    fclose($h);
    foreach ($subjects as $subject) {
        if(!isset($data[$subject[1]])) {
            $data[$subject[1]] = [];
        }
        $data[$subject[1]][] = $subject[2];
    }
    foreach ($data as $subject => $links) {
        if(count($links) == 1) {
            echo "<p><a href=" . $links[0]. ">$subject</a></p>'n";
        } else {
            $i = 1;
            echo "<p>$subject</p>'n";
            echo "<ul>'n";
            foreach ($links as $link) {
                echo "<li><a href='"$link'">link$i</a></li>'n";
                $i++;
            }
            echo "</ul>'n";
        }   
    }
}
?>

使用file_get_contents()的问题是将所有文件内容检索到$subjects中。

你必须使用不同的方法。例如fgets():

$fp = fopen("./subjects.txt", "r");
if ($fp){
    while (($line = fgets($fp)) !== false){
        // So here you can treat each line individually.
        // You can use explode (";", $line) for example if the line is not empty  
    }
}
fclose($fp);

使用fgets()将允许您单独解析文件的每一行

如前所述,使用数据库进行此操作要容易得多,可能需要3行代码。这里有一个你可以使用的方法。

$data = '18.10.2015,"Math",http: //address.html
17.10.2015,"English",http: //address1.html
18.10.2015,"English",http: //address2.html
19.10.2015,"Science",http: //address3.html
17.10.2015,"Math",http: //address4.html';
preg_match_all('~^(.*?),"(.*?)",(.*?)$~m', $data, $fields);
array_multisort($fields[2], SORT_STRING, $fields[1], $fields[3]);
$lastcat = '';
foreach($fields[2] as $key => $cat) {
    if($cat != $lastcat) {
        echo $cat . "'n";
    }
    $lastcat = $cat;
    echo $fields[3][$key] . "'n";
}
输出:

English
http: //address1.html
http: //address2.html
Math
http: //address4.html
http: //address.html
Science
http: //address3.html

array_multisort是对类别进行分组的方式。

这里有一个regex101的演示,说明这个regex在做什么。https://regex101.com/r/wN3nB2/1

更新单记录检查(只运行1个测试):

$data = '18.10.2015,"Math",http: //address.html
17.10.2015,"English",http: //address1.html
18.10.2015,"English",http: //address2.html
19.10.2015,"Science",http: //address3.html
17.10.2015,"Math",http: //address4.html';
preg_match_all('~^(.*?),"(.*?)",(.*?)$~m', $data, $fields);
array_multisort($fields[2], SORT_STRING, $fields[1], $fields[3]);
$lastcat = '';
foreach($fields[2] as $key => $cat) {
    if((empty($fields[2][($key +1)]) && $cat != $lastcat)|| ($cat != $lastcat && !empty($fields[2][($key +1)]) && $fields[2][($key +1)] != $cat)) {
        //single record
        echo $cat . $fields[3][$key] . "'n";
    } else {
        if($cat != $lastcat) {
            echo $cat . "'n";
        }
        $lastcat = $cat;
        echo $fields[3][$key] . "'n";
    }
}