PHP is one of the most widely used languages for server-side pro­gram­ming. Over the years, it has become a core component of many modern websites and web tech­no­lo­gies. For beginners, however, getting started with PHP can feel chal­len­ging. This PHP tutorial in­tro­duces you to the fun­da­ment­als of the language and explains its most important operators, loops and functions in a clear and practical way.

Key Takeaways

  • You need a web server with a PHP in­ter­pret­er to run the examples, for instance via XAMPP, the PHP built-in server, or Docker.
  • The PHP basics cover syntax, echo, variables, strict typing, con­cat­en­a­tion operators, and cal­cu­lat­ing with variables.
  • You pass data with the $_GET and $_POST su­per­g­lob­als and control the program flow with if, match, and loops.
  • Further chapters cover file op­er­a­tions, object-oriented pro­gram­ming, and clean code with Composer and namespaces.
  • The tutorial closes with a PDO database example and security measures such as prepared state­ments, output escaping, and password hashing.

How to prepare for the PHP tutorial

Our tutorial is primarily aimed at complete beginners. However, for some examples it is helpful to have a basic un­der­stand­ing of modern web de­vel­op­ment and HTML. To follow the examples on your own computer, make sure you have the following set up:

  • Web server including PHP in­ter­pret­er
  • Install PHP
  • Web browser
  • Text editor

XAMPP

As a server en­vir­on­ment, we recommend the free local test en­vir­on­ment XAMPP, provided by Apache Friends for Windows, Linux and macOS. XAMPP is intended solely for testing purposes. The software bundle allows de­velopers to quickly set up a complete local en­vir­on­ment for scripts, HTML pages and stylesheets. However, it is not designed for secure operation as a publicly ac­cess­ible web server.

XAMPP tutorials can provide you with more detailed in­stall­a­tion in­struc­tions.

Web hosting
The hosting your website deserves at an un­beat­able price
  • Loading 3x faster for happier customers
  • Rock-solid 99.99% uptime and advanced pro­tec­tion
  • Only at IONOS: up to 500 GB included

PHP built-in server

Since version 5.4, PHP has included an in­teg­rated de­vel­op­ment server that is par­tic­u­larly suitable for simple tests and learning purposes. This built-in server does not require any ad­di­tion­al server software such as Apache or NGINX. The only re­quire­ment is an installed PHP version on your system. You can then start the server directly from the command line in the project directory:

php -S localhost:8000
bash

PHP then serves the files in the current folder at the address http://localhost:8000 in the web browser. The built-in server is es­pe­cially suitable for initial PHP ex­per­i­ments, small test scripts, or quickly trying out code examples.

Docker and Docker Compose

A slightly more advanced al­tern­at­ive is to use Docker. Docker makes it possible to en­cap­su­late de­vel­op­ment en­vir­on­ments in con­tain­ers. This allows web servers, PHP, and databases to be con­figured exactly as they will later run in the pro­duc­tion en­vir­on­ment. For PHP projects, Docker Compose is often used to start multiple services together. The entire con­fig­ur­a­tion is stored in a file (‘docker-compose.yml’) and can be started with a single command.

In­tro­duc­tion to PHP syntax

Once you have set up your local web server (for example, with XAMPP), you should check whether PHP is installed correctly and ready to run scripts. A script is a program that is not compiled into binary code be­fore­hand but executed by an in­ter­pret­er instead. Open your preferred text editor and enter the following PHP script:

<?php
phpinfo();
?>
php

PHP scripts always follow the same pattern. The opening PHP tag <?php signals that a script en­vir­on­ment is being started. This is followed by the actual PHP code in the form of state­ments. In the example, this is the call to the phpinfo() function. Most PHP functions require one or more para­met­ers placed inside the brackets; for phpinfo() these are optional. Each statement ends with a semicolon (;). To close the script en­vir­on­ment, the closing PHP tag is used: ?>. This is optional for pure PHP files.

Save the text file under the name ‘test’ in the .php format (PHP script) and start your web server. If you are using the XAMPP test en­vir­on­ment, place ‘test.php’ in the XAMPP directory under ‘htdocs’ (C:\xampp\htdocs).

Image: The test.php file in the htdocs folder
To run the test.php file via XAMPP, you must place it in the htdocs folder.

You can now access the sample file in your web browser using the following URL: http://localhost/test.php. If you are using a different web server or a custom XAMPP con­fig­ur­a­tion, choose the URL that matches the re­spect­ive file path.

By entering the URL http://localhost/test.php, you instruct your web browser to request the ‘test.php’ file from the web server. The Apache HTTP server or your preferred web server software retrieves the file from the cor­res­pond­ing directory. The .php extension indicates that the file contains PHP code. When the file is requested, the PHP in­ter­pret­er in­teg­rated into the web server takes over. It parses the document and re­cog­nises the opening PHP tag <?php. The in­ter­pret­er then executes the PHP code and generates HTML output, which the web server delivers to the browser.

Note

The phpinfo() function is the shorthand form of the default value phpinfo(INFO_ALL). It outputs detailed in­form­a­tion about your web server’s PHP con­fig­ur­a­tion. If no PHP version can be found, the web browser displays an error message or returns the PHP code to the browser without in­ter­pret­ing it.

Output ‘Hello World!’ with echo

If PHP has been installed suc­cess­fully, it’s time to write your first script. A good starting point is the PHP echo statement. Unlike phpinfo(), echo is not a function but a language construct that allows you to output text as a string.

Defin­i­tion

Language con­structs are state­ments used in PHP to control the program flow. In addition to echo, language con­structs include state­ments such as if, for, do, include, return, exit, and die. Therefore, unlike functions, brackets are not required in this case.

Create a new PHP file for your first script and enter the following code:

<?php
echo 'Hello World!';
php

The opening tag <?php starts a script en­vir­on­ment. This is followed by the echo language construct and the string ‘Hello World!’ enclosed in single quotation marks. Pay attention to the semicolon after the statement. Instead of ‘Hello World!’, you can use any text. Since this is a pure PHP file, we have omitted the closing PHP tag.

Tip

The closing PHP tag ?> does not need to be used in pure PHP files. This helps avoid ac­ci­dent­al empty lines or invisible char­ac­ters at the end of the file that can lead to error messages such as ‘Headers already sent’.

Save the script as ‘hello.php’ in the ‘htdocs’ folder on your web server and open the file in your web browser using the URL http://localhost/hello.php. If the code was trans­ferred correctly, the browser window should now display the character string you used:

Image: Text output with the echo language construct
You will now see the output ‘Hello World’. in your browser.

Any text you output with echo can be marked up with HTML tags if needed. These are then in­ter­preted by the web browser according to the HTML spe­cific­a­tion. Try it yourself using the following script:

<?php
echo '<h1>Hello World!</h1>
<p>This is my first PHP page.</p>';
php

When you open the file in your browser, the script output appears as follows:

Image: Result of a script execution with HTML tags
The output can be formatted with HTML tags in the PHP script.

The string ‘Hello World!’ enclosed in <h1> tags is in­ter­preted by the browser as a first-level heading. This is followed by a line break and the paragraph defined by the <p> tag.

