admin管理员组

文章数量:1130349

The url I am trying to rewrite looks like this.

root_domain/something/something-else/also-different-1030/?success=1289

With this rewrite rule I am trying to catch the url and direct it to the post with ID 1289.

function my_success_rewrite_rule() {
    add_rewrite_rule( '.+success=([0-9]+)$', 'index.php?p=$matches[1]', 'top' );    
}
add_action( 'init', 'my_success_rewrite_rule' );

Here is the regex I tested for the url.
/

In the regex you can see that group 1 catches the post ID or $matches[1]. When I remove the ? from the url it works perfect and redirects any url with success=1289 at the end to the post with ID 1289.

However when I include the ? in the url it does not work, despite taking care of that in the regex by specifying . for any character and + as quanitfier for any number of occurrences and then success at the beginning of the regex before the capture group, the characters inside the ( ) followed by a $ to mark the end of the url string.

What does my rewrite rule need to look like to be able to keep the ? in the url and still rewrite the url to show post 1289 in this case? I am not sure how to escape or take care of the ?. Using .+\?success, so escaping the ? does not work.

I am also using Monkeyman Rewrite Analyzer and it shows me that the rewrite rule is being caught correctly.

I am also using flush_rewrite_rules( true ); in functions.php file to flush the rules each time I save, this to avoid having to manually update the permalinks settings page in the dashboard.

Also I am not adding a rewrite tag since p is a public query var, so no need to add that to WP since I want to get the post by ID, so I need to use p=$matches[1] (I think, pls correct me if this is wrong thinking, thx).

edit
To explain better why I think I need a ? in the url is this. The url is what the user is redirected to upon clicking a verification link. I could of course also omit the ? from the url the user is redirected to but I am not sure if that then is ok or the correct way of doing this.

if ( $verify === $verification ) {
    update_post_meta( $form_id, 'verification_id', 'verified', $verify );
    wp_safe_redirect( $url . '?success=' . $form_id );
}

So when the verification code is fine I update the post meta, then I take the original url the user was on when doing the verification and add the ?success=$form_id. I thought for WP to handle this fine and for me to also be able to use $_GET['success'] I have to have the ? in the url.

For example later on I am doing this to output information from the post I want.

function catch_success() {
    var_export( $_GET );
    if ( isset( $_GET['success'] ) ) {
        $post_id = $_GET['success'];
        $post = get_post( $post_id );
        var_export( $post );
        $user_reserved_seats = get_post_meta( $post_id, 'user_reserved_seats', true );
        var_export( $user_reserved_seats );
    }
}
add_action( 'template_redirect', 'catch_success' );

And initially I thought, to be able to use the catch_success function I need to have a ? in the url.

But instead of doing all that I should just omit the ? and redirect to the post I want to right after the verification link checks out?

Because as it stands now I think I have 2 redirects, 1 from the verification link and then from there to the success link and 2 from the success link to the post in question, 1289. I should just redirect to the post in question directly form the verification link, yes? Or I could omit the ? and still have the /success=1289 link redirected with a rewrite rule, to post 1289?

Bit of history, I asked this recently and is has to do with this in the sense that this is a follow up or the next step.

The url I am trying to rewrite looks like this.

root_domain/something/something-else/also-different-1030/?success=1289

With this rewrite rule I am trying to catch the url and direct it to the post with ID 1289.

function my_success_rewrite_rule() {
    add_rewrite_rule( '.+success=([0-9]+)$', 'index.php?p=$matches[1]', 'top' );    
}
add_action( 'init', 'my_success_rewrite_rule' );

Here is the regex I tested for the url.
https://regex101/r/nUENTl/1/

In the regex you can see that group 1 catches the post ID or $matches[1]. When I remove the ? from the url it works perfect and redirects any url with success=1289 at the end to the post with ID 1289.

However when I include the ? in the url it does not work, despite taking care of that in the regex by specifying . for any character and + as quanitfier for any number of occurrences and then success at the beginning of the regex before the capture group, the characters inside the ( ) followed by a $ to mark the end of the url string.

What does my rewrite rule need to look like to be able to keep the ? in the url and still rewrite the url to show post 1289 in this case? I am not sure how to escape or take care of the ?. Using .+\?success, so escaping the ? does not work.

I am also using Monkeyman Rewrite Analyzer and it shows me that the rewrite rule is being caught correctly.

I am also using flush_rewrite_rules( true ); in functions.php file to flush the rules each time I save, this to avoid having to manually update the permalinks settings page in the dashboard.

Also I am not adding a rewrite tag since p is a public query var, so no need to add that to WP since I want to get the post by ID, so I need to use p=$matches[1] (I think, pls correct me if this is wrong thinking, thx).

