RequestFactory: optimized script path detection performance

Micro-optimization. 

Benchmark:
~~~php
$datasets = [
	'a' => [new UrlScript('/projects/blog/www/'), '/projects/blog/www/index.php', '/projects/blog/www/'],
	'b' => [new UrlScript('/projects/blog/www/contact'), '/projects/blog/www/index.php', '/projects/blog/www/'],
	'c' => [new UrlScript('/projects/blog/www/index.php'), '/projects/blog/www/index.php', '/projects/blog/www/index.php'],
];

$tests = [
	'old' => function ($testCount, UrlScript $url, $script, $expected) {
		for ($x = 0; $x < $testCount; $x++) {
			$path = strtolower($url->getPath()) . '/';
			$script = strtolower($script) . '/';
			$max = min(strlen($path), strlen($script));
			for ($i = 0; $i < $max; $i++) {
				if ($path[$i] !== $script[$i]) {
					break;
				} elseif ($path[$i] === '/') {
					$url->setScriptPath(substr($url->getPath(), 0, $i + 1));
				}
			}
		}
		Assert::same($expected, $url->scriptPath);
	},
	'new' => function ($testCount, UrlScript $url, $script, $expected) {
		for ($x = 0; $x < $testCount; $x++) {
			$path = $url->getPath();
			$max = min(strlen($path), strlen($script)) - 1;
			for ($i = 0, $j = 0; $i <= $max; $i++) {
				if ($path[$i] !== $script[$i] && strcasecmp($path[$i], $script[$i])) {
					break;
				} elseif ($path[$i] === '/') {
					$j = $i;
				} elseif ($i === $max) {
					$j = $i + 1;
				}
			}
			$url->setScriptPath(substr($path, 0, $j + 1));
		}
		Assert::same($expected, $url->scriptPath);
	},
];

$testCount = 10000;
$padLength = max(array_map('strlen', array_keys($datasets))) + 3;
foreach ($tests as $testName => $testCallback) {
	printf("Test %s:\n", $testName);
	foreach ($datasets as $datasetName => $dataset) {
		$time = -microtime(TRUE);
		$testCallback($testCount, ...$dataset);
		$time += microtime(TRUE);
		printf("  %s%5.0f ms\n", str_pad($datasetName, $padLength), $time * 1e3);
	}
	printf("\n");
}
~~~

Results:
~~~
Test old:
  a    1056 ms
  b    1058 ms
  c    1083 ms

Test new:
  a      58 ms
  b      60 ms
  c      79 ms
~~~

I think it's readable enough. And I would not say that PHP has crappy scope boundaries – they just follow different rules than C/C++ (and other languages, of course).