strcspn can be a little confusing. I regularly have to consult the manual after going awhile without using it because I get strcspn and strspn mixed up because they do the exact opposite thing. Though I have an idea for remembering which one is which right now and I'll get to that later.
strcspn basically looks for characters that aren't in that character mask. From the manual,
int strcspn ( string $str1 , string $str2 [, int $start [, int $length ]] )
Returns the length of the initial segment of str1 which does not contain any of the characters in str2.
If you track down the function in the source, you come to this where you can see how the function works internally. It just walks through the string looking for something it doesn't expect, then looks for something it does expect and returns the length of that segment.
etc/standard/string.c:1571
PHPAPI size_t php_strcspn(char *s1, char *s2, char *s1_end, char *s2_end)
{
register const char *p, *spanp;
register char c = *s1;
for (p = s1;;) {
spanp = s2;
do {
if (*spanp == c || p == s1_end) {
return p - s1;
}
} while (spanp++ < (s2_end - 1));
c = *++p;
}
/* NOTREACHED */
}
- PHPAPI size_t php_strcspn(char *s1, char *s2, char *s1_end, char *s2_end)
- {
- register const char *p, *spanp;
- register char c = *s1;
-
- for (p = s1;;) {
- spanp = s2;
- do {
- if (*spanp == c || p == s1_end) {
- return p - s1;
- }
- } while (spanp++ < (s2_end - 1));
- c = *++p;
- }
- /* NOTREACHED */
- }
Any time strcspn returns a number other than zero, there's bad characters in the input and we overwrite the entire bad input with the default value. This is just a simple course of action after finding bad input, in reality you would probably end up looking for possible typos, check a 301 table, or something along those lines.
Now, as far as that trick for remembering which function does which I mentioned earlier, I'll have to borrow a comment from the PHP manual.
strcspn() can also be thought of as analogous to the following regular expression:
<?php
// where ... represents the mask of characters
preg_match('/[^ ...]/', substr($subject, $start, $length) );
?>
- <?php
- // where ... represents the mask of characters
- preg_match('/[^ ...]/', substr($subject, $start, $length) );
- ?>
If I remember strcspn and strspn as character classes from regular expressions, I just have to remember that in a negated character class there is that extra character "^" and in the function name strcspn there is also an extra character "c".
--
I really can't say much about is_readable, I use it in the example because the tone of the conversation seems to be security and mistake-prevension-wise is_readable is less accident prone than something like file_exists. I prefer to use file_exists. I'm pretty good about making sure something is going to work before it goes live, by using defaults the way I do I'm not going to get an error about an unreadable file except in a catastrauphic failure, and there's no reason for my file permissions to change later on.
Strong with this one, the sudo is.