Skip to content

Commit afb4600

Browse files
committed
feat(php): Add PHP 8.5 support
1 parent 935a2d2 commit afb4600

File tree

8 files changed

+272
-166
lines changed

8 files changed

+272
-166
lines changed

.github/workflows/build.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ jobs:
8787
strategy:
8888
matrix:
8989
os: [ubuntu-latest, macos-latest, windows-latest]
90-
php: ["8.1", "8.2", "8.3", "8.4"]
90+
php: ["8.1", "8.2", "8.3", "8.4", "8.5"]
9191
rust: [stable, nightly]
9292
clang: ["15", "17"]
9393
phpts: [ts, nts]
@@ -173,7 +173,7 @@ jobs:
173173
runs-on: ubuntu-latest
174174
env:
175175
clang: "17"
176-
php_version: "8.4"
176+
php_version: "8.5"
177177
steps:
178178
- name: Checkout code
179179
uses: actions/checkout@v5
@@ -186,7 +186,7 @@ jobs:
186186
debug: true
187187

188188
- name: Install libphp-embed
189-
run: sudo apt update -y && sudo apt install -y libphp8.4-embed
189+
run: sudo apt update -y && sudo apt install -y libphp8.5-embed
190190

191191
- name: Setup Rust
192192
uses: dtolnay/rust-toolchain@master

Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
FROM rust:latest AS base
2-
ARG PHP_VERSION=8.4
2+
ARG PHP_VERSION=8.5
33
WORKDIR /tmp
44
RUN <<EOF
55
set -e

