04 Генерация выходных данных и ошибок.
Вы можете использовать регулярные потоки C++ для ввода-вывода, с обычным << оператором и специальными функциями, такими как std::endl. Однако не рекомендуется использовать потоки «std::cout» и «std::cerr».
Когда PHP работает как модуль веб-сервера, stdout перенаправляется на терминал, с которого был начат процесс веб-сервера. На рабочих серверах такой терминал неактивен, поэтому любой вывод, который вы отправляете на stdout, будет потерян. Использование std::cout в расширениях, которые выполняются в модуле веб-сервера, таким образом, не работает. Но даже когда PHP работает как скрипт CLI (и std::cout работает), вы все равно не должны писать прямо в stdout. Запись на stdout будет обходить все обработчики вывода, которые могут быть настроены с помощью сценария пользовательского пространства PHP.
Библиотека PHP-CPP предлагает поток Php::out, который можно использовать вместо него. Эта переменная Php::out является экземпляром хорошо известного класса std::ostream и учитывает всю буферизацию вывода, установленную в PHP. Он по сути аналогичен функции echo() в PHP-скриптах.
Php::out - это обычный объект std::ostream. Это приводит к тому, что он использует внутренний буфер, который необходимо очистить. Эта очистка происходит автоматически, когда вы добавляете 'std::endl' к выходу или когда вы добавляете 'std::flush' явно.
/** * Пример функции, которая показывает, как генерировать вывод */ void example() { // эквивалент C ++ функции echo () Php::out << "example output" << std::endl; // генерировать вывод без новой строки и обеспечивать его очистку Php::out << "example output" << std::flush; // или вызовите метод flush () Php::out << "example output"; Php::out.flush(); // как и все функции PHP, вы можете вызвать функцию echo () // из кода C ++ Php::echo("Example output\n"); }
Ошибки, предупреждения и уведомления
Если вы хотите вызвать ошибку PHP (эквивалент C++ для функции trigger_error()), вы можете использовать один из потоков Php::error, Php::notice, Php::warning и Php::deprecated. Это также экземпляры класса std::ostream.
/** * Пример функции, которая показывает, как генерировать вывод */ void example() { // генерировать уведомление PHP Php::notice << "this is a notice" << std::flush; // генерировать предупреждение PHP Php::warning << "this is a warning" << std::flush; // информировать пользователя о том, что был выполнен вызов устаревшей функции Php::deprecated << "this method is deprecated" << std::flush; // генерировать фатальную ошибку Php::error << "fatal error" << std::flush; // этот код больше не будет вызываться Php::out << "regular output" << std::endl; }
В приведенном выше примере вы можете видеть, что мы использовали std :: flush, а не std :: endl. Причиной этого является то, что std :: endl внутренне выполняет две вещи: добавляет новую строку и сбрасывает буфер. Для ошибок, уведомлений и предупреждений нам не нужна новая строка, но нам все равно нужно сбросить буфер, чтобы фактически генерировать результат.
В потоке Php :: error есть что-то очень своеобразное: когда вы его очищаете, скрипт PHP заканчивается фатальной ошибкой, и ваш C ++-алгоритм немедленно падает! Под капотом, PHP-движок делает longjump в место deep inside двигателя Zend. В примере функция «Php :: out <<» регулярный вывод »; поэтому оператор никогда не выполняется.
Все это очень необычно и (по нашему мнению) противоречит общим правилам достойной разработки программного обеспечения. Функция, генерирующая выход, не должна вести себя как выброс исключения. Код, который похож на обычный код, должен также вести себя как обычный код, а не делать неожиданные вещи, например, перепрыгивать из текущего стека вызовов. Поэтому мы советуем не использовать Php::error - или использовать его с особой осторожностью.