Skip to content

Commit ae55816

Browse files
committed
Make CSV deprecation less annoying to deal with
1 parent a3b7cc2 commit ae55816

File tree

81 files changed

+392
-326
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

81 files changed

+392
-326
lines changed

ext/spl/spl_directory.c

Lines changed: 45 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -365,6 +365,7 @@ static zend_result spl_filesystem_file_open(spl_filesystem_object *intern, bool
365365
intern->u.file.delimiter = ',';
366366
intern->u.file.enclosure = '"';
367367
intern->u.file.escape = (unsigned char) '\\';
368+
intern->u.file.is_escape_default = true;
368369

369370
intern->u.file.func_getCurr = zend_hash_str_find_ptr(&intern->std.ce->function_table, "getcurrentline", sizeof("getcurrentline") - 1);
370371

@@ -2273,16 +2274,33 @@ PHP_METHOD(SplFileObject, getChildren)
22732274
/* return NULL */
22742275
} /* }}} */
22752276

2277+
static int spl_csv_enclosure_param_handling(const zend_string* escape_str, const spl_filesystem_object *intern, uint32_t arg_num)
2278+
{
2279+
if (escape_str == NULL) {
2280+
if (intern->u.file.is_escape_default) {
2281+
php_error_docref(NULL, E_DEPRECATED, "the $escape parameter must be provided,"
2282+
" as its default value will change,"
2283+
" either explicitly or via SplFileObject::setCsvControl()");
2284+
if (UNEXPECTED(EG(exception))) {
2285+
return PHP_CSV_ESCAPE_ERROR;
2286+
}
2287+
}
2288+
return intern->u.file.escape;
2289+
} else {
2290+
return php_csv_handle_escape_argument(escape_str, arg_num);
2291+
}
2292+
}
2293+
22762294
/* {{{ Return current line as CSV */
22772295
PHP_METHOD(SplFileObject, fgetcsv)
22782296
{
22792297
spl_filesystem_object *intern = spl_filesystem_from_obj(Z_OBJ_P(ZEND_THIS));
22802298
char delimiter = intern->u.file.delimiter, enclosure = intern->u.file.enclosure;
2281-
int escape = intern->u.file.escape;
2282-
char *delim = NULL, *enclo = NULL, *esc = NULL;
2283-
size_t d_len = 0, e_len = 0, esc_len = 0;
2299+
char *delim = NULL, *enclo = NULL;
2300+
size_t d_len = 0, e_len = 0;
2301+
zend_string *escape_str = NULL;
22842302

2285-
if (zend_parse_parameters(ZEND_NUM_ARGS(), "|sss", &delim, &d_len, &enclo, &e_len, &esc, &esc_len) == FAILURE) {
2303+
if (zend_parse_parameters(ZEND_NUM_ARGS(), "|ssS", &delim, &d_len, &enclo, &e_len, &escape_str) == FAILURE) {
22862304
RETURN_THROWS();
22872305
}
22882306

@@ -2302,23 +2320,12 @@ PHP_METHOD(SplFileObject, fgetcsv)
23022320
}
23032321
enclosure = enclo[0];
23042322
}
2305-
if (esc) {
2306-
if (esc_len > 1) {
2307-
zend_argument_value_error(3, "must be empty or a single character");
2308-
RETURN_THROWS();
2309-
}
2310-
if (esc_len == 0) {
2311-
escape = PHP_CSV_NO_ESCAPE;
2312-
} else {
2313-
php_error_docref(NULL, E_DEPRECATED, "Passing a non-empty string to the $escape parameter is deprecated since 8.4");
2314-
if (UNEXPECTED(EG(exception))) {
2315-
RETURN_THROWS();
2316-
}
2317-
escape = (unsigned char) esc[0];
2318-
}
2323+
int escape_char = spl_csv_enclosure_param_handling(escape_str, intern, 3);
2324+
if (escape_char == PHP_CSV_ESCAPE_ERROR) {
2325+
RETURN_THROWS();
23192326
}
23202327

2321-
if (spl_filesystem_file_read_csv(intern, delimiter, enclosure, escape, return_value, true) == FAILURE) {
2328+
if (spl_filesystem_file_read_csv(intern, delimiter, enclosure, escape_char, return_value, true) == FAILURE) {
23222329
RETURN_FALSE;
23232330
}
23242331
}
@@ -2329,14 +2336,14 @@ PHP_METHOD(SplFileObject, fputcsv)
23292336
{
23302337
spl_filesystem_object *intern = spl_filesystem_from_obj(Z_OBJ_P(ZEND_THIS));
23312338
char delimiter = intern->u.file.delimiter, enclosure = intern->u.file.enclosure;
2332-
int escape = intern->u.file.escape;
2333-
char *delim = NULL, *enclo = NULL, *esc = NULL;
2334-
size_t d_len = 0, e_len = 0, esc_len = 0;
2339+
char *delim = NULL, *enclo = NULL;
2340+
size_t d_len = 0, e_len = 0;
23352341
zend_long ret;
23362342
zval *fields = NULL;
2343+
zend_string *escape_str = NULL;
23372344
zend_string *eol = NULL;
23382345

2339-
if (zend_parse_parameters(ZEND_NUM_ARGS(), "a|sssS", &fields, &delim, &d_len, &enclo, &e_len, &esc, &esc_len, &eol) == FAILURE) {
2346+
if (zend_parse_parameters(ZEND_NUM_ARGS(), "a|ssSS", &fields, &delim, &d_len, &enclo, &e_len, &escape_str, &eol) == FAILURE) {
23402347
RETURN_THROWS();
23412348
}
23422349

@@ -2354,23 +2361,12 @@ PHP_METHOD(SplFileObject, fputcsv)
23542361
}
23552362
enclosure = enclo[0];
23562363
}
2357-
if (esc) {
2358-
if (esc_len > 1) {
2359-
zend_argument_value_error(4, "must be empty or a single character");
2360-
RETURN_THROWS();
2361-
}
2362-
if (esc_len == 0) {
2363-
escape = PHP_CSV_NO_ESCAPE;
2364-
} else {
2365-
php_error_docref(NULL, E_DEPRECATED, "Passing a non-empty string to the $escape parameter is deprecated since 8.4");
2366-
if (UNEXPECTED(EG(exception))) {
2367-
RETURN_THROWS();
2368-
}
2369-
escape = (unsigned char) esc[0];
2370-
}
2364+
int escape_char = spl_csv_enclosure_param_handling(escape_str, intern, 4);
2365+
if (escape_char == PHP_CSV_ESCAPE_ERROR) {
2366+
RETURN_THROWS();
23712367
}
23722368

2373-
ret = php_fputcsv(intern->u.file.stream, fields, delimiter, enclosure, escape, eol);
2369+
ret = php_fputcsv(intern->u.file.stream, fields, delimiter, enclosure, escape_char, eol);
23742370
if (ret < 0) {
23752371
RETURN_FALSE;
23762372
}
@@ -2383,11 +2379,11 @@ PHP_METHOD(SplFileObject, setCsvControl)
23832379
{
23842380
spl_filesystem_object *intern = spl_filesystem_from_obj(Z_OBJ_P(ZEND_THIS));
23852381
char delimiter = ',', enclosure = '"';
2386-
int escape = (unsigned char) '\\';
2387-
char *delim = NULL, *enclo = NULL, *esc = NULL;
2388-
size_t d_len = 0, e_len = 0, esc_len = 0;
2382+
char *delim = NULL, *enclo = NULL;
2383+
size_t d_len = 0, e_len = 0;
2384+
zend_string *escape_str = NULL;
23892385

2390-
if (zend_parse_parameters(ZEND_NUM_ARGS(), "|sss", &delim, &d_len, &enclo, &e_len, &esc, &esc_len) == FAILURE) {
2386+
if (zend_parse_parameters(ZEND_NUM_ARGS(), "|ssS", &delim, &d_len, &enclo, &e_len, &escape_str) == FAILURE) {
23912387
RETURN_THROWS();
23922388
}
23932389

@@ -2405,25 +2401,17 @@ PHP_METHOD(SplFileObject, setCsvControl)
24052401
}
24062402
enclosure = enclo[0];
24072403
}
2408-
if (esc) {
2409-
if (esc_len > 1) {
2410-
zend_argument_value_error(3, "must be empty or a single character");
2411-
RETURN_THROWS();
2412-
}
2413-
if (esc_len == 0) {
2414-
escape = PHP_CSV_NO_ESCAPE;
2415-
} else {
2416-
php_error_docref(NULL, E_DEPRECATED, "Passing a non-empty string to the $escape parameter is deprecated since 8.4");
2417-
if (UNEXPECTED(EG(exception))) {
2418-
RETURN_THROWS();
2419-
}
2420-
escape = (unsigned char) esc[0];
2421-
}
2404+
int escape_char = php_csv_handle_escape_argument(escape_str, 3);
2405+
if (escape_char == PHP_CSV_ESCAPE_ERROR) {
2406+
RETURN_THROWS();
2407+
}
2408+
if (escape_str != NULL) {
2409+
intern->u.file.is_escape_default = false;
24222410
}
24232411

24242412
intern->u.file.delimiter = delimiter;
24252413
intern->u.file.enclosure = enclosure;
2426-
intern->u.file.escape = escape;
2414+
intern->u.file.escape = escape_char;
24272415
}
24282416
/* }}} */
24292417

ext/spl/spl_directory.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ struct _spl_filesystem_object {
8282
char delimiter;
8383
char enclosure;
8484
int escape;
85+
bool is_escape_default;
8586
} file;
8687
} u;
8788
zend_object std;

ext/spl/tests/SplFileObject/SplFileObject_fgetcsv_basic.phpt

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,20 @@ SplFileObject::fgetcsv default path
33
--FILE--
44
<?php
55
$fp = fopen('SplFileObject__fgetcsv1.csv', 'w+');
6-
fputcsv($fp, array(
7-
'field1',
8-
'field2',
9-
'field3',
10-
5
11-
));
6+
fputcsv(
7+
$fp,
8+
[
9+
'field1',
10+
'field2',
11+
'field3',
12+
5,
13+
],
14+
escape: '',
15+
);
1216
fclose($fp);
1317

1418
$fo = new SplFileObject('SplFileObject__fgetcsv1.csv');
19+
$fo->setCsvControl(escape: '');
1520
var_dump($fo->fgetcsv());
1621
?>
1722
--CLEAN--

ext/spl/tests/SplFileObject/SplFileObject_fgetcsv_delimiter_basic.phpt

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,23 @@
11
--TEST--
2-
SplFileObject::fgetcsv with alternative delimiter
2+
SplFileObject::fgetcsv with alternative separator
33
--FILE--
44
<?php
55
$fp = fopen('SplFileObject__fgetcsv2.csv', 'w+');
6-
fputcsv($fp, array(
7-
'field1',
8-
'field2',
9-
'field3',
10-
5
11-
), '|');
6+
fputcsv(
7+
$fp,
8+
[
9+
'field1',
10+
'field2',
11+
'field3',
12+
5,
13+
],
14+
separator: '|',
15+
escape: '',
16+
);
1217
fclose($fp);
1318

1419
$fo = new SplFileObject('SplFileObject__fgetcsv2.csv');
20+
$fo->setCsvControl(escape: '');
1521
var_dump($fo->fgetcsv('|'));
1622
?>
1723
--CLEAN--

ext/spl/tests/SplFileObject/SplFileObject_fgetcsv_delimiter_error.phpt

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,22 @@
11
--TEST--
2-
SplFileObject::fgetcsv with alternative delimiter
2+
SplFileObject::fgetcsv() delimiter error
33
--FILE--
44
<?php
55
$fp = fopen('SplFileObject__fgetcsv3.csv', 'w+');
6-
fputcsv($fp, array(
7-
'field1',
8-
'field2',
9-
'field3',
10-
5
11-
), '|');
6+
fputcsv(
7+
$fp,
8+
[
9+
'field1',
10+
'field2',
11+
'field3',
12+
5,
13+
],
14+
escape: '',
15+
);
1216
fclose($fp);
1317

1418
$fo = new SplFileObject('SplFileObject__fgetcsv3.csv');
19+
$fo->setCsvControl(escape: '');
1520
try {
1621
var_dump($fo->fgetcsv('invalid'));
1722
} catch (ValueError $e) {

ext/spl/tests/SplFileObject/SplFileObject_fgetcsv_enclosure_basic.phpt

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,24 @@
11
--TEST--
2-
SplFileObject::fgetcsv with alternative delimiter
2+
SplFileObject::fgetcsv with alternative enclosure
33
--FILE--
44
<?php
55
$fp = fopen('SplFileObject__fgetcsv4.csv', 'w+');
6-
fputcsv($fp, array(
7-
'field1',
8-
'field2',
9-
'field3',
10-
5
11-
), ',', '"');
6+
fputcsv(
7+
$fp,
8+
[
9+
'field1',
10+
'field2',
11+
'field3',
12+
5,
13+
],
14+
enclosure: '"',
15+
escape: '',
16+
);
1217
fclose($fp);
1318

1419
$fo = new SplFileObject('SplFileObject__fgetcsv4.csv');
15-
var_dump($fo->fgetcsv(',', '"'));
20+
$fo->setCsvControl(escape: '');
21+
var_dump($fo->fgetcsv(enclosure: '"'));
1622
?>
1723
--CLEAN--
1824
<?php

ext/spl/tests/SplFileObject/SplFileObject_fgetcsv_enclosure_error.phpt

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,24 @@
11
--TEST--
2-
SplFileObject::fgetcsv with alternative delimiter
2+
SplFileObject::fgetcsv() enclosure error
33
--FILE--
44
<?php
55
$fp = fopen('SplFileObject__fgetcsv5.csv', 'w+');
6-
fputcsv($fp, array(
7-
'field1',
8-
'field2',
9-
'field3',
10-
5
11-
), ',', '"');
6+
fputcsv(
7+
$fp,
8+
[
9+
'field1',
10+
'field2',
11+
'field3',
12+
5,
13+
],
14+
escape: '',
15+
);
1216
fclose($fp);
1317

1418
$fo = new SplFileObject('SplFileObject__fgetcsv5.csv');
19+
$fo->setCsvControl(escape: '');
1520
try {
16-
var_dump($fo->fgetcsv(',', 'invalid'));
21+
var_dump($fo->fgetcsv(enclosure: 'invalid'));
1722
} catch (ValueError $e) {
1823
echo $e->getMessage(), "\n";
1924
}

ext/spl/tests/SplFileObject/SplFileObject_fgetcsv_escape_basic.phpt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
--TEST--
2-
SplFileObject::fgetcsv with alternative delimiter
2+
SplFileObject::fgetcsv with alternative escape
33
--FILE--
44
<?php
55
$fp = fopen('SplFileObject__fgetcsv6.csv', 'w+');
@@ -14,7 +14,6 @@ var_dump($fo->fgetcsv(',', '"', '"'));
1414
unlink('SplFileObject__fgetcsv6.csv');
1515
?>
1616
--EXPECTF--
17-
Deprecated: SplFileObject::fgetcsv(): Passing a non-empty string to the $escape parameter is deprecated since 8.4 in %s on line %d
1817
array(3) {
1918
[0]=>
2019
string(3) "aaa"

ext/spl/tests/SplFileObject/SplFileObject_fgetcsv_escape_default.phpt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@ var_dump($fo->fgetcsv());
1313
<?php
1414
unlink('SplFileObject__fgetcsv7.csv');
1515
?>
16-
--EXPECT--
16+
--EXPECTF--
17+
Deprecated: SplFileObject::fgetcsv(): the $escape parameter must be provided, as its default value will change, either explicitly or via SplFileObject::setCsvControl() in %s on line %d
1718
array(3) {
1819
[0]=>
1920
string(4) "aa\""

ext/spl/tests/SplFileObject/SplFileObject_fgetcsv_escape_error.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
--TEST--
2-
SplFileObject::fgetcsv with alternative delimiter
2+
SplFileObject::fgetcsv() escape error
33
--FILE--
44
<?php
55
$fp = fopen('SplFileObject__fgetcsv8.csv', 'w+');

ext/spl/tests/SplFileObject/SplFileObject_fputcsv.phpt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ SplFileObject::fputcsv(): functionality tests
44
<?php
55
$file = __DIR__ . '/SplFileObject_fputcsv.csv';
66
$fo = new SplFileObject($file, 'w');
7+
// Suppress deprecation notice
8+
$fo->setCsvControl(escape: '\\');
79

810
$list = array (
911
0 => 'aaa,bbb',
@@ -42,7 +44,7 @@ echo '$list = ';var_export($res);echo ";\n";
4244

4345
$fp = fopen($file, "r");
4446
$res = array();
45-
while($l=fgetcsv($fp))
47+
while($l=fgetcsv($fp, escape: '\\'))
4648
{
4749
$res[] = join(',',$l);
4850
}

ext/spl/tests/SplFileObject/SplFileObject_fputcsv_002.phpt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ SplFileObject::fputcsv(): Checking data after calling the function
33
--FILE--
44
<?php
55
$fo = new SplFileObject(__DIR__ . '/SplFileObject_fputcsv1.csv', 'w');
6+
$fo->setCsvControl(escape: '');
67

78
$data = array(1, 2, 'foo', 'haha', array(4, 5, 6), 1.3, null);
89

ext/spl/tests/SplFileObject/SplFileObject_fputcsv_variation1.phpt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ foreach ($csv_lists as $csv_list) {
4242
} else {
4343
$fo = new SplFileObject($file, $file_modes[$mode_counter]);
4444
}
45+
$fo->setCsvControl(escape: '');
4546
$delimiter = $csv_list[0];
4647
$enclosure = $csv_list[1];
4748
$csv_field = $csv_list[2];

0 commit comments

Comments
 (0)