From 570091e60d3e112de4fc5818f2cd70f4a5dd360d Mon Sep 17 00:00:00 2001 From: Eric Lippmann Date: Thu, 17 Jan 2019 14:40:29 +0100 Subject: [PATCH 1/2] Add is_iterable() polyfill --- composer.json | 2 +- src/polyfill-php71.php | 15 +++++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) create mode 100644 src/polyfill-php71.php 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/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 @@ + Date: Thu, 17 Jan 2019 14:41:26 +0100 Subject: [PATCH 2/2] Add function str_putcsv --- src/functions.php | 44 +++++++++++++++++++++++++++++++++++++ tests/php/FunctionsTest.php | 27 +++++++++++++++++++++++ 2 files changed, 71 insertions(+) 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/tests/php/FunctionsTest.php b/tests/php/FunctionsTest.php index f300818..f74f68a 100644 --- a/tests/php/FunctionsTest.php +++ b/tests/php/FunctionsTest.php @@ -61,4 +61,31 @@ public function testArrayvalException() { Stdlib\arrayval(null); } + + public function testStrPutcsv() + { + $data = [ + [ + 'Name' => '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)); + } }