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/ ).
Related
Just startet to feel the real usefulness for classes and methods (Object Oriented Programming) in PHP. However I still lack the understanding and experience declaring methods and variables the proper way.
I what cases should I declare a method/variable static VS declaring it non-static? What questions do I ask myself to answer this question?
Static means that you can access the functions without first creating an instance of the class. This makes it a lot like a normal function. You tend to make functions static if you want to group functions together that are related, but do not need a specific instance of the class to run.
Non-static members require an instance of the class. Typically you will use this.
If we have a class Circle and it has function area(), then it would be non-static as it needs a specific circle to find the area of. Now imagine we have a PrintText class with a printBold() function. We don't need an instance since it only depends on the inputs. However it is convenient to have the PrintText class because we could have printBold(), printItalics(), etc.
This question already has answers here:
Is this a reasonable way to handle getters/setters in a PHP class?
(8 answers)
Closed 9 years ago.
What is the best way to access the property of a PHP Class? I can either use the Built-in php accessor magic methods or should I hard code the get*() and set*() methods. What would be most efficient and best for refactoring the code later on when I am working on a large code base. I am asking this for a very large code base. Think of it as a development of a social network.
I can't say what is better or worse if I don't know the purpose of it.
In my opinion it is better to use dedicated getter/setter and not coding __get() or __set() magic methods.
For the two reasons:
My IDE it will not auto-complete pseudo-properties that are coded in magic methods. I don't know what type the property should be and even if there is one with this name.
When I need to change behaviour of getter/setter it's easy to locate where it is. I change only the method code, not the large __get() or __set().
Sometimes I use something like
public function __get($name){ // no error handling, but should be some
return $this->{'get'.$name}();
}
and the getter as well
public function getX(){ ...}
public function getY(){ ...}
and so on.
This allows me to shorten typing, but leaving all to getter.
Calling a pseudo-property has also some disadvantage for me as any warning/error/exception/... would be sent in the __get() method, not the getter -- I would not know what $name was given and so on.
EDIT
Using dedicated methods for getting and setting properties is also more clear in inheritance. Documenting software can mark that the getter was overridden, so I know which class change the code, and which uses the code from it's ancestors. In __get() it will be marked overridden if I change code for $name eg. "coordinates", but I don't change "seaLevel" (I mean it's not always clear what has been overridden).
Variable encapsulation, Set/Get methods are best practices but why do we have a chance to declare a variable public if it's not meant to be used anyway? Would it have been better if variables were always private by default with no chance of making them public since all of the tutorials I read says they should be encapsulated with set/get methods? Is there any valid use case for public variables at least in PHP OOP?
In fact it's just the other way round: Theoretically getters/setters are wrong. The properties defines the state of an object, where the methods defines the behaviour. Getters/Setters only intercept the read and write access to properties, but they break the semantic meaning completely: Now reading the status of an object is a behaviour of the object.
To make properties to look like properties again there is a RFC on the road :)
https://wiki.php.net/rfc/propertygetsetsyntax
Set/Get methods are best practices but why do we have a chance to declare a variable public if it's not meant to be used anyway?
Best practices and not meant to be used is not the same. A language needs to offer different tools for different use-cases and should be consistent.
PHP objects always supported public members and when differentiated visibility was introduced, for backwards compatible reasons public members are very useful.
Would it have been better if variables were always private by default with no chance of making them public since all of the tutorials I read says they should be encapsulated with set/get methods?
That question can not be specifically answered, it's too subjective and there are too many different use-cases that would result in a different answers.
Is there any valid use case for public variables at least in PHP OOP?
Start with backwards compatiblity. If you can not refactor your code but would need to rewrite it completely all the time, this would be very expensive.
let's see..
this's a real world Email API class from CakePHP EmailComponent. to use this class you only need to "set" some property then just send()
$this->Email->to = 'ss#b.co';
$this->Email->from = 'me#b.co';
$this->Email->title = 'xxx';
$this->Email->msg = 'blabla..';
$this->Email->send();
in fact there is a lot of private properties and function inside this class but it's private.
Class has (single) responsibility to do something.
Encapsulation is to publish only what people use to do that thing and keep technical/infrastructure inside as private.
This might be a stupid question but I have to ask:
I have a big group of related functions for a project I am doing. The functions need to access a few global variables, so I was thinking about putting them into a class and loading the class as needed. I suppose my other option is to just include them as unrelated functions in an included PHP file, but putting them into 1 class seems to make sense. Is this an acceptable practice? I have worked with people who did this but it always seemed to not quite be in the spirit of good OOP practices because the classes were almost never instantiated but the functions were still called. Or maybe I'm over thinking it.
Any input would be awesome, thanks a bunch.
A class does make the most sense. Whenever you can eliminate global variables, it is a good thing. Whether the class is instantiated or a static helper usually depends on the context. However, for future unit testing, instantiations allow dependency injection.
According to http://en.wikipedia.org/wiki/Class_%28computer_programming%29, a class defines constituent members which enable class instances to have state and behavior. If you will be providing only behavior (functions) and not state (properties), you should include your functions in an include file and forgo the overhead of a class.
Correct me if I'm wrong but this seems like you should create a class that acts as a static service, where no explicit instantiation is needed of the class, yet you will still call the methods contained within this class.
Now, if you're thinking of storing those global variables in the class, obviously that's no longer a static class because there would have to be some sort of lifetime for the object, and at which point you'd have to instantiate the class first and then make calls to those methods.
Regardless, if they're all related functions working on the same data, it certainly makes sense to group them within their own class.
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.