It's a question I've had for a long time.
I've wanted to ask this for a long time, and I'm posting the question in the hope that it won't be closed because it's based on opinions... If that happens, it could be an answer for me : No.
The question I have is whether we can talk about Object Oriented Programming (OOP) in PHP in the strict sense of the word or if, on the contrary, only some OOP principles can be applied in PHP.
I expect answers, if any, based on documentation and evidence.
When I see the examples of the PHP Manual in this regard, or the so-called magic methods , it gives the impression that basic OOP concepts are violated, as is the case of creating setters
public access.
The specific question is the following: Can we say that with PHP you can do OOP in the strict sense of the word? Why?
To answer this let's check several points:
1) Quoting the PHP documentation:
According to the documentation, as of PHP 5, we have a full object model:
__get()
__set()
__call()
__construct()
PHP POO ESTRICTO + 1;
2) Basics of OOP and its role in PHP:
In the OOP we can find characteristics that are fundamental to consider the language as OO, among them:
1) Abstraction
2) Inheritance
3) Encapsulation
3) Concealment
4) Polymorphism
5) Modularity
6) Garbage Collection
According to Lei, OOP theorists focused on the 3 main points (those in bold ) as the fundamentals of OOP.
Now, let's check if PHP meets the fundamentals:
Employing the fundamentals of OOP in PHP:
The 3 fundamentals of OOP are fulfilled.
PHP POO ESTRICTO + 1;
3) Magic Methods VS Class Method
To access the properties of a class we have two methods, the classic method and the magic method:
Classic Method : In this method we define our own
getters
andsetters
:Magic Method : In this method we use the magic methods that PHP brings, such as
__get()
and__set()
:When do I use what kind of methods?:
The answer is found in the "Overloading" section of the official PHP documentation.
But first let's understand some basic concepts:
What is overload?:
Is there then overloading in PHP? :
NO, let's remember that PHP is not typed:
Therefore, in PHP there is no overloading by parameter types.
Besides we cannot control the number of arguments that are passed to the function, for example Javascript, using arguments[], therefore there is no overloading by number of parameters.
But PHP does not get out of hand, since it creates : "Magic methods" and together with this an overload simulation . (some say this PHP property is misnamed)
Quoting: http://php.net/manual/en/language.oop5.overloading.php
So if overloading doesn't exist in PHP: what role do magic methods play to simulate it?
What are magical methods?:
We could then say that:
NOTE: It should be noted that what we would do with these magic methods would be to be able to modify them to overshadow (shadowing) the default function they have inside the class.
Let's look at an example of overloading using a magic method:
Using the magic method
__construct()
, we are overloading the constructor to react based on the passed parameters, calling the same method.Now let's use another method for example
__call()
:What function does __call() have?
-Allows you to capture the invocation of non-existent methods.
This method can be re-defined to meet the needs of the system or, as in this case, provide overloading.
Taking advantage of this functionality we can control the function we are calling and redirect to the specific function we are referring to.
Let's look at an example:
In this example we overload our class with a different number of parameters and also a different type. In conclusion it is possible to overload (mock) in PHP.
PHP POO ESTRICTO + 1
;WAIT : Wouldn't Polymorphism then be the same as overloading? Why, if so, are you doing polymorphism and not overloading? :
NO , polymorphism refers to a set of methods with the same Name and the same Number of Parameters and Types , but that are defined in different Classes, previously we passed different data types.
Let's look at an example of polymorphism:
PHP POO ESTRICTO +1;
4) Our magical methods of interest:
Quoting the PHP overload documentation we find this:
Tenemos dos puntos de interés: Ámbito Activo y Propiedades Inaccesibles
Ambito activo:
Propiedades innacesibles: Son aquellas propiedades que bien estan ocultas, o no estan definidas.
Citando lo anterior, como la sobrecarga usa los metodos magicos, y estos debes de poder acceder a propiedades innacesibles.
Se fundamenta la razón de ser métodos públicos, ya que, te deben permiten obtener valores que no están en tu ámbito, ademas de crearlos dinamicamente si NO existen, cumpliendo su rol, interactuar con métodos/propiedades innacesibles.
Veamos el ejemplo en una clase:
En este caso al usar
obtenerAtributo( )
ocambiarAtributo( )
estamos trabajando bajo atributos que están definidos dentro de la clase. Pero en el último llamado deotroAtributo
estamos definiendo un valor que no existe.Aqui entra el papel de
__set
y__get
, los cuales nos permiten trabajar bajo propiedades o métodos inexistentes:1) Si los quisiera redifinir para controlar como obtener y cambiar variables usaría:
2) Estos métodos nos permiten controlar el acceso o el cambio de propiedades.
3) No son sustitutos de los
getters/setters
, ya que, nos permiten trabajar en modos que de la forma clásica daría error, más que todo son para manejo de errores, ejemplo obteniendo/cambiando atributos que no existen, comparando con JavaScript podrían usarse como si quisiéramos evitar que se crearan objetos sinnew
.4) Podría definirse a los métodos mágicos como los
Object Watchers
de Javascript, ya que estos crean propiedades inexistentes para funcionar, pero claro esta golpea en el rendimiento del código.Entonces sabiendo cuando usarlos, ¿Cual es mas eficiente?
Ocurre un problema, son públicos y pueden acceder a mis propiedades privadas, ¿que hago?:
Como es fácil violar la encapsulación en PHP:
Veamos un ejemplo:
Tendremos dos soluciones:
1) Si trabajas con mas personas: Documentar.
2) Si no queremos documentar, para evitar usar dichos metodos, haremos lo siguiente, re-declarar los métodos mágicos:
A pesar de que estos métodos "crean" propiedades y métodos dinámicos, en ninguno de los casos funcionan como se esperaba porque los redefinimos, así podemos evitar esos posibles "fallos" de encapsulamiento.
¿Y si quiero utilizar mis propios metodos get/set?:
Sencillamente agregamos nuestros propios métodos privados:
Entonces, podemos observar que aunque si pueden generar aberturas de seguridad en el encapsulamiento de PHP, podemos proteger las propiedades, por su misma capacidad de servir (los metodos magicos) como administradores de propiedades y metodos mas adaptables a las necesidades.
PHP POO ESTRICTO + 1;
En conclusión: PHP: SI ES POO ESTRICTO.
1) Cumple con los fundamentos de la POO:
Herencia.
Abstracción.
Encapsulamiento.
2)Tiene los elementos básicos como son:
Objetos, clases y métodos.
Visibilidad privada, protegida y pública
Metodos privados y públicos
Puede emplear propiedades estáticas
Sobrecargar sus métodos.
3) Puede ademas tener polimorfismo y sobrecarga (gracias a los métodos mágicos):
4) Tiene métodos mágicos con los que:
Ampliar las capacidades de PHP como POO.
Administrar los errores en PHP, y permiten redefinir las propiedades accesoras del objeto (aumentado así la encapsulación).
Los métodos mágicos se pueden opacar (shadowing).
According to wikipedia the PHP paradigm is:
And the definition of the OOP paradigm is:
Yes, you can do OOP in the strict sense of the word, but you also have to see that those of us who are starting out in OOP usually mix the different paradigms. Among my projects I continually find jumps between one paradigm and another, especially on small scales. When you work in C everything is imperative and easy to read, so sometimes you write code in Java or PHP following this paradigm. But actually if it is OO. The same thing happens to me in Python. Initially, it did not use its own classes, it did everything with functions, not to mention inheritance or abstraction.
Over time you gain more practice in one or another paradigm. In this case, it does not depend so much on PHP, but on how much you really know the paradigm and how much you know how to apply it. Although in the latter there will be those who differ.
UPDATE
On magical methods. In python everything can be overridden and accessed from anywhere. There are no private, nor public. They exist, but they are mentions about the format of the code. For example, a _VAR variable should not be accessed from outside the class. They are conventions that are reached. This is called concealment and it is one of the features of OOP. JAVA is very strict in this sense, because it is designed for teamwork. A leader, Jr developers, etc. Python no, it's freer. Trust the good practices of the programmer. And then PHP has its chores in these ideas. In any case, when you develop a project in OOP, the least you want is to have to access methods of other classes and override them. Create confusion. Personally, I am only interested in the get and set with the results that it describes. Accessing magic methods has some complications that I don't want.