include — Возможно ли для сценария командной строки PHP обновить себя и перезапустить с новым кодом?

Много месяцев назад, когда я только начинал программировать, я кодировал MUD (многопользовательская Dungeon — текстовая «MMO» для еще до того, как в интернете появились картинки, для всех вас, молодые!). Он был написан на C, и я выучил тонну, и одна из самых крутых вещей, которые я узнал во время кодирования этой грязи, было создание отдельных областей кода, скомпилированных в виде связанных библиотек (я так полагаю, так они называются? закодирован в C), и я смог динамически обновлять / изменять код игры без необходимости выключать его / перезагружать. Отключите старую библиотеку, переместите новую на место, снова включите, включите эту функцию.

Сегодня: у меня есть скрипт командной строки PHP, который выполняет некоторые задачи сервера. Перед лекцией, да, я знаю, что это не лучший / самый эффективный язык, чтобы делать это. Но из-за определенных факторов, это язык, на котором написано прямо сейчас.

Скрипт, который я запускаю, на самом деле выполняется на 4 разных серверах, и когда он запускается, есть вызывающий скрипт, который запускает wget, чтобы получить обновленный «основной» код с главного сервера, включает его и запускает. Вот код:

#!/usr/bin/php -q
<?php
echo "Grabbing latest code...\n";
`wget -N http://blahblahblah.php`;
`wget -N http://blahblahothercode.php`;

include('blahblahblah.php');
?>

Итак, мой вопрос — возможно ли, пока он работает, обновить свой собственный код и перезагрузить себя? Мое текущее решение — это выйти () после использования команды оболочки ‘at’ для перезапуска. Неуклюжий, но он может достичь цели.

Проблема заключается в том, что при запуске сценария он получает ключ шифрования из стандартного ввода, который необходимо ввести при запуске сценария. Я никогда не хочу, чтобы этот ключ сохранялся на диске где-либо (я не хочу, чтобы ключ, сохраненный во временном файле, был снова считан или в любой истории команд для ‘at’). ИДЕАЛЬНО, я бы хотел оставить ключ в памяти и просто «заменить» работающий код. Если это даже возможно с PHP.

Когда мы в конечном итоге переделываем это в C ++, у нас есть выбор библиотек, но на данный момент, есть ли способ сделать это в PHP?

Просто подумал, прежде чем я нажму на submit … когда PHP нажимает на команду include, он выполняет включение один раз при запуске или запускает включение каждый раз, когда видит это? Это может быть вариант, если я зациклился на включении …?

0

Решение

Согласно комментарию (копия / вставка):

Существует только 1 способ, и он называется надзором за процессом. Вы форкаете, когда ваш родительский процесс содержит эту информацию о кодировке. ключ (в переменной). Теперь самое интересное — ребенок — это бегущий код. Теперь, что вы делаете — вам нужно обнаруживать изменения в файлах (цикл обработки событий, stat () с опросом — все, что вы можете использовать). Как только вы обнаружите изменение, произошедшее в дочернем процессе, он убивает себя (выход, смерть, что угодно). Теперь мы возвращаемся к родителю — родитель получает сигнал о том, что его дочерний элемент вышел. Вы снова загружаете его (да, снова разветвляетесь). Повторите навсегда. Тем не менее, ваш ключ находится в памяти и может быть найден так.

Обновление: я использовал этот подход некоторое время, однако я также использую расширение LibEV и PHP для работы с ним, чтобы реагировать на события статистики (изменения файла). Вы можете посмотреть расширение здесь: https://github.com/m4rw3r/php-libev

0

Другие решения

Есть способ, но он, вероятно, не будет красивым. Основная проблема заключается в том, что большинство вещей (функций, классов и т. Д.) В PHP именуются и, будучи определенными, не могут быть переопределены.

Вы можете обойти это, используя только анонимные функции и объекты; таким образом, вы можете просто включить модуль снова, и он просто переопределит старые анонимные функции новыми. Вы получите что-то похожее на код LUA или JavaScript.

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

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

0

Вы всегда можете использовать

eval('?>' . file_get_contents('updated.php') . '<?php ');

Я бы избежал этого уродливого подхода, хотя.

Приветствия.

0
По вопросам рекламы [email protected]