我认为您最好在数据库查询中而不是使用 PHP 来处理这个问题。使用您当前的代码,您将进行数十次效率低下的数据库调用。
拉记录
WordPress 将所有自定义字段存储在wp_postmeta
表中,可以按如下方式检索。
mysql> SELECT post_id, meta_value FROM wp_postmeta WHERE meta_key = 'LAST NAME';
+---------+-------------------+
| post_id | meta_value |
+---------+-------------------+
| 4 | Spielberg |
| 6 | AveryTiredman | <-- in the list twice
| 8 | bLanguage |
| 10 | aWakeMahn |
| 12 | dScreensAreBrukin |
| 14 | Aluloby |
| 16 | AaLetterC |
| 19 | AveryTiredman | <--
+---------+-------------------+
8 rows in set (0.00 sec)
我已经使用自定义字段创建了多个帖子LAST NAME
来复制您的网站。如您所见,上面的查询提取了我作为自定义字段输入的所有姓氏。
您可以使用以下内容过滤和排序结果。
mysql> SELECT meta_value AS last_name FROM wp_postmeta
WHERE meta_key = 'LAST NAME' and meta_value LIKE 'a%'
GROUP BY meta_value
ORDER BY meta_value;
+---------------+
| last_name |
+---------------+
| AaLetterC |
| Aluloby |
| AveryTiredman | <-- only shown once
| aWakeMahn |
+---------------+
4 rows in set (0.00 sec)
如您所见,上面的查询仅提取以字母开头的唯一记录,"a"
并按名称对它们进行排序。
注意:我将列名更改为与SELECT meta_value AS last_name
.
与 WordPress 一起使用
WordPress 有自己的数据库类,其中包含一个名为的方法get_results()
,可以让您运行自己的查询。该方法将返回一个允许您访问列名的对象数组。
<?php $directors = $wpdb->get_results("SELECT meta_value AS last_name FROM wp_postmeta WHERE meta_key = 'LAST NAME' and meta_value LIKE 'a%' GROUP BY meta_value ORDER BY meta_value") ?>
<ol>
<?php foreach( $directors as $director ) : ?>
<li><?php echo $director->last_name ?></li>
<?php endforeach ?>
</ol>
我知道您对此并不陌生,因此我尝试将其列出,以便您了解发生了什么。如果您有任何问题,请告诉我,我会尽力帮助您。
更新
制作带有链接以通过导演过滤的页面的最简单方法是使用自定义页面模板。基本上,创建一个以page-directors.php
以下内容命名的文件。然后添加一个新页面并将模板设置为"Directors Page"
.
<?php
/**
* Template Name: Directors Page
*/
// get a distinct set of the first letters available
$letters = $wpdb->get_results("SELECT DISTINCT substring(meta_value, 1, 1) as letters FROM wp_postmeta WHERE meta_key = 'LAST NAME' ORDER BY meta_value", ARRAY_N);
// get the letter from the URL
// and make sure there is only a single letter
$director_letter = filter_input(INPUT_GET, 'director', FILTER_VALIDATE_REGEXP, array('options' => array('regexp' => '/^[a-z]$/i')));
// set a default if none is available
if( $director_letter == false ) {
$director_letter = 'a';
}else {
$director_letter = strtolower($director_letter);
}
// don't trust user's input
$director_letter = mysql_real_escape_string($director_letter);
// same query as before but includes letter from user
$directors = $wpdb->get_results("SELECT meta_value AS last_name FROM wp_postmeta WHERE meta_key = 'LAST NAME' and meta_value LIKE '$director_letter%' GROUP BY meta_value ORDER BY meta_value");
get_header();
?>
<div id="primary">
<div id="content" role="main">
<?php while ( have_posts() ) : the_post(); ?>
<!--
CSS:
#director_letters li {
list-style: none;
display: inline;
}
-->
<ol id="director_letters">
<?php foreach( $letters AS $letter ) : ?>
<li><a href="<?php echo add_query_arg('director', strtolower($letter[0])) ?>"><?php echo strtoupper($letter[0]) ?></a></li>
<?php endforeach ?>
</ol>
<h2>Directors</h2>
<ol>
<?php foreach( $directors AS $director ) : ?>
<li><?php echo $director->last_name ?></li>
<?php endforeach ?>
</ol>
<?php endwhile; // end of the loop. ?>
</div>
</div>
<?php get_footer() ?>
更新#2
如果您使用我已经为您编写的代码和 SQL 查询,您应该能够弄清楚。我不想只给你答案,因为你不会那样学习。所以这就是我要做的。我将为您提供完成它所需的步骤,并让您弄清楚。如果您有任何问题或遇到困难,请发表评论,我会帮助您。
您需要创建另一个将导演的姓氏作为GET
参数的自定义页面模板。这将与我用来显示董事姓氏的第一个字母的完全相同。
接下来,您将需要查询该wp_postmeta
表并选择与主管post_id
WHERE
的meta_value
姓氏相同的值。
您将需要遍历帖子 ID 并显示帖子的标题。
注意:您会发现很方便的一个功能是get_the_title()
. 您可以传递帖子的 id,它将返回标题。
到目前为止,我向您展示的所有内容都可以用来回答您的问题。但是,正如我之前所说,如果您遇到无法解决的问题,请告诉我。
此外,一旦您完成此功能,请将代码添加回您的原始问题。很有可能我们可以大大提高它的效率:)
PS如果您不理解我提供给您的某些代码,请告诉我。拥有你不理解的代码对你没有任何好处:)
更新#3
我制作了一个视频,从头开始解释所有步骤。首先是提取导演的姓氏,然后显示所有字母,最后显示导演的所有 WordPress 帖子。