PHP check in a function to redirect a non-trailing

2019-08-23 11:02发布

i've a function that control paginated Wordpress content and redirect numbered URLs to its parent URL.

The function is working perfectly but i want that the redirect 301 for numbered URLs that don't have a final trailing slash, fires directly to the trailing slash URL. For example:

https://www.example.com/how-to-do-something/1111

should redirect immediately to

https://www.example.com/how-to-do-something/

At the moment, instead the redirect 301 is working but pass for https://www.example.com/how-to-do-something and then to https://www.example.com/how-to-do-something/.

But, at the same time, this check should not invalidate the numbered URLs with final trailing slash, that are already good, for example:

https://www.example.com/how-to-do-something/1111/ redirect perfectly to https://www.example.com/how-to-do-something/ in one shot. So there is to do nothing for those.

the function is the following:

global $posts, $numpages;

 $request_uri = $_SERVER['REQUEST_URI'];

 $result = preg_match('%\/(\d)+(\/)?$%', $request_uri, $matches);

 $ordinal = $result ? intval($matches[1]) : FALSE;

 if(is_numeric($ordinal)) {

     // a numbered page was requested: validate it
     // look-ahead: initialises the global $numpages

     setup_postdata($posts[0]); // yes, hack

 $redirect_to = isset($ordinal) ? '/': (($ordinal > $numpages) ? "/$numpages/" : FALSE);

     if(is_string($redirect_to)) {

         // we got us a phantom
         $redirect_url = get_option('home') . preg_replace('%'.$matches[0].'%', $redirect_to, $request_uri);

         // redirect to it's parent 301
             header($_SERVER['SERVER_PROTOCOL'] . ' 301 Moved Permanently');

         header("Location: $redirect_url");
         exit();

     }
 }

How can i achieve this PHP check from non-trailing slash URL directly to trailing slash without invoke the htaccess rule that i have to force the trailing slash? Thanks for your patience and time.

2条回答
你好瞎i
2楼-- · 2019-08-23 11:06

Looking again at your code there are some things that don't add up:

  1. The line $redirect_to = isset($ordinal) ? '/': (($ordinal > $numpages) ? "/$numpages/" : FALSE); will always return '/' because $ordinal is always set within the if statement.

  2. Does the 'home' option return a url with a trailing slash? to make sure you need the 'trailingslashit' function, i.e., trailingslashit(get_option('home'))

  3. Overall I would approach this a bit differently. This is what I would do (fill free to change it to your needs):

$request_uri = $_SERVER['REQUEST_URI'];

$uriParts = explode('/', trim($request_uri, '/'));

$ordinal = array_pop($uriParts);

if (is_numeric($ordinal)) {
  setup_postdata($posts[0]);
  $redirect_url = trailingslashit(get_option('home')) . implode('/', $uriParts) . '/';
  header($_SERVER['SERVER_PROTOCOL'] . ' 301 Moved Permanently');
  header("Location: $redirect_url");
  exit();
}

Hope this helps.

查看更多
孤傲高冷的网名
3楼-- · 2019-08-23 11:10

Wordpress has a function that adds a trailing slash:

trailingslashit($string);
查看更多
登录 后发表回答