I don't think there's anything wrong with relying on native functions, but if you are just trying to figure out how something like strpos could work behind the scenes, here is a very basic example that only uses language constructs:
function my_strpos ($haystack, $needle, $offset = 0) {
// for loop with indexes for both strings, up to the length of $haystack
for ($h_index=$offset, $n_index=0; isset($haystack[$h_index]); $h_index++, $n_index++) {
if ($haystack[$h_index] == $needle[$n_index]) { // *CHARACTERS MATCH*
if (!isset($start_pos)) $start_pos = $h_index; // set start_pos if not set
if (!isset($needle[$n_index + 1])) return $start_pos; // all characters match
} else { // *CHARACTERS DON'T MATCH*
$n_index = -1; // reset $needle index
unset($start_pos); // unset match start pos.
}
}
// all charactes of $haystack iterated without matching $needle
return false;
}
This is obviously a naive implementation which doesn't check for valid input or handle errors, but hopefully it will demonstrate one possible method of finding one string within another.
If you really want to know how strpos does work behind the scenes, here is a great (although a bit dated) article about how to understand the PHP source, that happens to use strpos as an example.