1

So, in the process of trying to bug fix an unexpected error, I have come to the conclusion that the following is somehow unacceptable in php:

$pattern = "/\/sc2\/en\/profile\/693604\/1\/EGIdrA\/ladder\/";
$subject = "\/sc2\/en\/profile\/693604\/1\/EGIdrA\/ladder\/";
preg_match($pattern, $subject, $result);

I have no idea how or why - all I know is that if I have this line, then various debugging echoes of various words at various locations both before and after this line are no longer echoed. There are no loops anywhere, so I am quite confused as to why this is causing a problem.

phihag
  • 278,196
  • 72
  • 453
  • 469
Zhe Zhang
  • 11
  • 3
  • So after this line the page just does nothing? Have you excluded this and tested it in a new script? – TJHeuvel May 27 '11 at 08:07
  • Yes, after this line, which is expected to return false, the page does nothing. Furthermore, if this line is here, then some things before this line no longer function either. Commenting out this line fixes everything. What I mean is, for example, echo "Test line 1"; //The line in question echo "Test line 2"; IF the line in question is not commented out, then neither "Test line 1" nor "Test line 2" get echoed. If however I comment out the line, then both test lines are echoed. If I fix the preg_match() so that there is a match, then no such error occurs. – Zhe Zhang May 27 '11 at 08:17
  • You've introduced a syntax error `$subject ='...'l` in process of editing the question too. But I couldn't change it as edits must be at least 6 characters different. – Adam Lynch May 27 '11 at 08:17
  • And just to be clear - the each echo and the line in question are on their own line. Apparently I can't newline in comments here :/ – Zhe Zhang May 27 '11 at 08:17
  • Yea, the 1 at the end of line 2 is supposed to be a ; but that syntax error is of course not in the code. – Zhe Zhang May 27 '11 at 08:18

3 Answers3

4

There is no need to escape slashes in strings. '\/' is the same as '\\/', i.e. the string \/.

In regular expressions, \/ escapes a slash if you're using slashes to terminate the expression. You don't need that, simply choose another terminator, like #:

preg_match('#^/sc2/en/profile/693604/1/EGIdrA/ladder/$#',
           '/sc2/en/profile/693604/1/EGIdrA/ladder/', $result);

A single call to preg_match does not halt execution of a program. However, a variety of errors and warnings can be emitted - for example, you're missing a terminating / in the regular expression which yields

PHP Warning:  preg_match(): No ending delimiter '/' found

Check your server's php settings (namely error_reporting and log_errors) for warning and error output configuration. On many systems, /var/log/apache*/error.log contains all php errors and warnings. Note that a set display_errors can modify the output and make it an invalid XML document or confuse advanced output buffering.

phihag
  • 278,196
  • 72
  • 453
  • 469
  • My PHP error log actually shows no errors within the last 10 hours. Actually have a further even more confusing result, wherein matches are found but print_r is not printing correctly... for instance my output is Array ( [0] => Note the lack of closing brace.. – Zhe Zhang May 27 '11 at 08:50
  • @Zhe Zhang That means it is probably misconfigured. In a development environment, you should always set `error_reporting = E_ALL | E_STRICT` (you can check with `phpinfo()`). It would be great if you could produce a minimal `print_r` example that just prints out `Array ( [0] =>` and ask why in a new question (maybe give me a pointer). – phihag May 27 '11 at 08:54
  • Ah... it's a negative preg_match result that is causing the print_r to break mid execution... really weird. – Zhe Zhang May 27 '11 at 09:03
  • Curiously if I copy paste it in to a new file a negative preg_match result does NOT cause execution break. Instead print_r shows an empty array like I expect. – Zhe Zhang May 27 '11 at 09:05
  • Meh, 2shared turned into an html file, but here it is: (I bet I did some horrrrible mistake at 5am haha) http://www.2shared.com/file/J8mhTLoB/bnet_parser.html – Zhe Zhang May 27 '11 at 09:06
  • @Zhe Zhang That means surrounding code is responsible for the problem. Is the array recursive? Are you using output buffering? Edit: NVM, looking at the code ... – phihag May 27 '11 at 09:07
  • I managed to create a short 8 line bit of code which exhibits the same breaking of output. Whatever is causing is there is likely the same as in the larger file: http://www.2shared.com/file/SzeWK344/testbug.html – Zhe Zhang May 27 '11 at 09:18
  • @Zhe Zhang I got a shorter one: `print_r(array(' – phihag May 27 '11 at 09:23
  • Ah. Though, the pattern '/ – Zhe Zhang May 27 '11 at 09:27
  • @Zhe Zhang Got it! It's a chromium/chrome bug. Works fine with firefox. You can temporarily add `header('Content-Type: text/plain');` on top of the php document to make the problem go away. – phihag May 27 '11 at 09:28
  • omg wtf it magically matches up and works now, how the hell did you ever think of that O.O – Zhe Zhang May 27 '11 at 09:30
  • And what's the cause of that chrome bug anyways, just curious if you happen to know. – Zhe Zhang May 27 '11 at 09:31
  • @Zhe Zhang I filed a bug report, should be fixed relatively soon: http://code.google.com/p/chromium/issues/detail?id=84179 . By the way, I can't not notice you are parsing HTML with regular expressions. In many cases, it's way easier to parse HTML with XML+xpath. – phihag May 27 '11 at 10:02
2

Here's why:

preg_match('/^\/$/', '\/'); // false
preg_match('/^\/$/', '/'); // true
Denis de Bernardy
  • 75,850
  • 13
  • 131
  • 154
  • Hmm, I expected it to return false, but what surprised me was that it completely broke execution of the script, in that test echoes no longer appeared. – Zhe Zhang May 27 '11 at 08:09
  • oops, didnt mean to hit enter. But, changing it did fix everything. Do false returns really screw with script execution that much? o.o – Zhe Zhang May 27 '11 at 08:09
0

You should not escape slashes / in input string, it's enough to escape them in pattern

preg_match('/^\/sc2\/en\/profile\/693604\/1\/EGIdrA\/ladder\/$/',
       '/sc2/en/profile/693604/1/EGIdrA/ladder/', $result);

(or like phihag mentioned, use i.e. # for pattern termination)

petho
  • 677
  • 4
  • 10
  • Is having the escape slashes in the input what caused the line to not execute though? I did expect it to not match - but I didn't expect it to halt script execution. – Zhe Zhang May 27 '11 at 08:23
  • @Zhe Zang No, not exactly. I updated my answer thusly. Please note that `echo` is not a reliably debugging utility due to output (and other) buffering. I updated my answer to include a short primer on warning and error logging. – phihag May 27 '11 at 08:49
  • i would say that "escaping" slashes in input isn't really escaping slashes, since they are not expected to be escaped(in input string you would only escape quotes like \' ). So parser doesn't know what to do with escaping slash, since it's not escaping anything. You have to or not use \ or if you want it in that input string use \\ – petho May 27 '11 at 08:59