Lesson 1 - Introduction to object-oriented programming in PHP
Welcome to the first lesson of our object-oriented programming in PHP course. If you've gotten this far, you have at least successfully passed the Basic PHP constructs course. In this course, we will get into what is known as object-oriented programming and most importantly, you will learn to think in an object-oriented way. It's something different than what we have done up until now, and we will no longer treat the script like lines of code that the interpreter executes individually.
Why program in an object-oriented way?
Knowledge of object-oriented programming in PHP is absolutely essential, because it allows you to create web application architectures (the separatation of the logic and presentation layers) and use third party components. Developing serious projects without objects is exhausting, inefficient and the final result will be always of low quality.
Object-oriented programming's creation (OOP hereinafter) was no coincidence, but the result of certain needs and desires in development and developers. OOP is a modern software development methodology, that is supported by most programming languages. A common mistake is that people think that OOP should only be used on certain kinds of programs, and is needlessly complicated in any other case. Quite the contrary! OOP is a philosophy, it is a new a new way of looking at programs and of communication between their parts. You should always use it put it into practice no matter the project. Whether you are making a simple utility or a complex database system, OOP is the way to go. OOP is not just a technology or a recommended program structure, it is a new way of thinking, a new perspective, and a new era in software development.
First and foremost, we'll look into the past and see how people programmed before and what specific problems OOP resolved. It is important for you to understand why OOP was created in the first place.
The evolution of methodologies
There is a big difference between programming 40 years ago, and programming nowadays. The first computers didn't have the greatest overall performance and their software was rather simple. However, hardware development was (and still is) so fast that the number of transistors in microprocessors doubled every year (Moore's Law). Unfortunately, people were not able to keep up the pace, if you will, as hardware developed. Faster computers require increasingly sophisticated and complex software. In other words, people continually want more and more out of their computers. At one point, it was found out that around 90% of software is created with delays, additional costs or not finished at all. Developers searched for new ways of writing programs. Several new approaches were brought forth, more precisely, paradigms (ways of thinking):
1. Machine code
Here, all a program was, is a set of instructions. We couldn't name variables or enter mathematical expressions. The source code was specific to the current hardware (processor). This paradigm was replaced soon after it was established.
A program that adds up two numbers (83 and -2) would look like this:
2104 1105 3106 7001 0053 FFFE 0000
As you can see, programming in machine code isn't a good idea. Even basic tasks required several lines!
2. The non-structured paradigm
The non-structured approach is sort of like the assembly language, a set of instructions that are executed line by line. Here, the code is not dependent on the hardware and is human readable. This approach enabled the creation of more complex programs for a while. However, there were still many pitfalls: the only way to repeat something or branch was the GOTO statement. GOTO essentially was used to "jump" to different parts in the program. All of the aforementioned locations were set by a line number in the source code, which is obviously impractical. When they added a new line to the code, the numbers no longer matched and the code broke. Later on, they gained the ability to define "labels". This was eventually brought down by the absence of loops. This method of writing programs is very confusing and soon failed to be sufficient for the development of complex programs.
Here is the same example program in ASM:
ORG 100 LDA A ADD B STA C HLT DEC 83 DEC –2 DEC 0 END
Remember that the enormous improvement and expansion of computers over the past few decades has been the cause of the growth of software demand and the growth of programmer demand as well. Certainly, there are people who can write bulletproof programs in ASM or other low languages, but how many are there? How much would cost to hire this superhuman? It is necessary to have a way that even less experienced programmers could use to write high-quality programs and not have to go through 5 years of trial and error to do so.
3. Structured programming
Structured programming is the first paradigm that lasted for a substantial amount of time and was sufficient for the development of new programs. In structured programs, we use loops and branching. This is basically where you are now with what you have learned here so far.
Programs here can be decomposed into functions (methods), which we have already covered. When people refer to structured programming they often mention functional decomposition. The problem is decomposed into several subproblems and each subproblem is then solved with a set of functions with its respective parameters.
The disadvantage to structured programming is that a function can only do one thing. Meaning that when we want different behavior, we'd have to write a new one. There is no way to reuse old code and modify it a little bit, we need to write things over again and over again, which is a waste of time and leads to errors. This can be partially worked around by using parametrized functions (in which case the number of parameters grows fast) or using global variables. However, with global data comes a new danger: functions have access to each other's data. This is the beginning of the end, we would have to make sure that there is no global data being overwritten anywhere between functions, which would lead to uncontrollable problems. The entire program would consist of unencapsulated code blocks and would be very difficult to maintain. Any modification would increase the complexity of the program. The program would eventually get to a point where the cost of adding new features would increase so much that doing so would no longer be worthwhile. The official representatives of this approach include the C language and Pascal.
Our example program using a structured approach would look like this:
function add($a, $b)
return $a + $b;
$c = add(83, -2);
Between structured programming and object-oriented programming, there was a meta-approach called modular programming. It allowed for the encapsulation of specific functionality into modules. Regardless, there was no way to modify and reuse code.
As I mentioned at the beginning of the article, sometimes it is said that simple programs should not be written using OOP, and should be written structurally. The latter is not true. If we violate the OOP philosophy at all, the outcome could only bring loads of stress. As we can never know whether a program will not become popular, and a small utility could very well become something more serious. Then again, you would get to a point where the program would not longer be upgradable and you'd either have to throw it away or rewrite it using OOP.
Non-object-oriented methods of writing code are referred to as "spaghetti code" because of their lack of clarity (everything is all tangled together).
OOP is a philosophy and a way of thinking, designing and implementing, where reusability is the main point of focus. This approach was inspired by the industrial revolution - the invention of basic components that are used continually. When a house is built, they don't mold bricks and forge nails because it is cheaper and more efficient for them to buy them in bulk.
Creating a program made up of components is cheaper and more convenient. You can trust it, as it was tested (components always work because they are tested and maintained). If there is a problem, you fix it at a single known place. We are motivated to write clear code because it can be used by others or by ourselves in other projects. Let's face it, humans are lazy by nature and knowing that code would never again be reused would likely discourage us from writing it in the first place.
Don't worry, we will use all of the stuff we went over in the first course, however, our code from now on will be structured using objects that communicate.
Despite the fact that we won't create our first application until the next lesson, let's take a peek at what our example would look like in an object-oriented way. The Add() function won't just be flying around but will be bound to the "calculator" object, which is a component in our application.
public function add($a, $b)
return $a + $b;
$calculator = new Calculator();
$c = $calculator->add(83, -2);
I suppose code doesn't tell you much at the moment but worry not young padawan! We will go over all of the details and create our first object-oriented application in the next lesson - First object-oriented application in PHP