edit
To explain better why I think I need a ? in the url is this. The url is what the user is redirected to upon clicking a verification link. I could of course also omit the ? from the url the user is redirected to but I am not sure if that then is ok or the correct way of doing this.

if ( $verify === $verification ) {
    update_post_meta( $form_id, 'verification_id', 'verified', $verify );
    wp_safe_redirect( $url . '?success=' . $form_id );
}

So when the verification code is fine I update the post meta, then I take the original url the user was on when doing the verification and add the ?success=$form_id. I thought for WP to handle this fine and for me to also be able to use $_GET['success'] I have to have the ? in the url.

For example later on I am doing this to output information from the post I want.

function catch_success() {
    var_export( $_GET );
    if ( isset( $_GET['success'] ) ) {
        $post_id = $_GET['success'];
        $post = get_post( $post_id );
        var_export( $post );
        $user_reserved_seats = get_post_meta( $post_id, 'user_reserved_seats', true );
        var_export( $user_reserved_seats );
    }
}
add_action( 'template_redirect', 'catch_success' );

And initially I thought, to be able to use the catch_success function I need to have a ? in the url.

But instead of doing all that I should just omit the ? and redirect to the post I want to right after the verification link checks out?

Because as it stands now I think I have 2 redirects, 1 from the verification link and then from there to the success link and 2 from the success link to the post in question, 1289. I should just redirect to the post in question directly form the verification link, yes? Or I could omit the ? and still have the /success=1289 link redirected with a rewrite rule, to post 1289?

Bit of history, I asked this recently and is has to do with this in the sense that this is a follow up or the next step.

Share Improve this question edited Oct 24, 2018 at 20:01 lowtechsun asked Oct 24, 2018 at 17:41 lowtechsunlowtechsun 3924 silver badges22 bronze badges 5
  • 1 I don't think the question mark is a part of the URL at all, that's a part of the get parameters. Even if you can match it with a regular expression, it won't be a part of the input that gets passed to the rewrite rules. This will never work with the question mark in the rewrite rule ( because that's not how URLs work ) – Tom J Nowell Commented Oct 24, 2018 at 18:42
  • @TomJNowell Very useful info, still working on understand it thoroughly. I added more info to why I think I need a ? in the url, but if you understand that all I am after is a success page with info about the item that got verified as a form response I might have to just make it simple and direct to the post without redirects. Not sure whether to have a always on static success page where users see their form submit success once and otherwise other info/public info, or if I have a one-time visible per user submit form success page with related user item data and a dynamic url. – lowtechsun Commented Oct 24, 2018 at 20:05
  • @TomJNowell and you are right, I found this The question mark is used as a separator, and is not part of the query string. here. Though now I am also a bit more confused, how then does rewriting work with a use case like this ? Meaning, how can/could example/?success=1234 then be translated to example/?p=1234 as there is a ? in the url. – lowtechsun Commented Oct 24, 2018 at 20:11
  • 1 It isn't, because neither URL is a pretty permalink, neither would be matched by rewrite rules. The job of rewrite rules is to take /Im/a/foo/bar and turn it into something of the form /index.php?queryvar1=foo&queryvar2=bar etc, it's not a search replace. E.g. you can't rewrite on to a different PHP file, and you can't match GET parameters ( the whole point of permalinks is to hide them in the first place ). There is no hotfix kludge or hack that will make it match the ? or anything after it, that's not how URLs work – Tom J Nowell Commented Oct 24, 2018 at 20:15
  • 1 As for how does it match things like /?p=123? It doesn't, there are no rewrite rules involved in GET parameters, and you can't match GET parameters – Tom J Nowell Commented Oct 24, 2018 at 20:19
Add a comment  | 

1 Answer 1

Reset to default 2

The root problem here is a misunderstanding of how URLs work. What you see in the browser is not a full URL, but something to make it easier to understand

For example, take this URL:

http://example/test/?foo=bar#bananas

Here we have instructions to:

  • Via HTTP protocol aka http://
  • contact the server at example aka https://example
  • and do a GET HTTP request for /test/ aka https://example/test/
  • With the parameters foo=bar aka https://example/test/?foo=bar

WP Rewrite rules operate on the request, aka the /test/, so you can never match ?foo=bar part of a URL. The GET parameter foo gets put inside the $_GET array. Note how the # component is never sent, this part of the address is entirely client side.

So in order for your test to work, you will need to do two things:

  • Match on to the /something/something-else/also-different-1030/ part
  • Then check $_GET['success'] to see if it has a valid value

