PHP eval возвращает ноль, но возврат вызывается - PullRequest
0 голосов
/ 12 января 2010

У меня есть, я думаю, довольно простой вопрос, но я не могу понять, что я делаю неправильно. У меня есть функция, которую я вызываю с помощью функции PHP eval. Я ожидаю, что саморазвитый ArrayList получит в результате. Но вместо этого, когда я использую gettype, я вижу результат NULL. Хотя я использую return в функции eval-ed.

Насколько я знаю, я играю это по документации, но почему-то это не работает. Есть предложения?

Фрагмент кода

<?php
                $widgetList = new ArrayList();

                for($i = 0; $i < $selectedTemplate->Regions->count(); $i++)
                {
                    $region = $selectedTemplate->Regions->item($i);

                    if($region->Widget->selectiveContent == 1)
                    {
                        $widgetList->add($region->Widget);
                    }
                }

                if($widgetList->count() > 0)
                {
            ?>
            <tr>
                <td colspan="2">
                    <strong>Widget instellingen</strong>
                    <hr size="1" width="100%" color="#333"/>
                </td>
            </tr>
            <?php
                    for($i = 0; $i < $widgetList->count(); $i++)
                    {
            ?>
            <tr>
                <td class="w150">
                    <?= $widgetList->item($i)->title ?>
                </td>
                <td>
                    <select name="widget_<?= $widgetList->item($i)->id ?>" class="full">
                    <?php
                        $itemList = eval($widgetList->item($i)->functionCall);
                        for($j = 0; $j < $itemList->count(); $j++)
                        {
                            $selected = null;
                            if($_POST["widget_".$widgetList->item($i)->id] == $itemList->item($j)->id)
                            {
                                $selected = " selected=\"selected\"";
                            }
                    ?>
                        <option value="<?= $itemList->item($j)->id ?>"<?= $selected ?>><?= $itemList->item($j)->title ?></option>
                    <?php
                        }
                    ?>
                    </select>
                </td>
            </tr>
            <?php
                    }
                }
            ?>

Eval-ed code

public function getNavigationByLanguageId(Integer $parent, ArrayList $objectList, Integer $language)
    {
        $query  = DataAccess::getAdapter()->query("
                    SELECT      *
                    FROM        `navigation`
                    WHERE       `parent_id`     = ".$parent->value."
                    AND         `language_id`   = ".$language->value."
                    AND         `website_id`    = ". $_SESSION["currentSite"]["id"]."
                    ORDER BY    `sort_order`");

        while($result = DataAccess::getAdapter()->fetchAssoc($query))
        {
            $link = new Model_Navigation();

            $link->id           = $result["id"];
            $link->language     = $result["language_id"];
            $link->parent       = $result["parent_id"];
            $link->Page         = Model_Page::getPageById(new Integer($result["page_id"]));
            $link->title        = $result["title"];
            $link->externalUrl  = $result["external_url"];
            $link->sortOrder    = $result["sort_order"];

            $objectList->add($link);
            Model_Navigation::getNavigationByLanguageId(new Integer($result["id"]), $objectList, $language);
        }

        return $objectList;
    }

Оцениваемая функция: Model_Navigation::getNavigationByLanguageId(new Integer(0), new ArrayList(), new Integer(7));

Еще несколько пояснений по коду Я использую эту функциональность в моей новой CMS. Пользователь может создавать шаблоны и размещать виджеты в определенных областях, почти так же, как и функциональность портлета, предоставляемая jQuery. Я установил виджеты для веб-сайта, я встроил опцию для вызова функции для получения списка объектов, когда виджет помечен как «Выборочное содержимое».

Здесь я пытаюсь добиться использования eval для возврата ArrayLists из значения $ widget-> functionCall.

Ответы [ 4 ]

5 голосов
/ 12 января 2010

В этой строке, что является содержимым $ widgetList-> item ($ i) -> functionCall? $ itemList = eval ($ widgetList-> item ($ i) -> functionCall);

Чтобы eval мог что-либо вернуть, $ widgetList-> item ($ i) -> functionCall ДОЛЖЕН начинаться с токена return

например, если

$widgetList->item($i)->functionCall == 'return myFunc();';

тогда ты в порядке

Но если

$widgetList->item($i)->functionCall == 'myFunc();';

Тогда вот почему eval () ничего не возвращает. Кроме того, следите за любыми ошибками, сгенерированными при выполнении eval () - если ваш код не может разобрать или выдает какие-либо ошибки, это также может объяснить, почему eval () ничего не возвращает.

Вы должны быть в состоянии полностью отказаться от вызова eval, но в худшем случае используйте call_user_func ()

Edit: Для вашего примера:

eval('return Model_Navigation::getNavigationByLanguageId(new Integer(0), new ArrayList(), new Integer(7));');

Это может быть записано как:

call_user_func(array('Model_Navigation', 'getNavigationByLanguageId'), new Integer(0), new ArrayList(), new Integer(7));

Это, вероятно, предпочтительнее, так как избегает накладных расходов на компиляцию, реже ломается и т. Д.

2 голосов
/ 12 января 2010

Если вы запустите

function foo() {
  bar();
}
function bar() {
  return 1;
}
$x=foo();
var_dump($x);

, на выходе будет `NULL '.Хотя bar () возвращает значение, foo () - нет.Возвращаемое значение bar () теряется.То же самое, если вы используете eval ()

function bar() {
  return 1;
}
$x=eval('bar();');
var_dump($x);
$x=eval('return bar();');
var_dump($x);

print

NULL
int(1)
1 голос
/ 12 января 2010

Eval - зло (и в большинстве случаев хакерское). Я бы предложил опубликовать ваш код, и мы можем покончить с этой частью кода для вас.

0 голосов
/ 12 января 2010

Если вы запускаете код вне функции eval, и он в порядке, то вам, вероятно, нужно проверить документацию по функции eval ()

Убедитесь, что строка, которая будет «оценена», «не неправильная» / отформатирована правильно.

...