PHP eval () функция - PullRequest
       15

PHP eval () функция

0 голосов
/ 12 марта 2011

PHP функция eval () выглядит довольно интересной функцией. Может кто-нибудь объяснить, почему это работает в данной ситуации, в строке: 14

function Parse($inFrontEnd)
{       
    // Now create an array holding translation tokens with some from above
    // Load translation table into buffer
    $tableLines = file(Utilities::GetRelativePath(TTABLE_DIR).TTABLE); // Array of lines from TTable.cfg
    // Explode by whitespace
    foreach($tableLines as $aLine)
    {
        $lineParts = EXPLODE(' ', $aLine);
        $word = "/".$lineParts[0]."/";
        $definition = $lineParts[1];
        // Add key (word) => value (definition) to array
        // Eval() to return value of the const
        Main::$translateChars[$word] = eval("return $definition;"); 
    }
    // Read data from template file
    $parseArray = file($inFrontEnd); // Load FrontEnd source code into array ready for parse
    /* Perform the translation of template by the translation table defined data */
    $parseArray = preg_replace(array_keys(Main::$translateChars), array_values(Main::$translateChars), $parseArray);
    return $parseArray;
}

Итак, что я здесь делаю, так это чтение шаблона из каталога шаблонов. Файл templatename.php содержит текстовые токены, записанные в виде констант, которые затем переводятся с помощью регулярных выражений, заменяя токены данными, содержащимися в константах с их именами, возвращая, таким образом, полностью проверенную страницу веб-страницы, которая печатается для пользователя. смотреть. Это позволяет страницам быть очень динамичными, позволяя повторно использовать эти токены на многих веб-страницах (шаблонах).

Мой вопрос: у меня некоторое время были проблемы со строкой, которая использует eval (). То, что я пытаюсь сделать, это заполнить массив с каждым ключом, являющимся именем константы, прочитанной из, как я назвал, таблицы перевода (TTable.cfg), которая содержит имя каждого токена и константу с ним связано:

НАЗВАНИЕ НАЗВАНИЯ
CSS_INCLUDE CSS_INCLUDE
SHOW_ALL_POSTS SHOW_ALL_POSTS
...

То есть с протоколом [TOKEN] [CONSTANT] [CR] [LF]

Ключи в массиве были бы созданы нормально, но значения возвращали бы ноль или ломали мой код, когда у меня был связан ключ с: constant ($ definition); Он жаловался, что не может найти объявленные константы. Однако, когда я использую в этой строке eval как есть, каждый ключ связан с: eval ("return $ definition;"); это работает так, как я хочу - значения как данные соответствующих им констант.

Я прошу прощения за длину этого поста. Я не смог найти другого примера для моего вопроса, кроме случая, в котором я его нашел.

Ответы [ 3 ]

2 голосов
/ 12 марта 2011

Значение переменной $definition заменяется на определение строки "return $definition;", так как вы используете двойные кавычки. Следовательно, то, что передается в eval, важно примерно так: "return FOO;", где FOO - значение переменной $ definition.

Теперь этот код оценивается с использованием eval(), и результат возвращается как результат оценки, которая является значением константы FOO (разной на каждой итерации).

Использование constant в этом случае имеет больше смысла: это быстрее, потенциально безопаснее и более читабельно.

if ( defined( $definition ) ) {
    $constval = constant( $definition );
}
else {
    $constval = $definition;
}

Это также даст вам некоторое представление о том, почему это работает при использовании eval(), а не только constant(); PHP заменяет неизвестные константы соответствующими именами, поэтому eval работает в вашем случае. Тем не менее, любой другой способ вызовет предупреждение и станет плохой практикой, поскольку он не дает понять, что происходит с читателем.

1 голос
/ 12 марта 2011

Помните, eval это зло, поэтому не используйте его, когда вы можете избежать его. Здесь вы можете просто использовать constant.

0 голосов
/ 12 марта 2011

Самый крошечный из упущений. Я забыл очистить $ Definition после того, как взорвал его из каждой строки таблицы перевода. Таким образом, простая отделка () решила проблему.

   constant($definition);

Теперь работает.

Сумасшедший: D

...