Можно ли динамически перезагружать PHP-код во время работы скрипта?
у меня есть многопользовательский сервер, который использует PHPSockets и, таким образом, полностью написан на PHP.
в настоящее время, когда я делаю какие-либо изменения в PHP server-script, я должен убить скрипт, а затем запустить его снова. Это означает, что любые пользователи онлайн отключены (обычно это не проблема, потому что на данный момент их не так много).
теперь я переписываю сервер-скрипт, чтобы использовать пользовательские классы PHP и сортировать вещи немного (вы не хотите знаешь, как противно это выглядит сегодня). Сегодня я думал: "разве нельзя внести изменения в источник php без перезапуска всего скрипта?".
например, я планирую иметь main.php
файл, который включает user.php
, который содержит класс MyUser
и game.php
, который содержит класс MyGame
. теперь предположим, что я хотел бы изменить user.php
и "перезагрузить" сервер, чтобы изменения в user.php
вступает в силу, без отключение каких-либо онлайн-пользователей?
Я попытался найти другие вопросы, которые ответили на это, ближе всего я получил этот вопрос:изменение запущенного скрипта и его перезагрузка без его убийства (php), что, однако, не решает проблему отключения онлайн-пользователей.
обновление
мои собственные решения этого были:
- в особых случаях включите файл external.php, к которому можно получить доступ несколько переменных и используйте их, как хотите. При этом я должен был убедиться, что в коде нет ошибок, так как весь сервер рухнет, если я попытаюсь получить доступ к несуществующему методу.
- перепишите все это на Java, что дало мне возможность добавить систему плагинов с использованием динамической перезагрузки классов. Работает как заклинание. Прощай РНР.
7 ответов
разве нельзя внести изменения в источник php без перезапуска всего скрипта?
[...]
Я планирую иметь main.php-файл, который включает пользователей.РНР который содержит класс MyUser
в вашем случае, вы не можете. Классы могут быть определены только один раз за выполнение скрипта. Вам нужно будет перезапустить скрипт, чтобы переопределить эти классы.
Я не слишком хорошо знаком с PHP, но я бы предположил, что процесс создан для запуска скрипта, при этом он копирует инструкции, необходимые для запуска программы, и начинает выполнение на CPU, во время этого, если бы вы "обновили" инструкции, вам нужно было бы убить процесс ultimate и перезапустить его. Включает в себя причудливый способ связывания ваших классов и файлов вместе, но в конечном итоге процессор будет иметь эту информацию отдельно от того, где файл из них хранится, и это в конечном счете разные, пока вы не перезапустить процесс.
Я не знаю ни одной системы, в которой вы можете создавать код и активно редактировать его и видеть изменения во время выполнения этого кода. Большинство активных программ требуют перезагрузки для перезагрузки нового исходного кода.
Runkit позволит вам добавлять, удалять и переопределять методы (среди прочего) во время выполнения. Хотя вы не можете изменить определенные свойства класса или существующих экземпляров, это позволит вам изменить поведение этих объектов.
Я не рекомендую это как постоянное решение, но это может быть полезно во время разработки. В конце концов, вы захотите сохранить состояние игры в файлах, базе данных,memcache для, etc.
нельзя include
снова файл с тем же class
, но вы можете сделать это с помощью array
. Вы также можете конвертировать из array
to class
, Если вам действительно нужно сделать так. Это относится только к данным, но не к поведению (методам).
Как насчет хранения объекта пользователя в APC кэш в то время как ваш основной скрипт загружается из кэша и проверяет каждый так часто для нового кода операции.
чтобы включить функцию в кэш, необходимо включить Класс SuperClosure. Примером может служить:
if (!apc_exists('area')) {
// simple closure
// calculates area given length and width
$area = new SuperClosure(
function($length, $width) {
return $length * $width;
}
);
apc_store('area', $area);
echo 'Added closure to cache.';
} else {
$func = apc_fetch('area');
echo 'Retrieved closure from cache. ';
echo 'The area of a 6x5 polygon is: ' . $func(6,5);
}
простое решение используйте $MyUser вместо MyUser
require MyUserV1.php;
$MyUser = 'MyUserV1';
$oldUser = new $MyUser('your name');
//Some time after
require MyUserV2.php;
$MyUser = 'MyUserV2';
$newUser = new $MyUser('your name');
Каждый объявленный класс остается в памяти, но не используется при последнем выходе MyUserV1
вы можете сделать их наследниками абстрактного класса MyUser для использования is_a
Я не знаю много об этих вещах с играми на ПК, но вы можете попробовать, чтобы получить все переменные из базы данных для пользователя, а затем обновлять текстовые поля или кнопки, используя эти переменные
в web используется AJAX (изменение данных без обновления страницы).Не для программирования?