private methods and variables in PHP usage [duplicate] - php

This question already has answers here:
What is the difference between public, private, and protected?
(16 answers)
Closed 9 years ago.
I have been thinking about the usage of private variables and methods in php.
I am not going to talk about a class of car or anything like that. I want to talk about an own script.
What is the difference between using public or private for the programmer and the owner of the script.
if the script is a calculator, and I am the only one who will meinten the code in the future. when do I have to use private variables of methods. How this is going to change anything in the script?
Also, If it's about touching the variable ? if anyone tries to change the value, and he couldn't because of the private thing. He will go directly to change it using the setters ?
I need a good example that I can see private methods or variables have good benefits for programmer or the end user.
I was programming some scripts, and a guy told me to not use var in classes. I asked him why ? he said that you have to use public or private .. and asked why ?
Why to use setter if there is a way to change the variable directly?
Why to use getter if there is a way to change the variable directly?

First of all, when you're developing strong-OO classes, you should be exposing as little of the internal semantics of your class as possible (obviously without affecting functionality).
Some variables are only valuable inside the context of the class itself, and would make no sense to a developer using the class. Making the variable public allows anyone using the class to change such a variable at will, despite the fact that they may not know what it's used for. In PHP this can be a particular problem when you don't even have type safety to at least mitigate the damage that can be done.
Consider this: You have a class which wraps around some I/O operations. Let's call it FileReader
class FileReader {
public $_handle;
public function __construct($filepath) {
$this->_handle = fopen($filepath, 'r');
if ($this->_handle === NULL) {
throw new Exception("Unable to open the file for reading");
}
}
// ... the rest of the class
}
Now you can see that the class opens up a handle to a file. By making the $_handle variable public, you've exposed it to any and all people working on your class. They don't need to know about the raw file handle you have open, they just want to use your nice class to perform some read operation. However, it IS public; not only can they see it, but they can change it. This is bad, especially when your other code assumes that the $_handle variable is valid.
$reader = new FileReader();
$reader->_handle = "I hope this doesn't break anything. /trololol";
$reader->someOperation(); // oh no! Our file handle has just been changed to something completely wrong, this is now going to the break the class.
Such ridiculous scenarios can be avoided entirely by making the variable private in the first place. For more (and better) example of what each access modifier does, and when to apply them see this answer.
Now, onto getters and setters. In your question, you seem to assume that all getters and setters are written the following way:
class Foo {
private $_bar;
public function getBar() {
return $this->_bar;
}
public function setBar($newBar) {
$this->_bar = $newBar
}
}
In which case, you're absolutely right there is no difference between that and changing the $_bar variable to be public in the first place.
However, getter and setter methods give you control over how your variables are being set by an external developer, so you can instantly detect when they're going to make a boo-boo and avoid undefined behaviour later on. For example:
class Foo {
private $_bar;
public function getBar() {
return $this->_bar;
}
public function setBar($newBar) {
// Now we're going to ensure that $newBar is always an integer
if (!is_int($newBar)) {
// not an integer, throw out an exception to let the developer know that somewhere is setting invalid input
throw new Exception("Expected an integer value for 'Bar'");
}
$this->_bar = $newBar;
}
}
This is not only making your class far more robust, but also making the life of the developer using your class a hell of a lot easier. Rather than having to debug an extremely weird issue somewhere later on when the class attempts to use the corrupt value of $_bar, they can easily tell from a stack trace where the corrupt value was set from and fix it at the source.
There is plenty of documentation about variable access and getter/setter methods out there, and it applies to a whole range of languages so don't be afraid to look up articles that were based on C++/C#/VB.NET, they all roughly translate to the same material.

The end user doesn't see the code, so there's no (dis)advantage there.
For the programmer, declaring things that aren't needed outside the object as private is just a good programming practice and a protection mechanism. Technically, if you're a perfect programmer, and you don't care about how your code looks, using private will provide you no benefits. However, private members enforce the black box model -- you only care about what the object does, not about how it works (when looking at it from the outside). In the end, if for any reason you (or somebody else) needs/wants to use your code, they'll know what methods and properties to use/invoke in order to get the functionality the object has, without modifying the internal values the object needs to maintain. It may or may not give you any advantage -- it's just about how the code looks like. That's what good programming practices are for, and they are usually followed because experience says they tend to minimize errors.
As for var, it was deprecated. Meaning it could (and will) be removed in the future.