allowed_bindings.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,7 @@ bind! {
271271
zend_hash_get_current_key_zval_ex,
272272
zend_hash_get_current_data_ex,
273273
zend_hash_move_backwards_ex,
274+
zend_hash_key_type,
274275
zend_array_count,
275276
gc_possible_root,
276277
ZEND_ACC_NOT_SERIALIZABLE,

build.rs

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,7 @@ enum ApiVersion {
268268
Php82 = 2022_08_29,
269269
Php83 = 2023_08_31,
270270
Php84 = 2024_09_24,
271+
Php85 = 2025_09_25,
271272
}
272273

273274
impl ApiVersion {
@@ -285,7 +286,7 @@ impl ApiVersion {
285286

286287
/// Returns the maximum API version supported by ext-php-rs.
287288
pub const fn max() -> Self {
288-
ApiVersion::Php84
289+
ApiVersion::Php85
289290
}
290291

291292
pub fn versions() -> Vec<Self> {
@@ -295,6 +296,7 @@ impl ApiVersion {
295296
ApiVersion::Php82,
296297
ApiVersion::Php83,
297298
ApiVersion::Php84,
299+
ApiVersion::Php85,
298300
]
299301
}
300302

@@ -313,6 +315,7 @@ impl ApiVersion {
313315
ApiVersion::Php82 => "php82",
314316
ApiVersion::Php83 => "php83",
315317
ApiVersion::Php84 => "php84",
318+
ApiVersion::Php85 => "php85",
316319
}
317320
}
318321

@@ -323,6 +326,7 @@ impl ApiVersion {
323326
ApiVersion::Php82 => "EXT_PHP_RS_PHP_82",
324327
ApiVersion::Php83 => "EXT_PHP_RS_PHP_83",
325328
ApiVersion::Php84 => "EXT_PHP_RS_PHP_84",
329+
ApiVersion::Php85 => "EXT_PHP_RS_PHP_85",
326330
}
327331
}
328332
}
@@ -344,7 +348,10 @@ impl TryFrom<u32> for ApiVersion {
344348
x if ((ApiVersion::Php83 as u32)..(ApiVersion::Php84 as u32)).contains(&x) => {
345349
Ok(ApiVersion::Php83)
346350
}
347-
x if (ApiVersion::Php84 as u32) == x => Ok(ApiVersion::Php84),
351+
x if ((ApiVersion::Php84 as u32)..(ApiVersion::Php85 as u32)).contains(&x) => {
352+
Ok(ApiVersion::Php84)
353+
}
354+
x if (ApiVersion::Php85 as u32) == x => Ok(ApiVersion::Php85),
348355
version => Err(anyhow!(
349356
"The current version of PHP is not supported. Current PHP API version: {}, requires a version between {} and {}",
350357
version,
@@ -371,7 +378,7 @@ fn check_php_version(info: &PHPInfo) -> Result<()> {
371378
// The PHP version cfg flags should also stack - if you compile on PHP 8.2 you
372379
// should get both the `php81` and `php82` flags.
373380
println!(
374-
"cargo::rustc-check-cfg=cfg(php80, php81, php82, php83, php84, php_zts, php_debug, docs)"
381+
"cargo::rustc-check-cfg=cfg(php80, php81, php82, php83, php84, php85, php_zts, php_debug, docs)"
375382
);
376383

377384
if version == ApiVersion::Php80 {
@@ -416,6 +423,7 @@ fn main() -> Result<()> {
416423
println!("cargo:rustc-cfg=php82");
417424
println!("cargo:rustc-cfg=php83");
418425
println!("cargo:rustc-cfg=php84");
426+
println!("cargo:rustc-cfg=php85");
419427
std::fs::copy("docsrs_bindings.rs", out_path)
420428
.expect("failed to copy docs.rs stub bindings to out directory");
421429
return Ok(());

docsrs_bindings.rs

Lines changed: 173 additions & 129 deletions
Large diffs are not rendered by default.

src/constant.rs

Lines changed: 63 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -107,13 +107,26 @@ impl IntoConst for &str {
107107
flags: GlobalConstantFlags,
108108
) -> Result<()> {
109109
unsafe {
110-
zend_register_string_constant(
111-
CString::new(name)?.as_ptr(),
112-
name.len() as _,
113-
CString::new(*self)?.as_ptr(),
114-
flags.bits().try_into()?,
115-
module_number,
116-
);
110+
#[cfg(php85)]
111+
{
112+
let _ = zend_register_string_constant(
113+
CString::new(name)?.as_ptr(),
114+
name.len() as _,
115+
CString::new(*self)?.as_ptr(),
116+
flags.bits().try_into()?,
117+
module_number,
118+
);
119+
}
120+
#[cfg(not(php85))]
121+
{
122+
zend_register_string_constant(
123+
CString::new(name)?.as_ptr(),
124+
name.len() as _,
125+
CString::new(*self)?.as_ptr(),
126+
flags.bits().try_into()?,
127+
module_number,
128+
);
129+
}
117130
};
118131
Ok(())
119132
}
@@ -127,13 +140,26 @@ impl IntoConst for bool {
127140
flags: GlobalConstantFlags,
128141
) -> Result<()> {
129142
unsafe {
130-
zend_register_bool_constant(
131-
CString::new(name)?.as_ptr(),
132-
name.len() as _,
133-
*self,
134-
flags.bits().try_into()?,
135-
module_number,
136-
);
143+
#[cfg(php85)]
144+
{
145+
let _ = zend_register_bool_constant(
146+
CString::new(name)?.as_ptr(),
147+
name.len() as _,
148+
*self,
149+
flags.bits().try_into()?,
150+
module_number,
151+
);
152+
}
153+
#[cfg(not(php85))]
154+
{
155+
zend_register_bool_constant(
156+
CString::new(name)?.as_ptr(),
157+
name.len() as _,
158+
*self,
159+
flags.bits().try_into()?,
160+
module_number,
161+
);
162+
}
137163
};
138164
Ok(())
139165
}
@@ -150,15 +176,29 @@ macro_rules! into_const_num {
150176
module_number: i32,
151177
flags: GlobalConstantFlags,
152178
) -> Result<()> {
153-
Ok(unsafe {
154-
$fn(
155-
CString::new(name)?.as_ptr(),
156-
name.len() as _,
157-
(*self).into(),
158-
flags.bits().try_into()?,
159-
module_number,
160-
)
161-
})
179+
unsafe {
180+
#[cfg(php85)]
181+
{
182+
let _ = $fn(
183+
CString::new(name)?.as_ptr(),
184+
name.len() as _,
185+
(*self).into(),
186+
flags.bits().try_into()?,
187+
module_number,
188+
);
189+
}
190+
#[cfg(not(php85))]
191+
{
192+
$fn(
193+
CString::new(name)?.as_ptr(),
194+
name.len() as _,
195+
(*self).into(),
196+
flags.bits().try_into()?,
197+
module_number,
198+
);
199+
}
200+
};
201+
Ok(())
162202
}
163203
}
164204
};

src/types/array/iterators.rs

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@ use crate::{
1515
types::Zval,
1616
};
1717

18+
#[cfg(php85)]
19+
use crate::ffi::zend_hash_key_type_HASH_KEY_NON_EXISTENT;
20+
1821
/// Immutable iterator upon a reference to a hashtable.
1922
pub struct Iter<'a> {
2023
ht: &'a ZendHashTable,
@@ -59,11 +62,16 @@ impl<'a> Iter<'a> {
5962
zend_hash_get_current_key_type_ex(ptr::from_ref(self.ht).cast_mut(), &raw mut self.pos)
6063
};
6164

62-
// Key type `-1` is ???
63-
// Key type `1` is string
64-
// Key type `2` is long
65-
// Key type `3` is null meaning the end of the array
66-
if key_type == -1 || key_type == 3 {
65+
// Key type `-1` (pre-PHP 8.5) or HASH_KEY_NON_EXISTENT (PHP 8.5+) is ???
66+
// Key type `1` is string (HASH_KEY_IS_STRING)
67+
// Key type `2` is long (HASH_KEY_IS_LONG)
68+
// Key type `3` is null meaning the end of the array (HASH_KEY_NON_EXISTENT)
69+
#[cfg(php85)]
70+
if key_type == zend_hash_key_type_HASH_KEY_NON_EXISTENT {
71+
return None;
72+
}
73+
#[cfg(not(php85))]
74+
if key_type == 3 {
6775
return None;
6876
}
6977

@@ -157,7 +165,12 @@ impl DoubleEndedIterator for Iter<'_> {
157165
zend_hash_get_current_key_type_ex(ptr::from_ref(self.ht).cast_mut(), &raw mut self.pos)
158166
};
159167

160-
if key_type == -1 {
168+
#[cfg(php85)]
169+
if key_type == zend_hash_key_type_HASH_KEY_NON_EXISTENT {
170+
return None;
171+
}
172+
#[cfg(not(php85))]
173+
if key_type == 3 {
161174
return None;
162175
}
163176

tools/update_bindings.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,5 @@ docker buildx build \
99
--platform linux/amd64 \
1010
--target docsrs_bindings \
1111
-o type=local,dest=. \
12-
--build-arg PHP_VERSION=8.4 \
12+
--build-arg PHP_VERSION=8.5 \
1313
.

0 commit comments

Comments
 (0)