Skip to content

Commit e63d212

Browse files
rudi-augmentclaude
andcommitted
Release 1.6.0 — PHP 8.2+, serialization, and bug fixes
- Drop PHP < 8.2 support, require PHP >= 8.2 - Implement __serialize/__unserialize on all data structures using the O: format, replacing the deprecated Serializable interface (C: format) - Fix sort/sorted/ksort/ksorted to accept null comparators (#134) - Save and restore global compare FCI around sort callbacks to support nested comparators (#48) - Guard allocate methods against negative capacity values (#33) - Update CI matrix for PHP 8.2–8.5, PHPUnit 11 - Update package.xml and composer.json for PHP 8.2+ and tests ^1.6 - Remove legacy Serializable interface, arginfo.h, and PHP < 8.2 compat code Thanks to @simPod, @ndossche, and @NorthNick for their contributions. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 1a867ad commit e63d212

45 files changed

Lines changed: 284 additions & 496 deletions

Some content is hidden

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

.github/workflows/main.yml

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,6 @@ jobs:
1515
fail-fast: false
1616
matrix:
1717
php:
18-
- "7.4"
19-
- "8.0"
20-
- "8.1"
2118
- "8.2"
2219
- "8.3"
2320
- "8.4"

composer.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,10 @@
1212
],
1313
"minimum-stability": "dev",
1414
"require": {
15-
"php": ">= 7.4.0"
15+
"php": ">= 8.2.0"
1616
},
1717
"require-dev": {
18-
"php-ds/tests": "^1.5"
18+
"php-ds/tests": "^1.8"
1919
},
2020
"scripts": {
2121
"test" : "php test.php",

config.m4

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,6 @@ dnl Classes
7474
PHP_ADD_BUILD_DIR($ext_builddir/src/php/handlers, 1)
7575

7676
PHP_ADD_EXTENSION_DEP(ds, spl)
77-
PHP_ADD_EXTENSION_DEP(ds, json)
7877
fi
7978

8079

config.w32

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -89,11 +89,4 @@ if (PHP_DS != "no") {
8989
]);
9090

9191
ADD_EXTENSION_DEP('ds', 'spl');
92-
var dll = get_define('PHPDLL');
93-
if (null != dll.match(/^php7/)) {
94-
// only require dynamic json extension for PHP 7
95-
// json is built statically in PHP 8
96-
// https://github.com/php/php-src/pull/5495
97-
ADD_EXTENSION_DEP('ds', 'json');
98-
}
9992
}

package.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@
153153
<dependencies>
154154
<required>
155155
<php>
156-
<min>7.4.0</min>
156+
<min>8.2.0</min>
157157
</php>
158158
<pearinstaller>
159159
<min>1.4.0b1</min>

phpunit.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<phpunit
2-
backupGlobals = "false"
3-
backupStaticAttributes = "false"
2+
backupGlobals="false"
3+
failOnWarning="false"
44
>
55
<testsuites>
66
<testsuite name="all">

src/common.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,10 @@ int name##_unserialize( \
184184
index, \
185185
max - 1)
186186

187+
#define CAPACITY_INVALID(n) ds_throw_exception( \
188+
spl_ce_OutOfRangeException, \
189+
"Capacity must be non-negative, %ld given", (long) n)
190+
187191
#define OFFSET_OUT_OF_BOUNDS() ds_throw_exception( \
188192
spl_ce_OutOfBoundsException, \
189193
"Offset out of bounds")
@@ -241,15 +245,13 @@ int name##_unserialize( \
241245
"Immutable objects may not be changed")
242246

243247
// https://bugs.php.net/bug.php?id=80816
244-
#if PHP_VERSION_ID >= 80100
245248
#define spl_ce_Aggregate zend_ce_aggregate
246249
#define spl_ce_ArrayAccess zend_ce_arrayaccess
247250
#define spl_ce_Countable zend_ce_countable
248251
#define spl_ce_Iterator zend_ce_iterator
249252
#define spl_ce_Serializable zend_ce_serializable
250253
#define spl_ce_Stringable zend_ce_stringable
251254
#define spl_ce_Traversable zend_ce_traversable
252-
#endif
253255

