Seems like unfortunately there is no other way than doing a workaround! There are some options to do it and there is not "the one way to go". Depending on each usecase there might be different solutions. For my situation I will use the following code.
<?php
$csv = '0,1.2,"string"';
json_decode( "[$csv]", true );
But be aware that this will fail with multiline values at least!
Here are some tests:
<?php
$csv = '0,1.2,"string"';
var_dump(
json_decode( "[$csv]", true ) // works
, str_getcsv( $csv ) // converts everything to string
);
/*
array(3) { json_decode
[0]=>int(0)
[1]=>float(1.2)
[2]=>string(6) "string"
}
array(3) { str_getcsv
[0]=>
string(1) "0"
[1]=>
string(3) "1.2"
[2]=>
string(6) "string"
}
*/
$csv = '", as value in ,-separated csv"';
var_dump(
json_decode( "[$csv]", true ) // works also when separator is part of value
, str_getcsv( $csv ) // works also when separator is part of value but converts everything to string
);
/*
array(1) { json_decode
[0]=>string(29) ", as value in ,-separated csv"
}
array(1) { str_getcsv
[0]=>string(29) ", as value in ,-separated csv"
}
*/
$csv = '0,"value
with multiline"';
var_dump(
json_decode( "[$csv]", true ) // doesn't work as JSON can't handle multilines
, str_getcsv( $csv ) // works also with multilines but converts everything to string
);
/*
NULL json_decode
array(2) { str_getcsv
[0]=>string(1) "0"
[1]=>string(21) "value
with multiline"
}
*/
A very robust way seems to be the version from my original question as it relies on the native str_getcsv
-function and converts to appropriate types back afterwards. Performancewise this doesn't sound ideal to me but this should be only a concern when dealing with very heavy strings (which is the case for me).
<?php
$csv = str_getcsv('0,1.2,"string"');
foreach ( $csv as &$v ) if ( is_numeric( $v ) ) $v += 0;