Public, Private and Protected only matter in PHP if they are part of a function, or part of a class.
If you wanted to set a variable once and "lock it" so the value couldn't be changed later you can define it or set it as a const (constant).
public scope to make that variable/function available from anywhere,
other classes and instances of the object.
private scope when you want your variable/function to be visible in
its own class only.
protected scope when you want to make your variable/function visible
in all classes that extend current class including the parent class.
See here: http://php.net/manual/en/language.oop5.visibility.php

Related

PHP classes - is it preferable to use normal variables instead of properties?

For my latest website I’ve been trying to use classes. Mainly to teach myself more about OOP and learn through experience.
Whenever I needed a ‘variable’ within my class I created a property, for instance:
class someClass
{
var $valueToUseHere; // Only used internally - can I just use a variable?
public function doStuff()
{
$this->valueToUseHere = 60;
// Do more stuff here...
}
}
It is only now when I’ve been looking more into the code and trying to do some optimisation that I’ve noticed that my functions and classes are passing around some large objects. A lot of that bulk could be stripped away if I made all the properties that are only used inside the class into normal variables.
Are properties only used for variables that are needed outside the class and is it then acceptable to just use ‘normal’ variables within the class itself ?
Sorry if this question illustrates a lack of understanding on the subject. Unfortunately, this is where my learning is up to at this point. I’ve done some searching around “class properties vs variables” etc but not found a comprehensive answer to this.
Many thanks
It's somewhat vague what you're asking, but if valueToUseHere is not used outside of doStuff, then don't make it a property!
class someClass {
public function doStuff() {
$valueToUseHere = 60;
// Do more stuff here...
}
}
If there's no reason to share that value with other methods of the class or with the outside world, then there's no reason to clutter up your object with all sorts of properties. Not only may this cause tricky bugs with preserved state, it also forces you to be unnecessarily careful with your variable names across all object methods.
Actually class properties are variables as well. Basically you have three options:
Global variable, available everywhere, but not recommended because all parts of your code may depend on such a varialbe, changes can easily break stuff everywhere.
Class property (Note: you should define a visibility - public/protected/private) these properties are bound to the object instance and should be used for any state that the object needs to keep for further processing. Usually those might be used in more than one metohd of your class.
Variables inside a method like just
public function doStuff()
{
$valueToUseHere = 60;
// Do more stuff here...
}
The variable is just available inside the method and is thrown away at the end of the method execution.
That depends on your needs. If you are going to simply hold a value in a variable it's the best to keep it's simplicity and not define functions for setting or getting it's value. But sometimes you may need to have more controls on a variable in your class. For example you have defined an integer variable and you want it's values to be always between 10 and 1000 and also it should not be in 100,200,300,..,900. So here there is a good reason to set your variable access to private and create a public function to check what is required before setting a new value. Or in another example you may want to call another function or change another depended variable in your class exactly after this variable changed. Or if you want to make a variable read-only or write-only always you can define properties for controlling the variable value.
In brief you may prefer to use:
Properties: When you want to have control about get and set values
Variables: When you want to set or use a variable as its nature

There seems to be no point of using encapsulation

Two simple, classes, one checks length and returns true of false. Second checks if first class returned true or false and returns message depending on that. Now, my question is, what difference does it make whether I put my variables as public, protected or private(note: I know what they are).
Why would I do it, who, if I put my variables as public can access it?
I know what encapsulation is and how it tells to encapsulate all class members, but there seems to be no point really.. If it was IRL I can understand that yeah someone might take something off of my house, so I should keep them all locked.. but in programming doesn't seem to make any sense..
http://www.codeproject.com/Questions/161855/Encapsulation-and-why-we-must-use-it
This guy tells anyone can access class members, but who're these anyone? I thought PHP runs in server and access to it is restricted by default. Nobody beside you can access/edit the file..
class Length_class{
public $bus;
public $returned;
function __construct($bus){
$this->bus = $bus;
if($this->bus < 10){
$this->returned = false;
}else{
$this->returned = true;
}
}
}
class Length_class_extended extends Length_class{
function display_length(){
if($this->returned){
return "Length is $this->bus";
}else{
return "Length is $this->bus";
}
}
}
$Length_class_extended = new Length_class_extended(10);
echo $Length_class_extended->display_length();
Maybe it doesn't make sense in this little piece of code. But an actual application is way bigger than that with much more classes (and people) working on it.
The security that encapsulation provides is not about someone hacking your code. It is about someone that you know that is going to use your code and you want to say what he may or may not access.
You use encapsulation to specify what your class is and what it should do. It helps you with defining the responsibilities of your classes. And helps other developers to be aware of it without the need of knowing how you implemented that.
Well-encapsulated code provides painless (or at least a lesser pain) class modifications.
The primary reason for using access modifiers is when you provide the class for someone else to use. With encapsulation the other programmer can use your class within his code without ever needing to know what goes on inside your class.
He will have a list of methods to use and will only interact with the class through this interface. This forces him to use the method 'correctly' in a way that won't break either his program or the functioning of your class.
It may not seem relevant to you if you are the only person using the code and it is a relatively straightforward project, and it is perfectly possible to write functioning code with every member public - it is however good practice and worth doing anyway. It forces you to write in a 'good' style with real encapsulation and may save you a headache later on by stopping you from misusing your own class if you want to reuse the code in a wide variety of situations.

