[wp-trac] [WordPress Trac] #57580: Avoid errors from null parameters in add_submenu_page()
WordPress Trac
noreply at wordpress.org
Thu Dec 12 10:08:11 UTC 2024
#57580: Avoid errors from null parameters in add_submenu_page()
------------------------------------------+-----------------------------
Reporter: ipajen | Owner: (none)
Type: enhancement | Status: reopened
Priority: normal | Milestone: Future Release
Component: General | Version:
Severity: normal | Resolution:
Keywords: PHP81 has-patch dev-feedback | Focuses: administration
------------------------------------------+-----------------------------
Comment (by nprwp):
If you are going to make the parameter only accept a real string, which
could be sensible if you want the callee to check for nulls, although
personally I'd wish PHP could allow you to overload the function with a
version that does accept null, checks for it, then calls the original just
for obeying 'be liberal in what you accept, be conservative in what you
emit' principle (but alas, there's no support for that), it results in an
indirect problem too, which I think should be changed.
There's a way in which this interacts with another part of wordpress that
causes quite a few plugins (including paid ones that are hard to update)
to fail by using wordpress in a way that seems intended, given the
documentation of this other part.
I'm referring to the function {{{plugins_url()}}}, which is used by
plugins to serve files or otherwise figure out where they're installed,
which may be important to use php's file writing/reading functions do do
stuff.
{{{
plugins_url( null, __FILE__ )
}}}
is the typical way you see this function called, which then indirectly
calls {{{wp_is_stream}}}. The function signature looks like this:
{{{
/**
* Retrieves a URL within the plugins or mu-plugins directory.
*
* Defaults to the plugins directory URL if no arguments are supplied.
*
* @since 2.6.0
*
* @param string $path Optional. Extra path appended to the end of the
URL, including
* the relative directory if $plugin is supplied.
Default empty.
* @param string $plugin Optional. A full path to a file inside a plugin
or mu-plugin.
* The URL will be relative to its directory.
Default empty.
* Typically this is done by passing `__FILE__` as
the argument.
* @return string Plugins URL link with optional paths appended.
*/
}}}
Notice how each parameter says "optional"? This usually, in terms of type
hints, in a (strongly) typed language with no ability for optional
parameters, as is the case with php7, which is still supported by
wordpress, the normal way to do it is to pass NULLs for values you don't
need if you need to pass parameter !#2, but not parameter !#1. This is
''very'' common for this function; as if your plugin has a simple file
structure, it typically doesn't have a subdirectory for downloadable files
but uses the regular path.
Inverting the order of the parameters (which was badly chosen) is not
really an option because it'd break everyone's code. So you're left with
only the option to ignore it and let plugins break everywhere or fix it
for them.
This ability to pass both NULL and a value is represented as {{{string?}}}
which is different from {{{string}}} in that it **accepts nulls**. Yet,
you're effectively asking for a strict {{{string}}} in plugins_url while
denoting the param as 'optional'; but it works for PHP8 in one way and for
PHP7 in another.
Should this function gain a null check that casts the value to 'empty
string' for its first parameter? A lot of plugins pass null and it appears
to be a sensible thing to do for compatibility reasons, which then gets
them snafu'd (and the user a bunch of warning messages that mess up their
site) for choosing to use {{{NULL}}} instead of {{{''}}} when sites update
to PHP8.
--
Ticket URL: <https://core.trac.wordpress.org/ticket/57580#comment:32>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform
More information about the wp-trac
mailing list