0

I have inherited some old code and need to convert the create_function to an anonymous function. I have done that but since I cannot see the code in the anonymous function I do not know if it equals the code in the former create_function.

Here is the code and my question is: is 'my translation' equal to the 'original code'?

public static function makePhpVdtorFromRegex($regex, $match = TRUE)
{
    //original code
    $s = 'return '.($match?'':'0 == ').'preg_match(\'/'.addslashes($regex).'/\',$v);';
    return create_function('$v', $s);

    // my translation
    return function($v) use ($regex, $match) {
        return ($match?'':'0 == ').preg_match('/'.addslashes($regex).'/',$v);
    };
}

I believe makePhpVdtorFromRegex stands for 'Make PHP Validator From Regex'. The problem in validating this is I am not sure where the actual validator is used as this anonymous function is stored in an array which is used to validate input at some later time doing form input validation.

Because $regex and $match only exist within makePhpVdtorFromRegex() they will not be available when the validator is ultimately run, right? So I suspect my translation is not going to work?

2
  • Make a few test cases and test. Since you're using use you'll effectively bind the created function to the values from the outer call (what's called a closure, since you'll "close" over the given variables and their value will be kept from what their value was when the function was created). Commented Apr 8, 2021 at 20:58
  • Thanks. Did not know use() bound to the original values. Commented Apr 9, 2021 at 16:29

1 Answer 1

1

To mimic the original behaviour, you should be able to replace it with (for testing purposes, I turned the method into a function):

function makePhpVdtorFromRegex($regex, $match = true) {

    if ($match) {

        return function($value) use ($regex) {

            return preg_match('/'.addslashes($regex).'/', $value);
        };
    }
    
    return function($value) use ($regex) {
        
        // Same as '0 == preg_match(...)' from original code
        return !preg_match('/'.addslashes($regex).'/', $value);
    };
}

$validator = makePhpVdtorFromRegex('^[a-z]+$');

// Check if something matches

var_dump($validator('abc')); // true

// Check if something doesn't match
 
$validator = makePhpVdtorFromRegex('^[a-z]+$', false);

var_dump($validator('123')); // true

If you've the chance to look into the actual form validation later on & maybe even take control of the regular expressions themselves, you could rewrite this code to something much simpler, like:

function getRegexValidator() {

    return function($regex, $value) {

        return preg_match($regex, $value);
    };
}

$validator = getRegexValidator();

// Check if something matches

var_dump($validator('/^[a-z]+$/', 'abc')); // true

// Check if something doesn't match

var_dump(!$validator('/^[a-z]+$/', '123')); // true
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks. I had the same thought that it would be more elegant to create a different anonymous function depending on the value of $match so just pasted your code. After about 8 hours I finally found where the validator is used and can confirm it matches the old create_function result. As far as your future suggestion this shopping cart was purchased from a vendor over 10 years and was built generically to handle dozens if not hundreds of customers. Hence, nothing seems to be straightforward and I am changing as little as possible to keep the gears running as before.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.