Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit f756b96

Browse files
authored
Make CSV deprecation less annoying to deal with (#15569)
1 parent e73a855 commit f756b96

File tree

88 files changed

+408
-341
lines changed

Some content is hidden

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

88 files changed

+408
-341
lines changed

‎UPGRADING‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -581,11 +581,11 @@ PHP 8.4 UPGRADE NOTES
581581
- SPL:
582582
. The SplFixedArray::__wakeup() method has been deprecated as it implements
583583
__serialize() and __unserialize() which need to be overwritten instead.
584-
. Passing a non-empty string for the $enclosure parameter of:
584+
. Using the default value for $escape parameter of:
585585
- SplFileObject::setCsvControl()
586586
- SplFileObject::fputcsv()
587587
- SplFileObject::fgetcsv()
588-
is now deprecated.
588+
is now deprecated. It must be passed explicitly either positionally or via named arguments.
589589
RFC: https://wiki.php.net/rfc/deprecations_php_8_4#deprecate_proprietary_csv_escaping_mechanism
590590

591591
- Standard:
@@ -595,11 +595,11 @@ PHP 8.4 UPGRADE NOTES
595595
RFC: https://wiki.php.net/rfc/raising_zero_to_power_of_negative_number
596596
. Unserializing strings using the uppercase 'S' tag is deprecated.
597597
RFC: https://wiki.php.net/rfc/deprecations_php_8_4#unserialize_s_s_tag
598-
. Passing a non-empty string for the $enclosure parameter of:
598+
. Using the default value for $escape parameter of:
599599
- fputcsv()
600600
- fgetcsv()
601601
- str_getcsv()
602-
is now deprecated.
602+
is now deprecated. It must be passed explicitly either positionally or via named arguments.
603603
RFC: https://wiki.php.net/rfc/deprecations_php_8_4#deprecate_proprietary_csv_escaping_mechanism
604604

605605
- XML:

‎ext/phar/tests/phar_oo_008.phpt‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ class MyCSVFile extends SplFileObject
3333
{
3434
function current(): array|false
3535
{
36-
return parent::fgetcsv(',', '"');
36+
return parent::fgetcsv(',', '"', escape: '');
3737
}
3838
}
3939

@@ -44,14 +44,14 @@ $v = $phar['a.csv'];
4444
echo "===3===\n";
4545
while(!$v->eof())
4646
{
47-
echo $v->key() . "=>" . join('|', $v->fgetcsv()) . "\n";
47+
echo $v->key() . "=>" . join('|', $v->fgetcsv(escape: '')) . "\n";
4848
}
4949

5050
echo "===4===\n";
5151
$v->rewind();
5252
while(!$v->eof())
5353
{
54-
$l = $v->fgetcsv();
54+
$l = $v->fgetcsv(escape: '');
5555
echo $v->key() . "=>" . join('|', $l) . "\n";
5656
}
5757

@@ -66,7 +66,7 @@ class MyCSVFile2 extends SplFileObject
6666
function getCurrentLine(): string
6767
{
6868
echo __METHOD__ . "\n";
69-
return implode('|', parent::fgetcsv(',', '"'));
69+
return implode('|', parent::fgetcsv(',', '"', escape: ''));
7070
}
7171
}
7272

‎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-
intescape = intern->u.file.escape;
2282-
char*delim = NULL, *enclo = NULL, *esc=NULL;
2283-
size_td_len = 0, e_len=0, esc_len=0;
2299+
char*delim = NULL, *enclo=NULL;
2300+
size_td_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-
intescape = (unsigned char) '\\';
2387-
char*delim = NULL, *enclo = NULL, *esc=NULL;
2388-
size_td_len = 0, e_len=0, esc_len=0;
2382+
char*delim = NULL, *enclo=NULL;
2383+
size_td_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
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /