[wp-trac] [WordPress Trac] #30891: Unchecked property overloading is detrimental to OOP.
WordPress Trac
noreply at wordpress.org
Sat Jan 3 12:57:04 UTC 2015
#30891: Unchecked property overloading is detrimental to OOP.
--------------------------+-----------------------------
Reporter: aercolino | Owner:
Type: defect (bug) | Status: new
Priority: normal | Milestone: Awaiting Review
Component: General | Version: 4.0
Severity: normal | Keywords:
Focuses: |
--------------------------+-----------------------------
Original Summary: Unchecked property overloading is detrimental to OOP.
[http://php.net/manual/en/language.oop5.overloading.php#language.oop5.overloading.members
Property] and
[http://php.net/manual/en/language.oop5.overloading.php#language.oop5.overloading.methods
Method] overloading (allowed by magic methods !__get, !__set, !__isset,
!__unset, and !__call) have been thoroughly introduced into WP code for
Backward Compatibility, maybe starting from Changeset/21512, but mostly
since version 4.0.0.
The copy-&-paste-d code I'm referring to is:
{{{
#!php
/**
* Make private properties readable for backwards compatibility.
*
* @since 4.0.0
* @access public
*
* @param string $name Property to get.
* @return mixed Property.
*/
public function __get( $name ) {
return $this->$name;
}
/**
* Make private properties settable for backwards compatibility.
*
* @since 4.0.0
* @access public
*
* @param string $name Property to set.
* @param mixed $value Property value.
* @return mixed Newly-set property.
*/
public function __set( $name, $value ) {
return $this->$name = $value;
}
/**
* Make private properties checkable for backwards compatibility.
*
* @since 4.0.0
* @access public
*
* @param string $name Property to check if set.
* @return bool Whether the property is set.
*/
public function __isset( $name ) {
return isset( $this->$name );
}
/**
* Make private properties un-settable for backwards
compatibility.
*
* @since 4.0.0
* @access public
*
* @param string $name Property to unset.
*/
public function __unset( $name ) {
unset( $this->$name );
}
/**
* Make private/protected methods readable for backwards
compatibility.
*
* @since 4.0.0
* @access public
*
* @param callable $name Method to call.
* @param array $arguments Arguments to pass when calling.
* @return mixed|bool Return value of the callback, false
otherwise.
*/
public function __call( $name, $arguments ) {
return call_user_func_array( array( $this, $name ),
$arguments );
}
}}}
Unchecked overloading (i.e. lazy programming) is detrimental to OOP
because it neutralizes all protections. No matter what, all properties and
methods of classes with unchecked overloading are always public.
I mean, not only legacy properties and methods that existed before
introducing unchecked overloading but also all others that '''were, are
being and will be''' introduced afterward and really meant to be private
or protected.
This is a very important issue, whose implications will be appreciated in
the future. Currently, it all seems fine, but it's an illusion. As time
goes by, on one side the WP core will continue to migrate to PHP5 (and its
access rules) and on the other side theme and plugin hackers will continue
to squeeze WP as much as possible. When core developers introduce
protection for new properties and methods, they expect that protection to
be taken into account by the ecosystem, and finally by theme and plugin
developers, which are the ones those protections were thought for. BUT if
WP theme plugin and core developers will always be able to access whatever
they want as they please, then I wonder why PHP5 protections were
introduced in the first place.
Here is a tedious but simple fix (i.e. checked overloading):
{{{
#!php
if (! array_key_exists($name, $this->legacy_properties)) {
$trace = debug_backtrace();
trigger_error('Undefined property' ..., E_USER_NOTICE);
}
// rest of __get, __set, __isset, __unset code here
}}}
{{{
#!php
if (! array_key_exists($name, $this->legacy_methods)) {
$trace = debug_backtrace();
trigger_error('Call to undefined method' ..., E_USER_ERROR);
}
// rest of __call code here
}}}
If this issue is not fixed ASAP, developers will find these "backdoors"
and start to use them. Then it gets worse.
--
Ticket URL: <https://core.trac.wordpress.org/ticket/30891>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform
More information about the wp-trac
mailing list