7

I have a website which contains a search box which allows a user to enter a pattern which is then checked against large strings to see are there any matches within these strings for the user specified pattern. This is done using the PHP function preg_match().

However the problem occurs when the user enters an invalid pattern e.g one which causes an error like:

preg_match() [function.preg-match]: Unknown modifier.

The search feature needs to be able to handle any errors thrown by the preg_match() method and display a general pattern invalid message on the screen. I've looked online but I can't find a one catch all way of catching any error preg_match() can throw, anyone got any ideas?

AbraCadaver
  • 78,200
  • 7
  • 66
  • 87
olliejjc16
  • 361
  • 5
  • 20
  • Have you put it in a try/catch structure? – Jay Blanchard Apr 28 '16 at 15:35
  • preg doesn't throw exceptions... – Marc B Apr 28 '16 at 15:37
  • 1
    `set_error_handler()` and throw away... – AbraCadaver Apr 28 '16 at 15:40
  • Or just use http://php.net/manual/en/function.preg-quote.php – Mike Apr 28 '16 at 15:43
  • @Mike: Escapes but doesn't correct. Consider `/.*` missing delimiter, or `/.*/-` unknown modifier, etc... – AbraCadaver Apr 28 '16 at 15:46
  • @AbraCadaver I was thinking more along the lines of providing your own modifier instead of letting the user provide it and then just quote whatever string they provide, but reading the question again that probably wouldn't work, unless you want to allow limited search functionality. – Mike Apr 28 '16 at 15:50
  • 1
    See also: http://stackoverflow.com/questions/4440626/how-can-i-validate-regex – Mike Apr 28 '16 at 15:51
  • Hi all thanks for the help, I ended up using an @ before preg_match to suppress the errors as displayed in mikes link so thanks mike for that! – olliejjc16 Apr 28 '16 at 16:08
  • 1
    That was a good answer, however I thought it would be better to display the specific error, not just suppress and state _There was some error_. – AbraCadaver Apr 28 '16 at 18:24

3 Answers3

5

Try: preg_last_error() Detail page: http://php.net/manual/en/function.preg-last-error.php

Vijay
  • 491
  • 5
  • 3
3

For a simple example, set an error handler and throw an Exception or ErrorException:

function exception_error_handler($severity, $message, $file, $line) {
    throw new ErrorException($message, 0, $severity, $file, $line);
}
set_error_handler("exception_error_handler");

Then try/catch:

try {
    preg_match('/.*/hello', 'hello');
} catch (Exception $e) {
    echo 'Caught exception: ',  $e->getMessage(), "\n";
}

Caught exception: preg_match(): Unknown modifier 'h'

AbraCadaver
  • 78,200
  • 7
  • 66
  • 87
  • Unfortunately, not all regex errors can be caught this way. E.g. an invalid char encoding of the source string just made a `preg_match_all` in my project silently return `false`. (`preg_last_error` reported `PREG_BAD_UTF8_ERROR`, but no exception was ever raised. I did double-check with an unknown modifier, it had thrown happily.) – Sz. Nov 05 '17 at 23:30
0

Since PHP 8 you can also preg_last_error_msg() to get a human readable error message, as in:

if (preg_last_error() !== PREG_NO_ERROR) {
    throw new Exception(preg_last_error_msg());
}
Roben
  • 840
  • 9
  • 19