tags:

views:

117

answers:

6

what would be the shortest way to write this?

if(strpos($haystack, $needle)!==false){
    $len = strpos($haystack, $needle)+strlen($needle);
}else{
    $len = 0;
}

I remember that I saw some shortcut somewhere for this that checked and set a variable at the same time.

A: 

It is called the tenary operator and can be used like this:

$len = strpos($haystack, $needle) ? strpos($haystack, $needle)+strlen($needle) : 0;

You should use it with care though, because it can make some expressions quite hard to read.

Daff
A: 
$len = strpos($haystack, $needle) ? strpos($haystack, $needle)+strlen($needle) : 0;

See also Ternary Operation.

Ham
+1  A: 
$len=strpos($haystack, $needle);
if($len !== FALSE) {
    $len +=  strlen($needle);
}

and, in my opinion, ternary operator is terrible impact on readability.

Col. Shrapnel
What about the `0` default case?
deceze
@deceze PHP will cast it from FALSE later :)
Col. Shrapnel
I wouldn't bet on it, that totally depends on where and how `$len` is used next.
deceze
in my case its used in: return substr($haystack, $len);
YuriKolovsky
+5  A: 
$len = 0;
if(($pos = strpos($haystack, $needle)) !== false) {
    $len = $pos + strlen($needle);
}

I'd recommend against the ternary ?: operator, even if it is shorter.

deceze
oh ($pos = strpos($haystack, $needle)) !== false was what i was looking for. thanks!
YuriKolovsky
I'd recommend against assignment in if evaluation clause too, even if it is shorter ;)
Eineki
@Yuri For your information, this works because the assignment operation `$x = $y` yields the value of the assigned value (of `$y`) as the result of the whole expression. I.e. `($x = $y) == $y`. Hence you can compare the result of the whole expression immediately. :)
deceze
@Eineki True actually, but this is as short as possible without being really cruel. ;)
deceze
heck, I thought it won't work.
Col. Shrapnel
if(false !== $pos = strpos($haystack, $needle)) would be even shorter and still works fine
YuriKolovsky
@Yuri You should learn Perl, you can probably do the whole thing in about 10 chars there. You won't be able to decipher it after a week, but at least it's short. ;)
deceze
also some reasoning why you are against ternary operator would be great
YuriKolovsky
@deceze hahaha, i have been told that i should learn perl in the past. But instead i think ill learn python.
YuriKolovsky
@Yuri Re ternary: Just because it's really bad for readability, as others here have said. Readability is much more important than the number of characters. Python may be a good exercise in this regard. :o)
deceze
+2  A: 
$len = strpos($haystack, $needle);
$len = ($len !== false) ? $len + strlen($needle) : 0;
Pierre-Antoine LaFayette
very short! :Dalso very good.considering the function is extremely short and will never be looked at...
YuriKolovsky
This is not the same as the above code. Consider the case where `strpos` returns `0` (Not `false`).
Yacoby
what if strpos returns a 0?
YuriKolovsky
I agree, pretty nice, albeit bordering on obfuscation of intent. You may want to fix the evaluation part though, since `$len` may legitimately be `0`, in which case this code produces a bug.
deceze
@Yacoby, didn't see you comment there, that's what i also thought after some mins of looking at it.
YuriKolovsky
Right, since php considers 0 to be false in conditional contexts the comparison to false is required.
Pierre-Antoine LaFayette
A: 

A different approach:

$len = strlen(preg_replace('/(.*?'.preg_quote($needle,'/').')?.*/', '$1', $haystack));

Probably slower and more memory-intensive, but it does require less typing. So whether or not it's actually a shortcut depends on the definition. It does present a valid option if you're allergic to ternary operators and assignment within evaluation conditions.

You could also do

$len = preg_match('/'.preg_quote($needle,'/').'()/', $haystack, $m, PREG_OFFSET_CAPTURE)? $m[1][1] : 0

although again it's a bit wasteful of resources to be using preg_ functions to search for fixed strings.

intuited