Using trailingslashit in WordPress

When it comes to working with URLs, I believe that we should often be using trailingslashit in WordPress.

This is post is part of a larger discussion that I’ll be covering in more detail in another post, but here’s the gist of why I’m a fan of using trailingslashit.

Here’s why: there’s only a handful of operations that you can really be doing:

  • Setting up some type of rewrite rules or routes
  • Sniffing out parts of the URL to check for data
  • Redirecting (or protecting) users from content based on their status
  • …and maybe a few more

When it comes to examining the contents of the URL, one of the most common – if not the most common – way of doing it is using explode and then examine the various indexes of the array.

But in order to properly handle this, I think that we have an obligation to code defensively against URLs because we never know how users, third party libraries, or other clients are going to provide said URL.

And thus the case for always using trailingslashit in WordPress projects.

trailingslashit in WordPress

Simply put, trailingslashit will append a backslash to the end of a URL that’s passed as its parameter. If one already exists, then it won’t duplicate the existing trailing slash.

trailingslashit in WordPress

But the reasons for doing this aren’t arbitrary – it makes managing, parsing, and examining URL’s much easier, and here’s why:

Whenever you implement a trailing slash at the end of a URL, you are giving a definitive end point to your URL such that calling explode on a URL will allow you to have a fixed set of array indexes that contain each component.

Without having a trailing slash, you may end up running into an undefined index. Antonio offers a second opinion, which is completely viable, and which I’ll be discussing in the next post, too.

Consider this: Let’s say that you’re expecting a value to be at the last index of the array. If the trailing slash is present, then the value at the end of the array will always be two-off from the end; otherwise, it will be one-off from the end.

If the input is variable, then there’s no way to know which index to check. By applying trailingslashit, you can ensure the value for which you’re looking is always at the same index.

$arr_example = explode( '/', trailingslashit( $url ) );
$value = $arr_example[ count( $arr_example ) - 2 ];

Without using trailingslashit, you have no way of knowing if this index will actually exist at the end of the array or one index away from the end of the array, whereas using it will prevent that very problem from occurring.

Although there are multiple applications for this function, this is a safe guard when it comes to inspecting the last component of a URL.

That said, this isn’t the definitive way to go about handling trailing slashes. It’s a good way, but there’s another use case to consider. Thanks to thoughts by several commenters, I’ll be covering the flip side of this in the next post.

