php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Doc Bug #26940 strncmp using the length of the shorter string
Submitted: 2004-01-16 19:58 UTC Modified: 2004-01-17 15:57 UTC
From: ikindred at cox dot net Assigned:
Status: Closed Package: Documentation problem
PHP Version: 4.3.4 OS: FreeBSD 4.9
Private report: No CVE-ID: None
 [2004-01-16 19:58 UTC] ikindred at cox dot net
Description:
------------
http://www.php.net/manual/en/function.strncmp.php says:

"If any of the strings is shorter than len, then the length of that string will be used for the comparison."

strncmp() does not behave in this manner.  Not in PHP.  Not in C.

On reflection, I guess that PHP cannot just call the C library strncmp function, as C strings are terminated by \x00 while PHP strings are not so terminated and can therefore contain one or more \x00's.  So, maybe, just maybe, this is not a documentation problem, but an actual PHP bug.

There have been many times when I wished that len would fallback to the length of the shorter string... so perhaps this is not a documentation bug, but rather PHP bug????

For example, this usually happens when I am writing something like:

// note the tedious to write, performance degrading call to strlen ("staticPrefix")
if (strncmp ($dynamicString, "staticPrefix", strlen ("staticPrefix")) == 0)
{
  print "dynamicString starts with staticPrefix\n";
}
else
{
  print "dynmaicString does not start with staticPrefix\n";
}

If you decide this is a PHP bug (and not a documentation bug), then be careful, because "fixing" PHP will cause strncmp to behave significantly differently from its C language namesake and may break existing code.

One solution might be to make $len optional.  When $len is omitted, then the length of the shorter string is used.  This should not break code and is also not flagrantly inconsistent with the C language strncmp.  At present (PHP 4.3.4), omitting $len causes "Warning: Wrong parameter count for strncmp" and NULL is returned.

But even this has a major problem - I was wrong - it will break code: if either string (even/especially the dynamic one) is null or "", then strncmp will say the strings are equal!!!  This is not what I/we want.

You can remedy this problem by only falling back to the length of the second string, or the first, as long as you are consistent.  But I'd go with the second - that will look prettier if you have a whole bunch of strncmps one line after another with the same $dynamicString but different "staticPrefixes" of different lengths.

Have fun deciding what to do!  strncmp ($dynamic, "static") would definitely be useful, but it is assymetrical and un-C-like.  But it would be useful.  I'd say, go for it!  The documentation will need to be changed anyways, so I'll leave this bug here as a documentation bug.  If you agree that it's worth changing strncmp as I have described, once you fixed the docs, reclassify/forward this bug on.

Thanks!

Reproduce code:
---------------
<?php

print "a  aa: ". strncmp ("a" , "aa", 100). "\n";
print "aa aa: ". strncmp ("aa", "aa", 100). "\n";
print "aa a : ". strncmp ("aa", "a" , 100). "\n";

?>


Expected result:
----------------
If strncmp behaved as described, I would expect the following (as len would "fallback" to 1 in the first and third cases):

a  aa: 0
aa aa: 0
aa a : 0


Actual result:
--------------
The actual result:

a  aa: -1
aa aa: 0
aa a : 1

(This is what strncmp does in C.)

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2004-01-17 09:16 UTC] et@php.net
This bug has been fixed in the documentation's XML sources. Since the
online and downloadable versions of the documentation need some time
to get updated, we would like to ask you to be a bit patient.

Thank you for the report, and for helping us make our documentation better.

I fixed the documentation for now, since the documented behaviour would be highly undesirable imo. You can create a function to check the beginning of a string easily with for example
function starts_with($haystack, $needle) {
    return substr($haystack, 0, strlen($needle)) == (string)$needle;
}
or
function starts_with($haystack, $needle) {
    return !strncmp($haystack, $needle, strlen($needle));
}

 [2004-01-17 14:31 UTC] ikindred2 at cox dot net
Of course I can create my own functions.

Regarding your functions (renamed for clarity):

function starts_with1($haystack, $needle) {
    return substr($haystack, 0, strlen($needle)) == (string)$needle;
}

Note that starts_with1 ("0", "0.0") returns true, which is incorrect (as the string "0" does not start with the string "0.0").  "===" should be used instead of "==" (you gotta luv PHP).  Also, the call to substr creates an unnecessary string, which is computationaly inefficient and therefore undesirable.

function starts_with2($haystack, $needle) {
    return !strncmp($haystack, $needle, strlen($needle));
}

Yes, and this is pretty much what I do.  But this is more complicated to write and to read than is necessary, and it requires me spelling $needle correctly both times, which doesn't always happen, especially with the long descriptive varibale names I sometimes use.  Also, if $needle is actually $parent->$child->$needle, the tedium is even greater, and one 80-char line of code may very well spill into two 80 char lines.

I'm not going to pursue the matter further.  While there is clear benefit to improving strncmp, there is no clear right answer as to what should be done, and these types of discussions in open source projects often waste lots of everyone's time and energy when they turn into never-ending arguments.

Thanks for fixing the docs!
 [2004-01-17 15:57 UTC] et@php.net
Of course you have to use ===, forgot that when typing :)
I don't see any way to improve strncmp.
strncmp has to be symmetric, so strncmp($a,$b,$x) = -strncmp($b,$a,$x) for all $a, $b and $x.
Using the shorter value as the upper bound leads to the empty string being equal with all other strings, which is odd, like you pointed out. I don't see any way to modify it in a way that makes sense.
 [2020-02-07 06:12 UTC] phpdocbot@php.net
Automatic comment on behalf of et
Revision: http://git.php.net/?p=doc/en.git;a=commit;h=81ba6ffec0dd0c2075ed2512ca79f426a50baedd
Log: Fix Bug #26940 (strncmp using the length of the shorter string)
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu May 02 14:01:34 2024 UTC