Why cant i just use public property and not be looked down at

I see (and write) a lot of code like this:
class MyClass
{
private $_myProperty;
public function setMyPropert($myProperty)
{
$this->_myProperty = $myProperty;
}
public function getMyProperty()
{
return $this->_myProperty;
}
}
Since we are taught that class properties should always be private.
However, i really just want to do this in the above scenario:
class MyClass
{
public $myProperty;
}
Thats much less code and easier to read. But other developers would look down on this code and most likely it would fail code reviews etc. Even if not, i would still never do this for fear of someone else seeing it and making judgement.
Why though? Is this something that is just ingrained in developers of oop code? Or is there another reason that I'm missing, perhaps related to testing, future maintenance or other non obvious technical reason. I am talking specifically in a scenario where the getter/setter does noting more that get/set.
If you are doing nothing in your getters and setters, then yes, you may as well just make the property public. But setters are typically used to check the value to make sure it's valid:
public function setFoo($foo) {
if (!is_string($foo)) {
throw new InvalidArgumentException('No you foo-l!');
}
$this->foo = $foo;
}
It's a good idea to do that to ensure the integrity of the class, that's what encapsulation is for. And even if you're not doing this checking now, you may be adding it in the future after you have fixed the 3rd bug resulting from something setting invalid values. If you then suddenly start switching to method calls instead of property assignment, you'll have a hard time retrofitting all your code that's setting properties.
Best start with actual encapsulation as early as possible.
This really comes down to the open/closed principle:
software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification
In this context, the principle means that the members of a class should be private by default.
It might seem like, in some cases, you can just declare a public member. You can, but it's still true that you shouldn't do it as a rule. It's partly just avoiding bad habits -- exposing all a class's members to everyone is just sloppy.
It's also a question of signalling your intent: if someone sees a public member, what do they think? There's no immediate way of knowing if the author intended for the member to be public, or if they just didn't really know what they were doing.

Why are member variables usually private?

