Can delimiter errors be missing in preg / PHP regexp programmatically?
I need to determine if a regex is valid so that invalid ones can gracefully be rejected in the UI. Stack overflow is a clever abomination to do this with another regex that I plan to strenuously avoid.
There is a much simpler approach of doing match and error checking that returns the correct boolean result, but it would be interesting to get the reason for the failure / message as well:
// The error is that preg delimiters are missing
$testRegex = 'Location: (.+)';
// This bit is fine
$result = preg_match($testRegex, ''); // returns false i.e. failure
$valid = is_int($result); // false, i.e. the regex is invalid
// Returns PREG_NO_ERROR, which means no error occured
echo preg_last_error() . "\n";
If I run this I get it right:
PHP Warning: preg_match (): delimiter must not be alphanumeric or backslash in ... on line ...
However, the output of the error function 0
, which is PREG_NO_ERROR
. I would think this would return a non-zero error code - and it would be even better if I could get a clean version of the warning message.
It is of course possible that this is not available at all (i.e. only available for PHP's engine to print a warning). I am running 5.5.3-1ubuntu2.6 (cli)
.
source to share
This should work for you:
Here I am just enabling output buffering with ob_start()
. Then I commit the last error with error_get_last()
. Then I finish buffering the output ob_end_clean()
. After that you can check if the array is empty and if no error occurred.
ob_start();
$result = preg_match(".*", "Location: xy");
$error = error_get_last();
ob_end_clean();
if(!empty($error))
echo "<b>Error:</b> " . $error["message"];
else
echo "no error found!";
output:
Error: preg_match (): No ending delimiter '.' found
EDIT:
If you want, you can create your own error handler which basically just throws an exception for every error you usually get.
Then you can put your code in a block try - catch
and catch the exception.
set_error_handler(function($errno, $errstr, $errfile, $errline, array $errcontext) {
// error was suppressed with the @-operator
if (0 === error_reporting()) {
return false;
}
throw new ErrorException($errstr, 0, $errno, $errfile, $errline);
});
try {
$result = preg_match(".*", "Location: xy");
} catch(Exception $e) {
echo "<b>Error:</b> " . $e->getMessage();
}
Code for an error handler from Philip Gerber in this answer
source to share
Perhaps you could use error_get_last()
to get a little more information.
Array
(
[type] => 2
[message] => preg_match(): Delimiter must not be alphanumeric or backslash
[file] => /Users/ivan/Desktop/test.php
[line] => 6
)
type
- E_WARNING
and you can safely guess the function name string from the part message
, as it will always be in the same format.
Then you can do
$lastError = error_get_last()['message']; // php 5.5 expression
if(strpos($lastError, 'preg_match(): ') === 0){
$error = substr($lastError, 14);
}
And $error
will be var_dump
'ed up
string(47) "Delimiter must not be alphanumeric or backslash"
Or a null
Also, in response to another answer, you can turn off warnings using @preg_match(...)
so that you don't have to handle the output buffers yourself. error_get_last()
will catch the error anyway.
source to share