diff --git a/composer.json b/composer.json index d58bd82..31c0163 100644 --- a/composer.json +++ b/composer.json @@ -4,7 +4,7 @@ "type": "library", "license": "MIT", "autoload": { - "files": ["src/functions_include.php"], + "files": ["src/functions_include.php", "src/polyfill-php71.php"], "psr-4": { "ipl\\Stdlib\\": "src" } diff --git a/src/functions.php b/src/functions.php index 0470a1f..560866a 100644 --- a/src/functions.php +++ b/src/functions.php @@ -53,3 +53,47 @@ function arrayval($subject) get_php_type($subject) )); } + +/** + * Format the given input array as CSV string and return it + * + * The input array is always expected to be an array of rows. + * The keys of the first row will be automatically used as the header row. + * + * @param iterable $data + * @param string $delimiter Field delimiter + * @param string $enclosure Field enclosure + * @param string $escape Escape character + * + * @return string + * + * @throws \InvalidArgumentException + */ +function str_putcsv($data, $delimiter = ',', $enclosure = '"', $escape = '\\') +{ + $fp = fopen('php://temp', 'r+b'); + + if (! is_iterable($data)) { + throw new \InvalidArgumentException(sprintf( + 'str_putcsv expects arrays or instances of Traversable. Got %s instead.', + get_php_type($data) + )); + } + + foreach ($data as $row) { + fputcsv($fp, array_keys($row), $delimiter, $enclosure, $escape); + + break; + } + + foreach ($data as $row) { + fputcsv($fp, $row, $delimiter, $enclosure, $escape); + } + + rewind($fp); + $csv = stream_get_contents($fp); + fclose($fp); + $csv = rtrim($csv, "\n"); // fputcsv adds a newline + + return $csv; +} diff --git a/src/polyfill-php71.php b/src/polyfill-php71.php new file mode 100644 index 0000000..bf1a850 --- /dev/null +++ b/src/polyfill-php71.php @@ -0,0 +1,15 @@ + 'John Doe', + 'Age' => 45 + ], + [ + 'Name' => 'Richard Roe', + 'Age' => 38 + ], + [ + 'Name' => 'Jane Roe', + 'Age' => 27 + ] + ]; + + $csv = <<<'CSV' +Name,Age +"John Doe",45 +"Richard Roe",38 +"Jane Roe",27 +CSV; + + $this->assertSame($csv, Stdlib\str_putcsv($data)); + } }