Depending on your needs, echo can be used with both single (') and double quotes ("). If you only want to output text, it doesn’t matter which type of quotation marks you choose. However, this changes when PHP variables come into play.

Variables

The echo language construct offers more than just simple text output. After all, this can also be im­ple­men­ted very well without PHP using plain HTML. The real added value of echo is that the statement makes it possible to generate text dy­nam­ic­ally using variables.

Variables typically appear in the following form: $example.

Each variable consists of a dollar sign ($) followed by the variable name. Variables are used in PHP scripts to embed external data into web pages. These values can be of different types, ranging from simple numbers and strings to complete texts or even entire HTML document struc­tures.

In PHP, there are eight different variable types:

Variable type De­scrip­tion
String A string is a sequence of char­ac­ters. This can be a word, a sentence, a text, or the entire HTML code of a web page.
Integer An integer is a whole number without decimal places. It can be positive or negative.
Float A float is a floating-point number, i.e., a numeric value with decimal places. In pro­gram­ming languages, the decimal comma is written as a full stop (.). The precision is around 14 sig­ni­fic­ant digits; all digits are counted, not just those after the decimal point.
Boolean Boolean variables are the result of a logical operation and have only two values: TRUE and FALSE. This variable type is used, for example, when you work with con­di­tions.
Array An array is a variable that can contain multiple elements. It is a grouping of several similarly struc­tured data items that are combined into a single array.
Object The object variable type allows de­velopers to define their own data types. It is used in object-oriented pro­gram­ming. In our PHP tutorial for beginners, we exclude object variables.
NULL The value NULL rep­res­ents a variable without a value. For variables of the NULL type, this is the only possible value.
Resource A resource is a special variable that contains a reference to external resources, such as an open file, a database con­nec­tion, or a socket. Resources are managed by PHP itself. In our PHP tutorial for beginners, we exclude resource variables.

Cent­ral­ised content man­age­ment is usually handled using database systems. However, values for variables can also be defined directly in the script. This type of as­sign­ment follows the following pattern:

$example = "value";
php

The char­ac­ter­ist­ic dollar sign is followed by the variable name (in this case example). The variable is assigned a value using the equals sign (=), with string values enclosed in double quotation marks. Integer and float values, however, are written without quotation marks (for example, $example = 24; or $example = 2.7;).

PHP gives you the freedom to name variables as you see fit. However, the following re­stric­tions apply:

  • Every variable starts with a dollar sign.
  • A variable name is any string of letters, digits, and un­der­scores (e.g., $example_1).
  • A valid variable name always begins with a letter or an un­der­score ($example1 or $_example), never with a digit (incorrect: $1example).
  • PHP is case-sensitive. The scripting language dis­tin­guishes between uppercase and lowercase ($example ≠ $Example).
  • The variable name must not contain spaces or line breaks (incorrect: $example 1)
  • Character strings reserved by PHP for other purposes cannot be used as user-defined variables (e.g., $this)

Let’s look at this using an example:

<?php
$author = "John Doe";
echo "<h1>Hello World!</h1>
<p>This dynamic web page was created by $author.</p>";
php

After the opening PHP tag, the variable is defined and the value ‘John Doe’ is assigned to $author. When the script is executed, the variable $author is replaced with the value ‘John Doe’ each time it is ref­er­enced within the script. The following graphic shows how this appears in the web browser.

Image: Dynamic text creation with variables
Variables act as a kind of place­hold­er and enable dynamic text creation.

If there is an error and the web page was not created by John Doe but by his German colleague Max Muster­mann, you only need to update the variable $author to correct it. This approach is es­pe­cially efficient when a variable appears multiple times within a script. In that case, the change only needs to be made in one place, namely where the variable’s value is defined.

The ad­vant­ages of this design concept are clear. If elements of a website, such as content in the footer, are revised, the changes do not have to be made manually on every in­di­vidu­al subpage of the project. Instead, it is suf­fi­cient to update the cor­res­pond­ing entry in the database. The update is then auto­mat­ic­ally applied to all pages that use this data as variables.

If a variable is defined multiple times within a script, the most recent defin­i­tion over­writes the previous one. Any sub­sequent echo statement will therefore output the current value of the variable.

<?php
$author = "John Doe";
echo "<h1>Hello World!</h1>
<p>This dynamic web page was created by $author.</p>";
$author = "Max Mustermann";
echo " <p>Supported by $author.</p>";
php

In the code example, the variable $author is first assigned the value ‘John Doe’ and then replaced with the value ‘Max Muster­mann’.

Image: Overwriting variables
If a variable with the same name is defined multiple times, the last defin­i­tion over­writes the previous one.

Now let’s look at quotation marks. Unlike strings, in­di­vidu­al variables do not need to be enclosed in quotation marks:

<?php
$author = "John Doe";
echo $author;
php

However, if a variable is used within a string, you must use double quotation marks ("). These tell the PHP in­ter­pret­er to scan the string for variables and replace them with their cor­res­pond­ing values. Strings enclosed in single quotation marks ('), on the other hand, are treated as plain text and output exactly as written, even if they contain variables.

<?php
$author = "John Doe";
echo '<h1>Hello World!</h1>
<p>This dynamic web page was created by $author.</p>';
php

In this case, the variable is not in­ter­preted but simply output as plain text.

Image: Plain text output with single quotation marks
If a string is enclosed in single quotation marks and contains a variable, that variable is not in­ter­preted.
Note

You may now be wondering what happens if you omit the quotation marks al­to­geth­er. In that case, PHP will report a syntax error.

Strict typing with declare(strict_types=1)

By default, PHP tries to auto­mat­ic­ally convert different data types into one another. This behaviour is often called type juggling and can cause incorrect values to be processed without being noticed. With the directive declare(strict_types=1); you can se­lect­ively disable this behaviour. PHP then strictly checks during function calls whether passed arguments and return values match the declared variable types. The directive must be placed at the beginning of a PHP file and only applies to that file:

<?php
declare(strict_types=1);

function add(int $a, int $b): int
{
return $a + $b;
}
echo add(2, 3); 
echo add("2", 3);
php

In this example, the PHP function add() accepts only integer values. While the call with 2 and 3 works without issue, the second call triggers an error because the string "2" is not auto­mat­ic­ally converted to an integer. Strict typing helps identify such problems at an early stage and improves the main­tain­ab­il­ity and re­li­ab­il­ity of PHP code.

Error messages and escaping

If syntax errors occur, the PHP code is invalid and the page loaded in the browser may appear empty, or the PHP in­ter­pret­er may display an error message. This can happen, for example, if you use the echo statement with a string that is not enclosed in quotation marks:

<?php
echo Hello World!;
php

Error messages usually indicate where the error occurred and therefore provide valuable in­form­a­tion for troubleshoot­ing. You can view these messages in the XAMPP log file located at C:\xampp\logs\php_error_log.

Image: In the log file, you will see the following error message: Parse error
Errors are always displayed in the XAMPP log.

In the current example, the error is reported on line 2 of the program code, exactly where the quotation marks were in­ten­tion­ally omitted for demon­stra­tion purposes.

Syntax errors also occur when you want to output char­ac­ters as text that are as­so­ci­ated with a specific task in PHP. One example is the quotation mark ('). Char­ac­ters like this can only be output as text in PHP if you make it clear to the in­ter­pret­er that the character has been released from its original task. When working with single quotation marks, you have two options. You can enclose a string con­tain­ing single quotation marks in double quotation marks, or you can escape the single quotation marks with a preceding backslash, a process known as ‘escaping’:

<?php
echo '\'Hello World!\' ';
php
Image: The backslash used as an escape character in PHP
In PHP, the backslash is used as an escape character.

It’s also possible to combine single and double quotation marks:

<?php
echo " 'Hello World!' ";
php

But not like this:

<?php
echo ' 'Hello World!' ';
php

The spaces between the quotation marks were added in the examples for read­ab­il­ity.

Con­cat­en­a­tion operators

If you want to output multiple variables at the same time within a PHP script, you could do it the way you’ve learned so far:

<?php
$author1 = "John Doe";
$author2 = "Max Mustermann";
echo "<h1>Hello World!</h1>
<p>This dynamic web page was created by $author1 and $author2.</p>";
php

Simply include both variables directly within the string enclosed in double quotation marks, along with the rest of the text to be displayed. PHP auto­mat­ic­ally re­cog­nises variables by the dollar sign ($) and replaces them with their cor­res­pond­ing values.

Image: Text output with two variables
In theory, you can handle two variables exactly the same way as a single one.

Among de­velopers, however, this approach is generally con­sidered poor practice. The common guideline is that variables should not be embedded directly within a string. One reason is that many pro­gram­ming languages require this sep­ar­a­tion. More im­port­antly, PHP itself re­com­mends sep­ar­at­ing strings and variables, es­pe­cially in function calls or when working with more complex ex­pres­sions. For the sake of con­sist­ency and clarity, it is therefore advisable to apply this sep­ar­a­tion even in simple text output, even if it is not strictly required in such cases.

When working with variables, we’re always dealing with multiple elements that need to be con­cat­en­ated for output. In PHP, the con­cat­en­a­tion operator (.) is used for this purpose.

A cleaner version of the example shown above would therefore look as follows:

<?php
$author1 = "John Doe";
$author2 = "Max Mustermann";
echo '<h1>Hello World!</h1>
<p>This dynamic web page was created by ' . $author1 . ' and ' . $author2 . '.</p>';
php

So we’re dealing with three strings and two variables that are con­cat­en­ated into a single character sequence.

String1 Variable1 String2 Variable2 String3
’<h1>Hello World!</h1><p>This dynamic web page was created by ’ . $author1 . ’ and ’ . $author2 . ‘.</p>’

Note that the con­cat­en­a­tion operator joins strings or variables without adding spaces auto­mat­ic­ally. If a space is required, it must be included ex­pli­citly within the string inside the quotation marks, as shown in the example.

Image: Joining strings and variables with concatenation operators
It is con­sidered good pro­gram­ming practice to con­cat­en­ate multiple elements in the output using the con­cat­en­a­tion operator.

De­velopers use the con­cat­en­a­tion operator not only to combine strings and variables for text output, but also to extend variables. The following example shows how this works:

<?php
$example = 'Hello ';
$example .= 'World';
echo $example;
php

To extend the value of a variable, redefine it using the con­cat­en­a­tion operator directly before the equals sign. This is the commonly used shorthand notation for $example = $example . 'World';.

PHP appends the new value to the pre­vi­ously defined one. If you want a space between the two values, include it at the end of the first string, as shown in the example.

Image: Extending the value of a variable
The con­cat­en­a­tion operator is also used to con­cat­en­ate variables directly.

Embedding PHP in HTML

The PHP in­ter­pret­er is fun­da­ment­ally only concerned with code that is located between an opening and a closing PHP tag (with the latter being optional for pure PHP):

<?php [This area is parsed by the PHP interpreter] ?>

All other parts of the document are ignored by the in­ter­pret­er and passed to the web server unchanged. PHP code can therefore be freely in­teg­rated into HTML documents, for example to create templates for a content man­age­ment system. Make sure that HTML documents con­tain­ing PHP code are saved with the .php extension. Otherwise, the file will not be processed by the PHP in­ter­pret­er but delivered directly to the browser, causing the source code to appear as plain text on the website.

You can think of the PHP in­ter­pret­er as the web server’s lazy coworker who only starts working when ex­pli­citly asked, for example through an opening PHP tag.

If you want to combine HTML and PHP, write your HTML page as usual using the standard document structure and save it with the .php file extension:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>My first PHP page</title>
</head>
<body>
<h1>Hello World</h1>
<p>What is the current time and date?</p>
</body>
</html>
html

Now add a PHP script to your HTML document. Make sure that all the program code is located within the PHP tags.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>My first PHP page</title>
</head>
<body>
<h1>Hello World</h1>
<p>What is the current time and date?</p>
<p>Your current time and date is:
<?php
echo date("d.m.Y H:i:s");
?>.</p>
</body>
</html>
html

In the example, we combined the language construct echo with the PHP function date() to output the current date and time as text on the server side. The function’s parameter specifies the desired format as a string:

"d.m.Y H:i:s" (day.month.year hour:minute:second)

When the file is accessed in a web browser, the PHP in­ter­pret­er executes the script and embeds the current time as text into the HTML document. The web server then sends the generated output to the browser, where it is displayed as a webpage.

Image: Integrating PHP in HTML
You can embed PHP functions in your HTML code.

The PHP comment function

Like HTML, PHP code can also be commented out. Comments in the source code are ignored by the PHP in­ter­pret­er as long as they follow the correct syntax. PHP offers three different ways to write comments.

To comment out an entire line and exclude it from execution, use the hash symbol (#) or two forward slashes (//). The following example demon­strates both methods:

<?php
## This is a single line comment
echo '<h1>Hello World!</h1>
<p>This is my first PHP page.</p>';
// This is also a single-line comment!
php

Text editors and IDEs with syntax high­light­ing usually display comments in a different colour. Sections marked as comments within the PHP script never reach the browser, unlike HTML comments, because they are ignored by the PHP in­ter­pret­er during execution.

You can also insert comments that span multiple lines. To do this, begin the comment block with a slash followed by an asterisk (/*) and end it with an asterisk followed by a slash (*/).

<?php
/*
This is a multiple-lines comment block
that spans over multiple
lines
*/
echo '<h1>Hello World!</h1>
<p>This is my first PHP page.</p>';
php

Comments marked in this way are also not parsed and therefore do not appear on the website.

Image: Example of a multi-line comment
As you can see, comments are not output.

Pro­gram­mers use comments to structure the source code of their scripts, leave notes for later edits, or add internal in­form­a­tion such as the author or the date of creation. Comments are optional and should be used sparingly to ensure good read­ab­il­ity of the source code.

Cal­cu­lat­ing with variables

As part of this PHP tutorial, you have already worked with variables. So far, these variables have mainly been assigned string values, that is, sequences of char­ac­ters. Now we will look at variables that store integers or floating-point numbers (floats).

When variables contain numeric values, PHP allows you to perform cal­cu­la­tions with them. Let’s begin with a simple addition of two integers:

<?php
$number1 = 237;
$number2 = 148;
$result = $number1 + $number2;
echo "Result: " . $result;
php

First, we assign the integers 237 and 148 to the variables $number1 and $number2 and then define a variable called $result. This variable is meant to store the sum of the two variables. To do this, we use the arith­met­ic operator + (plus). Finally, we output the result of the addition as text using the language construct echo. Note that you do not need quotation marks when assigning numeric values to variables.

Image: Adding integers using a PHP script
You can calculate with numeric variables just like with numbers.

The following code example shows a selection of math­em­at­ic­al cal­cu­la­tions that can be performed server-side with PHP. The PHP operators used largely cor­res­pond to the stand­ard­ised math­em­at­ic­al symbols.

Arith­met­ic operator Operation Result
$number1 + $number2 Addition Sum of $number1 and $number2
$number1 - $number2 Sub­trac­tion Dif­fer­ence of $number1 and $number2
$number1 * $number2 Mul­ti­plic­a­tion Product of $number1 and $number2
$number1 / $number2 Division Quotient of $number1 and $number2
$number1 ** $number2 Ex­po­nen­ti­ation $number2-th power of $number1
<?php
$number1 = 10;
$number2 = 5;
$addition = $number1 + $number2; // Addition
$subtraction = $number1 - $number2; // Subtraction
$multiplication = $number1 * $number2; // Multiplication
$division = $number1 / $number2; // Division
$exponentiation = $number1 ** $number2; // Exponentiation

echo "Result of addition: " . $addition ."<br />";
echo "Result of subtraction: " . $subtraction . "<br />";
echo "Result of multiplication: " . $multiplication . "<br />";
echo "Result of division: " . $division . "<br />";
echo "5th power of 10 (10^5): " . $exponentiation . "<br />";
echo "Square root of 81: " . sqrt(81) . "<br />";
php

The output looks as follows:

Image: Calculating with variables
You can also perform common arith­met­ic op­er­a­tions in PHP using numeric variables.

For complex cal­cu­la­tions, you can combine the various arith­met­ic op­er­a­tions in a single script:

<?php
$number1 = 10;
$number2 = 5;
$result = 2 * $number1 + 5 * $number2 - 3 * sqrt(81);
echo "Result: " . $result;
php

The PHP in­ter­pret­er de­term­ines the values of the variables and cal­cu­lates:

2 * 10 + 5 * 5 - 3 * √81 = 20 + 25 - 27 = 18

The sqrt() function cal­cu­lates the square root of the value passed in brackets. The standard rules of operator pre­ced­ence apply, meaning that mul­ti­plic­a­tion and division are performed before addition and sub­trac­tion. The echo statement then outputs the result as a string in the browser.

Ex­pres­sions enclosed in brackets are also evaluated first in PHP. In the following example, we are working with floating-point numbers:

<?php
$number1 = 2.5;
$number2 = 3.7;
$result = 2 * ($number1 + 5) * ($number2 - 3) * sqrt(81);
echo "Result: " . $result;
php
Image: Calculation with floating-point numbers and bracketed terms
The cal­cu­la­tions also work with floating-point numbers.

Like most common pro­gram­ming languages, PHP also supports operators to increase or decrease numeric values by 1. A dis­tinc­tion is made between the pre-increment operator, the pre-decrement operator, the post-increment operator, and the post-decrement operator.

Operation Operator Result
Pre-increment ++$number The ++ operator in­cre­ments the value of the variable $number. The value is increased by 1 and the new value of $number is returned.
Pre-decrement --$number The -- operator decre­ments the value of the variable $number. The value is reduced by 1 and the new value of $number is returned.
Post-increment $number++ The current value of $number is returned first and then increased by 1.
Post-decrement $number-- The current value of $number is returned first and then decreased by 1.

Using pre-in­cre­ment­a­tion as an example, we demon­strate arith­met­ic op­er­a­tions with the increment and decrement operators. In the following script, the value of the variable $number is increased by 1, the updated value is stored in $result, and then output as a string:

<?php
$number = 0;
$result = ++$number;
echo "Result: " . $result;
php

If you increase the value 0 by 1, you get the result 1.

Image: Pre-incrementing the number 0
Pre-in­cre­ment­a­tion increases the value of the variable by one before it is output.

To calculate the pre-decrement of the variable $number, we use the same script but replace the pre-increment operator (++) with the pre-decrement operator (--):

<?php
$number = 0;
$result = --$number;
echo "Result: " . $result;
php

We decrement the value 0 stored in the variable $number, resulting in -1.

An increase before and after the output (pre- vs. post-…) of a value can be il­lus­trated with the following script:

<?php
$x = 0;
echo '<p>Result: ' . ++$x;
echo '<br>x has the value ' . $x;
echo '<p>Result: ' . $x++;
echo '<br>x has the value ' . $x, '</p>';
php

In both cases we get the same result. With pre-in­cre­ment­a­tion, the value of x is increased before the output in line 3, and with post-in­cre­ment­a­tion, it is increased after the output in line 5.

Image: The difference between pre- and post-incrementation
With pre-in­cre­ment­a­tion, the value of the variable is increased before output; with post-in­cre­ment­a­tion, it is increased af­ter­wards.

How to work with scalar and union types

PHP makes it possible to assign scalar types to variables, function para­met­ers, and return values. These include, among others, int, float, string, and bool. By spe­cify­ing the type ex­pli­citly, you define what kind of values a function expects and returns. This improves code read­ab­il­ity and helps detect common errors at an early stage.

<?php
declare(strict_types=1);

function hi(string $name): string {
return "Hello " . $name;
}
php

In this example, the custom hi() function expects a string as a parameter and also returns a string. If another data type is passed, PHP reports an error. In some cases, however, a function should accept multiple data types. PHP offers union types for this purpose. They allow you to specify several possible types separated by the pipe character |:

<?php
declare(strict_types=1);

function formatId(int|string $id): string {
return "ID: " . $id;
}
php

The formatId() function in this example accepts both integers and strings as para­met­ers. Other data types are not permitted. Union types therefore allow function sig­na­tures to remain flexible while still enforcing clear type con­straints.

How to use the su­per­g­lob­als $_GET and $_POST

You have now learned the PHP basics, un­der­stand how to work with variables, can con­cat­en­ate them, and perform cal­cu­la­tions. Now we’ll show you why variables are a central concept when pro­gram­ming scripts.

An important function of scripting languages is the ability to evaluate user input and transfer the values to another script. For data transfer, PHP relies on the su­per­g­lob­als $_GET and $_POST, which are pre­defined system variables that are available in all scopes. As as­so­ci­at­ive arrays (data fields), $_GET and $_POST store a set of variables as strings in a single variable.

PHP arrays can be compared to a cabinet with multiple drawers. Each drawer allows you to store data. To remember what is stored in which drawer, you label them with a variable name. Depending on the type of array, this label can be either an index or a key. In indexed arrays, each drawer receives a numeric index, while in as­so­ci­at­ive arrays the drawers are labelled with a key in the form of a string.

The su­per­g­lob­als $_GET and $_POST contain col­lec­tions of variables organised as keys. These keys allow you to access the values as­so­ci­ated with them. This concept will become clearer when we look at the $_GET and $_POST su­per­g­lob­als in more detail.

Trans­fer­ring data via $_GET

The $_GET su­per­g­lob­al rep­res­ents an array of variables that are passed to a PHP script using a URL.

If you oc­ca­sion­ally browse weblogs, online shops, or internet forums, you may have noticed the unusual structure of some URLs. A common pattern looks like this:

http://hostname/folder/filename.php?variablename=variablevalue

For a weblog, this pattern could appear as follows:

http://www.example-blog.com/index.php?id=1

This type of URL is re­l­at­ively easy to interpret. On a web server with the domain example-blog.com, a file named index.php is re­spons­ible for gen­er­at­ing a dynamic web page. The file typically contains HTML and PHP code, as well as ref­er­ences to external template files and stylesheets—in short, everything required to display the page.

The part after the question mark (?) indicates that the page is likely dynamic: id=1. This segment is known as an HTTP query string. It contains a variable (id) and a value (1) connected by an equals sign (=). URL para­met­ers like these are commonly used to generate dynamic pages, retrieve content from a database, or load the ap­pro­pri­ate template.

Dynamic web pages make it possible to separate content from present­a­tion. While ‘index.php’ contains all the in­form­a­tion about the structure of the website, it still has to be filled with content. This content is usually stored in a database and can be retrieved using the para­met­ers in the HTTP query string. In our example, the URL passes the parameter id=1 to ‘index.php’. This de­term­ines which content is read from the database and loaded into ‘index.php’. In a weblog, this is usually the ID of a specific article. In a forum, this could be used to retrieve a specific post, and in an online store, a specific product.

If a URL contains more than one parameter, they are joined with an ampersand (&).

www.example-blog.com/index.php?page=article&id=1

To demon­strate how $_GET works with a code example, a database is not required. In the following script, the $_GET su­per­g­lob­al reads the values of the variables firstname and lastname from an HTTP query string and assigns them to the PHP variables $variable1 and $variable2:

<?php

$variable1 = $_GET['firstname'];
$variable2 = $_GET['lastname'];

echo "Hello " . $variable1 . " " . $variable2 . "!";
php

The script is called using the following URL:

localhost/hello.php?firstname=John&lastname=Doe

In this case, the para­met­ers firstname=John and lastname=Doe are passed to the script. As in the previous examples, the values are output using the echo language construct.

Image: Passing data using $_GET
With $_GET you can read values for your variables from the URL.

Passing data via $_GET means that the trans­ferred data appears in the address bar. This allows anyone to see which para­met­ers are being passed at any time. One advantage of this method is that variables can be included directly in hy­per­links. Users can also save URLs con­tain­ing the HTTP query string as bookmarks in their browser.

Because GET para­met­ers appear in plain text in the URL, this method is not suitable for trans­mit­ting sensitive data, such as in­form­a­tion submitted through online forms. In addition, the amount of data that can be trans­mit­ted with $_GET is limited by the maximum length of a URL.

Note

These lim­it­a­tions can be avoided by using the POST HTTP method. The data passed this way can be found in the $_POST su­per­g­lob­al.

Passing data via $_POST

The HTTP methods GET and POST differ in how they transfer data. With the GET method, the trans­mit­ted data is included as URL para­met­ers. By contrast, data sent with $_POST is trans­ferred in the body of the HTTP request. This approach allows even large amounts of data to be passed from one script to another.

A central use case for the HTTP POST method is the transfer of HTML form data. We’ll demon­strate this using a news­let­ter sign-up as an example. Create a new PHP file named ‘page1.php’ and add the following block of code:

<form method="post" action="page2.php" >
Please send the newsletter to: <br />
Your first name: <input type="text" name="firstname" /><br />
Your last name: <input type="text" name="lastname" /><br />
Your email address: <input type="text" name="email" /><br />
<input type="submit" value="Submit form" />
</form>
html

The HTML <form> element is used to create forms. Its opening tag contains two at­trib­utes, which are method and action. The method attribute defines the transfer method, in this case HTTP POST. The action attribute stores the URL of a script that receives all the data captured via the following input fields. The example shows an HTML form with three input elements (input type="text") and a submit button (input type="submit"). The file ‘page2.php’ is defined as the data recipient.

To il­lus­trate data transfer using $_POST, we’ll use a simple script to process the form data, store the submitted values as PHP variables, and output them as text. Create a file named ‘page2.php’ and insert the following code:

<?php
$firstname = $_POST["firstname"];
$lastname = $_POST["lastname"];
$email = $_POST["email"];
echo "Hello " . $firstname . " " . $lastname . ", <br />
You have registered with the following email address: " . $email . ".";
php

Save both PHP files in the ‘htdocs’ folder of your test server and open ‘page1.php’ in your web browser using the following URL: http://localhost/page1.php. Your browser will now display the in­ter­act­ive web interface of your HTML form.

Image: Entering data via HTML form
You can now enter values in the HTML form that will be trans­ferred to your other script.

Enter any re­gis­tra­tion data and click the submit button to transfer the variables from one script to another. After con­firm­ing the input on ‘page1.php’, you will be re­dir­ec­ted directly to ‘page2.php’. The browser window then displays the result of the script execution based on the submitted data.

Image: Output of user data
The data has now been trans­ferred to the other script.

User inputs captured via the input fields in ‘page1.php’ are retrieved by ‘page2.php’ using the following pattern:

$_POST["Name of the input field"]

The line $firstname = $_POST["firstname"] retrieves the input from the form field firstname and stores it in the variable $firstname. The variable $firstname can then be output as a string using echo.

How to use the if construct and PHP com­par­is­on operators

So far, we have defined variables, trans­ferred them from one script to the next, and output them as strings. In the next step, you will learn how to tie the execution of code fragments to specific con­di­tions.

The if language construct gives you the ability to write scripts so that state­ments are only executed when a condition you define is met—for example, when the correct password is entered.

Con­di­tions in PHP are defined using the following basic structure:

<?php
if(expression)
{
statement;
}
php

This can be in­ter­preted as follows. The statement is executed only if the condition in the expression is met. A condition is con­sidered met when the if construct evaluates to TRUE. Otherwise, it evaluates to FALSE, and the statement is skipped.

As a rule, the if construct checks whether the value of a variable matches what has been defined in the condition. This control structure is usually im­ple­men­ted using com­par­is­on operators.

Com­par­is­on operators

Com­par­is­on operators are used when for­mu­lat­ing con­di­tions to place two arguments in a logical re­la­tion­ship that can be evaluated as true (TRUE) or false (FALSE). When com­par­is­on operators are used in PHP control struc­tures, they are applied to two variables in the expression of an if construct:

if ($a == $b)
{
statement;
}
php

In simple terms, the control structure works as follows. If the variable $a is equal to the variable $b, the state­ments defined in the statement block are executed.

The PHP com­par­is­on operators are based on those of the C pro­gram­ming language and in some cases differ sig­ni­fic­antly from tra­di­tion­al math­em­at­ic­al notation. The table below provides an overview.

Com­par­is­on operator De­scrip­tion Condition
== is equal to The condition is met if $a and $b have the same value.
=== is identical to The condition is met if $a and $b have the same value and are of the same data type. This can be il­lus­trated with an example where an integer (1) is compared to a string (“1”): 1 == "1" evaluates to TRUE, while 1 === "1" evaluates to FALSE. When checking whether two variables are equal, it is generally re­com­men­ded to use the com­par­is­on operator === (is identical).
!= is not equal to The condition is met if $a and $b have different values.
!== is not identical to The condition is met if $a and $b have different values or are of different data types.
< is less than The condition is met if the value of $a is less than the value of $b.
> is greater than The condition is met if the value of $a is greater than the value of $b.
<= is less than or equal to The condition is met if the value of $a is less than the value of $b or if $a and $b have the same value.
>= is greater than or equal to The condition is met if the value of $a is greater than the value of $b or if $a and $b have the same value.

The following script demon­strates this control structure. It compares two integers using the com­par­is­on operator < (is less than):

<?php
$number1 = 10;
$number2 = 20;

if ($number1 < $number2) {
echo "The condition is met";
}
php

The variables $number1 and $number2 are defined and assigned the values 10 and 20. A condition is then set. If $number1 is less than $number2, the string defined in the echo statement is output.

When the script is executed, the result confirms the condition: 10 is less than 20. The if construct therefore evaluates to TRUE, meaning the condition is met.

Image: The if language construct in use
The code after the if statement is executed when the specified condition is met.

If you want to define state­ments that should run when a condition is not met, you can extend the if control structure with the else language construct. This creates an if-else statement in PHP:

<?php
if(Condition a)
{
statement b;
}
else
{
statement c;
}
php

This script also checks whether condition a evaluates to TRUE or FALSE. If condition a is met, statement b is executed. If condition a is not met (FALSE), statement b is skipped and statement c is executed instead.

In the following example, the script is extended with the else construct, and the com­par­is­on operator < (is less than) is replaced with == (is equal):

<?php
$number1 = 10;
$number2 = 20;
if($number1 == $number2)
{
echo "The condition is met";
}
else
{
echo "The condition is not met";
}
php

This time, the if construct returns the result FALSE. The value of the variable $number1 is not equal to the value of the variable $number2. The condition is not met. Therefore, the statement listed under if is not executed; instead, the one defined under else is executed.

Image: The else language construct in use
If the if condition is not met, the code after the else statement is executed.
Note

If the execution of a code fragment is to depend on the equality of two values, a double equals sign (==) is used in PHP. The single equals sign (=) is used ex­clus­ively for assigning values to variables.

The negation of con­di­tions is done using a leading ex­clam­a­tion mark (!).

<?php
$number1 = 10;
$number2 = 20;

if ($number1 == $number2)
{
echo "The numbers are equal.";
}

if (!($number1 == $number2))
{
echo "The numbers are not equal.";
}
php

The example shows the condition $number1 == $number2 and its negation. !($number1 == $number2) cor­res­ponds to ($number1 != $number2).

A practical ap­plic­a­tion of if and else is a password prompt based on an HTML form. To il­lus­trate this, we will again use the PHP files ‘page1.php’ and ‘page2.php’.

Open ‘page1.php’ and insert the following form code:

<form action="page2.php" method="post">
Please enter your password: <input type="password" name="password" />
<input type="submit" value="Submit" />
</form>
html

The structure is the same as the form created earlier. This time, however, only a single input field is required for the password prompt. As before, the user input is sent to the ‘page2.php’ script.

The script is then modified with the following code so that the entered password is compared with a stored password:

<?php
$password = $_POST["password"];
if($password=="qwerty123")
{
echo "The password was correct";
}
else
{
echo "The password was incorrect";
}
php

The code works as follows. In line 2, a value is assigned to the $password variable, which is retrieved using the HTTP POST method. A control structure is then defined. The if construct in line 3 checks whether the value of the $password variable matches the string qwerty123. If this condition is met, the string ‘The password was correct’ is output. If the if statement evaluates to FALSE, the else branch in line 7 is executed and the string ‘The password was incorrect’ is displayed instead.

Next, the ‘page1.php’ script is called using the URL http://localhost/page1.php.

Image: Web interface of the HTML form for password prompt
You can now enter a password in the web form.

The browser displays the HTML form for the password prompt. After following the prompt, enter the password ‘qwerty123’ defined in the ‘page2.php’ script and click the submit button.

Image: The password prompt was correct
If you entered the correct password, the if condition from the script takes effect and a success message is displayed.

The web browser then auto­mat­ic­ally redirects to ‘page2.php’. In the back­ground, the if control structure compares the entered value with the stored password. Since qwerty123 == qwerty123 evaluates to TRUE, the script outputs the string ‘The password was correct’. Try entering a different password in the input field to see what happens.

Logical operators

Con­di­tions defined with com­par­is­on operators in the ex­pres­sion of an if construct can, if necessary, be combined with ad­di­tion­al con­di­tions in the same ex­pres­sion. For this purpose, PHP provides the logical operators AND and OR.

Tight binding Weak binding De­scrip­tion
&& AND Both con­di­tions connected by the operator must be TRUE.
|| OR Only one of the two con­di­tions connected by the operator needs to be TRUE.

To combine con­di­tions, PHP provides logical operators with both tight and weak binding. If only one of these notations is used, there is usually no no­tice­able dif­fer­ence. However, when both notations are combined, && and || have a higher pre­ced­ence than AND and OR. This is similar to operator pre­ced­ence in math­em­at­ics, where mul­ti­plic­a­tion is evaluated before addition, meaning * binds more tightly than +.

A practical example is again the password prompt. In most cases, login cre­den­tials consist of a username and a secret password. Access is granted only if both inputs match the data stored in the system.

We open the password prompt form in ‘page1.php’ again and add an ad­di­tion­al input field for the username:

<form action="page2.php" method="post">
Username: <input type="text" name="username" /><br />
Password: <input type="password" name="password" /><br />
<input type="submit" value="Submit" />
</form>
html

In the next step, we also need to adjust the control structure of the if construct. To do this, we use the logical operator AND to link the condition for the password prompt with a condition for querying the username.

<?php
$username = $_POST["username"];
$password = $_POST["password"];
if($username=="John Doe" AND $password=="qwerty123")
{
echo "Welcome to the members area " . $username . "!";
}
else
{
echo "Access denied";
}
php

The ‘page2.php’ script now receives the values for username and password and stores them in the variables $username and $password. The ex­pres­sion in the if construct now includes two con­di­tions connected by the logical operator AND. The if statement returns TRUE only if both con­di­tions are met ($username == "John Doe" and $password == "qwerty123").

Since the username is obtained through the username input field, it can be used directly in the text output with echo. After the phrase ‘Welcome to the members area’, the value of the $username variable is displayed. If one of the two con­di­tions is not met, the script outputs the message ‘Access denied’.

Image: Password prompt with two conditions
The login is only suc­cess­ful if both con­di­tions linked with AND evaluate to TRUE.

Logical operators can be combined in many ways. As a rule, AND has a higher pre­ced­ence than OR. Similar to math­em­at­ic­al ex­pres­sions, brackets can also be used in PHP to control the order in which con­di­tions are evaluated.

Con­di­tions with match

So far, decisions in PHP have been im­ple­men­ted using if and else state­ments. However, when a single value needs to be checked and different outcomes should occur depending on that value, if state­ments can quickly become difficult to read. For such cases, PHP provides the match statement.

<?php
$status = 404;
echo match ($status) {
200 => "OK",
404 => "Not found",
default => "Unknown status",
};
php

In this example, the value of the $status variable is evaluated. If it is 200, the match ex­pres­sion returns the text ‘OK’. If the value is 404, the result is ‘Not found’. If none of the specified values match, the default case applies and the result ‘Unknown status’ is returned.

Image: Message ‘Not found’
Since the `$status` variable is set to `404`, the second case of the `match` ex­pres­sion applies and the message ‘Not found’ is returned.

The most important dif­fer­ence from if-else is that match directly returns a value that can be assigned to a variable. This elim­in­ates the need to write as­sign­ments multiple times within in­di­vidu­al con­di­tions, and the code stays shorter, clearer, and easier to un­der­stand.

How to use loops (while, for)

Sometimes a script needs to run a specific section of code several times before the rest of the program code is executed. Pro­gram­ming languages use the concept of loops for this — also called PHP loops. There are three types of loops:

  • while loops
  • do-while loops
  • for loops

while loops

The while loop is the simplest type of loop available in PHP. The basic structure follows this pattern:

while (condition)
{
loop step and other statements
}
php

The while loop instructs PHP to execute the nested state­ments as long as the specified condition remains true. At the start of each iteration, the PHP in­ter­pret­er checks whether the condition is still met. The loop continues to run until the condition is no longer satisfied.

This principle can be demon­strated with a simple counting script:

<?php
$number = 1;
while ($number <= 10) {
echo $number++ . "<br />";
}
php

In the section ‘Cal­cu­lat­ing with variables’, the concept of in­cre­ment­ing was in­tro­duced. In the following script, this concept is used again. This time, however, a post-increment operator increases the value of the integer variable $number by 1 only after the text output via echo in each loop iteration. The condition for the while loop is defined as $number less than or equal to 10. The echo statement is therefore repeated until $number becomes greater than 10.

Image: The script counts up to 10 and then stops
As soon as the value 10 is reached, the loop stops.

When the script runs, it outputs a string showing the value of the $number variable in each loop iteration before it is in­cre­men­ted. As a result, the script counts from 1 to 10 and stops executing once the while condition is no longer satisfied.

do-while loops

The structure of the do-while loop is similar to that of the while loop. The only dif­fer­ence is that the condition is not checked at the beginning of each loop iteration, but only at the end. The basic pattern of a do-while loop cor­res­ponds to the following example:

do {
loop step and other statements
}
while (condition);
php

Written as a do-while loop, the previous script would look like this:

<?php
$number = 1;
do {
echo $number++ . "<br />";
}
while ($number <= 10);
php

The result remains the same in this case. The special feature of the do-while loop is that it is executed at least once, even if the condition is not met in any loop iteration.

for loops

In principle, the for loop in a PHP script has the same func­tion­al­ity as the while loop. Unlike the while loop, however, the initial value, condition, and statement are written on a single line rather than spread across three or more lines. The basic structure of the for loop follows this pattern:

for (initial value; condition; loop step)
statements
php

The already familiar example can therefore be written as a for loop in a more compact form:

<?php
for($number = 1; $number <= 10; $number++) {
echo $number . "<br /> ";
}
php

First, the value ‘1’ is assigned to the $number variable. PHP then checks whether the condition $number <= 10 is met. If the condition is true, the loop continues and the state­ments inside the loop are executed, in this case the echo statement. After that, the loop step is performed. Here it does not matter whether pre-increment or post-increment is used, since the result of this step is not used any further. Once the loop step is completed, the next iteration of the loop begins.

The initial value, the condition, and the loop step are optional elements of a for loop. In theory, even empty loops are possible, although they would not serve a practical purpose.

In principle, PHP scripts can be written using either a for loop or a while loop. However, one advantage of for loops is that the key para­met­ers of the loop are defined in a single place. This makes the loop easier to un­der­stand and reduces the risk of ac­ci­dent­ally creating an endless loop that continues running until the in­ter­pret­er’s memory is exhausted. In the previous example, such a situation would occur if the value of the $number variable were not increased.

If a loop should run at least once re­gard­less of the condition, the do-while loop is the ap­pro­pri­ate choice.

break and continue

The execution of a while, do-while, or for loop can be con­trolled using the break and continue state­ments. Use break to interrupt a loop at any point, and continue to skip a single loop iteration. Both state­ments are tied to a condition using if. The following example shows our counting script with a break:

<?php
for ($number = 1; $number <= 10; $number++) {
if ($number == 5) {
echo "At 5, we break out of the loop!";
break;
}
echo $number . "<br /> ";
}
php

In the for loop, we defined that the value of the $number variable, starting from an initial value of 1, should be increased by 1 in each loop iteration until the variable reaches the value 10. We now stop this loop early with the break statement as soon as $number reaches the value 5. The echo construct therefore only outputs the numbers 1 through 4.

Image: for loop with break
With break you can jump out of a loop as soon as a specific if condition is met.

If we only want to skip the output in the fifth iteration, but not stop the entire loop, we replace the break statement with continue:

<?php
for ($number=1; $number <= 10; $number++) {
if ($number == 5) {
echo "Number 5 is skipped!<br />";
continue;
}
echo $number . "<br /> ";
}
php

Instead of the digit 5, PHP outputs the text string ‘Number 5 is skipped!’ defined in the if statement.

Image: for loop with continue statement
With continue you can skip a loop iteration when a specific condition occurs.

How to perform file op­er­a­tions

Dynamic web content is based on sep­ar­at­ing content from present­a­tion. Scripting languages such as PHP therefore offer various functions that allow content from external data sources to be loaded into central template files. In practice, these data sources are often databases managed with systems like MySQL. It is also possible to include data from files. The following section shows how to read files as a string in a PHP script and how to store text output from a script in files.

Reading files

To read the contents of a file, PHP provides several functions. Two par­tic­u­larly useful ones are file() and file_get_contents(). The file_get_contents() function reads the entire contents of a file into a single string, whereas the file() function stores the contents as an array. Each element of this array rep­res­ents one line of the file. This makes it easier to output the lines in­di­vidu­ally when using file().

To demon­strate PHP file op­er­a­tions, we use the text file example.txt, which is placed in the htdocs folder of the test server. The file contains four lines of dummy text:

Image: Text file with four lines of sample text
Our text file contains four lines of sample dummy text.

First, we read the entire file as a string. To do this, we have to pass the name of the cor­res­pond­ing file as a parameter to the file_get_contents() function. This is done using the following pattern:

file_get_contents('example.txt')

The string that has been read can now be processed further. For example, it can be assigned to a variable and displayed as text in the web browser:

<?php
$example = file_get_contents('example.txt');
echo $example;
php

In the browser view, we see that the text string is output without para­graphs. The line breaks from the original file are not visible. This is because the web browser in­ter­prets the script’s text output as HTML code. Line breaks defined in text editors are lost in the process.

Image: The script reads the file example.txt
With the file_get_contents() function you can read the contents of a file and then process it in PHP.

If you want to keep the original structure, you have several options. You can manually add the HTML line break tag (<br>) to the source file using search and replace, wrap the file content in a <pre> tag, assign the CSS property white-space: pre-wrap to the area, or use the nl2br() function to tell PHP to auto­mat­ic­ally convert line breaks into HTML line breaks. Use the function with the following pattern:

<?php
$example = file_get_contents('example.txt');
echo nl2br($example);
php

When the echo language construct is used in com­bin­a­tion with nl2br(), PHP inserts an HTML line break before every new line.

Image: The nl2br() function in use
With the PHP nl2br() function you can create line breaks.

If you want to output the lines of a file in­di­vidu­ally, the file() function is a good choice. It reads a file, numbers all lines starting with 0, and stores their contents as elements of an array. Applied to our example, this results in the following mapping:

[0] = Lorem ipsum dolor sit amet, consectetuer adipiscing elit

[1] = Aenean commodo ligula eget dolor. Aenean massa.

[2] = Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.

[3] = Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem.

To output the re­spect­ive contents using echo, you only need to specify the desired line number. For example, the following script returns only the first line of the file ‘example.txt’ as output for the browser:

<?php
$example = file("example.txt");
echo $example [0];
php
Image: The file() function in use
The file() function is suitable for reading in­di­vidu­al lines from a file.

Writing files

PHP can not only read files but also create them and write content to them.

For this purpose, the PHP function file_put_contents() can be used. It expects two para­met­ers: the name of the file to be created or updated and the data to be written, either as a string or an array. The following script creates the file test.txt and writes the string This is a test! to the first line. The addition \r\n inserts a line break in the target file.

<?php
file_put_contents("test.txt", "This is a test! \r\n");
echo "test.txt has been created!";
php

Since file_put_contents doesn’t return any output to the browser, we add an echo statement that tells us which action is being performed.

Image: File operations: writing files
You can use the file_put_contents() function to write files.

If there is already a file with the same name in the target folder, it will be over­writ­ten. You can prevent this by setting the FILE_APPEND parameter:

<?php
file_put_contents("test.txt","The test was successful! \r\n", FILE_APPEND);
echo "test.txt has been updated!";
php

If the FILE_APPEND parameter is used with file_put_contents(), new content is added to the end of the existing file instead of over­writ­ing it.

Image: File operations: updating files
If you add the FILE_APPEND parameter, the content you pass to file_put_contents is added to your file.

What PHP writes to the target file doesn’t ne­ces­sar­ily have to be defined in the script. Al­tern­at­ively, you can transfer content from one file to another. The following script reads the content of example.txt and inserts it into the file test.txt:

<?php
$example = file_get_contents("example.txt");
file_put_contents("test.txt", $example, FILE_APPEND);
echo "test.txt has been updated!";
php
MyWebsite Now Plus
Create a business website
  • Pro­fes­sion­al templates, domain, and email
  • SEO tools and over 17,000 stock images
  • Easy online bookings

How to program using object-oriented prin­ciples

The object-oriented pro­gram­ming (OOP) paradigm is a method for dividing programs into small, man­age­able building blocks called objects. Each object belongs to a class, which defines the prop­er­ties and methods it has. Prop­er­ties are variables that store char­ac­ter­ist­ics of the object, while methods are functions that the object can execute. OOP helps structure code better, make it reusable, and easier to maintain, es­pe­cially in larger projects.

Classes

A class is the template for an object. You can think of a class as a blueprint, for example for a car, while an object is the actual car created from that blueprint. It defines which data an object contains and which functions it can perform. In the following example, we see the Car class:

class Car {
public string $make;
public string $model;
public function move () {
echo "The car is moving!";
}
}
$myCar = new Car();
$myCar->make = "VW";
$myCar->model = "Golf";
$myCar->move();
php

In this example, the Car class is defined, which has two prop­er­ties, $make and $model, as well as a move() method. Then an object of this class is created by assigning the class ‘Car’ to $myCar. With -> we access the prop­er­ties of the object and set $make to VW and $model to Golf. We then call the move() method, which outputs the text ‘The car is moving!’. The $this keyword would refer to the current object within the method.

Image: Object of the Car class
After an object of the Car class has been created, calling the `move()` function produces the cor­res­pond­ing output.

Con­struct­or property promotion

Since PHP 8.0, you can define and ini­tial­ise prop­er­ties directly in the con­struct­or, the method that is auto­mat­ic­ally executed when an object of a class is created. This removes the need to declare them sep­ar­ately in the class be­fore­hand, which makes the code shorter and easier to read.

class Product {
public function __construct(
public string $name,
public float $price
) {}
}
$product = new Product("Cup", 12.99);
echo $product->name;
echo $product->price;
php

In this example, the name and price prop­er­ties are declared directly in the con­struct­or. When the Product object is created, the values ‘Cup’ and ‘12.99’ are passed as arguments. The ex­pres­sions $product->name and $product->price are then used to access the values that were set auto­mat­ic­ally. Con­struct­or Property Promotion reduces the amount of code and improves read­ab­il­ity.

In­ter­faces

An interface defines which methods a class must have without spe­cify­ing their concrete im­ple­ment­a­tion. Classes that implement the interface must define these methods so that different classes can be handled in a con­sist­ent way.

<?php
interface Movable {
    public function move();
}

class Car implements Movable {
    public function move() {
        echo "The car is moving!";
    }
}

$myCar = new Car();
$myCar->move();
php

In this example, the Movable interface specifies that every im­ple­ment­ing class must provide a move() method. The Car class im­ple­ments this interface and defines the method ac­cord­ingly. An object of the class is then created and the method is called, which outputs the text ‘The car is moving!’.

Image: Object of the Car class according to the Movable interface
An interface defines that our class must include a method called move().

In­ter­sec­tion types

In­ter­sec­tion types have been available since PHP 8.1. They make it possible for an object to be required to fulfil several in­ter­faces at the same time. This is es­pe­cially useful when a function needs to ensure that an object has certain cap­ab­il­it­ies.

interface Loggable {}
function save(JsonSerializable&Loggable $object) {
echo "The object can save JSON data and log information.";
}
php

In this example, objects passed to the save() function must implement both the JsonSerializable and Loggable in­ter­faces. The com­bin­a­tion of the two in­ter­faces is rep­res­en­ted by &. This guar­an­tees that the function only works with objects that have both char­ac­ter­ist­ics.

Readonly prop­er­ties

Readonly prop­er­ties have been available since PHP 8.1. They can only be set once when an object is created and cannot be changed af­ter­wards. This is es­pe­cially useful for pro­tect­ing sensitive data from un­in­ten­tion­al modi­fic­a­tions.

class User {
public function __construct(
public readonly string $name
) {}
}
$user = new User("Max");
echo $user->name;
php

In this example, the name property is defined directly in the con­struct­or and declared as readonly. As a result, the value ‘Max’ cannot be modified after the object has been created. Any attempt to change it later will trigger an error. Readonly prop­er­ties are useful for values that should remain constant, such as user IDs or con­fig­ur­a­tion settings.

Property hooks

Property hooks have been available since PHP version 8.4 and allow you to execute logic directly when setting or reading a property. This is useful when values should be processed auto­mat­ic­ally.

class User {
public string $email {
set => strtolower($value);
get => strtoupper($this->email);
}
}
$user = new User();
$user->email = "Test@Example.com";
echo $user->email;
php

In this example, when a value is assigned to the email property, it is auto­mat­ic­ally converted to lowercase, while reading it auto­mat­ic­ally returns everything in uppercase. This lets you process data con­sist­ently without having to write ad­di­tion­al methods.

Asym­met­ric vis­ib­il­ity

With asym­met­ric vis­ib­il­ity, in­tro­duced in PHP 8.4, it is possible to define that a property can be read publicly but only modified within the class itself. This helps protect important data from un­con­trolled changes.

class Account {
    public private(set) float $balance = 0.0;

    public function deposit(float $amount) {
        $this->balance += $amount;
    }
}

$account = new Account();
$account->deposit(50);
echo $account->balance;
php

In this example, the account balance can be read publicly but may only be modified within the class. The deposit() method enables con­trolled increases to the balance. Any attempt to change $balance directly results in an error. This approach protects important data while still allowing access through permitted op­er­a­tions.

How to write clean PHP code

As a project grows in size, well-struc­tured and cleanly written code becomes in­creas­ingly important. Clean PHP code is easier to read, simpler to maintain, and less prone to errors. PHP ap­plic­a­tions therefore follow specific con­ven­tions and use tools that promote structure, clarity, and security.

Composer and PSR-4 (automatic class loading)

Composer is a key tool in modern PHP de­vel­op­ment. It is used to manage external libraries and to auto­mat­ic­ally load PHP classes. Without Composer, classes would have to be included manually using require or include, which can quickly become difficult to manage in larger projects. Composer commonly relies on the PSR-4 auto­load­ing standard. This standard defines how classes are located based on their name and file location. In practice, the name of a class cor­res­ponds to the folder structure in which it is stored.

A simple example il­lus­trates this principle. If a User class belongs to the App\Model namespace, the cor­res­pond­ing file is located in the src/Model folder:

<?php
namespace App\Model;
class User {
public function getName() {
return "Max Mustermann";
}
}
php

Thanks to PSR-4, this class can be used anywhere in the project without manually including the file. PHP loads it auto­mat­ic­ally as soon as it is needed. This makes the code more organised and reduces potential sources of errors.

Using namespaces for clearer code structure

Namespaces help logically group classes and avoid naming conflicts. In small scripts, it’s no problem to simply name classes User or Database. In larger ap­plic­a­tions, however, multiple classes may share the same name while serving different purposes. Namespaces let you clearly dis­tin­guish these classes. For example, there can be a User class for the database and another User class for frontend display without causing conflicts.

The following example shows how a namespace is used:

<?php
namespace App\Service;
class Mailer {
public function send() {
echo "Email has been sent.";
}
}
php

When using the class, the full name including the namespace is used or imported via use. This keeps the code un­am­bigu­ous and well struc­tured.

Using .env files and .gitignore in your project structure

A clear project structure is an important aspect of clean PHP code. In many PHP projects, the ap­plic­a­tion code is separated from publicly ac­cess­ible files and con­fig­ur­a­tion data. The PHP source code is often stored in its own directory, while the web server is con­figured to access only a public folder.

Con­fig­ur­a­tion values such as database cre­den­tials or API keys are typically not stored directly in the source code. Instead, .env files are used to keep these values in a central location. This improves security and makes it easier to switch between de­vel­op­ment and pro­duc­tion en­vir­on­ments.

A simple example of a .env file might look like this:

DB_HOST=localhost
DB_USER=root
DB_PASSWORD=secret
text

This file is de­lib­er­ately not stored in version control. This is handled by the .gitignore file, which specifies which files or folders should be ignored by Git. In .gitignore, the .env file is ex­pli­citly excluded so that sensitive data is not ac­ci­dent­ally published.

Error handling and logging

Handling errors differs between de­vel­op­ment and pro­duc­tion en­vir­on­ments. During de­vel­op­ment, it makes sense to display PHP error messages directly. This allows problems to be iden­ti­fied and fixed quickly.

In pro­duc­tion ap­plic­a­tions, error messages should not be visible, as they could reveal internal in­form­a­tion. Instead, errors are written to log files that are only ac­cess­ible to de­velopers.

In a de­vel­op­ment en­vir­on­ment, error output can be enabled as follows, for example:

<?php
ini_set('display_errors', 1);
error_reporting(E_ALL);
php

In a pro­duc­tion en­vir­on­ment, error display is disabled and logging is enabled. PHP then writes any errors that occur to a log file without showing them to website visitors. This keeps the ap­plic­a­tion stable and secure while still providing a clear record of errors.

How to connect to a database with PHP using PDO

To store or retrieve data with PHP, a database is required. In this example, we use MySQL, which is included in XAMPP by default. PHP can com­mu­nic­ate securely with the database using PDO (PHP Data Objects). PDO ensures that database commands are executed reliably, and offers prepared state­ments: place­hold­ers separate the SQL command from the user input so that it is not executed as part of the command.

Creating database and table

First, create a new database named testdb in phpMy­Ad­min. Inside this database, create a table called users. The table contains three columns. The id column uniquely iden­ti­fies each user, username stores the user name, and email stores the email address. The following SQL statement creates the table:

CREATE TABLE users (
id INT AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(50) NOT NULL,
email VARCHAR(100) NOT NULL
);
sql

Database op­er­a­tions in PHP

Now we create a file called ‘crud.php’ in the XAMPP ‘htdocs’ folder. In this example, we establish a con­nec­tion to the database and first demon­strate the basic CREATE, READ, UPDATE, and DELETE op­er­a­tions (CRUD):

<?php
// Establish database connection
$host = '127.0.0.1';
$db = 'testdb';
$user = 'root';
$pass = '';
$charset = 'utf8mb4';
$dsn = "mysql:host=$host;dbname=$db;charset=$charset";
$options = [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, // Make errors visible
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, // Data as array
];
try {
$pdo = new PDO($dsn, $user, $pass, $options);
} catch (PDOException $e) {
echo "Connection failed: " . $e->getMessage();
exit;
}

// CREATE: insert new user
$stmt = $pdo->prepare("INSERT INTO users (username, email) VALUES (:username, :email)");
$stmt->execute([
'username' => 'Max Mustermann',
'email' => 'max@example.com'
]);

// READ: fetch all users
$stmt = $pdo->query("SELECT * FROM users");
$users = $stmt->fetchAll();

// Output the user list
echo "<h2>User list</h2>";
foreach ($users as $user) {
echo "ID: " . $user['id'] . " – Name: " . htmlspecialchars($user['username']) . " – E-Mail: " . htmlspecialchars($user['email']) . "<br>";
}

// UPDATE: change a user's email
$stmt = $pdo->prepare("UPDATE users SET email = :email WHERE username = :username");
$stmt->execute([
'email' => 'max.mustermann@example.com',
'username' => 'Max Mustermann'
]);
echo "<p>The email address of Max Mustermann has been updated.</p>";

// DELETE: delete user
$stmt = $pdo->prepare("DELETE FROM users WHERE username = :username");
$stmt->execute([
    'username' => 'Max Mustermann'
]);
?>
php

First, a con­nec­tion to the database is es­tab­lished using PDO. For this step, the host, database name, username, password, and character set are specified. PDO helps ensure that SQL commands are executed securely and that errors are reported.

We then demon­strate the four basic op­er­a­tions:

  • CREATE (inserting data): With INSERT INTO, we insert a new user. The place­hold­ers :username and :email ensure that user input is processed securely.
  • READ (reading data): With SELECT * FROM users, we retrieve all existing records. Using fetchAll(), we store the results in an array and output them in a clear, organised list.
  • UPDATE (modifying data): With UPDATE, we can change a user’s email address. Again, we use place­hold­ers to safely insert the values.
  • DELETE (deleting data): With DELETE FROM users WHERE username = :username, we remove a specific user from the database. The :username place­hold­er ensures that the input is processed securely, pre­vent­ing attackers from tampering with the database. This lets us delete in­di­vidu­al records without affecting the entire table.

How to secure user input and data pro­cessing

Whenever PHP processes user input, a security risk can arise. Visitors may ma­nip­u­late form fields, submit un­ex­pec­ted data, or de­lib­er­ately attempt to misuse an ap­plic­a­tion. For this reason, PHP provides various functions that help validate, process, and store input securely.

Storing data securely in databases with prepared state­ments

One of the most common security vul­ner­ab­il­it­ies in PHP ap­plic­a­tions occurs when working with databases. If user input is inserted directly into SQL queries, a so-called SQL injection may occur. In this case, attackers insert their own SQL code into the query.

Prepared state­ments prevent this problem by strictly sep­ar­at­ing SQL code from user data. PHP provides the PDO database interface for this purpose.

<?php
$stmt = $pdo->prepare("SELECT * FROM users WHERE username = :username");
$stmt->execute([
'username' => $username
]);
php

The code prepares a database query that searches the users table for all users whose username matches a specific value. Instead of writing the username directly into the SQL command, the :username place­hold­er is used, which is only filled with an actual value when the query is executed. This way, PHP separates the SQL code from the user data and prevents input from ma­nip­u­lat­ing the command.

Securing output with output escaping

Not only storing data but also dis­play­ing it can pose risks. If user input is shown in the browser without filtering, cross-site scripting (XSS) can occur. In such cases, malicious code may be executed in other users’ browsers. To prevent this, output must be escaped. In PHP, this is typically done with the htmlspecialchars() function so that the text is displayed but not in­ter­preted as code.

<?php
echo htmlspecialchars("<h1>Hello World!</h1>", ENT_QUOTES, 'UTF-8');
php
Image: PHP function htmlspecialchars()
When you use htmlspe­cial­chars(), HTML code is in­ter­preted as a simple string.

Filtering user input with filter_input()

PHP provides filter_input() as a way to validate and sanitise user input as it is read. This makes it possible to detect invalid or unwanted values at an early stage. A simple example is reading an email address:

<?php
$email = filter_input(INPUT_POST, 'email', FILTER_VALIDATE_EMAIL);
php

If the input is not a valid email address, the false value is returned by the function. If the field was not submitted at all, the result is null. Therefore, check for both cases. This way, the code can respond in a targeted manner before further pro­cessing the data.

Storing passwords securely with password_hash()

Passwords should never be stored in plain text. Simple en­cryp­tion is also not suf­fi­cient. For this purpose, PHP provides the password_hash() function, which securely hashes passwords.

<?php
$hash = password_hash($password, PASSWORD_DEFAULT);
php

During a later login, the entered password can be verified using the password_verify() function:

<?php
if (password_verify($password, $hash)) {
echo "Login successful";
}
php

The original password is never visible again. Even if a database leak occurs, the passwords remain protected.

Pre­vent­ing form ma­nip­u­la­tion with CSRF tokens

When working with forms, there is a risk that they may be submitted without the user’s knowledge. To prevent this, CSRF tokens are used. These are random strings that are generated each time the form is loaded.

<?php
$_SESSION['token'] = bin2hex(random_bytes(32));
php

This line generates a random security code that is difficult to guess and stores it in the user’s current session. The random_bytes(32) function creates 32 random bytes, meaning raw data that is not directly readable. The bin2hex() function then converts this raw data into a readable string of letters and numbers. The generated value is stored in $_SESSION['token'] and later used to verify whether a form actually ori­gin­ates from the same session.

File uploads with val­id­a­tion

File uploads are also par­tic­u­larly sensitive and can introduce security risks, since external files are uploaded to the server. Therefore, the file type and file size should always be checked.

A simple example of a file size check might look like this:

<?php
if ($_FILES['upload']['size'] > 1000000) {
echo "File is too big.";
}
php

The code checks the size of the uploaded file and compares it with a defined maximum value of 1,000,000 bytes. If the file exceeds this limit, an error message is displayed and the upload can be rejected. This prevents files that are too large from being stored on the server. In addition, it is important to verify that the file is actually of the expected type, such as an image. Files should never be stored on the server as ex­ecut­able without proper val­id­a­tion.

Reviewers

Go to Main Menu