В PHP, как и в большинстве других языков, ввод и вывод информации может осуществляться посредством потоков. В частности, при работе с CLI могут использоваться стандартные потоки (англ. standard streams) операционной системы.
И, не смотря на то, что чаще используются специальные функции и конструкции языка,
выполняющие те же действия прозрачно для пользователя, такие как, например,
echo
, print
и printf
, периодически возникает необходимость обратится напрямую к таким потокам.
Так, например, без стандартных потоков сложно обойтись при работе с получении данных из тела HTTP запроса,
при необходимости использования функций, которые поддерживают только ресурсы (fputcsv
) или, как было замечено ранее,
во время работы в консольном режиме.
Для этих целей можно использовать обработчики потоков ввода-вывода (англ. I/O streams wrappers) имеющие префикс php://
.
Полный список обработчиков и протоколов можно посмотреть здесь: http://www.php.net/manual/en/wrappers.php.
Так при работе в режиме CLI
может потребоваться вывести данные в стандартный поток вывода.
Для этого можно открыть поток на запись с помощью fopen
и передать полученный указатель в функцию fwrite
вместе с информацией для записи. Для стандартных потоков ввода-вывода PHP предоставляет константы STDIN
, STDOUT
и STDERR
,
в которые помещаются ресурсы на уже открытые потоки ввода, вывода и вывода ошибок соответственно.
(В документации они почему-то называются константами, хотя, во-первых хранят не скалярное значение,
а во-вторых их можно переопределить.)
Для работы с веб-сервером в основном используются потоки php://input
на ввод и php://output
на вывод.
Таким образом, если требуется отформатировать данные в формат CSV и возвратить клиенту полученный результат в качестве ответа сервера,
достаточно сделать следующее:
/**
* Exports $data as csv file
* @param array $data
*/
function csv_export(array $data = array()) {
// следующий код, разумеется будет работать если в поток вывод ничего не записывалось ранее
header('Content-Type: text/csv; charset=utf-8');
header(sprintf('Content-Disposition: attachment; filename="%s.csv";', date('Y-m-d\TH:i:s')));
header('Pragma: no-cache');
header('Expires: 0');
$output = fopen('php://output', 'w');
foreach ($data as $row) {
fputcsv($output, $row);
}
fclose($output);
}