将 php 数组过滤为仅包含与 $data 中的 $name 具有匹配值的元素
Filter a php array to only elements that have a matching value to $name in $data
我有一个 php 脚本获取 posts 文件夹中的所有文件夹并将它们放入列表中。
我有一个 $postinfo_str 变量分配给每个文件夹的 json 文件,我用来存储 post 日期和 category/tag 信息等。
我还有一个 $pagetitle 变量分配给每个文件夹的 title.php 包含文件。所以假设我在 "June 2018" 存档页面上,该文件中的文本将是 "June 2018"。如果我说的是 "Tutorials" 类别页面,那将是 title.php.
中的文本
在 json 文件中,我有:
{
"Arraysortdate": "YYYYMMDD",
"Month": "Month YYYY",
"Category": ["cat1", "cat2", "etc"]
}
我正在使用以 Arraysortdate 作为键的 krsort 对数组进行排序,从最新到最旧。
如何使用 $pagetitle 作为输入来过滤数组,查找 $postinfo_str 中是否有匹配项,如果没有,则从数组中删除该文件夹?
关于数组排序,我似乎能找到的是 $pageinfo_str 中的信息基本上是数组,因此 $title 是输入,输出是匹配文本$postinfo_str,而我希望输出是只有 $postinfo_str 中的匹配文本与输入($pagetitle)匹配的文件夹。
这是我的代码。请记住这是平面文件,我不希望数据库实现它。如果您需要解释,请参阅评论。
<?php
$BASE_PATH = '/path/to/public_html';
// initial array containing the dirs
$dirs = glob($BASE_PATH.'/testblog/*/posts/*', GLOB_ONLYDIR);
// new array with date as key
$dirinfo_arr = [];
foreach ($dirs as $cdir) {
// get current page title from file
$pagetitle = file_get_contents("includes/title.php");
// get date & post info from file
$dirinfo_str = file_get_contents("$cdir/includes/post-info.json");
$dirinfo = json_decode($dirinfo_str, TRUE);
// add current directory to the info array
$dirinfo['dir'] = $cdir;
// add current dir to new array where date is the key
$dirinfo_arr[$dirinfo['Arraysortdate']] = $dirinfo;
}
// now we sort the new array
krsort($dirinfo_arr);
foreach($dirinfo_arr as $key=>$dir) {
$dirpath = $dir['dir'];
$dirpath = str_replace('/path/to/public_html/', '', $dirpath);
?>
<!--HTML HERE SUCH AS--!>
<a href="<?=$dirpath;?>"> TEXT </a><br>
<?php
};
?>
我很难理解你的问题描述。您的代码示例有点令人困惑。它似乎为每个目录加载相同的 global includes/title.php
。意思是,$pagetitle
的值在每次迭代中都应该相同。如果这是有意的,您应该将该行移到循环之外。如果文件包含实际的 php 代码,您应该使用
$pagetitle = include 'includes/title.php';
或类似的东西。如果不是,您可能应该将其命名为 title.txt。如果它不是一个全局文件,您也应该将路径添加到 file_get_contents
/include
。 (但是,为什么不直接在 json 结构中添加标题呢?)
我假设这是在尝试提供最小代码示例时偶然发生的(?)...无论如何,我的答案都不是完美的答案,但希望可以进行调整一旦理解 ;o)
如果您只想要数组中满足特定属性的元素,您基本上有两种选择:
不要将这些元素放入(主要是您的代码)
foreach ($dirs as $cdir) {
// get current page title from file
$pagetitle = file_get_contents("includes/title.php");
// get date & post info from file
$dirinfo_str = file_get_contents("$cdir/includes/post-info.json");
$dirinfo = json_decode($dirinfo_str, TRUE);
// add current directory to the info array
$dirinfo['dir'] = $cdir;
// add current dir to new array where date is the key
// ------------ NEW --------------
$filtercat = 'cat1';
if(!in_array($filtercat, $dirinfo['Category'])) {
continue;
}
// -------------------------------
$dirinfo_arr[$dirinfo['Arraysortdate']] = $dirinfo;
array_filter
之后的数组,通过提供一个匿名函数
// ----- before cycling through $dirinfo_arr for output
$filtercat = 'cat1';
$filterfunc = function($dirinfo) use ($filtercat) {
return in_array($filtercat, $dirinfo['Category']));
}
$dirinfo_arr = array_filter($dirinfo_arr, $filterfunc);
您应该阅读有关匿名函数以及如何为它们提供本地变量的信息,以减轻痛苦。也许您的用例更适合 array_reduce
,这是相似的,除了您可以确定 "filter".
的输出
$new = array_filter($array, $func)
,只是一种花哨的写法:
$new = [];
foreach($array as $key => $value) {
if($func($value)) {
$new[$key] = $value;
}
}
更新 1
在我的代码示例中,您可以将 in_array($filtercat, $dirinfo['Category'])
替换为 in_array($pagetitle, $dirinfo)
- 如果您想匹配 json-struct(基本级别)中的任何内容 - 或者 ($pagetitle == $dirinfo['Month'])
如果你只想匹配月份。
更新 2
我明白,您可能刚刚开始接触 php 甚至编程,所以一些 "huge database" 的概念可能令人恐惧。但是说实话,从某种角度来看,文件系统也是一个数据库。然而,相比之下,它通常很慢,它也没有提供很多功能。
在长运行中,我强烈建议使用数据库。如果您不喜欢将数据放入 "some database server" 的想法,请使用 sqlite。但是,如果您以前从未接触过数据库,则需要学习曲线。在漫长的运行中,这将是值得花费的时间,因为它简化了很多事情。
我有一个 php 脚本获取 posts 文件夹中的所有文件夹并将它们放入列表中。
我有一个 $postinfo_str 变量分配给每个文件夹的 json 文件,我用来存储 post 日期和 category/tag 信息等。
我还有一个 $pagetitle 变量分配给每个文件夹的 title.php 包含文件。所以假设我在 "June 2018" 存档页面上,该文件中的文本将是 "June 2018"。如果我说的是 "Tutorials" 类别页面,那将是 title.php.
中的文本在 json 文件中,我有:
{
"Arraysortdate": "YYYYMMDD",
"Month": "Month YYYY",
"Category": ["cat1", "cat2", "etc"]
}
我正在使用以 Arraysortdate 作为键的 krsort 对数组进行排序,从最新到最旧。
如何使用 $pagetitle 作为输入来过滤数组,查找 $postinfo_str 中是否有匹配项,如果没有,则从数组中删除该文件夹?
关于数组排序,我似乎能找到的是 $pageinfo_str 中的信息基本上是数组,因此 $title 是输入,输出是匹配文本$postinfo_str,而我希望输出是只有 $postinfo_str 中的匹配文本与输入($pagetitle)匹配的文件夹。
这是我的代码。请记住这是平面文件,我不希望数据库实现它。如果您需要解释,请参阅评论。
<?php
$BASE_PATH = '/path/to/public_html';
// initial array containing the dirs
$dirs = glob($BASE_PATH.'/testblog/*/posts/*', GLOB_ONLYDIR);
// new array with date as key
$dirinfo_arr = [];
foreach ($dirs as $cdir) {
// get current page title from file
$pagetitle = file_get_contents("includes/title.php");
// get date & post info from file
$dirinfo_str = file_get_contents("$cdir/includes/post-info.json");
$dirinfo = json_decode($dirinfo_str, TRUE);
// add current directory to the info array
$dirinfo['dir'] = $cdir;
// add current dir to new array where date is the key
$dirinfo_arr[$dirinfo['Arraysortdate']] = $dirinfo;
}
// now we sort the new array
krsort($dirinfo_arr);
foreach($dirinfo_arr as $key=>$dir) {
$dirpath = $dir['dir'];
$dirpath = str_replace('/path/to/public_html/', '', $dirpath);
?>
<!--HTML HERE SUCH AS--!>
<a href="<?=$dirpath;?>"> TEXT </a><br>
<?php
};
?>
我很难理解你的问题描述。您的代码示例有点令人困惑。它似乎为每个目录加载相同的 global includes/title.php
。意思是,$pagetitle
的值在每次迭代中都应该相同。如果这是有意的,您应该将该行移到循环之外。如果文件包含实际的 php 代码,您应该使用
$pagetitle = include 'includes/title.php';
或类似的东西。如果不是,您可能应该将其命名为 title.txt。如果它不是一个全局文件,您也应该将路径添加到 file_get_contents
/include
。 (但是,为什么不直接在 json 结构中添加标题呢?)
我假设这是在尝试提供最小代码示例时偶然发生的(?)...无论如何,我的答案都不是完美的答案,但希望可以进行调整一旦理解 ;o)
如果您只想要数组中满足特定属性的元素,您基本上有两种选择:
不要将这些元素放入(主要是您的代码)
foreach ($dirs as $cdir) { // get current page title from file $pagetitle = file_get_contents("includes/title.php"); // get date & post info from file $dirinfo_str = file_get_contents("$cdir/includes/post-info.json"); $dirinfo = json_decode($dirinfo_str, TRUE); // add current directory to the info array $dirinfo['dir'] = $cdir; // add current dir to new array where date is the key // ------------ NEW -------------- $filtercat = 'cat1'; if(!in_array($filtercat, $dirinfo['Category'])) { continue; } // ------------------------------- $dirinfo_arr[$dirinfo['Arraysortdate']] = $dirinfo;
array_filter
之后的数组,通过提供一个匿名函数// ----- before cycling through $dirinfo_arr for output $filtercat = 'cat1'; $filterfunc = function($dirinfo) use ($filtercat) { return in_array($filtercat, $dirinfo['Category'])); } $dirinfo_arr = array_filter($dirinfo_arr, $filterfunc);
您应该阅读有关匿名函数以及如何为它们提供本地变量的信息,以减轻痛苦。也许您的用例更适合
array_reduce
,这是相似的,除了您可以确定 "filter". 的输出
$new = array_filter($array, $func)
,只是一种花哨的写法:
$new = [];
foreach($array as $key => $value) {
if($func($value)) {
$new[$key] = $value;
}
}
更新 1
在我的代码示例中,您可以将 in_array($filtercat, $dirinfo['Category'])
替换为 in_array($pagetitle, $dirinfo)
- 如果您想匹配 json-struct(基本级别)中的任何内容 - 或者 ($pagetitle == $dirinfo['Month'])
如果你只想匹配月份。
更新 2
我明白,您可能刚刚开始接触 php 甚至编程,所以一些 "huge database" 的概念可能令人恐惧。但是说实话,从某种角度来看,文件系统也是一个数据库。然而,相比之下,它通常很慢,它也没有提供很多功能。
在长运行中,我强烈建议使用数据库。如果您不喜欢将数据放入 "some database server" 的想法,请使用 sqlite。但是,如果您以前从未接触过数据库,则需要学习曲线。在漫长的运行中,这将是值得花费的时间,因为它简化了很多事情。