Skip to content

Commit 6fd3162

Browse files
Add preliminary PHP 8.1 support (#109)
* Bump PHP API version, remove flags removed from PHP API See following commits: - php/php-src@70195c3 - php/php-src@b5746a4 * Add PHP 8.1 to CI * Clippy lint * Fix PHP 8.1 support with new features
1 parent 0a0293a commit 6fd3162

File tree

6 files changed

+43
-21
lines changed

6 files changed

+43
-21
lines changed

.github/workflows/build.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ jobs:
1919
- nightly
2020
php:
2121
- '8.0'
22+
- '8.1'
2223
llvm:
2324
- '11.0'
2425
steps:

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ exclude = ["/.github", "/.crates", "/guide"]
1414
[dependencies]
1515
bitflags = "1.2.1"
1616
parking_lot = "0.11.2"
17+
cfg-if = "1.0"
1718
ext-php-rs-derive = { version = "=0.7.1", path = "./crates/macros" }
1819

1920
[build-dependencies]

allowed_bindings.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -190,5 +190,6 @@ bind! {
190190
zend_class_serialize_deny,
191191
zend_class_unserialize_deny,
192192
zend_objects_store_del,
193-
gc_possible_root
193+
gc_possible_root,
194+
ZEND_ACC_NOT_SERIALIZABLE
194195
}

build.rs

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,13 @@ use std::{
88
use regex::Regex;
99

1010
const MIN_PHP_API_VER: u32 = 20200930;
11-
const MAX_PHP_API_VER: u32 = 20200930;
11+
const MAX_PHP_API_VER: u32 = 20210902;
1212

1313
fn main() {
1414
// rerun if wrapper header is changed
1515
println!("cargo:rerun-if-changed=src/wrapper.h");
1616
println!("cargo:rerun-if-changed=src/wrapper.c");
17+
println!("cargo:rerun-if-changed=allowed_bindings.rs");
1718

1819
let out_dir = env::var_os("OUT_DIR").expect("Failed to get OUT_DIR");
1920
let out_path = PathBuf::from(out_dir).join("bindings.rs");
@@ -63,10 +64,25 @@ fn main() {
6364
.and_then(|ver| ver.as_str().parse::<u32>().ok())
6465
.expect("Unable to retrieve PHP API version from `php -i`.");
6566

66-
if api_ver < MIN_PHP_API_VER || api_ver > MAX_PHP_API_VER {
67+
if !(MIN_PHP_API_VER..=MAX_PHP_API_VER).contains(&api_ver) {
6768
panic!("The current version of PHP is not supported. Current PHP API version: {}, requires a version between {} and {}", api_ver, MIN_PHP_API_VER, MAX_PHP_API_VER);
6869
}
6970

71+
// Infra cfg flags - use these for things that change in the Zend API that don't
72+
// rely on a feature and the crate user won't care about (e.g. struct field
73+
// changes). Use a feature flag for an actual feature (e.g. enums being
74+
// introduced in PHP 8.1).
75+
//
76+
// PHP 8.0 is the baseline - no feature flags will be introduced here.
77+
//
78+
// The PHP version cfg flags should also stack - if you compile on PHP 8.2 you
79+
// should get both the `php81` and `php82` flags.
80+
const PHP_81_API_VER: u32 = 20210902;
81+
82+
if api_ver >= PHP_81_API_VER {
83+
println!("cargo:rustc-cfg=php81");
84+
}
85+
7086
let includes =
7187
String::from_utf8(includes_cmd.stdout).expect("unable to parse `php-config` stdout");
7288

src/builders/class.rs

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ use crate::{
77
error::{Error, Result},
88
exception::PhpException,
99
ffi::{
10-
zend_class_serialize_deny, zend_class_unserialize_deny, zend_declare_class_constant,
11-
zend_declare_property, zend_do_implement_interface, zend_register_internal_class_ex,
10+
zend_declare_class_constant, zend_declare_property, zend_do_implement_interface,
11+
zend_register_internal_class_ex,
1212
},
1313
flags::{ClassFlags, MethodFlags, PropertyFlags},
1414
types::{ZendClassObject, ZendObject, ZendStr, Zval},
@@ -242,12 +242,15 @@ impl ClassBuilder {
242242
};
243243

244244
// disable serialization if the class has an associated object
245-
//
246-
// TODO(david): change to support PHP 8.1 - uses a flag instead of the
247-
// serializable/deserializable properties
248245
if self.object_override.is_some() {
249-
class.serialize = Some(zend_class_serialize_deny);
250-
class.unserialize = Some(zend_class_unserialize_deny);
246+
cfg_if::cfg_if! {
247+
if #[cfg(php81)] {
248+
class.ce_flags |= ClassFlags::NotSerializable.bits();
249+
} else {
250+
class.serialize = Some(crate::ffi::zend_class_serialize_deny);
251+
class.unserialize = Some(crate::ffi::zend_class_unserialize_deny);
252+
}
253+
}
251254
}
252255

253256
for iface in self.interfaces {

src/flags.rs

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,14 @@ use crate::ffi::{
1010
ZEND_ACC_CHANGED, ZEND_ACC_CLOSURE, ZEND_ACC_CONSTANTS_UPDATED, ZEND_ACC_CTOR,
1111
ZEND_ACC_DEPRECATED, ZEND_ACC_DONE_PASS_TWO, ZEND_ACC_EARLY_BINDING, ZEND_ACC_FAKE_CLOSURE,
1212
ZEND_ACC_FINAL, ZEND_ACC_GENERATOR, ZEND_ACC_HAS_FINALLY_BLOCK, ZEND_ACC_HAS_RETURN_TYPE,
13-
ZEND_ACC_HAS_TYPE_HINTS, ZEND_ACC_HAS_UNLINKED_USES, ZEND_ACC_HEAP_RT_CACHE,
14-
ZEND_ACC_IMMUTABLE, ZEND_ACC_IMPLICIT_ABSTRACT_CLASS, ZEND_ACC_INTERFACE, ZEND_ACC_LINKED,
15-
ZEND_ACC_NEARLY_LINKED, ZEND_ACC_NEVER_CACHE, ZEND_ACC_NO_DYNAMIC_PROPERTIES,
16-
ZEND_ACC_PRELOADED, ZEND_ACC_PRIVATE, ZEND_ACC_PROMOTED, ZEND_ACC_PROPERTY_TYPES_RESOLVED,
17-
ZEND_ACC_PROTECTED, ZEND_ACC_PUBLIC, ZEND_ACC_RESOLVED_INTERFACES, ZEND_ACC_RESOLVED_PARENT,
18-
ZEND_ACC_RETURN_REFERENCE, ZEND_ACC_REUSE_GET_ITERATOR, ZEND_ACC_STATIC, ZEND_ACC_STRICT_TYPES,
19-
ZEND_ACC_TOP_LEVEL, ZEND_ACC_TRAIT, ZEND_ACC_TRAIT_CLONE, ZEND_ACC_UNRESOLVED_VARIANCE,
20-
ZEND_ACC_USES_THIS, ZEND_ACC_USE_GUARDS, ZEND_ACC_VARIADIC, ZEND_HAS_STATIC_IN_METHODS,
21-
Z_TYPE_FLAGS_SHIFT, _IS_BOOL,
13+
ZEND_ACC_HAS_TYPE_HINTS, ZEND_ACC_HEAP_RT_CACHE, ZEND_ACC_IMMUTABLE,
14+
ZEND_ACC_IMPLICIT_ABSTRACT_CLASS, ZEND_ACC_INTERFACE, ZEND_ACC_LINKED, ZEND_ACC_NEARLY_LINKED,
15+
ZEND_ACC_NEVER_CACHE, ZEND_ACC_NO_DYNAMIC_PROPERTIES, ZEND_ACC_PRELOADED, ZEND_ACC_PRIVATE,
16+
ZEND_ACC_PROMOTED, ZEND_ACC_PROTECTED, ZEND_ACC_PUBLIC, ZEND_ACC_RESOLVED_INTERFACES,
17+
ZEND_ACC_RESOLVED_PARENT, ZEND_ACC_RETURN_REFERENCE, ZEND_ACC_REUSE_GET_ITERATOR,
18+
ZEND_ACC_STATIC, ZEND_ACC_STRICT_TYPES, ZEND_ACC_TOP_LEVEL, ZEND_ACC_TRAIT,
19+
ZEND_ACC_TRAIT_CLONE, ZEND_ACC_UNRESOLVED_VARIANCE, ZEND_ACC_USES_THIS, ZEND_ACC_USE_GUARDS,
20+
ZEND_ACC_VARIADIC, ZEND_HAS_STATIC_IN_METHODS, Z_TYPE_FLAGS_SHIFT, _IS_BOOL,
2221
};
2322

2423
use std::{convert::TryFrom, fmt::Display};
@@ -76,13 +75,14 @@ bitflags! {
7675
const ConstantsUpdated = ZEND_ACC_CONSTANTS_UPDATED;
7776
const NoDynamicProperties = ZEND_ACC_NO_DYNAMIC_PROPERTIES;
7877
const HasStaticInMethods = ZEND_HAS_STATIC_IN_METHODS;
79-
const PropertyTypesResolved = ZEND_ACC_PROPERTY_TYPES_RESOLVED;
8078
const ReuseGetIterator = ZEND_ACC_REUSE_GET_ITERATOR;
8179
const ResolvedParent = ZEND_ACC_RESOLVED_PARENT;
8280
const ResolvedInterfaces = ZEND_ACC_RESOLVED_INTERFACES;
8381
const UnresolvedVariance = ZEND_ACC_UNRESOLVED_VARIANCE;
8482
const NearlyLinked = ZEND_ACC_NEARLY_LINKED;
85-
const HasUnlinkedUses = ZEND_ACC_HAS_UNLINKED_USES;
83+
84+
#[cfg(php81)]
85+
const NotSerializable = crate::ffi::ZEND_ACC_NOT_SERIALIZABLE;
8686
}
8787
}
8888

0 commit comments

Comments
 (0)