Предварительная компиляция файлов PHP - программирование
Подтвердить что ты не робот

Предварительная компиляция файлов PHP

В качестве учебного упражнения я пытаюсь сохранить скомпилированное состояние файла PHP, чтобы выполнить его позднее, без необходимости повторного просмотра zend_compile_file.

Первым делом я написал расширение, которое перехватывает zend_compile_file. Если запрос сделан для некомпилированного файла (например, file.php), он zend_op_array данные zend_op_array в другой файл (например, compiled-file.php). Если запрос сделан для такого скомпилированного файла, он загружает данные в новый zend_op_array и затем возвращает его.

Для простоты я проигнорировал все, что связано с классами и функциями, поэтому я не ожидаю, что мое расширение будет работать над сценарием, который содержит их. Но другие более простые сценарии должны работать, я думаю?

Ну, он работает на очень простых скриптах, но часто просто зависает и достигает максимального времени выполнения. Я обнаружил, что это всегда дает сбой на ложной условной ветки Например, этот скрипт будет работать:

<?php
$a = 10;
$b = 5;
if ($b < $a)
    echo $a;

Пока этот просто виснет

<?php
$a = 10;
$b = 5;
if ($b > $a)
    echo $a;

Мой вопрос: правильно ли я предположить, что для простых сценариев без функций или классов достаточно сделать zend_op_array копию zend_op_array и вернуть ее для репликации компиляции PHP? Если нет, какие еще шаги я должен предпринять, чтобы это заработало?

Вот соответствующие файлы моего расширения: opdumper.c oploader.c

РЕДАКТИРОВАТЬ: мне удалось "исправить" мою проблему, изменив этот код:

void dump_znode_op(FILE* fp, znode_op node, zend_uchar type)
{
    fwrite(&type, sizeof(type), 1, fp);
    switch(type) {
        case IS_UNDEF:
        case IS_UNUSED:
            break;
        ...
    }
}

к этому:

void dump_znode_op(FILE* fp, znode_op node, zend_uchar type)
{
    fwrite(&type, sizeof(type), 1, fp);
    switch(type) {
        case IS_UNDEF:
        case IS_UNUSED:
            fwrite(&(node.var), sizeof(node.var), 1, fp);
            break;
        ...
    }
}

(И, конечно, применяя подобное исправление к oploader.c)

Теперь я еще больше запутался... почему znode_op с типом IS_UNUSED заботится о его значении!??

4b9b3361