summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOlly Betts <olly@survex.com>2022-09-29 18:14:23 +1300
committerOlly Betts <olly@survex.com>2022-09-29 18:16:51 +1300
commit9a4dea06c81448f86187c115912b4062ad1b3031 (patch)
tree05d73ec5f32114fc331d21b88ab76111887b320c
parent20ed76a27b9419cb7e07c1a4adb444a087555fb4 (diff)
downloadswig-9a4dea06c81448f86187c115912b4062ad1b3031.tar.gz
[php] Add php:allowdynamicproperties feature
This follows PHP 8.2 deprecating dynamic features. The new feature also provides a clean way to fix the remaining PHP test case failure under PHP 8.2.
-rw-r--r--CHANGES.current23
-rw-r--r--Doc/Manual/Php.html48
-rw-r--r--Examples/test-suite/cpp_basic.i2
-rw-r--r--Source/Modules/php.cxx17
4 files changed, 86 insertions, 4 deletions
diff --git a/CHANGES.current b/CHANGES.current
index 6df9d6c5f..bbdcdfb3b 100644
--- a/CHANGES.current
+++ b/CHANGES.current
@@ -7,6 +7,29 @@ the issue number to the end of the URL: https://github.com/swig/swig/issues/
Version 4.1.0 (in progress)
===========================
+2022-09-29: olly
+ [PHP] Dynamic class properties are no longer supported by default.
+
+ Historically PHP has supported dynamic class properties and SWIG
+ has implemented them too (because we implement the magic __get(),
+ __set() and __isset() methods we need to include explicit
+ handling).
+
+ PHP 8.2 deprecates dynamic class properties - initially they'll
+ warn, and apparently they'll not work by default in PHP 9.0:
+ https://wiki.php.net/rfc/deprecate_dynamic_properties
+
+ In PHP code dynamic properties can be enabled for a class by
+ marking that class with the attribute `#[AllowDynamicProperties]`.
+
+ To follow this PHP change, in SWIG you now need to specify
+ `%feature("php:allowdynamicproperties", 1) Foo;` (or
+ `%feature("php:allowdynamicproperties", 1)` to enable it for
+ all wrapped classes). Unknown features are ignored, so you can add
+ it unconditionally and it'll work with older SWIG too.
+
+ *** POTENTIAL INCOMPATIBILITY ***
+
2022-09-19: wsfulton
#1484 Fixes for class inheritance with the same name in different namespaces
such as:
diff --git a/Doc/Manual/Php.html b/Doc/Manual/Php.html
index 72c914656..49d0474f7 100644
--- a/Doc/Manual/Php.html
+++ b/Doc/Manual/Php.html
@@ -30,6 +30,7 @@
<li><a href="#Php_nn2_6_3">Static Member Variables</a>
<li><a href="#Php_nn2_6_4">Static Member Functions</a>
<li><a href="#Php_nn2_6_5">Specifying Implemented Interfaces</a>
+<li><a href="#Php_nn2_6_6">Dynamic Properties</a>
</ul>
<li><a href="#Php_nn2_7">PHP Pragmas, Startup and Shutdown code</a>
</ul>
@@ -843,6 +844,53 @@ so:
If there are multiple interfaces, just list them separated by commas.
</p>
+
+<H4><a name="Php_nn2_6_6">32.2.6.6 Dynamic Properties</a></H4>
+
+
+<p>
+Historically PHP has supported dynamic class properties and SWIG
+has implemented them too (because we implement the magic <tt>__get()</tt>,
+<tt>__set()</tt> and <tt>__isset()</tt> methods we need to include explicit
+handling).
+</p>
+
+<p>
+PHP 8.2 <a
+href="https://wiki.php.net/rfc/deprecate_dynamic_properties">deprecates
+dynamic class properties</a> - initially they'll warn, and apparently they'll
+not work by default in PHP 9.0.
+</p>
+
+<p>
+In PHP code dynamic properties can be enabled for a class by
+marking that class with the attribute <tt>#[AllowDynamicProperties]</tt>.
+</p>
+
+<p>
+To follow this PHP change, as of SWIG 4.1.0 you now need enable dynamic
+properties for any classes you want to support them. To enable for class
+<tt>Foo</tt>:
+</p>
+
+<div class="code"><pre>
+%feature("php:allowdynamicproperties", 1) Foo;
+</pre></div>
+
+<p>
+or to enable them for all wrapped classes:
+</p>
+
+<div class="code"><pre>
+%feature("php:allowdynamicproperties", 1);
+</pre></div>
+
+<p>
+Note that unknown features are ignored, so you can add use these
+unconditionally in your interface file and it'll work with older SWIG too.
+</p>
+
+
<H3><a name="Php_nn2_7">32.2.7 PHP Pragmas, Startup and Shutdown code</a></H3>
diff --git a/Examples/test-suite/cpp_basic.i b/Examples/test-suite/cpp_basic.i
index c39206b13..8c31a9cf0 100644
--- a/Examples/test-suite/cpp_basic.i
+++ b/Examples/test-suite/cpp_basic.i
@@ -4,6 +4,8 @@
%warnfilter(SWIGWARN_RUBY_WRONG_NAME) global_cint; /* Ruby, wrong constant name */
+%feature("php:allowdynamicproperties", 1) Foo; /* Allow PHP-specific custom property testing in _runme.php */
+
%module cpp_basic
%newobject Bar::testFoo;
diff --git a/Source/Modules/php.cxx b/Source/Modules/php.cxx
index 3f12c0448..e6b9e991a 100644
--- a/Source/Modules/php.cxx
+++ b/Source/Modules/php.cxx
@@ -1056,12 +1056,12 @@ public:
" if (director) director->swig_disown();\n",
"}\n", NIL);
}
- Printf(f->code, "} else {\n");
if (swig_base) {
- Printf(f->code, "PHP_MN(%s%s___set)(INTERNAL_FUNCTION_PARAM_PASSTHRU);\n}\n", prefix, swig_base);
- } else {
- Printf(f->code, "add_property_zval_ex(ZEND_THIS, ZSTR_VAL(arg2), ZSTR_LEN(arg2), &args[1]);\n}\n");
+ Printf(f->code, "} else {\nPHP_MN(%s%s___set)(INTERNAL_FUNCTION_PARAM_PASSTHRU);\n", prefix, swig_base);
+ } else if (Getattr(class_node, "feature:php:allowdynamicproperties")) {
+ Printf(f->code, "} else {\nadd_property_zval_ex(ZEND_THIS, ZSTR_VAL(arg2), ZSTR_LEN(arg2), &args[1]);\n");
}
+ Printf(f->code, "}\n");
Printf(f->code, "fail:\n");
Printf(f->code, "return;\n");
@@ -1777,6 +1777,15 @@ public:
if (Getattr(n, "abstracts") && !GetFlag(n, "feature:notabstract")) {
Printf(s_oinit, " SWIG_Php_ce_%s->ce_flags |= ZEND_ACC_EXPLICIT_ABSTRACT_CLASS;\n", class_name);
}
+ if (Getattr(n, "feature:php:allowdynamicproperties")) {
+ Append(s_oinit, "#ifdef ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES\n");
+ Printf(s_oinit, " SWIG_Php_ce_%s->ce_flags |= ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES;\n", class_name);
+ Append(s_oinit, "#endif\n");
+ } else {
+ Append(s_oinit, "#ifdef ZEND_ACC_NO_DYNAMIC_PROPERTIES\n");
+ Printf(s_oinit, " SWIG_Php_ce_%s->ce_flags |= ZEND_ACC_NO_DYNAMIC_PROPERTIES;\n", class_name);
+ Append(s_oinit, "#endif\n");
+ }
String *swig_wrapped = swig_wrapped_interface_ce();
Printv(s_oinit, " zend_do_implement_interface(SWIG_Php_ce_", class_name, ", &", swig_wrapped, ");\n", NIL);