Well, I guess I blinked and missed the internal@ thread on this topic :)
Seriously though, if there was a thread on this subject, please point me
in the right direction.
In PHP 5.3 snaps, it appears that magic methods __isset, __unset, __get,
__set must have a public visibility or the engine will trigger a
warning. Why is this? It works as expected in 5.x branches.
I am not sure why this should be enforced as it should be up to the
developer as to which methods in the API should be exposed for direct
invocation.
If a developer never intends on a user calling $obj->__set(...), then it
should be allowed that the public call to that method be disallowed, but
still allow the magic functionality (b/c of the presence of that magic
function.)
Without getting too long winded, ill just put code and warnings below.
Cheers,
Ralph Schindler
script.php
<?php
class SomeMagic
{
public static function getInstance() {}
protected function __construct() { }
protected function __isset($name){}
protected function __unset($name){}
protected function __set($name, $value){}
protected function __get($name) {}
protected function __clone() {}
protected function __destruct() {}
}
Warnings:
$ /usr/local/php53/bin/php test-magicaccess.php
PHP Warning: The magic method __isset() must have public visibility and
can not be static in script.php on line 8
PHP Warning: The magic method __unset() must have public visibility and
can not be static in script.php on line 9
PHP Warning: The magic method __set() must have public visibility and
can not be static in script.php on line 10
PHP Warning: The magic method __get() must have public visibility and
can not be static in script.php on line 11
Hi!
In PHP 5.3 snaps, it appears that magic methods __isset, __unset, __get,
__set must have a public visibility or the engine will trigger a
warning. Why is this? It works as expected in 5.x branches.
I think it doesn't actually work as expected - because as far as I can
see, visibility is ignored on these methods. Consider this code:
class Foo {
private function __get($name) {
return 42;
}
}
$z = new Foo();
echo $z->bar;
On 5.2, it happily prints 42, even though you should not have access to
__get from outside the class, if it were true "private". Having
"private" there actually is somewhat misleading - while it looks like
internal API and thus can be changed by the class developer at will or
dropped altogether, it is actually a public API which is exposed to the
client.
I am not sure why this should be enforced as it should be up to the
developer as to which methods in the API should be exposed for direct
invocation.
I don't think magic methods are meant to be directly invoked. That's why
they are magic ;) In any case, since these methods are invoked in
"magic" way anyway, regardless of visibility, putting non-public
visibility on them makes little sense and actually makes people think
they can not be invoked from outside of the class - while it is not the
case, they can. Thus, even if there was no warning, I'd recommend never
putting non-public visibility on them.
Stanislav Malyshev, Zend Software Architect
stas@zend.com http://www.zend.com/
(408)253-8829 MSN: stas@zend.com
Hello there,
I don't have enough time to write more detailed example, but I still want to
write my opinion.
I totally agree with Stanislav, because for me magic functions should be
used in last leaf of some class extend tree. They are some kind of feature
when you are producing the non-framework, specific project coding stuff.
Which mean they should be not encapsulated and invisible.
If a developer never intends on a user calling $obj->__set(...), then it
should be allowed that the public call to that method be disallowed, but
still allow the magic functionality (b/c of the presence of that magic
function.)
Giving the "user" ability to call $obj->__set() is just some kind of speed
optimization, you just miss the magic thing. Another point of view is that
this __set() is still a function why you want to disable the function calls
and enable the functionality? B/c of the presence of that magic function?
What a drama! This is not fairy world where magic should be wonderful thing
which just happens. Think of us (developers) as wizards, who know how/why
this magic works!
Nothing personal just some thoughts.
Regards, Dimitar Isusov
In PHP 5.3 snaps, it appears that magic methods __isset, __unset, __get,
__set must have a public visibility or the engine will trigger a
warning. Why is this? It works as expected in 5.x branches.
Because that's what the manual says it should do. And there are
technical reasons outlined by others here already. Here is the internals
discussion about getting things straight:
http://news.php.net/php.internals/36813
Thanks,
--Dan
--
T H E A N A L Y S I S A N D S O L U T I O N S C O M P A N Y
data intensive web and database programming
http://www.AnalysisAndSolutions.com/
4015 7th Ave #4, Brooklyn NY 11232 v: 718-854-0335 f: 718-854-0409
Daniel Convissor escribió:
Because that's what the manual says it should do.
Right, however I disagree with the fact it is a warning, it should be a
fatal error IMHO.
--
"A computer is like an Old Testament god, with a lot of rules and no
mercy. "
Cristian Rodríguez R.
Platform/OpenSUSE - Core Services
SUSE LINUX Products GmbH
Research & Development
http://www.opensuse.org/