Setup separator in the class constructor#68
Setup separator in the class constructor#68Llewellynvdm merged 9 commits intojoomla-framework:2.0-devfrom
Conversation
|
Please remember to adjust the tests from #66 once they are merged. With this PR, direct access of the |
|
Okay guys, on second thought I decided not to do a magic _get/_set. Example when any extension creating a dynamic property , after adding __get it become not possible, and could lead to broken extension. Originaly I coded this: /**
* Magic method to access separator property.
*
* @param string $name The name of the property.
*
* @return string|null A value if the property name is valid, null otherwise.
*
* @since 2.1.0
* @deprecated 4.0 This is a B/C proxy for deprecated read accesses
*/
public function __get($name)
{
switch ($name) {
case 'separator':
\trigger_deprecation(
'joomla/registry',
'2.1.0',
'The $separator parameter will be removed in version 4.',
self::class,
self::class
);
return $this->separator;
default:
$trace = \debug_backtrace();
\trigger_error(
\sprintf(
'Undefined property via __get(): %1$s in %2$s on line %3$s',
$name,
$trace[0]['file'],
$trace[0]['line']
),
E_USER_NOTICE
);
return null;
}
}
/**
* Magic method to access separator property.
*
* @param string $name The name of the property.
* @param mixed $value The value of the property.
*
* @return void
*
* @since 2.1.0
* @deprecated 4.0 This is a B/C proxy for deprecated read accesses
*/
public function __set($name, $value)
{
switch ($name)
{
case 'separator':
\trigger_deprecation(
'joomla/registry',
'2.1.0',
'The $separator parameter will be removed in version 4.',
self::class,
self::class
);
$this->separator = $value;
break;
default:
if (property_exists($this, $name)) {
throw new \RuntimeException(
\sprintf(
'Cannot access protected or private property %s::$%s',
__CLASS__,
$name
)
);
}
$trace = \debug_backtrace();
\trigger_error(
\sprintf(
'Undefined property via __get(): %1$s in %2$s on line %3$s',
$name,
$trace[0]['file'],
$trace[0]['line']
),
E_USER_NOTICE
);
$this->$name = $value;
break;
}
}But after testing I found that next code will be broken after introducing magic: $params->potato = 1;
var_dump($params->potato); |
|
It appears that the Registry does not currently have a magic setter or getter, and setting any class value should not work or be done. The fact that setting values like Array access, however, is a feature due to If adding new magic methods will be a breaking change, we can deal with it in another PR. This PR was originally intended to allow for setting up the separator with the constructor, which seems all good. The Object access is an side-affect, not a feature. That is why this for example returns What does work is array access (as a feature), because of the So that mean this returns the actually value from inside the registry It even honors the separator: I would like to ask for the opinions of @wilsonge, @nibra or @HLeithner regarding dealing with these changes, what version should we target, and if @Fedik still not willing to add the magic methods will one of you open a PR for it? or what do you think should be done here? |
|
more about adding this can be found here #58 |
|
As stated in a comment on #58, object access is not desired. It is not part of the contract. $reg = new \Joomla\Registry\Registry();
$reg->potato = 1;has never been allowed. |
Yes and no 😉 However it planed to be removed in php 9, as far as I know. I just want to reduce a risk of break something untill then. Because Registry often used for |
Valid point. So issue a deprecation warning on object access for any value, and a special one for |
|
I recall #58 being previously blocked, has our stance on it changed? I personally like the object access from #58 and providing more ways to access data, as PHP is my preferred language. However, I am also content with a standard method and array access as being sufficient. Therefore, I do not wish to see object-like access added to the Registry at this point, as stated in the #58 thread. The two current access methods are already well-documented. If our opinion changes, I would not object. However, these changes do conflict with current best practices (which is to add restraint) of the industry. Since restrain on this low level is always seen in a good light from what I have understood at least... though not all agree obviously. Will they ever? So I would agree with @nibra that we should not change the access to that of #58 but still apply the patch as suggested by @wilsonge |
|
Added magic stuff |
|
We can't forbid to set properties in the magic getter and setter this would be a b/c break because now it's possible, so we have to do the same for all variables like for the separator and throw a deprecation warning that direct class variables access will not be allowed starting with 3.0, this will also effect Joomla 5.0 which would be off course a b/c break for unintended behavior. Which shouldn't effect too many extensions. at least we have to document this also in manual.joomla.org |
|
Yes this I can support, and this makes sense. |
|
So I change removing version from 4 to 3? |
|
Yes, please. So for clarity, we allow setting and getting of class properties with deprecation warning that direct class variables access will not be allowed starting with 3.0 (Keep the |
true private and protected function should not be available thru the magic functions. @Fedik a deprecation is not a fatal error, so we shouldn't trigger this exception for php 7.2 |
|
I cannot check currently on 7.2, but on 8 I have an |
yes because |
Sorry I can't check this right now, can you try using a old docker container? |
|
I have updated,
That should work, at least it working for me :) $a = new Registry;
$a->b = 1; // Works
var_dump($a->b); // Works
$a->b = 2; // Works
var_dump($a->b); // Works
$a->data = 3; // Here an exception
var_dump($a->data); // Here an exceptionNote: The magic methods does not called for existing public properties. |
That has never been part of the contract, so it is NOT a B/C break. Being able to set properties directly runs counter to the purpose of the registry. |
|
I hear you, but the promise is not just what is documented but also what is possible, as the code is part of the "document." Since the Registry allows this behavior without warning or any kind of notice, it will not be hard to prove that it is, in fact, part of the promise at this time. It will not help anyone to just break the code of those using it downstream. Giving them a heads-up is best practice. |
|
Yes the Registry at this time, without this PR, does in fact allow: |
Yes, that's a design failure. If that was allowed, it had to be included in toArray() and consorts, which it isn't. |
|
Design failure or not, we will have to give people a heads-up. Breaking things when you fix things without warning has never been a good experience for anyone. I don't understand why you would follow any other path, its not like we are adding the behavior we are in fact taking steps to repair the design failure in a none destructive way. |
This part of PHP behavior, it is there even if we do not want it 😉 I have added it to __set to reduce a chance to break something, when someone use this PHP feature. |
|
LGTM, however, maybe deprecation should be targeted at 4.0, since 3.0 is quite close to be released?! |
|
I am fine with any version :) |
I don't see a real reason to delay this, most of it is unintended behavior anyway. |
Summary of Changes
As discussed in #66.
This allows to set up Separator with constructor.
And deprecte direct access to separator property.
Documentation Changes Required
Yeap, should be noted somewhere :)