Opened 18 months ago
Last modified 4 weeks ago
#60190 new enhancement
Drop PHP 4 support for arrays with 1 object element
Reported by: |
|
Owned by: | |
---|---|---|---|
Milestone: | 6.9 | Priority: | normal |
Severity: | normal | Version: | |
Component: | Plugins | Keywords: | has-patch has-unit-tests early 2nd-opinion close |
Focuses: | Cc: |
Description (last modified by )
do_action( 'foo', array( (object) null ) );
function foo_cb( array $arg ) {}
add_action( 'foo', 'foo_cb' );
This will fail with a fatal error in PHP 7+, since do_action
(as the only one, this isn't an issue with apply_filters
or do_action_ref_array
) will convert arrays with only 1 object into that object.
The reason for that is some PHP 4 legacy behavior, see #48312
It's time to drop this PHP 4 support, as this prevent using native types in callback functions in cases where the argument is an array of objects.
Change History (15)
This ticket was mentioned in PR #5839 on WordPress/wordpress-develop by @kkmuffme.
18 months ago
#1
- Keywords has-patch has-unit-tests added
This ticket was mentioned in Slack in #core by kkmuffme. View the logs.
17 months ago
#4
@
17 months ago
This will fail with a fatal error in PHP 7+
Can you elaborate on that? The existing test_action_args_with_php4_syntax
test seems to work just fine without triggering errors.
#5
@
17 months ago
As outlined in OP it will lead to a fatal if any callback uses PHP native types for array; you'll get:
Fatal error: Uncaught TypeError: ... must be of type array, stdClass given
Now you could say: just use a union type array|object, but that is:
a) only available since PHP 8+
b) unnecessarily weakening the PHP type system to keep PHP 4 compat that has been deprecated since a decade at this point.
#6
@
16 months ago
- Keywords needs-unit-tests added; has-unit-tests removed
- Milestone changed from Awaiting Review to Future Release
- Type changed from defect (bug) to enhancement
- Version trunk deleted
As outlined in OP it will lead to a fatal if any callback uses PHP native types for array; you'll get:
A test to demonstrate this would be great, just for completeness sake
Right now this patch removes a unit test, but the test actually still passes with the proposed patch, so why remove it?
@kkmuffme commented on PR #5839:
15 months ago
#7
Yes, I added a test now (which would result in a fatal error without this PR on standard WP 6.5)
#8
@
15 months ago
- Keywords has-unit-tests added; needs-unit-tests removed
Right now this patch removes a unit test, but the test actually still passes with the proposed patch, so why remove it?
Tested it, not true. The test fails. Removed it again.
A test to demonstrate this would be great, just for completeness sake
Done. This test would result in a fatal error without the changes of this PR (tested on WP 6.5)
(had some confusion initially, since I wasn't familiar how the args are tested/returned in WP phpunit tests)
This ticket was mentioned in Slack in #core by kkmuffme. View the logs.
15 months ago
This ticket was mentioned in Slack in #core by kkmuffme. View the logs.
14 months ago
This ticket was mentioned in Slack in #core by mikachan. View the logs.
13 months ago
#14
@
4 weeks ago
- Keywords 2nd-opinion added
To clarify about the fatal error: this isn't actually related to native type handling, that's just where the fatal error occurs when a callback function receives an object as its first parameter instead of the expected array containing an object. The underlying problem is, as @kkmuffme mentions, that do_action
will convert arrays with only 1 object into that object before passing it to the callbacks. Regardless of whether a callback uses a type declaration, it'll receive a value of the wrong type as its first parameter.
While I'm in favour of the fix and the tests in https://github.com/WordPress/wordpress-develop/pull/5839 I'm concerned about what might break. This is essentially a revert of [46568]. #48312 provides an example of code that will behave differently after this fix:
do_action( 'some_action', array( $this ) );
Currently a callback hooked into this action receives the object as its first parameter instead of an array containing the object. This proposed change "fixes" that but will break any existing code that works around this funky behaviour.
Does the fix justify the back-compat break?
CC @david.binda @SergeyBiryukov @azaozz
#15
@
4 weeks ago
- Keywords close added
It's time to drop this PHP 4 support, as this prevent using native types in callback functions in cases where the argument is an array of objects.
This seems good however I tend to agree with @johnbillion that it shouldn't be breaking back-compat for existing code. The assumption is that there may be quite a few places that have adapted to using the existing code. Imho it seems better to perhaps document this well and leave it as-is.
The same seems to be valid for the desire to use native types in callback args. Generally it is a good idea, but unfortunately don't see how it can be implemented without breaking back-compat. (Well, there may be ways but seemingly not elegant at all.)
Drop PHP 4 support for
do_action
with 1 array<object> argument where the array contains only 1 element, in favor of better support for PHP 7+ native types