Essential PHP Course: The Direct Route to Laravel and CodeIgniter
Tools Needed for the Mini-Course
In this section, we'll talk about the tools we will need to carry out this mini-course.
Code Editor
As I always recommend, the most practical thing is to use a code editor. I use Visual Studio Code (VS Code), which looks like this. I have a Python project with Flash open here, but this interface is the same for any type of project.
It is not mandatory to use VS Code; you could even program in Notepad, although that would be quite masochistic of you. I recommend using a high-quality editor, like VS Code, for several reasons:
- It is cross-platform.
- It supports multiple technologies.
- It is stable and works very well on large projects.
If you decide to use VS Code, the only extension you need to install is the PHP one. You can search for it in the extensions section; it's usually called “PHP” and requires no additional configuration.
Web Browser
You can use the browser you prefer. I use Google Chrome, but any modern browser will work perfectly for this course.
PHP and Development Environment
PHP is essential for this course, and there are many ways to install it, depending on the operating system:
Windows or macOS: I recommend Laravel Herd, which is easy to install and configure. Although its name may sound advanced, it's very intuitive and will allow you to have everything ready to work with PHP, Laravel, or CodeIgniter projects.
Linux: Installation here depends on the distribution and requires specific commands. For example, you could use XAMPP, LAMP, or consult guides for your operating system.
Laravel Herd and similar tools facilitate development, as they automatically create clean URLs for your projects, unlike other environments like XAMPP or WAMP, where everything is manual.
Hello World
Previous steps:
- Start the server. The next thing you need to do is start your server.
If you use Laravel Herd, all necessary services will start automatically when you open it. For others, like XAMPP, there's usually a button that says 'Start'. You must be aware of any errors, such as if a port is already in use, etc. Remember that you can ONLY have one XAMPP-like service such as Laragon or Laravel Herd active at a time.- Once started, when you open localhost in your browser, you should see a welcome page from your server (Apache, Nginx, or whichever you use).
- Editor, select your editor, the recommended VSC, and create a folder on your server:
- If you are using Laragon or Herd, the default path would be something like:
- C:\Users\YourUser\Laragon\www
- C:\Users\YourUser\Herd
- Create a folder, suggested named “tests” (or "pruebas" if you prefer to keep the original name) and drag it to your VSC.
- If you are using Laragon or Herd, the default path would be something like:
Writing our first “Hello World”
In PHP, all code goes inside the tags:
C:\Users\YourUser\Herd\test.php
<?php
// Your PHP code goes hereTo display text on the screen, we use the echo function.
For example:
C:\Users\YourUser\Herd\test.php
<?php echo "Hello World";The quotes can be single 'Hello World' or double "Hello World".
Each instruction must end with a semicolon ;.
Save the file and reload the page in your browser, in Laravel Herd or Laragon:
http://tests.test/test.php (or http://pruebas.test/test.php)
Others:
http://localhost/tests/test.php (or http://localhost/pruebas/test.php)
There you have your first “Hello World” in PHP! 🎉
First Steps with PHP
We are at the point where we have already learned how to display our first Hello World in PHP without complications.
Remember that, to work with PHP and place any dynamic content, we must always use the opening tag <?php ?>. From here, we can take advantage of the full potential of PHP, which allows us to perform dynamic operations, work with object-oriented programming, manage dates, variables, classes, and much more. We will be covering all of this little by little throughout the course.
My goal is not just to teach you how to create variables or functions, but to give you the foundations to understand the logical reasoning behind each action, and to understand the “why” of what we are doing.
RECOMMENDATION: Viewing the Page Source in the Browser
Before moving on, it's advisable to always check the page's source code:
On Windows or Linux: right-click → View page source
On Mac: Ctrl + U
The browser only understands HTML, CSS, and JavaScript, plus static files like PDFs, images, or videos. Everything that PHP generates is interpreted on the server and sent as HTML to the browser. For example, even if your file is PHP, the browser only renders HTML.
Looking at the source code is a useful tool for you to see exactly what is being rendered.
HTML vs PHP
To illustrate this, we can create a file test2.html with the same message we put in PHP. When you open it, you will see that the output in the browser is the same, although the path changes.
This demonstrates a key principle: the browser only understands HTML, CSS, and JavaScript. PHP serves to add dynamism to these pages, for example:
<?php echo 5 + 5; // This will display 10 ?>With PHP we can:
- Perform dynamic operations
- Display dates
- Connect to databases
Create dynamic content that is then served as HTML
In contrast, if we try to place operations like 5 + 5 with PHP directly in an HTML file, the browser will not know what to do and will simply display it as text.
Best Practices with PHP Tags
When mixing PHP with HTML, it is important to correctly close the tags.
Example:
<?php echo "Hello World"; ?> <h1>This is an HTML title</h1>The opening <?php indicates the start of the PHP code.
The closing ?> is necessary if HTML content follows.
If the entire file is pure PHP, it is not mandatory to close the tag, and in fact, it is often recommended not to close it to avoid accidental whitespace or injections.
Spaghetti Code in PHP
When we mix logic, HTML, and operations in a single file, we get what is known as spaghetti code:
- Business logic
- Database connections
- User validations
- Static HTML
This works, but it is difficult to maintain and prone to errors. That's why, even though we must learn “pure” PHP to understand the basics, the ideal is to use a framework.
Frameworks to Avoid Spaghetti Code
A framework allows us to:
- Automatically follow best practices
- Separate logic from presentation
- Avoid common errors in pure PHP
Examples of lightweight frameworks we can use to learn:
- Laravel
- CodeIgniter
- Lumen
These frameworks help us create structured and maintainable applications, preventing us from ending up with a single file full of mixed PHP and HTML.
Summary
- PHP is interpreted on the server and delivers HTML to the browser.
- Always use <?php ?> for PHP code.
- Check the browser's source code to understand what is actually sent.
- Close PHP tags if you combine with HTML.
- Avoid spaghetti code by using frameworks.
With this, we have a solid foundation to start working with PHP correctly, understanding the difference between static and dynamic content, and prepared to advance toward more complex operations and the use of frameworks.
Variables in PHP
In this section, we will talk about variables in PHP. Honestly, the data types part doesn't make much sense in this context, as this is a fairly old article that I am updating. But back to the topic: I assume you already know how to program and are here to learn PHP and take the next step, which is then jumping to frameworks, which is one of the goals of this course.
Even so, let's quickly give a definition of a variable:
A variable is simply a way to access memory. That is, we have a piece of information (an integer, a string, a boolean, etc.) and we want to store it so we can use it throughout our application.
For example, suppose you are creating a form to request a person's details, such as name, age, etc. Each of these details can be stored in a variable, such as:
- A variable for the name
- A variable for the age
The use you make of these variables will depend on the purpose of your application, the business logic, and so on. In general terms, this is what a variable is.
Variable Syntax in PHP
In PHP, all variables begin with the $ symbol. This is an interesting peculiarity of PHP, as most other languages like Java, JavaScript, C#, among others, do not use the $.
Some important rules:
- They cannot contain spaces. For example, person name is not valid.
- They cannot start with numbers or special characters.
You can use letters, underscores \_, or uppercase letters, following naming conventions:
- Camel case: personName
- Snake case: person_name
Personally, I prefer camel case, but it's a matter of preference. The important thing is to maintain consistency and readability.
Data Types and Best Practices
In PHP, the data type is optional when declaring a variable, unlike other languages like Java or C#. However, it is always recommended to specify it. For example:
$name = "Andrés"; // string
$edad = 25; // integer
$activo = true; // booleanWe can check the data type using the gettype() function:
echo gettype($name); // string
echo gettype($edad); // integerIt is important to remember:
- Do not declare crazy or illegal names for variables.
- Do not use spaces or strange characters.
- You can include numbers after the first letter if necessary.
Types of Variables in PHP
Variables are the mechanism to access memory that programming languages make available to us; in this article we will see how to create a variable in PHP, its particularities, and data types in PHP.
Variable names in PHP must start with the '$' sign (without quotes) followed by the name of the variable, which cannot be null, nor begin with a number or a special character.
Example of Invalid Variables in PHP
$1var; // no puede comenzar por un numero
$ var; // no puede comenzar con un espacio vacio
$v ar // tampoco puede contener espacios vacios
var // falto el $Example of Valid Variables in PHP
$var;
$var1;
$_var;They are case-sensitive.
Example of Distinct Variables in PHP
$Var;
$VAr;
$var;In PHP it is not necessary to specify the data type before using them; they are declared when a value is assigned to them.
PHP Supports Eight Primitive Types
Four scalar types:
Two compound types:
- object
- array
And two special types:
Finally, we present a simple example of a person's data using several of the variable types we have already seen.
<?php
$age = 24; // Integer type variable.
$name = "pepe"; // String type variable.
$married = true; // Boolean type variable.
$salary = 4025.43; // Float type variable.
// Array of 4 data types
$person_array = array('age' => $age, 'name' => $name, 'married' => $married, 'salary' => $salary);
// Object of 4 data types
$person_object = (object)$person_array;
// We display the values of the variables
echo "Integer type variable: ";
echo $age;
echo "<br>";
echo "String type variable: ";
echo $name;
echo "<br>";
echo "Boolean variable: ";
echo $married;
echo "<br>";
echo "Double type variable: ";
echo $salary;
echo "<br>";
echo "Object type variable: ";
echo $person_object->age;
echo "-";
echo $person_object->name;
echo "-";
echo $person_object->married;
echo "-";
echo $person_object->salary;
echo "<br>";
echo "Array type variable:";
echo "<br>";
var_dump($person_array);
?>Interpreting the code above:
variable de tipo integer: 24
variable de tipo string: pepe
variable boolean: 1
variable de tipo double: 4025.43
variable de tipo object: 24-pepe-1-4025.43
variable de tipo array:
array(4) { ["anos"]=> int(24) ["nombre"]=> string(4) "pepe" ["casado"]=> bool(true) ["sueldo"]=> float(4025.43) }Booleans in PHP
This is the simplest data type that exists in PHP; a boolean expresses a truth value, which can only have one of two states: TRUE or FALSE; in both cases, they are case-insensitive.
<?php
$verdad = TRUE; // asigna el valor TRUE
$falso = FALSE; // asigna el valor FALSE
?>TRUE is equivalent to the value 1 and FALSE is equivalent to the value 0; that is, you can replace the value 1 and 0 with TRUE and FALSE respectively.
Integer in PHP
An integer is by definition a signed number without a decimal part; the same rule applies in PHP.
Notations for Integers in PHP
Integers can be specified using decimal (base 10), hexadecimal (base 16), octal (base 8), or binary (base 2) notation, optionally preceded by a sign (- or +) as the case may be:
- To use octal notation, the number is preceded by a 0 (zero).
- To use hexadecimal notation, the number is preceded by a 0x.
- To use binary notation, the number is preceded by a 0b.
Example: Integer Literals in PHP
<?php
$a = 1234; // decimal number
var_dump($a);
$a = -123; // a negative number
var_dump($a);
$a = 0123; // octal number (equivalent to 83 decimal)
var_dump($a);
$a = 0x1A; // hexadecimal number (equivalent to 26 decimal)
var_dump($a);
$a = 0b11; // binary number (equivalent to 3 decimal)
var_dump($a);
?>Interpreting the code above:
int(1234)
int(-123)
int(83)
int(26)
int(3)Range of an Integer in PHP (Integer Overflow)
If PHP encounters a number outside the limits of an integer, it will be interpreted as a float instead of an integer.
Example: Integer Overflow on 32-bit Systems in PHP
<?php
$large_number = 2147483647;
var_dump($large_number);
$large_number = 2147483648;
var_dump($large_number);
?>Interpreting the code above:
int(2147483647)
float(2147483648)Example: Integer Overflow on 64-bit Systems in PHP
<?php
$large_number = 9223372036854775807;
var_dump($large_number);
$large_number = 9223372036854775808;
var_dump($large_number);
?>Interpreting the code above:
int(9223372036854775807)
float(9.2233720368548E+18)How to use it in a control structure?
<?php
// it is not necessary to perform the comparison against a boolean type
if ($truth == TRUE) {
echo "this is true\n";
}
// because it can be written like this
if ($truth) {
echo "this is true\n";
}
?>Interpreting the code above:
this is true this is trueFloat in PHP
A float or floating-point number is a signed number with a decimal part; the same rule applies for PHP.
Notations for Floating-Point Numbers in PHP
Example of Floating-Point Numbers
<?php
$a = 1.234;
var_dump($a);
$b = 1.2e3;
var_dump($b);
$c = 7E-10;
var_dump($c);
?>Interpreting the code above:
float(1.234)
float(1200)
float(7.0E-10)Range of Floating-Point Numbers
The size of a float depends on the platform, although a common value consists of a maximum of ~1.8e308 with a precision of approximately 14 decimal digits (which is a 64-bit value in IEEE format).
NULL in PHP
The NULL value indicates that the variable assigned that value has no value assigned; that is, it indicates that the variable has no value whatsoever.
The variable is considered NULL when:
- The constant NULL has been assigned to it.
- No value has been assigned to it.
- Or it has simply been destroyed with the unset() method.
Type Juggling (Type Conversion)
In this entry, we will talk a little about type conversion in PHP when performing different operations, such as mathematical ones.
PHP is not a strongly typed language, which means that it does not control the data types of variables, and if you want to perform operations, PHP performs a type conversion according to the operation you want to perform; for the following example:
$string1 = "8";
$string2 = "4cuatro";
$stringFinal = $string1 + $string2;
echo "Vamos a sumar $string1 + $string2 <br>";
echo "resultado $stringFinal";It gives the following output:
We are going to add 8 + 4four
result 12 When trying to perform an addition operation, the PHP interpreter automatically converts the text contained in the variable $string1 from "8" to 8. A similar behavior happens with the variable $string2; the interpreter converts to a numerical value until it finds the first character "c", giving an implicit conversion of the value 4 to perform the addition operation, and both values are summed.
If, on the contrary, we apply the following example:
$string1 = "8";
$string2 = "c4uatro";
$stringFinal = $string1 + $string2;
echo "Vamos a sumar $string1 + $string2 <br>";
echo "resultado $stringFinal";We are going to add 8 + c4four
result 8 The interpreter again converts $string1 from "8" to 8, but for the value stored in the variable $string2, the interpreter detects that the first character is not numeric, being "c", and therefore there is nothing to convert, and the variable is evaluated by default as zero.
Other Aspects of the NULL Data Type
The constant NULL is case-insensitive.
Concatenation in PHP
Concatenation in PHP is done with the dot (.), not with the + as in other languages:
echo "Hello " . $name;This works to join strings. If you want to include variables directly inside a string, you can use double quotes:
echo "Hello $name"; // prints Hello AndrésWith single quotes, the content is taken as literal text:
echo 'Hello $name'; // prints Hello $nameThis is useful when you want to print something without PHP interpreting it as a variable.
Operations with Variables
You can perform arithmetic operations according to the data type.
Concatenation only works with strings; other types may require conversion.
Booleans, integers, and floats behave according to their type.
Examples:
$numero = 10;
$decimal = 10.5;
$esValido = true;
echo $numero + 5; // 15
echo $decimal + 4.5; // 15
echo $esValido ? 'Sí' : 'No'; // YesSingle quotes for literal text.
This serves as a basis for understanding how variables work in PHP and practicing their use before moving on to functions, classes, and other more advanced structures.
echo 'Hello '. $name. ' Hello';
echo "Hello $name Hello";Summary
Variables begin with $.
- They cannot contain spaces or start with numbers.
- Use camel case or snake case for readability.
- Data types are optional, but recommended.
- Concatenation with . or interpolation with double quotes.
Functions
Now let's move on to functions in PHP. How on earth can we implement functions in PHP?
Before that, let's recall the basic concept: functions exist to reuse code.
For example, even though we have seen practically nothing, suppose this is crucial or very important to you, and you want to print it in two parts: one in the header and another in a menu.
So, how would you do it as we have shown up to this point? You would have to duplicate it in those crucial parts. As I mentioned before: open the PHP block here, print the code, then open another block there, print it again... which is obviously a problem.
Imagine that it is more code, that it includes connecting to the database, validations, or that it simply changes in the future. Clearly, this is impractical.
That is why functions arise, which exist in practically every programming language. They are a key piece for modularization, organization, code simplification, and the creation of reusable components.
Creating our first function
Having clarified this, I am going to create a new file so as not to mix so many things. In this case, I called it functions.php.
To declare a function in PHP, just like before, we open the PHP block:
<?php ?>And now, yes, we create our first function:
function hello() {
echo "Hi";
}This is the basic structure:
- The reserved word function.
- The name of the function (no spaces or special characters).
- The parentheses.
The curly braces that contain the reusable code.
As a note: you cannot use reserved names as variables (although in PHP you can use $function because all variables have $, but not in other languages).
If you try to call a function that does not exist, you will get an error. But as long as it is only declared and not invoked, nothing will happen.
To invoke it, you simply do:
hello();Using Parameters
Now let's move on to another important part: parameters.
Let's design a function that receives a name:
function hello($name) { echo "Hello " . $name; }If you call it without parameters, PHP will indicate that the function expected one, but received zero.
To use it correctly:
hello("Andrés");Parameters simply represent the data that the function needs to execute its purpose.
A Function with Multiple Parameters
Now suppose a sum function:
function sum($a, $b) {
echo $a + $b;
}We call it like this:
sum(5, 10);Up to this point, it prints the result, but does not return anything. This becomes problematic when we want to use the calculated value outside the function.
Returning Values
If we want the function to “return” something to be reused, we use return:
function sum($a, $b) {
return $a + $b;
}Now we can do:
$result = sum(5, 10);
var_dump($result);This returns the type and value to you, thanks to var_dump.
Data Types in Arguments
Another important detail: if you do not declare types, PHP will try to convert the values automatically, which can generate silent errors.
For example, you could pass a string where a number was expected.
To avoid this, you can type like this:
function sum(int $a, int $b) {
return $a + $b;
}If you call:
sum("hello", 5);Now the error will be clear: the argument does not meet the type.
You can also allow multiple types:
function sum(int|float $a, int|float $b) {
return $a + $b;
}Declaring the Return Type
In addition to the type of the arguments, you can also type the value that the function will return:
function sum(int $a, int $b): int {
return $a + $b;
}This provides more consistency and security to the code.
If the function were to return strings, for example, you would simply indicate : string.
Other Useful Aspects
PHP also supports:
- variadic functions (function test(...$args)),
- arrow functions (fn($a) => $a * 2),
- and many internal functions like var_dump, gettype, etc.
- In general, with this you already have:
- How to declare functions,
- How to invoke them,
- How to use parameters,
- How to return values,
- How to use data types in parameters and returns.
🧠 Control Structures: The Use of Conditionals
1. Basic Concept: What is a Conditional?
A conditional is simply a control structure that allows making decisions based on a boolean condition (true or false). It is the equivalent of the if and else structures that exist in most programming languages.
Example: Is your age greater than 18? (True or False).
2. Comparison Operators
To establish a condition, we use comparison operators:
Strict equality (==): Compares if two values are equal. (Different from simple assignment: $age = 18;).
- Greater than (>): $age > 18
- Less than (<): $age < 18
- Greater than or equal to (>=): $age >= 18
- Less than or equal to (<=): $age <= 18
- Not equal to (!= or <>)
Practical Example: Age Validation
Let's consider the validation of the age of majority, which in many places is from 18 years old.
<?php
$age = 18;
// We use the "Greater than or equal to" operator (>=) to include 18
if ($age >= 18) {
echo "You are an adult. Congratulations, now you have to work.";
} else {
echo "You are a minor.";
}
?>- Problem with only > (Greater than): If we use $age > 18, the code will fail if the age is exactly 18, because 18 is not greater than 18.
- Solution: The >= operator solves this by comparing whether it is greater than or exactly equal to the specified value.
Nesting Conditions: elseif
When we have multiple conditions that are mutually exclusive (that is, we only want one of them to be met), we must nest the code using elseif.
If we do not nest the conditionals, all blocks whose condition is met will be executed, which is incorrect for most logic (such as determining a grade range).
🎓 Grade Example (Exclusive Logic)
We want to evaluate if a person is excellent, good, or needs improvement, based on ranges:
- Excellent: Greater than or equal to 90.
- Good: Greater than or equal to 70.
- Needs Improvement: Less than 70.
<?php
$grade = 75;
if ($grade >= 90) {
echo "You are excellent."; // If it enters here, it ignores the rest
} elseif ($grade >= 70) {
echo "You are good. An average like everything in your life."; // If it enters here, it ignores the 'else'
} elseif ($grade >= 50) {
echo "You need to improve.";
} else {
echo "You are a 'zapacuco'."; // If none of the above conditions were met
}
?>Advantage of elseif: PHP evaluates the first if. If it is true, it executes the block and exits the entire structure. If it is false, it moves to the next elseif and repeats the process. This ensures that only a single block of code is executed, guaranteeing the correct logic.
Example with 75:
- $nota >= 90 (75 >= 90) - False.
- elseif ($nota >= 70) (75 >= 70) - True. - Executes and exits.
⚙️ Control Structures: The use of switch
The switch is another control structure that, while similar to if/else, offers a cleaner and more appropriate implementation for evaluating multiple cases.
1. ❓ The Problem of Multiple Conditions
Although if/else works for any evaluation, its readability becomes complicated when four, five, or more nested or sequential conditions are needed.
For example, if we needed to evaluate the nota variable with multiple ranges (greater than 90, greater than 80, greater than 70, etc.), the chain of else if becomes dense:
if ($grade > 90) {
// ...
} else if ($grade > 80) {
// ...
} else if ($grade > 70) {
// ...
}
// ... and so on.For these scenarios, the switch is a more suitable and easier-to-read alternative.
2. 📝 Basic switch Syntax
The switch structure evaluates a single expression (variable, function return, etc.) against a series of predefined cases (case).
switch ($condition_to_evaluate) {
case $value1:
// Code to execute if value1 is met
break;
case $value2:
// Code to execute if value2 is met
break;
// ... more cases
default:
// Code to execute if no case is met
break;
}Key Elements:
- switch (condition): This is where the variable or value we want to evaluate is placed (e.g., grade, day).
- case value:: Defines a specific condition. Note that a colon : is used instead of curly braces {}.
- break;: Essential. Just as else prevents unnecessary re-evaluation in the if/else structure, the break ensures that, once a case is met, the program stops evaluating the subsequent cases and immediately exits the switch.
- If you remove the break, the program will execute the code for that case and continue executing the code for the next case until it finds a break or finishes the structure.
3. 🎯 The Default Case (default)
The default is the equivalent of else in the if/else structure.
- Function: If none of the case conditions are met, the code block within default will always execute.
- Location: By convention, it is always placed as the last case to evaluate.
- Use: You can use it to handle unexpected values (e.g., if you expect a day of the week, but the user enters "X") or to define a base action if the value does not match any specific case.
Practical Example (Days of the Week)
If we want to evaluate the variable day, a switch is perfect for the seven days.
<?php
$day = "Monday";
switch ($day) {
case 'Monday':
echo "The week begins."; // Enters here
break;
case 'Friday':
echo "Last working day.";
break;
default:
echo "It's a normal day."; // Enters if the day is 'Tuesday', 'W', etc.
// The break here is optional, as it is the last case.
break;
}
?>Reminder: The case conditions are evaluated in the order they are arranged. It is crucial that the order makes sense for your application's logic.
4. 🚀 Practice Tips
To familiarize yourself with the switch, I recommend:
- Think about the Logic: Create a business scenario (e.g., handling order statuses, assigning categories to scores).
- Implement the switch: Write the structure for that scenario.
- Convert and Compare: Use AI tools (like your editor's code assistant) to convert your switch to an if/else and vice versa. This will help you understand how the two structures are mapped: the default will always be the final else.
Ternary Operator?: - Coalescing?? and Null Safety
We're going to explore two very useful operators in PHP for performing short conditional statements and handling value assignment, especially when it comes to avoiding null types.
The two operators we'll look at are:
- Ternary Operator (? :)
- Null Merge Operator (Null Coalescing Operator, ??)
1. Ternary Operator (? :)
The ternary operator is the most concise way to replace a simple if-else structure that assigns a value to a variable.
We start with the previous conditional:
$age = 5;
$older = false; // It is initialized to avoid nulls
if ($age >= 18) {
$older = true;
} else {
$older = false;
}condition ? value_if_true : value_if_false - If the condition is true, it assigns the first value; otherwise, it assigns the second.
And the ternary operator looks like:
$age = 20; $older = ($age >= 18) ? true : false;The main advantage is that it allows for clean assignments without the need to initialize the variable before or use multiple lines of code.
2. The Null Coalescing Operator (??)
This operator (also known as the Null Coalescing Operator) is used to check if a variable or expression is null and, if so, assign it a default value. It is very useful for handling user input data (like forms) and ensuring there is always a defined value.
variable ?? default_value - If variable is not null, use its value. If variable is null, use default_value.
/**
* Demonstrating the Null Coalescing Operator (??)
* This operator returns its first operand if it exists and is not NULL;
* otherwise it returns its second operand.
*/
$userValue = null;
$defaultValue = 10;
// Scenario 1: $userValue IS null
// Check if $userValue is non-null. Since it IS null, $defaultValue (10) is assigned.
$result = $userValue ?? $defaultValue;
echo "Scenario 1 (null input):" . "<br>";
echo "\$userValue is: " . var_export($userValue, true) . "<br>";
echo "\$defaultValue is: $defaultValue" . "<br>";
echo "\$result = \$userValue ?? \$defaultValue; -> Result: **$result**" . "<br>";
echo "<hr>";
// Scenario 2: $userValue is NOT null
$userValue = 50;
$defaultValue = 10;
// Check if $userValue is non-null. Since it IS 50 (not null), 50 is assigned.
$result = $userValue ?? $defaultValue;
echo "Scenario 2 (non-null input):" . "<br>";
echo "\$userValue is: $userValue" . "<br>";
echo "\$defaultValue is: $defaultValue" . "<br>";
echo "\$result = \$userValue ?? \$defaultValue; -> Result: **$result**" . "<br>";The Importance of Avoiding Nulls (Null Safety)
The use of operators like ?? is closely linked to the concept of **Null Safety** in programming.
In many languages (like JavaScript), attempting to access a method or property of a variable that is null or undefined causes a fatal error (an exception).
Although in PHP some string functionalities are handled using helper functions (str_lower() instead of $string->toLowerCase()), the ?? is essential to avoid ambiguity and errors that arise when working with null references in the application's flow. It ensures that the variable will always have a value to work with.
Challenges
🔹 1. Function that says whether a number is even or odd
Create a function that receives a number and returns "Even" or "Odd".
You must implement it using conditionals AND with the ternary operator (?:)
Challenge Resolution:
With Conditionals
/**
* Checks if a number is even or odd using a standard if-else structure.
*
* @param mixed $number The value to check.
* @return string The result of the check or an error message.
*/
function isEvenOrOdd($number) {
// 1. Data Validation: Ensure the input value is numeric.
if (!is_numeric($number)) {
return "The entered value is not a number.";
}
// 2. Conditional Check using the Modulo Operator (%).
// If the remainder of the division by 2 is 0, the number is even.
if ($number % 2 === 0) {
return "The number $number is even.";
}
// Otherwise, the number must be odd.
else {
return "The number $number is odd.";
}
}We use it:
echo isEvenOrOdd(10) . "<br>"; // 10 is even. echo esParOImpar(7) . "<br>"; // 7 is odd. echo isEvenOrOdd("ABC") . "<br>"; // Not a number.With Ternaries
This is the implementation with the ternaries:
/**
* Checks if a number is even or odd using the ternary operator.
*
* @param mixed $number The value to check.
* @return string The result of the check or an error message.
*/
function isEvenOrOddTernary($number) {
// 1. Input Validation: Ensure the value is a number.
if (!is_numeric($number)) {
return "The entered value is not a number.";
}
// 2. Main Logic: Use the ternary operator to determine if it is even or odd.
// The expression ($number % 2 === 0) checks if the remainder of the number divided by 2 is 0.
$res = ($number % 2 === 0)
? "The number $number is even." // Value if TRUE (EVEN)
: "The number $number is odd."; // Value if FALSE (ODD)
// 3. Return the result.
return $res;
/*
* OPTIONAL: The function can be simplified by removing the intermediate variable $res
* and returning the ternary result directly:
*
* return ($number % 2 === 0)
* ? "The number $number is even."
* : "The number $number is odd.";
*/
}💡 Extra: Arrow Functions (fn)
Taking advantage of the single-line simplification, we can refactor the function using an **Arrow Function (fn)**, a PHP feature for functions defined in a single statement.
The arrow function is a concise form of representation. By definition, it always returns the value of the expression placed after the arrow, without the need to use the return keyword.
/**
* Checks if a number is even or odd using the Arrow Function syntax.
* * This format is concise and only allows a single expression.
*
* @param int $number The numeric value to check.
* @return string The result of the check.
*/
// The 'fn(parameters) => expression' syntax performs an implicit 'return' of the expression.
$arrowFunction = fn($number) =>
($number % 2 === 0)
? "The number $number is even." // Value returned if EVEN
: "The number $number is odd."; // Value returned if ODD
// Usage: The variable ($arrowFunction) is called as if it were the function.
echo $arrowFunction(12) . "<br>";
// Output: The number 12 is even.<br>
echo $arrowFunction(7);
// Output: The number 7 is odd.Note on Typing: In modern versions of PHP, it is recommended to add type signatures (arguments and returns) for greater robustness and to dispense with manual validations like is_numeric().
/**
* Checks if a number is even or odd, enforcing argument and return types.
* * @param int $number The number to check.
* @return string The result of the check.
*/
// The ': string' ensures the function must return a string.
// The 'int $number' ensures the input must be an integer.
function isEvenOrOddTyped(int $number): string {
// If you pass a value that is not an integer (like a string),
// PHP will throw a TypeError at the function call (this is good practice).
// Ternary operator logic remains the same.
return ($number % 2 === 0)
? "The number $number is even."
: "The number $number is odd.";
}
// Usage Example:
echo isEvenOrOddTyped(42) . "<br>";
// Output: The number 42 is even.
// Example of how it enforces typing (would throw an error if uncommented
// and strict types were enabled):
// echo isEvenOrOddTyped("hello"); // This would cause a fatal TypeError
// if 'declare(strict_types=1);' was used.Another implementation:
$parOImparFlecha = fn(int $numero) : string => ($numero % 2 == 0) ? "The number $numero is EVEN." : "The number $numero is ODD.";🔹 2. Function that calculates the final price with discount
The function receives a price and a discount percentage.
It must return the final price AND a message indicating the applied Discount:
- Invalid Price, if the price is NOT a number or is negative
- Invalid Discount (must be between 0 and 100), if the discount is greater than 100, negative, or not a number
- Price without discount:, If the discount is 0
- Free Product, if the discount is 100
- Price with discount, for all other cases
The implementation must be done with conditionals and also with switch
Challenge Resolution:
We define the function and start by validating data integrity. It's a good practice to stop execution as soon as an invalid value is detected.
function calcularPrecioFinal($precio, $descuento): string {
// 1. PRICE VALIDATION (Invalid or Negative)
// We use OR (||) because if ANY of the conditions is met, it's an error.
if (!is_numeric($precio) || $precio < 0) {
return "ERROR: Invalid or negative price entered.";
}
// 2. DISCOUNT VALIDATION (Invalid or Out of Range 0-100%)
if (!is_numeric($descuento) || $descuento < 0 || $descuento > 100) {
return "ERROR: Invalid discount. Must be between 0% and 100%.";
}
// Note on typing: If the function signature includes types (e.g., (float $precio, int $descuento): string),
// the is_numeric() check can be omitted.
// Price formatting for output (e.g., $10.00)
$precioFormateado = number_format($precio, 2);
// 3. SPECIAL CASE: 0% Discount
if ($descuento == 0) {
return "Full price. No discount. Total: $precioFormateado.";
}
// 4. SPECIAL CASE: 100% Discount
if ($descuento == 100) {
return "The product is FREE! Total: $0.00.";
}
// 5. GENERAL CASE: Valid Discount (between 1% and 99%)
// If execution reaches this point, we don't need further checks (it's not invalid, not 0%, not 100%).
// Final price calculation:
// a) Calculate the discount percentage: $descuento / 100 (e.g., 50 / 100 = 0.5)
// b) Multiply by the price to get the discount amount: $precio * 0.5 = $25.00
// c) Subtract that amount from the base price.
$precioFinal = $precio - ($precio * ($descuento / 100));
$precioFinalFormateado = number_format($precioFinal, 2);
return "Price with a $descuento% discount. Total: $precioFinalFormateado.";
}Once the data is valid (numeric and within an acceptable range), we proceed to evaluate the special cases (0% and 100%).
// 3. SPECIAL CASE: 0% Discount
if ($descuento == 0) {
return "Full price. No discount. Total: $precioFormateado.";
}
// 4. SPECIAL CASE: 100% Discount
if ($descuento == 100) {
return "The product is FREE! Total: $0.00.";
}
// 5. GENERAL CASE: Valid Discount (between 1% and 99%)
// If execution reaches this point, we don't need further checks (it's not invalid, not 0%, not 100%).
// Final price calculation:
// a) Calculate the discount percentage: $descuento / 100 (e.g., 50 / 100 = 0.5)
// b) Multiply by the price to get the discount amount: $precio * 0.5 = $25.00
// c) Subtract that amount from the base price.
$precioFinal = $precio - ($precio * ($descuento / 100));
$precioFinalFormateado = number_format($precioFinal, 2);
return "Price with a $descuento% discount. Total: $precioFinalFormateado.";
}Let's test different scenarios:
echo calcularPrecioFinal(50, 0) . "<br>"; // No discount: $50.00
echo calcularPrecioFinal(100, 25) . "<br>"; // Normal discount: $75.00
echo calcularPrecioFinal(80, 100) . "<br>"; // Free: $0.00
echo calcularPrecioFinal(10, -5) . "<br>"; // ERROR: Invalid discount.
echo calcularPrecioFinal("ABC", 25) . "<br>";// ERROR: Invalid price.💡 Note on the Use of return
In this function, the else structure is not used because each condition that handles a specific business case uses the keyword return.
When a function encounters a return, execution terminates immediately, regardless of the code that follows.
- If the function enters the if for invalid price, it returns the error and does not execute the rest of the code.
- If the function enters the if for 0% discount, it returns the full price and does not execute the final calculation code.
This avoids nesting multiple if/else statements and makes the logic flow flat and easy to follow.
🏗️ The Nightmare of Forms in PHP
Now, the next step is where things get a bit ugly. We're going to start working with forms. And why do I say it gets ugly? Because this is one of the things that annoys me the most about PHP: making a form in pure PHP can lead to many problems if the code is not organized well.
It's very easy to end up with spaghetti code, a bunch of messy files that immediately cause errors. However, it is equally important to know how it works, even if it is cumbersome.
📝 Basic Elements of an HTML Form
It all starts with a normal form. A form with its action and its method.
GET Method
By convention (good practices), we use GET requests for queries.
- Risk: You shouldn't (although technically you can) use GET to create users or send sensitive data, such as credit cards.
Reason: Everything travels in the URL, which is extremely insecure due to the multiple vulnerabilities that can be exploited (something I will explain to you little by little throughout this course).
POST Method
The POST request type is more secure.
- Difference: It no longer travels directly in the URL, but as a request body (something called the body).
- Viewing: This can be seen in the browser by opening the Developer Tools (F12) and checking the Network section (which is very useful for my own developments).
Action and Form Fields
The action (who wants to process it) is where things start to get annoying in PHP: it can be the same file or another file you want to reference.
In this case, we'll use a POST request type to simulate a simple contact form: name, surname, email, and a message.
- Fields: A normal text field, an input (type text, email, etc.) or a textarea for the message is used.
- Required HTML: It's vital to know HTML and JavaScript, so I assume you have that knowledge. You can search for "HTML forms" on Google if you don't.
- Name (name): It is extremely important to assign it a name, as this is how you will reference it from PHP.
- placeholder: It's a label that appears inside the input. Usually, for good practice, a label tag is also included, but I don't want to complicate the exercise.
- type="email": The validations offered by the browser for email type fields are excellent; anything free is appreciated.
- textarea: Used for the content of the message (a large text field) so the user can express themselves freely.
The form looks like this:
04_formularios.php
<form action="04_forms.php" method="POST">
<input
type="text"
name="name"
placeholder="Name"
value=""
style="width: 100%; margin-top: 5px; padding: 8px; border: 1px solid #ccc;"
>
<input
type="text"
name="surname"
placeholder="Last Name"
value=""
style="width: 100%; margin-top: 5px; padding: 8px; border: 1px solid #ccc;"
>
<input
type="email"
name="email"
placeholder="Email"
value=""
style="width: 100%; margin-top: 5px; padding: 8px; border: 1px solid #ccc;"
>
<textarea
name="message"
placeholder="Message"
style="width: 100%; margin-top: 5px; margin-bottom: 5px; min-height: 100px; padding: 8px; border: 1px solid #ccc;"
></textarea>
<div style="display: flex; justify-content: flex-end;">
<button
type="submit"
style="
background-color: green;
color: white;
padding: 10px 15px;
border: none;
cursor: pointer;
font-weight: bold;
"
>
Send
</button>
</div>
</form>Processing data in PHP
To process the data, we use PHP and the $_POST array:
04_formularios.php
$all_values = [
'name' => $_POST['name'] ?? '',
'surname' => $_POST['surname'] ?? '',
'email' => $_POST['email'] ?? '',
'message' => $_POST['message'] ?? ''
];- We use $_POST. This syntax ($) indicates that it is an internal PHP element, and in this case, $_POST refers to the POST method that we defined in the HTML form.
- For example, $_POST['name'] accesses the value sent from the form.
- If the request was configured by GET in the form:
- <form action="04_formularios.php" method="GET">
- It would be $_GET['name'] instead.
- The ?? '' operator prevents null values if the user didn't send anything.
- Remember that name, surname, etc., must match the names of the HTML inputs.
The first thing I find awful is that one of the ways of working in PHP is to process everything in the same file. This inevitably leads to spaghetti code, since if it's a contact form, you'll likely want to save the data in the database, which would involve making the connection and the process right there.
Arrays in PHP are similar to other programming languages. We declare a variable and use square brackets ([]) to indicate that it is an array.
Data Visualization
To test our form, we can use print_r() or var_dump() in PHP, which allows us to see the structure of the data sent:
echo '<pre>';
print_r($all_values);
echo '</pre>';
var_dump($all_values);This is useful for debugging and initial testing.
Remember that data sent by GET will appear in the URL, while data sent by POST will not.
😩 The Complication of Manually Processing a Form
The problem is that, apart from the enormous freedom, the code we are going to implement is a bit complicated and difficult to read as we include all these functionalities:
- Validations.
- Database injection.
- To demonstrate a problem, if a user enters malicious code, for example:
- The errors will be displayed on the screen:
- Solution: To sanitize user data, we will use the htmlspecialchars() function. This converts special HTML characters into entities, preventing injected code from running.
- Error handling.
- Returning the previous value (notice that, upon reloading, the previous value is lost, which shouldn't happen).
I agree to receive announcements of interest about this Blog.
Learn PHP from scratch with this comprehensive guide. We cover variables, functions, conditionals (if/else, switch), and best practices to avoid spaghetti code. Prepare your foundation for mastering frameworks like Laravel!
Algunas recomendaciones:
Benjamin Huizar Barajas
Laravel Legacy - Ya había tomado este curso pero era cuando estaba la versión 7 u 8. Ahora con la ac...
Andrés Rolán Torres
Laravel Legacy - Cumple de sobras con su propósito. Se nota el grandísimo esfuerzo puesto en este cu...
Cristian Semeria Cortes
Laravel Legacy - El curso la verdad esta muy bueno, por error compre este cuando ya estaba la versi...
Bryan Montes
Laravel Legacy - Hasta el momento el profesor es muy claro en cuanto al proceso de enseñanza y se pu...
José Nephtali Frías Cortés
Fllask 3 - Hasta el momento, están muy claras las expectativas del curso