0

i'm trying to create a table view helper in Zend Framework , it takes an array of models and generate an html table that displays the model properties.

The user can add extra columns to display operations like update ,delete models ,.

so the user can add a string like that

  $columnContent =   '<a href=\'update/$item[id]\'>update</a>' ; 

note that i use simple quotes to cache the string to be evaluated later

my problem is , is there a way to evaluate that string in a context , later on ?

so i need to mimic the " " behavior of strings in Php , thanks.

something like :

// in the context , where $item is a row of an array of models :

$myVar = evaluatemyString($columnContent);

EDIT :

i'm not looking for the eval function which doesnt work in my case , ( i think ).

EDIT 2 :

i need to put the result of the in a variable too.

mpm
  • 20,148
  • 7
  • 50
  • 55
  • 7
    Eeeeeeeeeeeeeeeek. Want you want to do looks soooooooooo wrong. – PeeHaa Apr 16 '12 at 19:45
  • 2
    Not only Eeeeeeek (which is a matter of taste), but this has been asked (and answered) before - possible duplicate of [PHP dynamically accessing variable value](http://stackoverflow.com/questions/8356464/php-dynamically-accessing-variable-value) – hakre Apr 16 '12 at 19:51
  • well , i dont want to developp a template engine just for that, and it is not the same as "eval" just that i want to deffer the "rendering" of the string. – mpm Apr 16 '12 at 19:53
  • What you want to do is called "string interpolation". If you are going to re-create string interpolation you can do this with preg_replace_callback. Optionally, instead of passing to $columnContent a string, you could pass it a function (lambda) which returns your desired string. You just need to feed your lambda a context when you call it. – Wil Moore III Apr 16 '12 at 22:12
  • yeah , that's what i finally ended up doing anyway , given the "eval" outrage , wish it was ruby :)... – mpm Apr 16 '12 at 23:13

3 Answers3

0

The eval function in PHP

eval($columnContent);
mamadrood
  • 739
  • 5
  • 12
  • 3
    What do you think will that eval call do? I'd say, it gives you errors and that's all. – hakre Apr 16 '12 at 19:49
  • i dont want to directly print the content of the string , i need to put it in a variable. – mpm Apr 16 '12 at 19:54
  • So... `$var = eval('return "' . $columnContent. '"')` could work. – mamadrood Apr 16 '12 at 19:55
  • @mamadrood I still think you shouldn't do that. Read: you just should NEVER EVER do that. However your syntax is still wrong. It should be: `$test = eval('return "' . $columnContent . '";');` Again **DON'T** do it :-) – PeeHaa Apr 16 '12 at 20:00
  • @RepWhoringPeeHaa why not ? it is perfectly safe code unless someone hacks my source , but i'd have to fix other problems in that case. – mpm Apr 16 '12 at 20:08
  • @camus I wouldn't need to 'hack' your source when I can add anything in `$columnContent` as a user. – PeeHaa Apr 16 '12 at 20:09
0

Use "templates" (the quotes are intended) instead. Have a look at intl, especially messageformatter. Also there are the good old printf()-functions (inlcuding sprintf() and so on)

KingCrunch
  • 128,817
  • 21
  • 151
  • 173
  • printf/sprintf doesnt work in my case , i'll take a look at templates , but basically , i have 2 choices , do that or use callbacks , but i dont want to have to write callbacks eachtime i invoke my helper , what's the point of writing helpers then. – mpm Apr 16 '12 at 20:06
0

Here is a simple UTF-8 safe string interpolation example. The regular expression forces variables with the following rules:

  1. Prefixed with @
  2. object:property notation (denotes an associative array key "object" whose value is also an associative array)

In other words, instead of variables like: $item[id] You will have variables like: @user:id

<?php

// <a href="update/@user:name">update</a>
//$template = '<a href="update/@user:name">update</a>';

// <a href="update/500">update</a>
$template = '<a href="update/@user:id">update</a>';

// fixture data
$db[499]  = array('user' => array('id' => 499));
$db[500]  = array('user' => array('id' => 500));

// select record w/ ID = 500
$context  = $db[500];

// string interpolation
$merged = preg_replace_callback('/@(?:(?P<object>[^:]+):)(?P<property>[\w][\w\d]*){1}/iu', function($matches) use($context) {
  $object   = $matches['object'];
  $property = $matches['property'];

  return isset($context[$object][$property])
       ? $context[$object][$property]
       : $matches[0];
}, $template);


echo "TEMPLATE: ${template}", PHP_EOL;
echo "MERGED  : ${merged}",   PHP_EOL;
Eric
  • 95,302
  • 53
  • 242
  • 374
Wil Moore III
  • 6,968
  • 3
  • 36
  • 49