15 Replies to “Using trailingslashit in WordPress”

  1. Mmm…

    Without trailingslashit() you have no way of knowing if this index will actually exist.

    In every case, your index will exist.

    For example,

    explode( '/', 'example.com' );

    will return the following array

    array( [0] => 'example.com' )

    so, in example.com, there is no / but explode() will always return at least an array with the passed string.

    So I cannot understand your args. I know that is better to have all URLs with trailing slashes or to have all URLs with no trailing slashes but I cannot understand your args in favor of the former against the latter.

    1. There was a typo in the code of the original post that I resolved so the code now reads explode( '/', trailingslashit( 'http://example.com/individual/100/first-name/?action=view' ) );

      But consider, for example, if there were multiple parameters such as http://example.com/individual/100/first-name/?action=view.

      Sure, that’s a contrived example, but it should drive the point home a little bit more than the original post.

      I’ve actually updated the post to give a better example than looking at the final parameter and, instead, look at something that’s located in the middle of the URL.

          1. It’s more correct, but trailingslashit() still doesn’t guarantee there will be a value at a specific index.

            I’ll use you’re example:

            $url = 'http://example.com/';
            $arr_example = explode( '/', trailingslashit( $url ) );
            $value = $arr_example[2];

            In that case, $value is always going to be "example.com"…regardless of the use of trailingslashit().

            In this case, all trailingslashit() does is add 1 extra empty string to the end of the array (because you are exploding at every ‘/’).

            If you change the index to some arbitrarily large number that doesn’t exist in the array, it will not exist whether trailingslashit() is used or not.

            Example:
            $url = 'http://example.com/';
            $arr_example = explode( '/', trailingslashit( $url ) );
            $value = $arr_example[9];

            Here, $value will always be a blank string because there isn’t a value of the array at an index of 9.

            trailingslashit() is a useful function, but I don’t think it does what you’re trying to suggest here…unless you’re just trying to add an extra index to the end of the array.

            1. I clarified the post even further, but the point that I’m trying to make is that if you have a URL coming from the user and you want to inspect the last part of the URL if a slash will be present.

              This means that the element for which you’re looking may be the last element or it may be the second to last element.

              For example:

              $url = 'http://example.com/individual/view/1/?action=view/';
              print_r( explode( '/', $url ) );

              Yields:

              Array ( [0] => http: [1] => [2] => example.com [3] => individual [4] => view [5] => 1 [6] => ?action=view [7] => )

              Where as:

              $url = 'http://example.com/individual/view/1/?action=view';
              print_r( explode( '/', $url ) );

              Yields:

              Array ( [0] => http: [1] => [2] => example.com [3] => individual [4] => view [5] => 1 [6] => ?action=view )

              This is basically a defensive coding practice meant to ensure that when you’re looking for an element, it’s at the place you expect (rather than accidentally hitting a one off).

              Granted, the initial post should have been clearer but hopefully that clarifies it a bit :).

              1. “Without using trailingslashit, you have no way of knowing if this index will actually exist the end of the array or one index away from the end of the array, whereas using it will prevent that very problem from occurring.” That updated explanation helped clarify it for me versus the original text of the article. Like the others, I was confused initially because the index seemed to exist regardless of using trailingslashit() or not. Keep up the great articles, I’ve learned a lot so far. By the way, in the text I quoted, you are missing a word after ‘exist’.

  2. Thanks Tom. Sorry if I was being difficult…Just trying to clarify! Makes a lot more sense now.

    Basically, you can’t be positive about whether there will be extra parameters tacked on to the end or not, so using trailingslashit() ensures that you will always grab the last “slug” as opposed to any additional parameters that might show up.

    1. Oh, I don’t see it as difficult – I see it as being kept honest :).

      I like having other people chime in to provide sanity checks. I’d like to think I don’t need them but, you know, it is Friday and it’s been a long week so the comments are welcome!

    2. Using trailingslashit() ensures that you will always grab the last “slug” as opposed to any additional parameters that might show up.”

      Sorry but I don’t agree. What do you think about using untrailingslashit() in place of trailingslashit()? You will get the same result but with no trailing empty strings when calling explode().

      First case (URL with a trailing slash):

      $url = 'http://example.com/individual/view/1/?action=view/';
      $arr_example = explode( '/', untrailingslashit( $url ) );
      $value = $arr_example[count( $arr_example ) - 1];

      The value of value is ?action=view.

      Second case (URL without a trailing slash):

      $url = 'http://example.com/individual/view/1/?action=view';
      $arr_example = explode( '/', untrailingslashit( $url ) );
      $value = $arr_example[count( $arr_example ) - 1];

      The value of value is ?action=view too.

      And this is valid for every arr_example item.

      1. Honestly, it’s all sort of use-case specific. I think the point Tom was trying to make was to prevent the breaking of a bit of code in the event that you are looking for the last “slug”, or value from the path only, and some extra parameters get added to the end of a URL. In your example Antonio, if for some reason you didn’t have those parameters you would get a different result for $value.

        $url = 'http://example.com/individual/view/1/';
        $arr_example = explode( '/', untrailingslashit( $url ) );
        $value = $arr_example[count( $arr_example ) - 1];

        The value of $value is 1.

        $url = 'http://example.com/individual/view/1/?action=view';
        $arr_example = explode( '/', untrailingslashit( $url ) );
        $value = $arr_example[count( $arr_example ) - 1];

        The value of $value is ?action=view.

        Another option to what Tom has suggested would be to use parse_url($url, PHP_URL_PATH); to return only the path. Then you’d be positive you were excluding any parameters that might show up at the end.

        So something like this:
        $url = 'http://example.com/individual/view/1/?action=view';
        $path = parse_url( $url, PHP_URL_PATH );
        $arr_example = explode( '/', $path );
        $value = $arr_example[count( $arr_example ) - 2];

        1. I agree with Will in that it’s use-case specific. And I don’t disagree with Antionio.

          This actually leads into a larger discussion about trailing slashes, files, directories, and web servers.

          I think there’s another post to be written about this so I’m going to aim to do that on Monday to discuss those points.

          That way, we’ll have all bases covered (between when to using a trailing slash and when not to use a trailing slash).

          Thanks for the thoughts, guys!

  3. trailingslashit doesn’t check for a trailing slash at the end of a URL. It just uses untrailingslashit to remove any trailing slashes already present, and then adds one on the end. So if you want finer control, you might as well just use untrailingslashit and then work from that.

    1. Which would basically be:

      $url = untrailingslashit( $url );

      or

      $url = untrailingslashit( $url ) . '/';

      or something similar depending on your needs ;).

      This particular set of functions is turning out to be a lot of fun discussing, so I’m going to try to bring all of this together in a post on Monday.

      Thanks Shea!

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.