views:

8600

answers:

10

I need two functions that would take a string and return if it starts with the specified character/string or ends with it.

For example:

$str='|apples}';

echo startsWith($str,'|'); //Returns true
echo endsWith($str,'}'); //Returns true
+13  A: 

Here you go:

function startsWith($haystack,$needle,$case=true) {
    if($case){return (strcmp(substr($haystack, 0, strlen($needle)),$needle)===0);}
    return (strcasecmp(substr($haystack, 0, strlen($needle)),$needle)===0);
}

function endsWith($haystack,$needle,$case=true) {
    if($case){return (strcmp(substr($haystack, strlen($haystack) - strlen($needle)),$needle)===0);}
    return (strcasecmp(substr($haystack, strlen($haystack) - strlen($needle)),$needle)===0);
}

Credit to:

WebDevHobo
Can you edit your answer and copy and paste the code in it for future reference in case the links go down. You can select the code and hit ctrl + k to highlight it. Then I can accept your answer
Click Upvote
Editted, should be good now.
WebDevHobo
I edited to make it a bit more readable
Click Upvote
strtolower is not the best way to make case insensitive functions. In some locales casing is more complex than just upper and lower.
Sander Rijken
I see complaining and no solution... If you're gonna say it's bad, then you should give an example of how it should be as well.
WebDevHobo
@WebDevHobo: that's why I added an answer myself a day before your comment. For your code strcasecmp was indeed the right thing to do.
Sander Rijken
+1  A: 

Your best bet would be to use regular expressions and your functions would look something like this...

function startsWith($needle, $haystack)
{
   return preg_match('^'.$needle, $haystack);
}

function endsWith($needle, $haystack)
{
   return preg_match($needle .'$', $haystack);
}
Scott
need to preg_quote() $needle (and add slashes around the RE)
Greg
WarningMessage: preg_match() [function.preg-match]: No ending delimiter '^' found
Click Upvote
preg_match is overkill when substr would work here.
ceejayoz
+19  A: 
function startsWith($string, $char)
{
    $length = strlen($char);
    return (substr($string, 0, $length) === $char);
}

function endsWith($string, $char)
{
    $length = strlen($char);
    $start =  $length *-1; //negative
    return (substr($string, $start, $length) === $char);
}

Use this if you don't want to use a regex.

MrHus
+1 This is cleaner than the accepted answer. Also, `$length` is not needed in the last line of the `endsWith()`.
too much php
+10  A: 

All answers above seem to do loads of unnecessary work, strlen calculations, string allocations (substr) etc. The 'strpos' and 'stripos' functions return the index of the first occurrence of $needle in $haystack

function startsWith($haystack,$needle,$case=true)
{
   if($case)
       return strpos($haystack, $needle, 0) === 0;

   return stripos($haystack, $needle, 0) === 0;
}

function endsWith($haystack,$needle,$case=true)
{
  $expectedPosition = strlen($haystack) - strlen($needle);

  if($case)
      return strrpos($haystack, $needle, 0) === $expectedPosition;

  return strripos($haystack, $needle, 0) === $expectedPosition;
}
Sander Rijken
`endsWith()` function has an error.Its first line should be (without the -1): `$expectedPosition = strlen($haystack) - strlen($needle);`
Enrico Detoma
Corrected, thanks
Sander Rijken
+4  A: 

The regex functions above, but with the other tweaks also suggested above:

 function startsWith($needle, $haystack) 
 {
     return preg_match('/^'.preg_quote($needle)."/", $haystack);
 }

 function endsWith($needle, $haystack) 
 {
     return preg_match("/".preg_quote($needle) .'$/', $haystack);
 }
tridian
+3  A: 

I realize this has been finished, but you may want to look at strncmp as it allows you to put the length of the string to compare against, so:

function startsWith($haystack, $needle, $case=true) {
    if ($case)
        return strncasecmp($haystack, $needle, strlen($needle)) == 0;
    else
        return strncmp($haystack, $needle, strlen($needle)) == 0;
}
James Black
+2  A: 

Based on James Black's answer, here is its endsWith version:

function startsWith($haystack, $needle, $case=true) {
    if ($case)
        return strncmp($haystack, $needle, strlen($needle)) == 0;
    else
        return strncasecmp($haystack, $needle, strlen($needle)) == 0;
}

function endsWith($haystack, $needle, $case=true) {
     return startsWith(strrev($haystack),strrev($needle),$case);

}

Note: I have swapped the if-else part for James Black's startsWith function, because strncasecmp is actually the case-insensitive version of strncmp.

bobo
+1  A: 

If speed is important for you, try this.(I believe it is the fastest method)

Works only for strings and if $haystack is only 1 character

function startsWithChar($needle, $haystack)
{
   return ($needle[0] === $haystack);
}

function endsWithChar($needle, $haystack)
{
   return ($needle[strlen($needle) - 1] === $haystack);
}

$str='|apples}';
echo startsWithChar($str,'|'); //Returns true
echo endsWithChar($str,'}'); //Returns true
echo startsWithChar($str,'='); //Returns false
echo endsWithChar($str,'#'); //Returns false
lepe
A: 

Here's just a fix on Sander Rijken's method. The $expectedPosition calculation is slightly off in endsWith. (The last -1 is not necessary).

    function startsWith($string, $prefix, $caseSensitive = true) {
    if(!$caseSensitive) {
        return stripos($string, $prefix, 0) === 0;
    }
    return strpos($string, $prefix, 0) === 0;
}

function endsWith($string, $postfix, $caseSensitive = true) {
    $expectedPostition = strlen($string) - strlen($postfix);

    if(!$caseSensitive) {
        return strripos($string, $postfix, 0) === $expectedPostition;
    }
    return strrpos($string, $postfix, 0) === $expectedPostition;
}
mqchen
A: 

My personal preference would be eliminating all code repeats, so here is another version of Sander Rijken's method:

function contains($haystack, $needle, $case = true, $pos = 0)
{
    if ($case)
    {
        $result = (strpos($haystack, $needle, 0) === $pos);
    }
    else
    {
        $result = (stripos($haystack, $needle, 0) === $pos);
    }

    return $result;
}

function starts_with($haystack, $needle, $case = true)
{
    return contains($haystack, $needle, $case, 0);
}

function ends_with($haystack, $needle, $case = true)
{
    return contains($haystack, $needle, $case, (strlen($haystack) - strlen($needle)));
}
Orhan Kupusoglu