The url I am trying to rewrite looks like this.

root_domain/something/something-else/also-different-1030/?success=1289

With this rewrite rule I am trying to catch the url and direct it to the post with ID 1289.

function my_success_rewrite_rule() {
    add_rewrite_rule( '.+success=([0-9]+)$', 'index.php?p=$matches[1]', 'top' );    
}
add_action( 'init', 'my_success_rewrite_rule' );

Here is the regex I tested for the url.
/

In the regex you can see that group 1 catches the post ID or $matches[1]. When I remove the ? from the url it works perfect and redirects any url with success=1289 at the end to the post with ID 1289.

However when I include the ? in the url it does not work, despite taking care of that in the regex by specifying . for any character and + as quanitfier for any number of occurrences and then success at the beginning of the regex before the capture group, the characters inside the ( ) followed by a $ to mark the end of the url string.

What does my rewrite rule need to look like to be able to keep the ? in the url and still rewrite the url to show post 1289 in this case? I am not sure how to escape or take care of the ?. Using .+\?success, so escaping the ? does not work.

I am also using Monkeyman Rewrite Analyzer and it shows me that the rewrite rule is being caught correctly.

I am also using flush_rewrite_rules( true ); in functions.php file to flush the rules each time I save, this to avoid having to manually update the permalinks settings page in the dashboard.

Also I am not adding a rewrite tag since p is a public query var, so no need to add that to WP since I want to get the post by ID, so I need to use p=$matches[1] (I think, pls correct me if this is wrong thinking, thx).

edit
To explain better why I think I need a ? in the url is this. The url is what the user is redirected to upon clicking a verification link. I could of course also omit the ? from the url the user is redirected to but I am not sure if that then is ok or the correct way of doing this.

if ( $verify === $verification ) {
    update_post_meta( $form_id, 'verification_id', 'verified', $verify );
    wp_safe_redirect( $url . '?success=' . $form_id );
}

So when the verification code is fine I update the post meta, then I take the original url the user was on when doing the verification and add the ?success=$form_id. I thought for WP to handle this fine and for me to also be able to use $_GET['success'] I have to have the ? in the url.

For example later on I am doing this to output information from the post I want.

function catch_success() {
    var_export( $_GET );
    if ( isset( $_GET['success'] ) ) {
        $post_id = $_GET['success'];
        $post = get_post( $post_id );
        var_export( $post );
        $user_reserved_seats = get_post_meta( $post_id, 'user_reserved_seats', true );
        var_export( $user_reserved_seats );
    }
}
add_action( 'template_redirect', 'catch_success' );

And initially I thought, to be able to use the catch_success function I need to have a ? in the url.

But instead of doing all that I should just omit the ? and redirect to the post I want to right after the verification link checks out?

Because as it stands now I think I have 2 redirects, 1 from the verification link and then from there to the success link and 2 from the success link to the post in question, 1289. I should just redirect to the post in question directly form the verification link, yes? Or I could omit the ? and still have the /success=1289 link redirected with a rewrite rule, to post 1289?

Bit of history, I asked this recently and is has to do with this in the sense that this is a follow up or the next step.

The url I am trying to rewrite looks like this.

root_domain/something/something-else/also-different-1030/?success=1289

With this rewrite rule I am trying to catch the url and direct it to the post with ID 1289.

function my_success_rewrite_rule() {
    add_rewrite_rule( '.+success=([0-9]+)$', 'index.php?p=$matches[1]', 'top' );    
}
add_action( 'init', 'my_success_rewrite_rule' );

Here is the regex I tested for the url.
https://regex101/r/nUENTl/1/

In the regex you can see that group 1 catches the post ID or $matches[1]. When I remove the ? from the url it works perfect and redirects any url with success=1289 at the end to the post with ID 1289.

However when I include the ? in the url it does not work, despite taking care of that in the regex by specifying . for any character and + as quanitfier for any number of occurrences and then success at the beginning of the regex before the capture group, the characters inside the ( ) followed by a $ to mark the end of the url string.

What does my rewrite rule need to look like to be able to keep the ? in the url and still rewrite the url to show post 1289 in this case? I am not sure how to escape or take care of the ?. Using .+\?success, so escaping the ? does not work.

I am also using Monkeyman Rewrite Analyzer and it shows me that the rewrite rule is being caught correctly.

I am also using flush_rewrite_rules( true ); in functions.php file to flush the rules each time I save, this to avoid having to manually update the permalinks settings page in the dashboard.

Also I am not adding a rewrite tag since p is a public query var, so no need to add that to WP since I want to get the post by ID, so I need to use p=$matches[1] (I think, pls correct me if this is wrong thinking, thx).

