环境参数
PHP 7.4 + Nginx/Apache
车站数据
12306(客站): https://kyfw.12306.cn/otn/resources/js/framework/station_name.js
moerail.ml(所有站点, ~270KB): http://moerail.ml/station.js
代码
数据转换 - data-transfer.php
代码:
<?php
$s = file_get_contents("station_12306.csv");
//12306数据下载后请保存为 station_12306.csv
$s = ltrim($s, "var station_names ='@");
$s = rtrim($s, "';");
$array = explode("@", $s);
$s = implode("\n", $array);
$s = strtr($s, "|", ",");
$file = fopen("station_12306.csv", "wb");
fwrite($file, $s);
fclose($file);
echo "station_12306.csv 转换完毕.<br>";
$s = file_get_contents("station.js");
//12306数据下载后请保存为 station.js
$s = ltrim($s, "var stationNames = '@");
$s = rtrim($s, "';");
$array = explode("@", $s);
$s = implode("\n", $array);
$s = strtr($s, "|", ",");
$s = str_replace(" ", "", $s);
$file = fopen("station_moerail.csv", "wb");
//自动转换为 station_moerail.csv
fwrite($file, $s);
fclose($file);
echo "station_moerail.csv 转换完毕.<br>";
查询页面(以moerail数据为准) - query.php
代码:
注: 转换后的车站数据文件为station_moerail.csv
, 表单HTML文件下以html/form_query.html
为准, 此html文件中不包含任何php代码
<?php
if(!isset($_GET["station"]) || empty($_GET["station"])) {
include "html/form_query.html"; //仅展示输入框
} else {
$station = $_GET["station"];
include "html/form_query.html";
$file = fopen("station_moerail.csv", "rb");
$feedback = "";
while (!feof($file)) { //逐行读取数据
$line = fgets($file, 9999);
if(substr_count($line, $station) > 0) { //寻找符合的车站行
$feedback = $feedback.$line."|"."";
}
}
$result = rtrim($feedback, "|");
//移除$feedback字符串中最后一个无用的 "|" 字符
$resultArray = explode("|", $result);
//把String $feedback分割为数组存入$resultArray
//$resultArray中储存了查询到的所有数据
//数据HTML展示
echo '<br><br>
<table frame="box" rules="all">
<tr>
<th>站名</th>
<th>拼音码</th>
<th>电报码</th>
<th>TMIS</th>
</tr>
';
foreach ($resultArray as $value) {
//$value中储存的是单个车站的各种数据, 继续向下分割, 获得各项信息输出
$array = explode(",", $value);
echo "<tr><td>$array[1]</td><td>$array[0]</td><td>$array[2]</td><td>$array[3]</td></tr>";
}
echo "</table>";
echo "已展示所有检索到的内容.";
fclose($file);
}
查询表单 - form_query.html
部分代码:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>查询 | JonRail</title>
</head>
<body>
<style>
* {
font-family: 'Bahnschrift';
}
input{
font-size: 14pt;
padding: 5px;
}
input::-webkit-input-placeholder {
color: #DDDDDD;
font-size: 12pt;
}
input:focus{
outline: 1px solid #000;
}
table, th, td {
padding: 8px;
font-size: 12pt;
}
</style>
<h1>查询</h1>
<form action="../query.php" method="GET"> <!-- ../ 是上级目录 -->
<input type="text" name="station" id="station" size="32" placeholder="漯河东/lhd/UDN/22355" autocomplete="off" />
<br>
<!--<input type="button" class="btn" value="查询" />-->
</form>
</body>
</html>
过程解析 (moerail数据为准)
- data_transfer.php 数据转换:
JS数据, 以下数据显示了北京北、北京东两个车站的数据, 我们以此为例:
var stationNames = '@bjb|北京北|VAP|12713|京2@bjd|北京东|BOP|12158|京2';
移除左右多余的字符, 数据按X|X|X|X|X@X|X|X|X|X
保留, 结果为:
bjb|北京北|VAP|12713|京2@bjd|北京东|BOP|12158|京2
按@分割字符串, 将每个车站的数据逐行排列, 结果为:
bjb|北京北|VAP|12713|京2
bjd|北京东|BOP|12158|京2
将”|”替换为”,”并储存为csv文件, 最终结果为:
bjb,北京北,VAP,12713,京2
bjd,北京东,BOP,12158,京2
那么, 该csv文件的结构就是:
拼音码,车站名,电报码,TMIS码,车站所属行政区及限制代码
注: 车站限制代码具体内容请见 http://moerail.ml/bureau.js 和 客里表
- query.php 接收数据、处理数据
表单采用 GET
方式提交数据, 那么我们后端就采用 $_GET["station"]
来接收用户所输入的文本, 例如用户输入为北京
, 接下来我们需要遍历csv数据文件每行, 逐行查找北京
这个字段, 如果搜寻到有关的行, 那么就把这一行的数据储存进string $feedback
中, 不同行之间用|
字符隔开;
$file = fopen("api/station_moerail.csv", "rb");
$feedback = "";
while (!feof($file)) {
$line = fgets($file, 9999); //逐行扫描
if(substr_count($line, $station) > 0) { //如果能够在该行中找到$station文本
$feedback = $feedback.$line."|".""; //该行数据存入变量
}
}
接下来, 移除最右侧一个无效的|
字符, 将string $result
按|
字符分割, 存入array $resultArray
中,
$result = rtrim($feedback, "|");
$resultArray = explode("|", $result);
此时该数组中的数据结构大致为:
0 -> 'bjb,北京北,VAP,12713,京2'
1 -> 'bjd,北京东,BOP,12158,京2'
输出表格头, 接下来开始处理上述数组中的内容, 进行最终展示
echo '<br><br>
<table frame="box" rules="all">
<tr>
<th>站名</th>
<th>拼音码</th>
<th>电报码</th>
<th>TMIS</th>
</tr>
';
使用foreach()
遍历上述数组, 每一次遍历, 就可以输出一行表格内容, 下面的代码就将array $resultArray
中的每一项文本数据存入string $value
, 在遍历过程中, 只需要关注string $value
即可.
我们先把string $value
按,
分割, 存入数组array $array
, 接下来直接获取数组中的具体文本, 进行HTML输出展示.
期间, array $array
结构大致是:
0 -> 'bjb'
1 -> '北京北'
2 -> 'VAP'
3 -> '12713'
4 -> '京2'
最后输出剩余HTML内容、关闭文件流即可.
foreach ($resultArray as $value) {
$array = explode(",", $value);
echo "<tr><td>$array[1]</td><td>$array[0]</td><td>$array[2]</td><td>$array[3]</td></tr>";
}
echo "</table>";
echo "已展示所有检索到的内容.";
fclose($file);