I just started to learn object oriented programming today and just by observation noticed that in all examples, member variables are private. Why is that usually the case?
// Class
class Building {
// Object variables/properties
private $number_of_floors = 5; // These buildings have 5 floors
private $color;
// Class constructor
public function __construct($paint) {
$this->color = $paint;
}
public function describe() {
printf('This building has %d floors. It is %s in color.',
$this->number_of_floors,
$this->color
);
}
}
Also, if you declare the member variable to be public, what is the syntax for accessing it outside of the class it was declared in?
And finally, do you have to prepend "public" or "private" to every variable and function inside a class?
EDIT: Thanks all for your answers, can anyone please confirm if you have to prepend "public" or "private" to every variable and function inside a class?
Thanks!
Rule of thumb is to try to hide information as much as possible, sharing it only when absolutely necessary.
Russian coders sometimes say Public Morozov at unnecessarily wide access modifiers, alluding to a story about improper information disclosure and about further punishment caused by that - Pavlik Morozov:
a 13-year old boy who denounced his father to the authorities and was in turn killed by his family...
Private variables can't be accessed from outside, that gives you control.
But if you put them Public then you can access it lke this
$your_object_instance->Your_variable
For example
$building = new Building();
echo $building->number_of_floors;
but you have to put your number_of_floors variable to public, if you want to access private member then you need to implement new method in Building class
public function getNumberOfFloors()
{
return $this->number_of_floors;
}
so your code should look like this
$building = new Building();
echo $building->getNumberofFloors();
It's to make the coding easier for you, and to make you less likely to make mistakes. The idea is that only the class can access its private variables, so no other classes elsewhere in your code can interfere and mess something up by changing the private variables in unexpected ways. Writing code like this, with a bunch of autonomous classes interacting through a small number of strictly controlled public methods, seems to be an easier way to code. Big projects are much easier to understand because they are broken up into bite sized chunks.
Making variables private keeps calling code from depending on the implementation details of your class so you can change the implementation afterward without breaking the calling code.
You can declare more than one variable on the same line and only use private or public once:
private $number_of_floors = 5, $color;
See also PHP docs' "Classes and Objects".
Senad's answer is correct in that it is good programming practice to make variables you do not want exterior methods to access private.
However, the reasoning for it in memory managed/garbage collected languages is that when you maintain a reference to an object, it is not able to be garbage collected, and can cause memory leaks.
Hope this helps!
I really dont know how to answer such question, but i describe u the best as per php manual
The visibility of a property or method can be defined by prefixing the
declaration with the keywords public, protected or private. Class
members declared public can be accessed everywhere. Members declared
protected can be accessed only within the class itself and by
inherited and parent classes. Members declared as private may only be
accessed by the class that defines the member.
Property Visibility
Class properties must be defined as public, private, or protected. If
declared using var, the property will be defined as public.
Methods declared without any explicit visibility keyword are defined as public.
for more information see Visibility
It's to prevent properties from being directly manipulated from the outside and possibly putting the object into an inconsistent state.
One of the fundamentals of OOP is that an object should be responsible for maintaining its own state and keeping it internally consistant, for example not allowing a property that's only meant to hold positive integers from being set to -343.239 or making sure an internal array is structured properly. A sure fire way of doing this is make it impossible for the values of properties to be directly set from the outside. By making the property private, you're preventing outside code from manipulating it directly, forcing it to go through a setter method that you have written for the job. This setter can do checks that the proposed change won't put the object into an inconsistent state and prevent any changes that would.
Most books and examples aimed at beginners tend to use very simple objects so it may not make sense as to why you need to go through all the private properties and getters and setters molarchy, but as the complexity of an object increases, the benefits become increasingly obvious. Unfortunately, complex objects are also not much good as teaching aids for beginners, so this point can be easily lost at first.

Is it really that wrong not using setters and getters?