edit
To explain better why I think I need a ? in the url is this. The url is what the user is redirected to upon clicking a verification link. I could of course also omit the ? from the url the user is redirected to but I am not sure if that then is ok or the correct way of doing this.

if ( $verify === $verification ) {
    update_post_meta( $form_id, 'verification_id', 'verified', $verify );
    wp_safe_redirect( $url . '?success=' . $form_id );
}

So when the verification code is fine I update the post meta, then I take the original url the user was on when doing the verification and add the ?success=$form_id. I thought for WP to handle this fine and for me to also be able to use $_GET['success'] I have to have the ? in the url.

For example later on I am doing this to output information from the post I want.

function catch_success() {
    var_export( $_GET );
    if ( isset( $_GET['success'] ) ) {
        $post_id = $_GET['success'];
        $post = get_post( $post_id );
        var_export( $post );
        $user_reserved_seats = get_post_meta( $post_id, 'user_reserved_seats', true );
        var_export( $user_reserved_seats );
    }
}
add_action( 'template_redirect', 'catch_success' );

And initially I thought, to be able to use the catch_success function I need to have a ? in the url.

But instead of doing all that I should just omit the ? and redirect to the post I want to right after the verification link checks out?

Because as it stands now I think I have 2 redirects, 1 from the verification link and then from there to the success link and 2 from the success link to the post in question, 1289. I should just redirect to the post in question directly form the verification link, yes? Or I could omit the ? and still have the /success=1289 link redirected with a rewrite rule, to post 1289?

Bit of history, I asked this recently and is has to do with this in the sense that this is a follow up or the next step.

Share Improve this question edited Oct 24, 2018 at 20:01 lowtechsun asked Oct 24, 2018 at 17:41 lowtechsunlowtechsun 3924 silver badges22 bronze badges 5
  • 1 I don't think the question mark is a part of the URL at all, that's a part of the get parameters. Even if you can match it with a regular expression, it won't be a part of the input that gets passed to the rewrite rules. This will never work with the question mark in the rewrite rule ( because that's not how URLs work ) – Tom J Nowell Commented Oct 24, 2018 at 18:42
  • @TomJNowell Very useful info, still working on understand it thoroughly. I added more info to why I think I need a ? in the url, but if you understand that all I am after is a success page with info about the item that got verified as a form response I might have to just make it simple and direct to the post without redirects. Not sure whether to have a always on static success page where users see their form submit success once and otherwise other info/public info, or if I have a one-time visible per user submit form success page with related user item data and a dynamic url. – lowtechsun Commented Oct 24, 2018 at 20:05
  • @TomJNowell and you are right, I found this The question mark is used as a separator, and is not part of the query string. here. Though now I am also a bit more confused, how then does rewriting work with a use case like this ? Meaning, how can/could example/?success=1234 then be translated to example/?p=1234 as there is a ? in the url. – lowtechsun Commented Oct 24, 2018 at 20:11
  • 1 It isn't, because neither URL is a pretty permalink, neither would be matched by rewrite rules. The job of rewrite rules is to take /Im/a/foo/bar and turn it into something of the form /index.php?queryvar1=foo&queryvar2=bar etc, it's not a search replace. E.g. you can't rewrite on to a different PHP file, and you can't match GET parameters ( the whole point of permalinks is to hide them in the first place ). There is no hotfix kludge or hack that will make it match the ? or anything after it, that's not how URLs work – Tom J Nowell Commented Oct 24, 2018 at 20:15
  • 1 As for how does it match things like /?p=123? It doesn't, there are no rewrite rules involved in GET parameters, and you can't match GET parameters – Tom J Nowell Commented Oct 24, 2018 at 20:19
Add a comment  | 

1 Answer 1

Reset to default 2

The root problem here is a misunderstanding of how URLs work. What you see in the browser is not a full URL, but something to make it easier to understand

For example, take this URL:

http://example/test/?foo=bar#bananas

Here we have instructions to:

  • Via HTTP protocol aka http://
  • contact the server at example aka https://example
  • and do a GET HTTP request for /test/ aka https://example/test/
  • With the parameters foo=bar aka https://example/test/?foo=bar

WP Rewrite rules operate on the request, aka the /test/, so you can never match ?foo=bar part of a URL. The GET parameter foo gets put inside the $_GET array. Note how the # component is never sent, this part of the address is entirely client side.

So in order for your test to work, you will need to do two things:

  • Match on to the /something/something-else/also-different-1030/ part
  • Then check $_GET['success'] to see if it has a valid value

本文标签: url rewritingTrouble with question mark in rewrite rule