jjwdesign
jjwdesign

Reputation: 3322

PHP: How to parse template expressions without eval()

I have a complex object with both objects and arrays. It's too large to post the data object here (defined as $this->data in my class). I also have a configuration file with simple "{{name.something}}" template expressions. I'm trying to write a simple expression parser to parse the configuration strings, such as "{{patient.firstname}}".

Example Expressions:

{{patient.firstname}}, {{patient->firstname}} or even {{patient.customfields[0].customfieldvalue}}

The code below seems to work well. Now that I've got it working, I'm questioning the usage and safety of the eval() function. The config file does not include any user entered data. Is this code safe? Is there a way to re-write this without eval()?

<?php
// Note - This is only part of the class.

/*
 * Parse Template Value Expressions
 * Allows complex object data to be used. Examples:
 * {{patient.firstname}}, {{patient->firstname}} or even {{patient.customfields[0].customfieldvalue}}
 */
private function _parseDataValue($value = '') {

    // Parse Template Expressions: Allows data input to be used {{name}}, {{name1.name2}}, etc
    if ($value != '' && preg_match('/\{\{([a-z0-9\-_\[\]\>\.]+)\}\}/i', trim($value))) {
        $value = preg_replace_callback('/\{\{([a-z0-9\-_\[\]\>\.]+)\}\}/i', 
                array(&$this, '_buildDataCallback'), trim($value));
    }
    return $value;
}

/*
 * Parse Template Value Expressions Callback Method
 */
private function _buildDataCallback($matches) {

    $out = '';
    if (isset($matches[1])) {
        $var = $matches[1];
        @eval("\$out = \$this->data->$var;");
    }
    return $out;
}

?>

Upvotes: 0

Views: 293

Answers (1)

Fredster
Fredster

Reputation: 776

You can use curly braces to get an object's property with a variable name.

(PHP dynamic name for object property)

I think this would replace your usage of eval():

 <?php
  $out = $this->data->{$var};

Upvotes: 1

Related Questions