Is there an Actionscript equivalent to PHP's __get() and __set() magic methods? I want to be able to override the behavior of getting/setting member variables.
There is no such thing, unfortunately.
All you can do is check for the existence of a specific property, by using either
myObject.hasOwnProperty (name)
on simple Objects or some variant of describeType() for Class instances, for example
describeType(myObject).accessor
to get an XMLList of all accessor methods or
describeType(myObject).variable
to get an XMLList of all variables.
describeType(), however, is quite expensive in terms of performance, so it pays to have some sort of type hash map to store the lists for each type and do lookups for types that have already been described once.
You could also use try/catch blocks around the parts where undefined properties might be accessed, but this also "eats" away a lot of performance, if many errors are thrown.
Found it.
Extending the Proxy class allows you to solve this problem.
Related
I know this is kind of a question of faith and has been asked many times before, but the answers I've found were either too general, didn't apply to my use case, or didn't satisfy otherwise.
I'm currently building an application that uses classes as representation for database tables. These classes don't offer any methods of their own, I've written a parser class for each one that works with their objects and returns the data in the format I need, which makes the parent classes nothing more than data storages and makes a nice distinction between data and logic.
Now, the consensus in OOP seems to be that you always have to use getters and setters instead of accessing class attributes directly.
An argument I've often heard is that using getters and setters gives the possibility of extending those functions later on, but in my opinion this goes against YAGNI and some other concepts I can't remember the name of right now - that a method should do exactly what you would expect from its name. If I wanted to do something more than simply set a value, I would write a new method, not put that into my setter method, since that one is, per definition, only supposed to set attributes. So I might as well skip the setter and just access the attribute directly.
Another one is that you can put validation in your setters, which I already do in my API that accesses these classes. In my opinion you shouldn't just pass values and have the object tell you if your value is okay or not, but instead validate those values first before you pass them to the object.
I do understand the purpose of private/protected attributes in "usual" classes, but when the class is literally just a data container without any methods, is this really needed? In other words: is there a glaring disadvantage to using public values, when the setter methods for those (were they private) would all just look like public function getAttr($attr) { $this->atrr = $attr; } anyway?
You only need a data structure, but the only suitable PHP construct is the class.
Typically, in object-oriented analysis, design and programming, a class is a model of a thing or concept and it encapsulates any knowledge and/or behaviour of the thing or concept.
However, in the context of this question, encapsulation is not needed since you only require a data structure.
Is there some crucial difference in writing the registry class in MVC with magic methods and writing the class with "regular" get and set methods?
For example, if I write the class with __get and __set I would access the registry objects through $registry->foo, and the other case would be $registry->getObject('foo'), or something like that, you understand me. I'm interested in the differences between these two, is something better or maybe depends on the particular situation or no difference?
There is no difference. It's mostly language specific. Use of registry is same for all languages and it's up to you how you solve read/write problem on implementation level. Only important thing is correctness of implementation everything else depends on: a) project level coding conventions; b) your taste; c) language abilities.
People tend not to access directly a public object but instead via its accessor, there is nothing difference at all, only using an accessor method is more preferable because it offers a better look for what is meant encapsulation and thus is a good practice.
In PHP it makes almost no difference. While getters and setters strictly define class interface and allows you to put additional code such as data validation into them, magic methods may facilitate your work if there are many properties to operate with. But in heavy load magic is significantly slower.
If your class acts as an entity only, you may use magic. You might be also interested in Nette\Object approach.
Lets just ignore for a moment that registry is kinda an anti-pattern.
Use of __set() and __get() comes with a minor performance penalty. But that can be ignored.The real problem will become noticeable later.
What if you have to store something that requires additional computation before it is set or returned. For example, what if you are storing time. Lets say, outside Registry you are using time in a "pretty" format, but you are storing it in unix-time format. This would require to add a special exception go your magic getters & setters.
What if you store more then one such value. What if something changes and your application has to migrate from metric to imperial system.
As you add more and more conditions to the stored information, this all usually results in huge switch statements in __get() and __set(). Really bad design choice.
Can someone please explain how overloading in PHP works? The manual doesn't do a very good job of it. I'm still thinking of overlaoding in the Java sense, but I know overloading in PHP is a completely different animal. All the PHP manual says is that overloading provides a mechanism for adding new properties and methods to a class at runtime, but it doesn't explain how PHP achieves this. Thanks in advance. Rylie
All the PHP manual says is that overloading provides a mechanism for adding new properties and methods to a class at runtime, but it doesn't explain how PHP achieves this.
The very manual page you linked to explains how the thing that PHP calls "overloading" works. You're pretty correct in that it has little to do with what the entire rest of the world calls overloading. In fact, the manual page says right at the top:
PHP's interpretation of "overloading" is different than most object oriented languages. Overloading traditionally provides the ability to have multiple methods with the same name but different quantities and types of arguments.
PHP has reserved a handful of special method names that you can optionally define in a class. They fall into two categories:
__get, __set, __isset and __unset are called when an instance variable (object property) is fetched, set, checked for existence, or unset respectively. All receive the name of the property as the first argument, and __set receives the new value as the second argument. These methods are only called when either the property does not exist or can not be accessed from the caller's scope (i.e. protected/private). It's worth noting that without these methods, PHP will silently create new instance variables on demand, when asked to.
__call and __callStatic are called when a method is called that, again, doesn't exist or can't be accessed from the caller's scope. The former is called for instance methods, the latter for class methods. The first argument is the name of the method called, and the second is an array of the arguments, by value (references are dereferenced).
These functions allow you to simulate adding methods to a class/instance after creation, though their use is clunky and awkward. Further, using them breaks autocomplete in IDEs.
Using anonymous functions might seem like a natural complement to this functionality, but it is currently not possible to bind an the instance ($this) to one at run time. This functionality was removed during the 5.3 beta because it couldn't be made clear and obvious. This has been corrected in PHP's current trunk, but it's unknown when the trunk will be stabilized for release.
Still on the PHP-OOP training wheels, this question may belong on failblog.org. =)
What are the benefits of method chaining in PHP?
I'm not sure if this is important, but I'll be calling my method statically. e.g.
$foo = Bar::get('sysop')->set('admin')->render();
From what I've read, any method which returns $this is allowed to be chained. I just learned this is new in PHP5. Seems to me there may be speed benefits if I don't have to instantiate a whole new object (calling it statically) and just select the few methods I need from the class?
Do I have that right?
There are no significant performance benefits to using either approach, especially on a production server with byte code cache.
Method chaining is just a shorter way of writing things. Compare with the longer version:
$foo = Bar::get('sysop');
$foo -> set('admin');
$foo -> render();
It does have some quirks, though: a typical IDE (such as Eclipse) can auto-complete your code in the longer version (as long as the type of $foo is known) but needs you to document the return type of all methods to work in the short version.
It still instantiates an object; it's just never assigned to a variable. Basically, you're just calling the methods of an anonymous object.
I think any cycle-savings would be negligible, but I think the unassigned objects would be freed immediately after this line of code, so you may have some memory savings (you could accomplish the same by setting assigned objects to null when you were done with them).
The main reason people use method chaining is for convenience; you're doing a lot in one line of code. Personally, I think it's messy and unmaintainable.
if I don't have to instantiate a whole
new object (calling it statically) and
just select the few methods I need
from the class?
Wrong! To return $this, the class has to be instantiated.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 1 year ago.
Improve this question
I always thought you should never set/get a member variable directly. E.g.
$x = new TestClass();
$x->varA = "test":
echo $->varB;
I thought you should always use object methods to access member variables.
But I've just been looking at __set and __get, which imply it's ok to access members directly.
There's no right answer here.
In the beginning, direct access to member variables was considered a bad idea because you lose the ability to make that access conditional upon some set of arbitrary programming logic. That's why we have the terror of getter and setter methods.
Having magic methods like __set and __get removes this concern. You can have users of your object access member variables all you want and then if you discover you need some programatic logic around that access, you can use the magic methods.
However, particularly in PHP, __set and __get aren't free from a performance perspective. Also, remember that __set and __get are only invoked when an inaccessible (private, protected, etc.) member variable is accessed. This means there's no way to invoke __set and __get from within a class, outside of removing the member variable from the class definition, which makes your class less clear.
Like most things PHP, there's no clear "best" way to handle this.
Not only in PHP but in object oriented programming in general, if a class has member variables for which it's not necessary to execute code when they are accessed, there's no need to make setters and getters, and the variables can be accessed directly.
Accessing properties (variables) of an object is OK if those are public.
If they are protected/private (which is something new in PHP 5, that didn't exist in PHP 4), you can't access them directly.
Doing this or going through accessors depends on what you need / want to do :
if you only want to access data, you do not need accessors
if you want to perform some actions when data is accessed (check for the correctness of a value, for instance), you should use accessors -- bet it maginc method __get/__set or not.
Using those two magic methods has the advantage that it is transparent for the user ; and you can add them whenever you want, without forcing your users to rewrite their code.
But note that using getters/setters is said to have a cost (it costs some CPU, when you speak about performance, as you have to call a method)
In the end, there is no "right way", not "best way" : there are two ways, and it's up to you to choose which one fits the best for your needs.
For my own projects, here's what I generally do :
when I don't need to check anything, I don't use getters/setters
when I need some special behaviour, I declare my variables as protected/private, and create a special getter/setter (like getName/setName)
this has the advantage of having a phpdoc for each method, and hinting in the IDE I use, btw
Prior to PHP 5, you could do that. With the introduction of PHP 5, you can declare private variables. So it's not unusual to see PHP 4 codes which access variables directly because there is no rules for private variables.
I think it's ok to access class variables directly. If you want to keep other classes from modifying those variables you can make them private. If you have a public getter and setter that strictly copies the value passed to class field I think that's just overcomplicated approach.
The only situation I can think of where you would want to use getter or setter is when you have to process the value somehow.
The right thing to do from a purist OO perspective is create your own setter/getter method (ideally by overloading PHP's) that makes the relevant data available. (PHP is effectively providing you with generic versions of this with __get and __set, but these will let you get/set anything, which most likely isn't ideal.)
You should also set all of the variables (and indeed methods) within a class to have the correct visibility (private, protected, etc.) hence forcing you to use the set/get methods.
Look at the manual:
http://us2.php.net/manual/en/language.oop5.magic.php
Magic Methods
The function names __construct, __destruct, __call, __callStatic, __get, __set, __isset, __unset, __sleep, __wakeup, __toString, __invoke, __set_state and __clone are magical in PHP classes. You cannot have functions with these names in any of your classes unless you want the magic functionality associated with them.
Caution
PHP reserves all function names starting with __ as magical. It is recommended that you do not use function names with __ in PHP unless you want some documented magic functionality.
Just do good OOP ( I suggest you to declare getters and setters against accessing variables directly..) and forget about __get and __set.. If I'm not wrong there is also a __call for calling arbitrary methods.They are MAGIC methods they aren't meant for ordinary operations.
You shouldn't be using __get and __set or __call unless you are writing very particular code (es some framework, or something for proxying calls to other objects like in the php library Javabridge http://php-java-bridge.sourceforge.net/ ).