I'm wondering is there anyway to create 'Get-Set' method only once that can be use to every attribute
The following code is not correct. Just to make sure you know what I'm looking for
class someClass {
private $attrA;
private $attrB;
private $attrC;
public function get($attr){
return $this->$attr;
}
public function set($attr, $value){
$this->$attr = $value;
}
}
Yes, you can use the magic methods __get() and __set() in the exact way you describe.
More info on the official web site.
Do you want public fields or public properties ?
In case you want properties, where an operation or validation is done when trying to read or trying to modify a property's value, then, I strongly recommend make individual "getter (s)" and individual "setter (s)" for your properties.
It looks difficult at first, but eventually it will make your code extensible and customizable...
Otherwise, just do plain public fields.
Related
Learning PHP in a OOP way and i often come across people who makes functions like this.
public function getUsername() {
return $this->username;
}
Is there some security reasoning behind this? Instead of just calling the username property of the class directly? Why wrap getting a property around a function.
This type of functions are used for accessing private or protected members of class. You can not access them them directly outside of the class as they can be accessible only inside the class. So what would you do if you want to access a private member? The answer is this.
Lets take an example -
class A {
private $x;
public $y;
public function test() {
echo $this->x;
}
}
$obj = new A();
$obj->x; // Error : You can not access private data outside the class
$obj->y; // Its fine
$obj->test(); // it will print the value of $x
Hope this will help.
In OOP, class should hide its implementation details, and just provide necessary public functions. Users are more concerned with function rather than details.
For example you have class Test. You are using direct access to property and you have hundred place like $obj->date = 'now' etc.
class Test {
public $date;
}
But what if you need to insert some code before updating value or modificate input value? In this case you have to find all usage of the property and update it. But if you will use getters/setters you can insert some code into them.
class Test {
private $date;
public getDate() { return $this->date; }
public setDate($date) {
// here some modification value or something else
$this->date = $date;
}
}
A quick reason is that you be writing a piece of code and want to prevent a user from overwriting a value in an object instance (a good example is configuration data).
Writing functions in the way you have stated also provides a standard interface which is essential when developing complex programs. It would be crazy to have a team of developers working with the one class and not defining access to variables!
Here is a good explanation of the PHP OOP basics and explains private, public and protected
http://php.net/manual/en/language.oop5.basic.php
If I get a class looks like this :
class a {
public $aa;
public $ab;
}
$t = new a();
now,
If I type $t->, I would got a tip list under zend Studio, but now I need to do something like this:
class a {
public $aa;
public $ab;
public function __get( $name ){
$this->$name = x;
return $this->$name;
}
}
so, what should I do? First I still want to get that tip list, and only public attribute could be listed. and idea about this?
It seems to me, that you're having two interlocking problems here.
If you add public fields to your class, then you can see them in autocomplete suggestions and it is easier for you to write code, but if you do that, then __get is not executed because this is a visible property and __get is only called for the invisible properties.
If you remove the public fields (or make them private so as to make them invisible), then your __get is executed but you don't get any autocomplete suggestions as there are no visible fields. This way your code works, but it is harder for you to write the code as you get no autocomplete suggestions.
So my suggestion to you would be to forget the __get functionality altogether. Pretend that it does not exist (since it does not do what you want it to do anyway). Use member functions instead of public properties and you'll get the autocomplete suggestions as well as your code executed. Yes you'll have to implement more methods that way, but that's life, you can't always have everything you want, you have to compromise.
What you can do is use something from the Java book and define methods for getters and setters (so either function getName() and function setName($value) or if you prefer you can use function name($value = null) and either set or get depending on the passed in value) or you can assign those values in a constructor if you don't care about the laziness part and the only thing you'll do is assign values.
Lets assume I have a class Test, which has got a private attribute called $_list, and a public setter.
Public setter is used to set the attribute value from the outside.
class Test {
private $_list;
public function getList() {
return $this->_list;
}
public function setList($list) {
$this->_list = $list;
}
public function initialize() {
$list = array();
/* ... Some code that fills the $list with values etc. ... */
// 1) Set value directly
$this->_list = $list;
// 2) Use public setter
$this->setList($list);
}
}
The question is - do I need to use public setter to set private attribute value inside class?
Which way is are better - #1 or #2? And why?
Which way do you prefer?
I would like to see a complete answer with the explaination of advantages and disadvantages of each way.
Thanks.
As it was written above, both are acceptable, but the correct answer is: Rather use the direct attribute access, but sometimes you better use the setters.
Number 1, (property access) Pros:
Easily readable and slighty faster
Gives you the approach that this is an simple attribute of the object
Number 2, (setter) Pros:
You can do custom action on setting the attribute (e.g. initialize other attributes, caches, or call a method on the parameter object)
You treat the attribute as a sub-element of the class, which may have own logic implemented.
I think that proposing that there is no logic behind using a variable is more important. If it is simple, make it look simple. If it's not, you can still use setters.
You could also ask the same about getters versus property access, the above applies as well.
What are getters and setters in PHP5?
Can someone give me a good example with an explanation?
This is concept for data hiding (or encapsulation) in OOP. For example if you want to have a certain property in your class let's say 'Amount' and give the client of you class the option to change or extract its value You should make your variable 'Amount' private (not visible for those who use your class) and generate two methods a getter and a setter that manipulates your value (that are public).
The reason is to be able to validate data or manipulate it before setting or getting your value. Here is a brief example:
class test {
private $count; //those who use your class are not able to see this property, only the methods above
public function setCount( $value )
{
//make some validation or manipulation on data here, if needed
$this->count = $value;
}
public function getCount()
{
return $this->count;
}
}
Attributes of classes can be private. That means only the object can read and write its own private attributes. Therefore you need methods to do that. The methods that read and return an attribute value are called getters and those that write attributes are called setters. With these methods the classes can control what’s going out and what’s coming in. This concept is called encapsulation.
Getters and Setters are quite new concept in PHP 5 in the form of two magical functions __get() and set(). These two functions set or get property value of an object dramatically as explained in the following example.
class Datatype{
private $thing;
public function _set($k,$v){
$this->$k = $v;
}
public function __get($k){
return $this->$k;
}
}
The PHP manual is really not very verbose on the issue, but there is a very detailed example that should explain a lot. Magic methods: Property overloading
I have a very special case in which I need to call a protected method from outside a class. I am very conscious about what I do programmingwise, but I would not be entirely opposed to doing so in this one special case I have. In all other cases, I need to continue disallowing access to the internal method, and so I would like to keep the method protected.
What are some elegant ways to access a protected method outside of a class? So far, I've found this.
I suppose it may be possible create some kind of double-agent instance of the target class that would sneakily provide access to the internals...
In PHP you can do this using Reflections.
To invoke protected or private methods use the setAccessible() method
http://php.net/reflectionmethod.setaccessible (just set it to TRUE)
I would think that in this case, refactoring so you don't require this sort of thing is probably the most elegant way to go. In saying that one option is to use __call and within that parse debug_backtrace to see which class called the method. Then check a friends whitelst
class ProtectedClass {
// Friend list
private $friends = array('secret' => array('FriendClass'));
protected function secret($arg1, $arg2) {
// ...
}
public function __call($method, $args) {
$trace = debug_backtrace();
$class = $trace[1]['class'];
if(in_array($class, $this->friends[$method]))
return $this->$method($args[0], $args[1]);
throw new Exception();
}
}
I think I need a shower.
This is a little kludgy, but might be an option.
Add a child class for the sake of accessing your protected function
public class Child extends Parent {
public function protectedFunc() {
return parent::protectedFunc();
}
}
Then, instantiate an instance of Child instead of Parent where you need to call that function.
I'm just throwing this out there since I haven't programmed in PHP in two years. Could you just add a function to the class that calls the protected method like so?
$obj->publicFunc = create_function('$arg', 'return $this->protectedFunc($arg);');
Edit:
I think Tom's correct in looking at the documentation for create_function. It looks like the scope of $this will be "wrong" when you try to call it with this example.
It looks like traditional anonymous functions are supported since PHP 5.3.0 as well (and my first solution probably won't work), so I'd probably write it like this instead:
$obj->publicFunc = function($arg) {
return $this->protectedFunc($arg);
};
Since I think it looks a little cleaner (and your IDE of choice will highlight it better of course).
Ugh, I tried using Reflection to call the method but PHP won't allow you to do that either. It seems that you're going to have to use some sort of child class like the other posters have suggested. If you find a method that works, the developers will likely classify it as a bug in the future and break your code when you upgrade to the next version.
I recommend extending the class.
I'd think about what is the matter with the program design if I have to call a private function?
It used to be the case when
your class is responsible for several things (it is really two or thre calsses wrapped together) or
the rules of encapsulation are broken (utility functions, for example)
By finding any way to walk around this questions, you'll be nowhere nearer to the real solution.
Suppose your method declaration goes like so:
protected function getTheFoo() {
...
}
protected function setTheFoo($val) {
...
}
Usage:
$obj->__get('the_foo');
$obj->__set('the_foo', 'myBar');
This bypasses the protected methods and goes directly straight to the instance variables.