I'm kind of new in PHP. For some reason in other types of programming languages like JAVA I have no problem with using setters and getters for every single variable, but when I'm programming in PHP probably because it is so flexible it feels kind of like a waste of time. It feels simpler to just set the class attributes as public most of the time and manipulating them like that. The thing is that when I do it like this I feel like I'm doing something wrong and going against OO principles.
Is it really that wrong not using setters and getters? Why or why not? How do you guys do it most of the time?
The main problem with not using property accessors is that if you find out you ever need to change a field to a property later on – to make it a computed property in a subclass, for instance – you’ll break clients of your API. For a published library, this would be unacceptable; for an internal one, just quite a lot of work fixing things.
For private code or small apps, it could be feasible to just wing it. An IDE (or text editor) will let you generate accessor boilerplate and hide it using code folding. This arguably makes using getters and setters mechanically fairly easy.
Note that some programming languages have features to synthesise the default field+getter+setter – Ruby does it via metaprogramming, C# has auto-implemented properties. And Python sidesteps the issue completely by letting you override attribute access, letting you encapsulate the attribute in the subclass that needs it instead of having to bother with it up front. (This is the approach I like best.)
The point of getters or setters is that you can still add logic to your modifications of the field in one place instead of everyplace you want to modify or retrieve the field. You also gain control at class level what happens with the field.
If we're talking strictly about PHP here and not about C#, Java, etc (where the compiler will optimise these things), I find getters and setters to be a waste of resources where you simply need to proxy the value of a private field and do nothing else.
On my setup, I made two crappy classes, one with five private fields encapsulated by five getter/setter pairs proxying the field (which looked almost exactly like java code, funnily enough) and another with five public fields, and called memory_get_usage() at the end after creating an instance. The script with the getter/setters used 59708 bytes of memory and the script with the public fields used 49244 bytes.
In the context of a class library of any significant size, such as a web site framework, these useless getters and setters can add up to a HUGE black hole for memory. I have been developing a framework for my employer in PHP (their choice, not mine. i wouldn't use it for this if i had the choice but having said that, PHP is not imposing any insurmountable restrictions on us) and when I refactored the class library to use public fields instead of getters/setters, the whole shebang ended up using 25% less memory per request at least.
The __get(), __set() and __call() 'magic' methods really shine for handling interface changes. When you need to migrate a field to a getter/setter (or a getter/setter to a field) they can make the process transparent to any dependent code. With an interpreted language it's a bit harder to find all usages of a field or method even with the reasonably good support for code sensitivity provided by Eclipse PDT or Netbeans, so the magic methods are useful for ensuring that the old interface still delegates to the new functionality.
Say we have an object which was developed using fields instead of getters/setters, and we want to rename a field called 'field' to 'fieldWithBetterName', because 'field' was inappropriate, or no longer described the use accurately, or was just plain wrong. And say we wanted to change a field called 'field2' to lazy load its value from the database because it isn't known initially using a getter...
class Test extends Object {
public $field;
public $field2;
}
becomes
class Test extends Object {
public $fieldWithBetterName = "LA DI DA";
private $_field2;
public function getField2() {
if ($this->_field2 == null) {
$this->_field2 = CrapDbLayer::getSomething($this->fieldWithBetterName);
}
return $this->_field2;
}
public function __get($name) {
if ($name == 'field')) {
Logger::log("use of deprecated property... blah blah blah\n".DebugUtils::printBacktrace());
return $this->fieldWithBetterName;
}
elseif ($name == 'field2') {
Logger::log("use of deprecated property... blah blah blah\n".DebugUtils::printBacktrace());
return $this->getField2();
}
else return parent::__get($name);
}
}
$t = new Test;
echo $t->field;
echo $t->field2;
(As a side note, that 'extends Object' bit is just a base class I use for practically everything which has a __get() and a __set() declaration which throws an exception when undeclared fields are accessed)
You can go backwards with __call(). This example is quite brittle, but it's not hard to clean up:
class Test extends Object {
public $field2;
public function __call($name, $args) {
if (strpos($name, 'get')===0) {
$field = lcfirst($name); // cheating, i know. php 5.3 or greater. not hard to do without it though.
return $this->$field;
}
parent::__call($name, $args);
}
}
Getter and setter methods in PHP are good if the setter has to do something, or if the getter has to lazy load something, or ensure something has been created, or whatever, but they're unnecessary and wasteful if they do nothing other than proxy the field, especially with a few techniques like the ones above to manage interface changes.
I am probably not going to get many upvotes on this one, but personally getters and even more so setters feel like a code smell to me. Designs should be behavior driven, not data driven. Of course, this is just an opinion. If you have an object that depends on a particular data field of another object this is very tight coupling. Instead it should depend on the behavior of that object which is far less brittle than its data.
But yes, property like getters and setters are a step up from a dependency on a field directly for this very reason. It is less brittle and loosens up the coupling between the objects.
Did you consider to use magic functions __set/__get? Using them you can easily merge all getter/setter function in only 2 functions!
There is a way to emulate get/set without actually using get/set function class, so your code remains tidy:
$person->name = 'bob';
echo $person->name;
Take a look at this class I have coded.
Typically, when using this class, you would declare all your properties protected (or private). In the event where you'd want to add a behaviour on a property, say strtolower() + ucfirst() on the "name" property, all you'd need to do is declare a protected set_name() function in your class and the behavior should get picked up automatically. Same can be accomplished with get_name().
// Somewhere in your class (that extends my class).
protected function set_name($value) { $this->name = ucfirst(strtolower($value)); }
//
// Now it would store ucfirst(strtolower('bob')) automatically.
$person->name = 'bob';
P.S.
Another cool thing is you can make up non-existing fields such as
echo $person->full_name;
without having such fields (as long as there is a get_full_name() function).
If you access these variable in your script lots of time and if you update yoru class often you should use setters and getter because but if you dont this , when you improve your class you have to update all files which uses this variable .
Secondly main reason why you do this is you should not access variable directly because class structure may change and this data can be providen differently.While you are getting data from class you should not care about how this data is generated .Class have to care about this data proccessing so you only should care what will you get.

Categories