首页 > 解决方案 > 将 php 数组过滤为仅与 $data 中的 $name 具有匹配值的元素

问题描述

我有一个 php 脚本,获取帖子文件夹中的所有文件夹并将它们放入列表中。

我为每个用于存储发布日期和类别/标签信息等的文件夹分配了一个 $postinfo_str 变量。

我还有一个 $pagetitle 变量分配给每个文件夹的 title.php 包含文件。假设我在“2018 年 6 月”存档页面上,该文件中的文本将是“2018 年 6 月”。如果我在说“教程”类别页面,那将是 title.php 中的文本。

在 json 文件中,我有:

{
     "Arraysortdate": "YYYYMMDD",
     "Month": "Month YYYY",
     "Category": ["cat1", "cat2", "etc"]
 }

我正在使用 krsort 和 Arraysortdate 作为键来订购最新到最旧的数组。

如何使用 $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
};
?>


标签: phparraysfilterglob

解决方案


我很难按照您的问题描述进行操作。您的代码示例有点令人困惑。它似乎为每个目录加载相同的全局。 includes/title.php意思是,每次迭代的值都$pagetitle应该相同。如果这是有意的,您可能应该将该行移到循环之外。如果文件包含实际的 php 代码,您可能应该使用

$pagetitle = include 'includes/title.php'; 

或类似的东西。如果不是,您可能应该将其命名为 title.txt。如果它不是一个全局文件,您可能也应该将路径添加到file_get_contents/ include。(但是,为什么不直接在 json 结构中添加标题?)

我假设这是在尝试提供最小代码示例时偶然发生的(?)......无论如何,我的答案不会是完美的答案,但希望一旦理解它就可以适应;o)

如果您只想要数组中满足某些属性的元素,则基本上有两种选择:

  1. 不要将这些元素放入(主要是您的代码)

    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;
    
  2. 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,这是相似的,除了您可以确定“过滤器”的输出。

$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 甚至编程,因此某些“巨大数据库”的概念可能会令人恐惧。但是,从某种角度来看,文件系统也是一个数据库。但是,它通常比较慢,它也没有提供很多功能。

从长远来看,我强烈建议使用数据库。如果您不喜欢将数据放入“某个数据库服务器”的想法,请使用 sqlite。但是,如果您以前从未处理过数据库,则涉及到学习曲线。从长远来看,这将是值得花费的时间,因为它简化了很多事情。


推荐阅读