0

I am trying to create a class to clean data for a brand before adding it to my database. As you can see I have added general filters (which can be used elsewhere). On the other hand, some fields will need a personalized cleaning. That's why I created 'function' in my array. My code is currently functional however the "create_function" function is deprecated and I would like to remove it but I cannot find an alternative without using "eval". Can you help me find a solution? Thank you.

<?php
class VehMarques
{
    private static $fields_allowed = [
    
    '_id' =>    
    [
        'instanceof' => '\MongoDB\BSON\ObjectID',
    ],
                
    'name' => 
    [
        'function' => 'if(!isset($name) && !isset($age)){return false;}',
    ],
                
    'user' =>
    [
        'required',
        'instanceof' => '\MongoDB\BSON\ObjectID',
    ],
    
    'centre' =>
    [
        'required',
        'instanceof' => '\MongoDB\BSON\ObjectID',
    ],
    
    'time' =>
    [
        'instanceof' => 'MongoDB\BSON\UTCDateTime',
    ],
    
    ];
    
    public static function add(array $fields)
    {
        $fields_options=array();
        foreach(self::$fields_allowed as $key => $val)
        {
            foreach($val as $key1 => $val1)
            {
                if(in_array($val1, array('required')))
                {
                    $fields_options[$val1][$key] = null;
                }
                else
                {
                    $fields_options[$key1][$key] = $val1;
                }
            }
        }
        
        if(!empty(self::$fields_allowed) && !empty(array_diff_key($fields, self::$fields_allowed)))
        {
            return false;
        }
        
        if(!empty($fields_options['function']))
        {
            foreach($fields_options['function'] as $func)
            {
                $func = preg_replace('/\$([a-zA-Z0-9]+)/', '$fields[\'$1\']', $func);
                
                if(create_function('$fields', $func)($fields) === false)
                {
                    return false;
                }
            }
        }
        
        if(!empty($fields_options['required']) && !empty(array_diff_key($fields_options['required'], $fields)))
        {
            return false;
        }
        
        if(!empty($fields_options['instanceof']))
        {
            foreach($fields_options['instanceof'] as $key => $val)
            {
                if(!($fields[$key] instanceof $val))
                {
                    return false;
                }
            }
        }
        
        if(!isset($fields['_id']))
        {
            $fields['_id'] = new \MongoDB\BSON\ObjectID();
        }
        
        if(!isset($fields['time']))
        {
            $fields['time'] = new MongoDB\BSON\UTCDateTime();
        }
        
        return true;
    }
}

$insert_marque = array(
'_id' => new \MongoDB\BSON\ObjectID(),
'name' => 'Test',
'user' => new \MongoDB\BSON\ObjectID(),
'centre' => new \MongoDB\BSON\ObjectID(),
'time' => new MongoDB\BSON\UTCDateTime()
);

var_dump(VehMarques::add($insert_marque));
?>
  • 2
    `create_function` *was* using `eval` behind the scenes anyway. What are you trying to achieve, exactly? Sounds like a XY problem to me. – Jeto Dec 31 '20 at 10:02
  • You won't be able to convert this exactly; PHP doesn't allow you to store anonymous functions in a static class property. But yes, knowing your actual use-case would help. – iainn Dec 31 '20 at 10:07
  • I'm trying to create a class to analyze the data before adding it to the database. Check the number of characters in a string, if the field is authorized, if the field is required etc. And for some fields, create a custom analysis function. – Alexis Bonnyaud Dec 31 '20 at 10:08
  • If these analysis functions aren't stored anywhere except in your PHP files, then why use strings as opposed to functions/objects with proper methods? You could even use anonymous functions. – Jeto Dec 31 '20 at 10:12
  • I would like to do a general analysis class and not add code to the general class that will only be used for a single field. And so used a custom function in this case. – Alexis Bonnyaud Dec 31 '20 at 10:17
  • I just edited my post to better show my use case. Can you look ? Thank you. – Alexis Bonnyaud Dec 31 '20 at 12:23
  • You can either define your filters as [callables](https://www.php.net/manual/en/language.types.callable.php) or redesign the whole thing and invoke some interfaces. – Álvaro González Jan 01 '21 at 13:29

0 Answers0