When and why should I use public
, private
, and protected
functions and variables inside a class? What is the difference between them?
Examples:
// Public
public $variable;
public function doSomething() {
// ...
}
// Private
private $variable;
private function doSomething() {
// ...
}
// Protected
protected $variable;
protected function doSomething() {
// ...
}
Public:
When you declare a method (function) or a property (variable) as
public
, those methods and properties can be accessed by:Example:
Protected:
When you declare a method (function) or a property (variable) as
protected
, those methods and properties can be accessed byOutsider members cannot access those variables. "Outsiders" in the sense that they are not object instances of the declared class itself.
Example:
The exact error will be this:
Private:
When you declare a method (function) or a property (variable) as
private
, those methods and properties can be accessed by:Outsider members cannot access those variables. Outsiders in the sense that they are not object instances of the declared class itself and even the classes that inherit the declared class.
Example:
The exact error messages will be:
Dissecting the Grandpa Class using Reflection
This subject is not really out of scope, and I'm adding it here just to prove that reflection is really powerful. As I had stated in the above three examples,
protected
andprivate
members (properties and methods) cannot be accessed outside of the class.However, with reflection you can do the extra-ordinary by even accessing
protected
andprivate
members outside of the class!Well, what is reflection?
Preamble
We have a class named
Grandpas
and say we have three properties. For easy understanding, consider there are three grandpas with names:Let us make them (assign modifiers)
public
,protected
andprivate
respectively. You know very well thatprotected
andprivate
members cannot be accessed outside the class. Now let's contradict the statement using reflection.The code
Output:
Common Misconceptions:
Please do not confuse with the below example. As you can still see, the
private
andprotected
members cannot be accessed outside of the class without using reflectionOutput:
Debugging functions
print_r
,var_export
andvar_dump
are debugger functions. They present information about a variable in a human-readable form. These three functions will reveal theprotected
andprivate
properties of objects with PHP 5. Static class members will not be shown.More resources:
It is typically considered good practice to default to the lowest visibility required as this promotes data encapsulation and good interface design. When considering member variable and method visibility think about the role the member plays in the interaction with other objects.
If you "code to an interface rather than implementation" then it's usually pretty straightforward to make visibility decisions. In general, variables should be private or protected unless you have a good reason to expose them. Use public accessors (getters/setters) instead to limit and regulate access to a class's internals.
To use a car as an analogy, things like speed, gear, and direction would be private instance variables. You don't want the driver to directly manipulate things like air/fuel ratio. Instead, you expose a limited number of actions as public methods. The interface to a car might include methods such as
accelerate()
,deccelerate()
/brake()
,setGear()
,turnLeft()
,turnRight()
, etc.The driver doesn't know nor should he care how these actions are implemented by the car's internals, and exposing that functionality could be dangerous to the driver and others on the road. Hence the good practice of designing a public interface and encapsulating the data behind that interface.
This approach also allows you to alter and improve the implementation of the public methods in your class without breaking the interface's contract with client code. For example, you could improve the
accelerate()
method to be more fuel efficient, yet the usage of that method would remain the same; client code would require no changes but still reap the benefits of your efficiency improvement.Edit: Since it seems you are still in the midst of learning object oriented concepts (which are much more difficult to master than any language's syntax), I highly recommend picking up a copy of PHP Objects, Patterns, and Practice by Matt Zandstra. This is the book that first taught me how to use OOP effectively, rather than just teaching me the syntax. I had learned the syntax years beforehand, but that was useless without understanding the "why" of OOP.
private - can be accessed from WITHIN the class only
protected - can be accessed from WITHIN the class and INHERITING classes
public - can be accessed from code OUTSIDE the class as well
This applies to functions as well as variables.
Reviving an old question, but I think a really good way to think of this is in terms of the API that you are defining.
public
- Everything marked public is part of the API that anyone using your class/interface/other will use and rely on.protected
- Don't be fooled, this is also part of the API! People can subclass, extend your code and use anything marked protected.private
- Private properties and methods can be changed as much as you like. No one else can use these. These are the only things you can change without making breaking changes.Or in Semver terms:
Changes to anything
public
orprotected
should be considered MAJOR changes.Anything new
public
orprotected
should be (at least) MINOROnly new/changes to anything
private
can be PATCHSo in terms of maintaining code, its good to be careful about what things you make
public
orprotected
because these are the things you are promising to your users.Extracted From :
http://php.net/manual/en/language.oop5.visibility.php
PHP manual has a good read on the question here.