254256
/**
255257
*

src/ds/ds_htable.c

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -183,11 +183,7 @@ static inline bool implements_hashable(zval *key) {
183183

184184
} else {
185185
zval equals;
186-
#if PHP_VERSION_ID >= 80000
187186
zend_call_method_with_1_params(Z_OBJ_P(a), Z_OBJCE_P(a), NULL, "equals", &equals, b);
188-
#else
189-
zend_call_method_with_1_params(a, Z_OBJCE_P(a), NULL, "equals", &equals, b);
190-
#endif
191187
switch (Z_TYPE(equals)) {
192188
case IS_TRUE:
193189
return true;
@@ -275,11 +271,7 @@ static uint32_t get_object_hash(zval *obj)
275271
{
276272
if (implements_hashable(obj)) {
277273
zval hash;
278-
#if PHP_VERSION_ID >= 80000
279274
zend_call_method_with_0_params(Z_OBJ_P(obj), Z_OBJCE_P(obj), NULL, "hash", &hash);
280-
#else
281-
zend_call_method_with_0_params(obj, Z_OBJCE_P(obj), NULL, "hash", &hash);
282-
#endif
283275

284276
switch (Z_TYPE(hash)) {
285277
case IS_LONG:

src/php/arginfo.h

Lines changed: 0 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -82,8 +82,6 @@ ZEND_ARG_TYPE_INFO(0, i, IS_LONG, 0) \
8282
ZEND_ARG_VARIADIC_INFO(0, v) \
8383
ZEND_END_ARG_INFO()
8484

85-
#if PHP_VERSION_ID >= 80100
86-
8785
#define ARGINFO_OFFSET_GET(name) \
8886
ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_##name, 0, 1, IS_MIXED, 0) \
8987
ZEND_ARG_TYPE_INFO(0, offset, IS_MIXED, 0) \
@@ -100,102 +98,21 @@ ZEND_END_ARG_INFO()
10098
ZEND_ARG_TYPE_INFO(0, offset, IS_MIXED, 0) \
10199
ZEND_END_ARG_INFO()
102100

103-
#elif PHP_VERSION_ID >= 80000
104-
105-
#define ARGINFO_OFFSET_GET(name) \
106-
ZEND_BEGIN_ARG_INFO_EX(arginfo_##name, 0, 0, 1) \
107-
ZEND_ARG_TYPE_INFO(0, offset, IS_MIXED, 0) \
108-
ZEND_END_ARG_INFO()
109-
110-
#define ARGINFO_OFFSET_SET(name) \
111-
ZEND_BEGIN_ARG_INFO_EX(arginfo_##name, 0, 0, 2) \
112-
ZEND_ARG_TYPE_INFO(0, offset, IS_MIXED, 0) \
113-
ZEND_ARG_TYPE_INFO(0, value, IS_MIXED, 0) \
114-
ZEND_END_ARG_INFO()
115-
116-
#define ARGINFO_OFFSET_UNSET(name) \
117-
ZEND_BEGIN_ARG_INFO_EX(arginfo_##name, 0, 0, 1) \
118-
ZEND_ARG_TYPE_INFO(0, offset, IS_MIXED, 0) \
119-
ZEND_END_ARG_INFO()
120-
121-
#else
122-
123-
#define ARGINFO_OFFSET_GET(name) \
124-
ZEND_BEGIN_ARG_INFO_EX(arginfo_##name, 0, 0, 1) \
125-
ZEND_ARG_INFO(0, offset) \
126-
ZEND_END_ARG_INFO()
127-
128-
#define ARGINFO_OFFSET_SET(name) \
129-
ZEND_BEGIN_ARG_INFO_EX(arginfo_##name, 0, 0, 2) \
130-
ZEND_ARG_INFO(0, offset) \
131-
ZEND_ARG_INFO(0, value) \
132-
ZEND_END_ARG_INFO()
133-
134-
#define ARGINFO_OFFSET_UNSET(name) \
135-
ZEND_BEGIN_ARG_INFO_EX(arginfo_##name, 0, 0, 1) \
136-
ZEND_ARG_INFO(0, offset) \
137-
ZEND_END_ARG_INFO()
138-
139-
#endif
140-
141-
#if PHP_VERSION_ID >= 80100
142-
143101
#define ARGINFO_NONE_RETURN_TYPE(name, type) \
144102
ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_##name, 0, 0, type, 0) \
145103
ZEND_END_ARG_INFO()
146-
#else
147-
148-
#define ARGINFO_NONE_RETURN_TYPE(name, type) \
149-
ZEND_BEGIN_ARG_INFO_EX(arginfo_##name, 0, 0, 0) \
150-
ZEND_END_ARG_INFO()
151-
152-
#endif
153104

154-
#if PHP_VERSION_ID >= 80000
155105
#define DS_BEGIN_ARG_WITH_RETURN_DS_INFO_EX(name, pass_by_ref, required_num_args, class_name, allow_null) \
156106
static const zend_internal_arg_info arginfo_##name[] = { \
157107
{ (const char*)(zend_uintptr_t)(required_num_args), ZEND_TYPE_INIT_CLASS_CONST(PHP_DS_NS_NAME#class_name, allow_null, 0), pass_by_ref},
158-
#elif PHP_VERSION_ID >= 70200
159-
#define DS_BEGIN_ARG_WITH_RETURN_DS_INFO_EX(name, pass_by_ref, required_num_args, class_name, allow_null) \
160-
static const zend_internal_arg_info arginfo_##name[] = { \
161-
{ (const char*)(zend_uintptr_t)(required_num_args), ZEND_TYPE_ENCODE_CLASS_CONST(PHP_DS_NS_NAME#class_name, allow_null), pass_by_ref, 0 },
162-
#else
163-
#define DS_BEGIN_ARG_WITH_RETURN_DS_INFO_EX(name, pass_by_ref, required_num_args, class_name, allow_null) \
164-
static const zend_internal_arg_info arginfo_##name[] = { \
165-
{ (const char*)(zend_uintptr_t)(required_num_args), PHP_DS_NS_NAME#class_name, IS_OBJECT, pass_by_ref, allow_null, 0 },
166-
#endif
167108

168-
#if PHP_VERSION_ID >= 80000
169109
#define DS_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(name, pass_by_ref, required_num_args, class_name, allow_null) \
170110
static const zend_internal_arg_info arginfo_##name[] = { \
171111
{ (const char*)(zend_uintptr_t)(required_num_args), ZEND_TYPE_INIT_CLASS_CONST(class_name, allow_null, 0), pass_by_ref},
172-
#elif PHP_VERSION_ID >= 70200
173-
#define DS_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(name, pass_by_ref, required_num_args, class_name, allow_null) \
174-
static const zend_internal_arg_info arginfo_##name[] = { \
175-
{ (const char*)(zend_uintptr_t)(required_num_args), ZEND_TYPE_ENCODE_CLASS_CONST(class_name, allow_null), pass_by_ref, 0 },
176-
#else
177-
#define DS_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(name, pass_by_ref, required_num_args, class_name, allow_null) \
178-
static const zend_internal_arg_info arginfo_##name[] = { \
179-
{ (const char*)(zend_uintptr_t)(required_num_args), class_name, IS_OBJECT, pass_by_ref, allow_null, 0 },
180-
#endif
181112

182-
#if PHP_VERSION_ID >= 80100
183113
#define DS_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(name, pass_by_ref, required_num_args, type, allow_null) \
184114
static const zend_internal_arg_info arginfo_##name[] = { \
185115
{ (const char*)(zend_uintptr_t)(required_num_args), ZEND_TYPE_INIT_CODE(type, allow_null, _ZEND_ARG_INFO_FLAGS(pass_by_ref, 0, 0)) },
186-
#elif PHP_VERSION_ID >= 80000
187-
#define DS_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(name, pass_by_ref, required_num_args, type, allow_null) \
188-
static const zend_internal_arg_info arginfo_##name[] = { \
189-
{ (const char*)(zend_uintptr_t)(required_num_args), ZEND_TYPE_INIT_CODE(type, allow_null, _ZEND_ARG_INFO_FLAGS(pass_by_ref, 0)) },
190-
#elif PHP_VERSION_ID >= 70200
191-
#define DS_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(name, pass_by_ref, required_num_args, type, allow_null) \
192-
static const zend_internal_arg_info arginfo_##name[] = { \
193-
{ (const char*)(zend_uintptr_t)(required_num_args), ZEND_TYPE_ENCODE(type, allow_null), pass_by_ref, 0 },
194-
#else
195-
#define DS_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(name, pass_by_ref, required_num_args, type, allow_null) \
196-
static const zend_internal_arg_info arginfo_##name[] = { \
197-
{ (const char*)(zend_uintptr_t)(required_num_args), NULL, type, pass_by_ref, allow_null, 0 },
198-
#endif
199116

200117
#define ARGINFO_ZVAL_RETURN_BOOL(name, z) \
201118
DS_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(name, 0, 1, _IS_BOOL, 0) \

src/php/classes/php_collection_ce.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,18 @@ PHP_DS_COLLECTION_ME(cls, copy) \
1515
PHP_DS_COLLECTION_ME(cls, count) \
1616
PHP_DS_COLLECTION_ME(cls, isEmpty) \
1717
PHP_DS_COLLECTION_ME(cls, jsonSerialize) \
18-
PHP_DS_COLLECTION_ME(cls, toArray)
18+
PHP_DS_COLLECTION_ME(cls, toArray) \
19+
PHP_DS_COLLECTION_ME(cls, __serialize) \
20+
PHP_DS_COLLECTION_ME(cls, __unserialize)
1921

2022
ARGINFO_NONE_RETURN_DS( Collection_copy, Collection);
2123
ARGINFO_NONE( Collection_clear);
2224
ARGINFO_NONE_RETURN_LONG( Collection_count);
2325
ARGINFO_NONE_RETURN_BOOL( Collection_isEmpty);
2426
ARGINFO_NONE_RETURN_TYPE( Collection_jsonSerialize, IS_MIXED);
2527
ARGINFO_NONE_RETURN_ARRAY( Collection_toArray);
28+
ARGINFO_NONE_RETURN_ARRAY( Collection___serialize);
29+
ARGINFO_ZVAL( Collection___unserialize, data);
2630

2731
void php_ds_register_collection();
2832

0 commit comments

Comments
 (0)