为具有多个查询参数的URL创建漂亮的链接



我正在开发一个更像搜索目录的网站,但还没有找到一个明确的答案,如何使用多个查询参数(Wordpress(从长URL中自动创建漂亮的链接。

例如,如果链接如下:website.com/search/search-results/?地址=98101,+西雅图,+华盛顿&承包商=水管工;纬度=1234&经度=9876&filter=20&order=距离

有没有办法让它看起来像这样:website.com/search/search-results/98101/seattle/washington/plumble/

而不必遍历每个链接,新的漂亮链接将显示与具有所有查询参数的页面相同的页面?

提前谢谢,我一整天都在想这个问题,这不是我的强项。。。

真的很有趣,也很技术性的问题。

以下内容尚未准备好生产。这是一个有效的概念证明

我只是在思考。您可以创建一个新的表(请参阅使用具有requested_url键和shortened_url值的插件创建表。整个系统将基于这种方法。

首先,我们在数据库中创建一个自定义表,如果它还不存在的话。此表将用于存储我们的URL。

<?php
add_action( 'after_switch_theme', function () {
global $wpdb;
$table_name = $wpdb->prefix . 'wpso74035985';

$charset_collate = $wpdb->get_charset_collate();
$create_ddl = "CREATE TABLE IF NOT EXISTS $table_name (
id mediumint(9) NOT NULL AUTO_INCREMENT,
requested_url varchar(55) DEFAULT '' NOT NULL,
shortened_url varchar(55) DEFAULT '' NOT NULL,
PRIMARY KEY  (id)
) $charset_collate;";

require_once ABSPATH . 'wp-admin/includes/upgrade.php';
maybe_create_table( $table_name, $create_ddl );
} );

然后,我们可以通过解析$_SERVER['QUERY_STRING']并通过get_query_var((验证url完整性来检索请求的url,因为它只检索WP_Query识别的公共查询变量。

然后,我们将在表中搜索请求的url,如果它还不存在,则设置一个新的密钥对值。

<?php
add_action( 'pre_get_posts', function ( $wp_query ) {
if ( ! is_admin() && $wp_query->is_main_query() ) {
if ( $wp_query->is_search() ) {
global $wp;
parse_str( filter_input( INPUT_SERVER, 'QUERY_STRING', FILTER_SANITIZE_STRING ), $variables );
$buffer = array();

foreach ( $variables as $variable => $value ) {

if ( get_query_var( $variable ) ) {

array_push( $buffer, array( $variable => $value ) );

};

};

$buffer = array_reduce( $buffer, 'array_merge', array() );

$requested_url = esc_url_raw( add_query_arg( $buffer, home_url( $wp->request ) ) );
global $wpdb;

$table_name = $wpdb->prefix . 'wpso74035985';
$results = $wpdb->get_results(

"SELECT * FROM $table_name"

);

$needle_key = array_search( $requested_url, array_column( $results, 'requested_url' ) );
if ( $needle_key === false ) {
$shortened_url = str_shuffle( base64_encode( random_bytes( 100 ) ) );
$shortened_url = preg_replace( '/W/s', '', $shortened_url );
$shortened_url = substr( $shortened_url, 0, 7 );

$wpdb->insert(
$table_name,
array(
'requested_url' => sanitize_url( $requested_url ),
'shortened_url' => sanitize_url( home_url( $shortened_url ) ), 
)
);
};
};
};
} );

这里没有真正的科学,$shortened_url只是一个7字节的字母数字字符串(为什么是7?Bit.ly一个著名的缩写使用了7个字符(。

通过template_redirect钩子,我们可以根据表检查缩短的url,并基于此进行重定向。

<?php
add_action( 'template_redirect', function () {
if ( is_404() ) {
global $wp;
$shortened_url = home_url( $wp->request );

global $wpdb;

$table_name = $wpdb->prefix . 'shortener';

$results = $wpdb->get_results(

"SELECT * FROM $table_name"

);

$needle_key = array_search( $shortened_url, array_column( $results, 'shortened_url' ) );

if ( $needle_key !== false ) {
$location = $results[$needle_key]->requested_url;

wp_safe_redirect( $location );

exit();
};
};
} );

由于我们首先检查404到is_404()(相当于限制了空请求的数量(,您还应该在根目录中包含404.php

在前端,您可以通过访问您的桌子

<?php
global $wpdb;

$table_name = $wpdb->prefix . 'wpso74035985';

$results = $wpdb->get_results(

"SELECT * FROM $table_name"

);
var_dump( $results );

现在,在你开始生产之前,有几件事需要理解,即使我们通过random_bytes()base64_encode()生成伪随机字符串,它们实际上并不是完全随机的,所以你可能会在某个时候遇到两个缩短的url相同的问题。你可以做一个while循环,在使用它之前不断检查这个缩短的url是否已经存在

您还希望尽可能多地限制搜索查询,以提高长期性能。

您可能还需要添加一个到期日期。

最新更新