4

In PHP I'm receiving a string from the user for a local file directory $path

I want to know if they've included the trailing slash (/) or not. I would like this to be cross platform so I'd like to use the PHP constant DIRECTORY_SEPARATOR

My failed attempts include trying to do a preg_match like

preg_match("/" . DIRECTORY_SEPARATOR . "$/", $path);

I basically just want an elegant way to test if the string ends with the DIRECTORY_SEPARATOR.

Shane Stillwell
  • 3,198
  • 5
  • 31
  • 53

5 Answers5

17

To fix your regexp:

preg_match("/" . preg_quote(DIRECTORY_SEPARATOR) . "$/", $path);

But there may be simpler ways to achieve your goal:

rtrim($path,DIRECTORY_SEPARATOR).DIRECTORY_SEPARATOR;
mvds
  • 45,755
  • 8
  • 102
  • 111
  • +1 Nice neat rtrim solution. (Like mine it will fail if DIRECTORY_SEPARATOR isn't a single character, but I've yet to see an OS that would cause problems.) – John Parker Aug 03 '10 at 14:18
  • I was thinking about not using `/` for regexp delimiter, but indeed, who knows what DIRECTORY_SEPARATOR may be invented in years to come... – mvds Aug 03 '10 at 14:21
  • btw this will not fail on multi-char DIRECTORY_SEPARATOR, for it will chop of the entire separator. (well, ok, if the last char of the filename would be a char contained in the multi-char DIRECTORY_SEPARATOR... but this would be very obscure) – mvds Aug 03 '10 at 14:23
  • True, perhaps "fail" is a bit excessive. How about "Its behaviour would be undefined". :-) – John Parker Aug 03 '10 at 14:25
  • This is perfect! Short, sweet and accomplishes the task. – Shane Stillwell Aug 03 '10 at 14:30
  • 2
    @mvds. Given it's PHP, they'd use `\\`, just like in namespaces, and no one's used it before... oh... wait a minute... – Marc B Aug 04 '10 at 04:35
  • `rtrim($path,DIRECTORY_SEPARATOR).DIRECTORY_SEPARATOR;` Caution: this will trim multiple trailing forward slashes. so `.//////` becomes `./` – Andrei Krasutski Nov 12 '16 at 22:22
1

what's wrong with a simple substr($path,-1)==DIRECTORY_SEPARATOR ?

bcosca
  • 17,371
  • 5
  • 40
  • 51
  • it would do the trick but once again, i think the asker fears directory separator might change in the future. It might not be more than one character of length, but more, ie, :: – fabjoa Aug 03 '10 at 14:47
  • 1
    unless the world is moving backward, i see no reason for a world asking for more characters to type on the command line – bcosca Aug 03 '10 at 14:57
0

A trival way of working this out would be to use...

$sepPresent = $path{strlen($path) - 1} == DIRECTORY_SEPARATOR ? true : false;

...which would be a lot more efficient than a regular expression. Then again, this will fail if DIRECTORY_SEPARATOR isn't a single character.

John Parker
  • 54,048
  • 11
  • 129
  • 129
0

Could also use array access notation

$endsInDS = $str[strlen($str)-1] === DIRECTORY_SEPARATOR;
Gordon
  • 312,688
  • 75
  • 539
  • 559
-1

I think depending on platform you can end up with an invalid regular expression on the first argument.

Your solution is elegant per design. Nice coding. But remember that directory separators usually are special characters. It may needs some escaping.

EDIT #1 I liked the proposed solution

$sepPresent = $path{strlen($path) - 1} == DIRECTORY_SEPARATOR ? true : false;

And to work it out I suggest:

$sepPresent = $path{strlen($path) - strlen(DIRECTORY_SEPARATOR)} === DIRECTORY_SEPARATOR ? true : false;
Davis Peixoto
  • 5,695
  • 2
  • 23
  • 35
  • This will not work for multi-char, since `$path{..}` gets 1 char only. better use `substr($path,-strlen(DIRECTORY_SEPARATOR))`. – mvds Aug 03 '10 at 14:52