OceanofPDF - Com PHP by Example A Practical Guide - Alex Vasilev
OceanofPDF - Com PHP by Example A Practical Guide - Alex Vasilev
Alex Vasilev
Alex Vasilev
https://doi.org/10.1007/979-8-8688-0258-4
This work is subject to copyright. All rights are reserved by the Publisher,
whether the whole or part of the material is concerned, specifically the rights
of translation, reprinting, reuse of illustrations, recitation, broadcasting,
reproduction on microfilms or in any other physical way, and transmission or
information storage and retrieval, electronic adaptation, computer software,
or by similar or dissimilar methodology now known or hereafter developed.
Trademarked names, logos, and images may appear in this book. Rather than
use a trademark symbol with every occurrence of a trademarked name, logo,
or image we use the names, logos, and images only in an editorial fashion
and to the benefit of the trademark owner, with no intention of infringement
of the trademark.
The use in this publication of trade names, trademarks, service marks, and
similar terms, even if they are not identified as such, is not to be taken as an
expression of opinion as to whether or not they are subject to proprietary
rights.
While the advice and information in this book are believed to be true and
accurate at the date of publication, neither the authors nor the editors nor the
publisher can accept any legal responsibility for any errors or omissions that
may be made. The publisher makes no warranty, express or implied, with
respect to the material contained herein.
and the sole member (owner) is Springer Science + Business Media Finance
Inc (SSBM Finance Inc).
source-code.
“All Rights are reserved by the Publisher except for Russian, Ukrainian and
Bulgarian rights”.
In memory of my dad. Thank you for all you gave, and sorry for all I didn’t
return.
Table of Contents
Summary��������������������������
������������������������������
������������������������������
�����������������������25
Introduction to Variables
������������������������������
������������������������������
�������������������������27
Assigning Values
������������������������������
������������������������������
������������������������������
�������48
Summary��������������������������
������������������������������
������������������������������
�����������������������52
Table of ConTenTs
Chapter 4: Arrays
������������������������������
������������������������������
��������������������91
Multidimensional Arrays
������������������������������
������������������������������
�����������������������107
Array Assignments
������������������������������
������������������������������
������������������������������
��111
Concatenating Arrays
������������������������������
������������������������������
����������������������������115
Comparing Arrays
������������������������������
������������������������������
������������������������������
���117
Summary��������������������������
������������������������������
������������������������������
���������������������125
Chapter 5: Functions
������������������������������
������������������������������
������������127
Creating Functions
������������������������������
������������������������������
������������������������������
��127
Recursion
������������������������������
������������������������������
������������������������������
����������������156
vi
Table of ConTenTs
Anonymous Functions
������������������������������
������������������������������
���������������������������162
Named Arguments
������������������������������
������������������������������
������������������������������
��164
Summary��������������������������
������������������������������
������������������������������
���������������������169
References
������������������������������
������������������������������
������������������������������
��������������171
Constants
������������������������������
������������������������������
������������������������������
����������������177
Global Variables
������������������������������
������������������������������
������������������������������
������179
Static Variables
������������������������������
������������������������������
������������������������������
�������182
Multiline Strings
������������������������������
������������������������������
������������������������������
������184
Using
Files����������������������������
������������������������������
������������������������������
�����������������187
Summary��������������������������
������������������������������
������������������������������
���������������������196
Copying Objects
������������������������������
������������������������������
������������������������������
������217
Special Methods
������������������������������
������������������������������
������������������������������
�����223
vii
Table of ConTenTs
Chapter 8: Inheritance
������������������������������
������������������������������
����������243
Overriding Methods
������������������������������
������������������������������
������������������������������
�248
Virtual Methods
������������������������������
������������������������������
������������������������������
�������261
Multilevel Inheritance
������������������������������
������������������������������
���������������������������266
Summary��������������������������
������������������������������
������������������������������
���������������������271
Abstract Classes
������������������������������
������������������������������
������������������������������
�����273
Interfaces
������������������������������
������������������������������
������������������������������
����������������278
Interface Inheritance
������������������������������
������������������������������
�����������������������������28
1
Traits
������������������������������
������������������������������
������������������������������
�����������������������285
A Namespace
������������������������������
������������������������������
������������������������������
����������292
Anonymous Classes
������������������������������
������������������������������
������������������������������
298
Summary��������������������������
������������������������������
������������������������������
���������������������300
Exception Handling
Principles��������������������������
������������������������������
�������������������303
Exception Classes
������������������������������
������������������������������
������������������������������
���307
Throwing Exceptions
������������������������������
������������������������������
�����������������������������31
0
viii
Table of ConTenTs
Rethrowing an Exception
������������������������������
������������������������������
����������������������328
Summary��������������������������
������������������������������
������������������������������
���������������������333
Using
Generators�������������������������
������������������������������
������������������������������
����������346
Iterators��������������������������
������������������������������
������������������������������
�����������������������353
Summary��������������������������
������������������������������
������������������������������
���������������������359
Using Buttons
������������������������������
������������������������������
������������������������������
����������373
Summary��������������������������
������������������������������
������������������������������
���������������������402
ix
published in English.
xi
xiii
Acknowledgments
To my dear children Anastasia and Bohdan, and all my family. Thank you
for your support and love. You give meaning to my life and encourage me to
move on.
I sincerely thank the great and professional Apress team for the outstanding
support and dedication provided throughout the process of bringing the book
to fruition. Their collective efforts have undoubtedly played a pivotal role in
making the book better.
xv
Introduction
There are many things in this universe you are not meant to understand.
Now, that does not mean they are not real.
PHP is designed to execute code on the server side. In other words, it is not
enough to know PHP. It is also necessary to understand how and for what it
is used. That is important since understanding the possibilities of a language
is the key to using it effectively.
About PHP
The PHP language is used for creating sites and web applications. It has a
long story, is popular among developers, and is supported by most host
servers.
xvii
InTroduCTIon
Details
The author of PHP is Rasmus Lerdorf. The project started as writing scripts
to support a personal web page and was initially titled Personal Homepages
Tools or PHP Tools. Then, it was transformed into an independent and
influential software product. Today, the name PHP is usually associated with
the phrase Hypertext Preprocessor, which is not far from the truth.
Note When writing this book, the current version is PHP 8. on the other
hand, in practice, the latest version of the language does not immediately
start to be used. There is some inertia here due to both objective and
subjective factors. Therefore, universal approaches relevant to the last few
language versions are considered. notably, there is no sixth version: the
seventh version follows after the fifth.
The reason is that the attempt to release the sixth version was highly
unsuccessful.
xviii
InTroduCTIon
The PHP 8 Standard PHP 8 introduced a JIT compiler (short for Just in
Time) for compiling PHP code to speed up program execution.
processor-level instructions.
Scripting languages are usually high-level ones. Unlike conventional
programs, scripts usually contain instructions for controlling ready-made
software components. In other words, a scripting language is a
straightforward language. Although, of course, not everything is always so
rosy.
Details
The C language has influenced the syntax of the PHP language. Therefore, if
you know languages such as C, C++, C#, or Java, you will find many
familiar syntax constructions.
If you are dealing with any conventional programming language, the process
of writing and using programs looks like follows. First, you create the
program code—in other words, you write a program. Then, that program
must be executed. How to do that depends on the language, but the most
crucial question is whether the program is compiled or interpreted. If the
program is compiled, a particular compiler program translates your program
into machine instructions (or something similar to them), and then those
instructions are executed. If the program is interpreted, a special interpreter
program reads your program and executes statements from the code. But
whatever happens, the important thing here is that you do all the operations
on the same computer. You run the program on the computer and get a result.
You can do anything you want with the result of the program execution, but
the critical point is that it is enough to have only one computer.
xix
InTroduCTIon
With the PHP language, things are somewhat different. To understand the
problem, let’s consider what happens when you access a web page and how
PHP is involved in that case.
In general terms, here is the scheme according to which the site is viewed on
the network. In this case, the main acting “characters” are the computer on
which you want to view the web page and the computer on which that page
is located. The first computer (on which you are trying to view the web
page) is called a client, and the computer on which the web page is located is
called a server.
Figure I-1. The scheme of the interaction between a client and a server
xx
InTroduCTIon
Note The server tells what to do, and the client’s browser performs the
necessary operations. Convenient but not always safe.
So, where is the place for PHP in this scheme? The answer is at the stage of
processing the request by the server. When the server receives a request from
a client, it processes the request, and while processing it, scripts can be
executed—in this case, PHP scripts.
Details
often, the script’s output is a generated HTMl code passed to the client.
But that is not all. Many programs try to exchange information over the
network. Processes on a client send signals to processes on a server and
back, and you need to know which signal is for which process. For that
purpose, you use ports. Ports are unique integer identifiers the processes use
to identify the signals sent to them. Therefore, requests from the client’s
browser and server responses must be synchronized by ports. That is, to
work effectively with PHP, you need to solve quite a few technical problems.
All that is considered step by step, as necessary.
xxi
InTroduCTIon
Let’s take the next step in studying PHP. Namely, focusing on how to
execute a program written in PHP. If you are talking about the “natural”
way of using PHP code, you would need a server and a client. That is two
computers. The script (the program) is hosted on the server, and you can
view the result of the program execution by accessing the web page on the
server through the client browser. But even if all these resources are
available, the described strategy is not very convenient since you need to
edit the program on one computer (the server) and check the result on
another computer (the client). So, it is clear that you would like to have a
more reliable strategy.
that is, approximately the same as in the case of other interpreted languages.
That is probably the easiest way to see what the result of running a program
is. Nevertheless, you should not forget that PHP
The Software
The book contains many examples, and in the process of studying them, it is
desirable to disassemble the program and examine the result of its execution.
That requires special software.
First of all, you have to install the software that supports PHP. To do that, go
to www.php.net, as shown in Figure I-2.
xxii
InTroduCTIon
You should find the software download section in that window and
download the necessary files.
Note In the simplest case, the installation comes down to unpacking the
archive downloaded from www.php.net. That will likely be enough for using
the PHP interpreter (php.exe file) in command-line mode. You may need to
perform additional settings for a more “comfortable” work regime involving
special software. If so, refer to the help information on the www.php.net
page and use the help for the relevant software product (for example, a code
editor).
xxiii
InTroduCTIon
Details
You can use the php -v command-line instructions to check the PHP
version.
To get PHP help, use the php -h command. Additional information about
PHP
If you use the Windows operating system, you can enter the cmd
instruction into the address bar of Windows Explorer to switch to the
terminal mode. Then, you must change to the PHP directory in the
terminal window. For example, if PHP is in the C:\PHP folder, the
appropriate command would be cd C:\PHP. An alternative is to navigate
to the PHP directory first and then enter the cmd instruction in the
Explorer address bar.
Note It is easy to find a suitable editor for processing PHP code if necessary.
However, such a strategy is mainly aimed at advanced users. That is why it
is beyond your attention.
There are other options as well. For example, the Visual Studio Code
development environment (the address is https://code.visualstudio.com)
is quite convenient. The browser opened on the project page is shown in
Figure I-3.
xxiv
InTroduCTIon
Figure I-3. The Visual Studio Code project support page Details
The first time you run the Visual studio Code application, you must confirm
the installation of the PHP support in the Customize section.
Another good option for developing PHP programs is the NetBeans IDE.
The installation files can be downloaded from http://netbeans.
xxv
InTroduCTIon
Details
You may need the Java development Kit (JdK) pre-installed on your
computer to use netbeans.
But once again, it is enough to install PHP and select a suitable code editor.
Note You will learn how to use the software (at the primary level) through
examples.
xxvi
InTroduCTIon
• Chapter 2 discusses variables and data types. There, you will learn how to
create variables, perform
• Chapter 3 is devoted to the control statements. You will get a notion of the
conditional statement, selection
PHP programs.
on arrays.
xxvii
InTroduCTIon
• Chapter 5 describes functions. You will learn how they are created, discuss
the mechanisms for passing
• Chapter 6 deals with links, constants, global and statistic variables, file
handling, and methods for
xxviii
InTroduCTIon
is used.
discussed in Chapter 10. You become familiar with the main exception
classes and learn how exceptions are
• Chapter 11 is devoted to generators and iterators. You will learn to use and
apply the generator functions in
documents.
At the end of each chapter, for convenience, a summary lists all the main
points discussed in the chapter.
xxix
CHAPTER 1
In this chapter, you will create your first PHP program. Namely, you will
examine some simple code and determine how it can be executed. There is
not much programming in the chapter, but a lot of information is essential
for using PHP.
The second task is much more complex than the first one.
So, let’s create your first PHP program. Namely, let’s define what your
program should do. Traditionally, the first program displays a message.
You will do the same. Your program displays a welcome message in the
output window (terminal). The program is shown in Listing 1-1.
<?php
print("Hello, PHP!");
?>
The program begins with the <?php statement and ends with the
?> statement. That is a standard situation for all programs in PHP. The
commands to be executed in the program are placed between these
instructions. In this case, there is a single command. It calls the print() built-
in function with "Hello, PHP!" passed as an argument.
Details
Text values are enclosed in double quotes. Also, text values can be enclosed
in single quotes. Both styles are almost equivalent, but there are essential
differences, which are discussed a little later.
It is also worth noting that every command in PHP ends with a semicolon.
Note Frankly speaking, print() is not exactly a function but rather a special
syntax construction of the PHP language. But since its properties are similar
to a function, consider it a function.
Details
The argument can be specified without parentheses when calling the print()
function. That means that instead of the print("Hello, PHP!") command, you
can use the print "Hello, PHP!" statement. Another alternative to the print()
function is the echo statement. Namely, the echo "Hello, PHP!"
Let’s explore several options, and you can choose the one you like the best.
So, the first thing to do is to create a file with the program, as in Listing 1-1,
and save that file with the .php extension. For example, name the file
hello.php, located in the D:\Books\php\codes folder. Next, execute the file.
At this stage, you need an interpreter, the php.exe file located in the folder
where PHP was installed. Let’s assume that PHP is installed in the C:\PHP
folder. The recipe for launching the program is simple: in the terminal’s
command line, you must execute php.exe, passing the hello.
php file to it (the file with the program) as a parameter. You can make that
simple. You need to specify the full path to the php.exe file in the command
line and, separated by a space, the full path to the file with the hello.php
program. The corresponding command would look as follows.
C:\PHP\php.exe D:\Books\php\codes\hello.php
Nevertheless, specifying the full path to the files is not very convenient.
In principle, you can move to the directory with the php.exe file installed
and save the files with the PHP code in the same place. So, if PHP is
installed in the C:\PHP folder, then to move to it, run the following
command in the command line.
cd C:\PHP
Details
If you need to change a directory and a disk, use the /d option. For example,
if you need to move from the D:\ drive to the C:\ drive, the command looks
like cd /d C:\.
If the hello.php file is located in the same folder as the php.exe file, then you
use the following command to run the program for execution.
php hello.php
4
CHAPTer 1 THe FIrsT ProgrAm
The same command can be used under the Windows operating system if you
add the path to the PHP folder to the Path environment variable and then
move to the folder with the program file.
Details
select the Advanced system settings item in the computer properties to get
the Path environment variable. In the System Properties window, select the
Environment Variables icon. In the Environment Variables window,
select the Path position and change the contents of the corresponding
variable.
Figure 1-1 shows the environment’s window with the hello.php file open.
Figure 1-1. The Visual Studio Code development environment window with
the hello.php program file open
In the environment window, open the folder with the program file.
(You can use the Open Folder command from the File menu.) The files
from this folder should appear in the Explorer section on the left side of the
development environment window. In this case, select the file with the
program. The file’s contents are displayed in the central part of the window.
You can run the program in the terminal, which is opened using 5
the New Terminal command from the Terminal menu. In the example, you
enter the following command in the terminal command line.
php hello.php
If you use the Windows operating system, the Path environment variable
must contain the path to the php.exe file. If not, you must specify the full
path to that file, and the command looks as follows.
C:\PHP\php.exe hello.php
If everything goes well, then the message displayed by the program should
appear in the terminal.
However, the most comfortable and free way to develop is to use the
NetBeans development environment (the site with the installation files is at
http://netbeans.apache.org). The NetBeans environment window is shown in
Figure 1-2.
Figure 1-2. The NetBeans window
6
CHAPTer 1 THe FIrsT ProgrAm
Figure 1-4. The window New Project for creating a new project In the
window, you select the type of application (a PHP project must be created).
The following New PHP Project window appears, as shown in Figure 1-5.
Figure 1-5. The New PHP Project window to set up the project parameters
You use the window to perform the project settings, such as the project name
(the Project Name field), project location (the Sources Folder field), and
some others (it makes sense to leave them as they are by default).
In the next window, a runtime environment is selected. You are interested in
running from the command line. To do that, select the Script (run in
command line) option in the Run As drop-down list, as shown in Figure 1-
6.
8
CHAPTer 1 THe FIrsT ProgrAm
The PHP Interpreter field specifies the location of the PHP interpreter (in
this case, C:\PHP\php.exe). The settings in other windows should be left
unchanged. Figure 1-7 shows the window of the newly created project.
Add the index.php file to the Source Files folder in the Projects tab if
necessary. To do that, select the PHP File item in the New submenu of the
context menu, as shown in Figure 1-8.
Enter the file name in the File Name field in the New PHP File window,
shown in Figure 1-9.
10
Figure 1-9. The File Name field with the name of the file Note In some
NetBeans versions, the index.php file is automatically created in the project
folder.
The code of the index.php file is entered in the editor window.
11
CHAPTer 1 THe FIrsT ProgrAm
Then, run the code for execution. To do that, click the icon with a large green
button on the toolbar or select the Run Project command from the Run
menu, as shown in Figure 1-11.
12
The result of executing the code is displayed in the output area at the bottom
of the NetBeans IDE window (see Figure 1-12).
Thus, you can edit the program code conveniently and run it for execution.
It is also worth noting that some settings related to working with PHP
are performed in a special window, which can be accessed using the Options
command from the Tools menu.
In NetBeans, you can create a single file with PHP code instead of creating a
project. To do that, in the NetBeans development environment window,
select the New File command from the File menu (see Figure 1-13).
13
CHAPTer 1 THe FIrsT ProgrAm
The New File window opens, in which you select the file type to be created
(see Figure 1-14).
14
CHAPTer 1 THe FIrsT ProgrAm
In particular, select Other in the Categories section and Empty File in the
File Types section. Then, the New Empty File window appears (see Figure
1-15).
Figure 1-15. The window to determine the file name In this window, you set
the file name (hello.php in the File Name field). The Folder field specifies
the file location (in this case, D:\Books\ php). As a result, an empty file is
created into which you enter the program, as shown in Figure 1-16.
15
CHAPTer 1 THe FIrsT ProgrAm
Figure 1-16. The file with the program in the NetBeans window To run the
file with the code for execution, select the Run File command in the Run
menu (see Figure 1-17).
After you run the program for execution, the result appears in the output area
at the bottom of the development environment window, as shown in Figure
1-18.
Figure 1-18. The result of executing the program from the file Note When
you run the file for execution, the Run File window appears, in which you
just need to click the OK button.
Details
Another regime of testing how PHP programs operate is using a server that
executes the programs. An external and local computer can be used as a
server. Let’s start with the second case.
HTML BASICS
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<?php
18
print("Hello, PHP!");
?>
</body>
</html>
This code must be saved in a .php file. It is the hi.php file located in the
D:\Books\php\codes directory.
HTML BASICS
19
Figure 1-19. Trying to open the hi.php file in a browser To get a different
result, you need to run a local server. To do that, run php.exe with the -S
option, followed by the localhost keyword, and, separated by a colon, a port
number for the local server. In principle, the port number is arbitrary, but
making it greater than 5000 is reasonable.
Details
After that, in the command line, specify the -t option and a link to the folder
you want to identify with the root directory of the local server. More
specifically, let’s say the command looks as follows.
The instruction runs the local server using port 6789. The server’s root
directory is identified with the D:\Books\php\codes folder. Such a command
is correct if the Path environment variable contains the path to the php.exe
file or if it is executed from the folder where the php.exe file is located. In
general, the command might look as follows.
20
If everything is done correctly, the local server is started. Now, open the
browser and enter the following instructions in the address bar.
localhost:6789/hi.php
As a result, when opening the hi.php file, your computer emulates a server
job. The result should look like what’s shown in Figure 1-20.
Figure 1-20. Displaying the hi.php file in the local server regime Note The
path to the displayed file begins from the folder specified when starting the
local server. In this case, it is the D:\ Books\php\codes folder.
You can use the mentioned NetBeans development environment to debug an
HTML code with a PHP script encapsulated in it. Creating a new project is
similar to the one discussed. However, when choosing a runtime
environment (see Figure 1-6), select PHP Built-in Web Server (running on
built-in web server) in the Run As drop-down list, as shown in Figure 1-21.
21
document
The Hostname field contains the local host’s name, and the Port field
contains the port number. You can leave the default values there.
As a result, you should create a new project with the index.php file. Enter
the HTML code (with the PHP script) in that file, as shown in Figure 1-22.
22
Figure 1-22. The project window with the HTML code and the PHP script
Note except for the page name, the code is the same as in Listing 1-2.
When you run the project, the browser opened on the local host is
automatically launched. The result is shown in Figure 1-23.
Details
Finally, another way to test the PHP code is to host the corresponding file on
an external server. That is the most reliable way of testing, but it has a
significant drawback since not everyone has such an opportunity. But in
general, the idea is simple. The file is uploaded to the server and then opened
using a browser. Figure 1-24 shows a browser window where the document
with the address www.vasilev.com.ua/php/hi.php is opened.
24
CHAPTer 1 THe FIrsT ProgrAm
Summary
command line.
?> instructions).
<!DOCTYPE html>
<html>
<head>
</head>
25
<body>
<?php
?>
</body>
</html>
26
CHAPTER 2
Variables and
Data Types
We can’t throw these things away. These are a part of who we are.
As usual, programs operate with data. And the data needs to be stored
somewhere. If you deal with small blocks of information, variables are a
good place to store it, which is the focus of this chapter. The chapter also
discusses the main data types used in programs and the basic operations
performed with variables.
Introduction to Variables
There is a rule in PHP: the name of a variable begins with the $ symbol (this
symbol is part of the variable name). To assign a value to a variable, you
specify the variable’s name, then put the assignment operator (equal
27
sign =) and the value to be assigned to it. For example, the $number=123
command assigns the integer 123 to the $number variable, and the
$text="Hello, PHP" command assigns the text value "Hello, PHP" to the
$text variable.
Variables do not have a type. But the value that the variable refers to has a
type. At different stages of program execution, the same variable can refer to
values of different types.
First, let’s look at Listing 2-1, a small example that uses a variable.
<?php
// Creating a variable:
$number=123;
/*
*/
?>
allowed in PHP.
28
CHAPter 2 VArIABles And dAtA tyPes
The difference between the commands is as follows. In the first case, the text
to be displayed is enclosed in single quotes. In the second case, the text is in
double quotes. In principle, in both cases, you get text. That means single
and double quotes are two different ways to create a text.
They are almost equal. But some differences also exist. In this case, both text
values ('The variable $number: ' and "the value $number") contain the name
of the $number variable. So, if the variable’s name occurs in the text
enclosed in single quotes, then when the text is displayed in the terminal, the
variable’s name is displayed. If the variable’s name is placed 29
CHAPter 2 VArIABles And dAtA tyPes
in the text enclosed in double quotes, then when displayed in the output
window, its value is substituted instead of the variable’s name. Therefore,
when executing the print 'The variable $number: ' command, exactly the text
in single quotes is displayed. But when executing the print "the value
$number" command, then, instead of the name of the $number variable, its
value 123 is substituted in the text.
Note As a result of calling the print() function, the value of the argument
passed to the function is displayed in the output window. But there is no line
break in the output area. therefore, two messages are displayed sequentially
in the program discussed, one after the other in the same line.
notably, many common tasks in PHP can be performed in different ways. the
examples are several types of comments, several ways to create text literals,
several instructions for displaying messages, and the list is not complete. the
situation is typical for PHP. In this sense, the language is very convenient
and “comfortable” if such a definition is suitable for a programming
language.
Details
Along with variables, you can also use constants. A constant differs from a
variable in a way that the value of the constant cannot be changed. to create
a constant, use the define() function, the first argument of which is the name
of the constant, and the second argument is the value of the constant. the
dollar symbol $ is not used in the constant name. Constant names usually
consist of capital letters. For example, the define("NUMBER",123)
command defines the NUMBER constant with the value 123. you can check
the existence of a constant with a specific name using the defined() function.
the function argument is the name of the constant (in quotes).
30
CHAPter 2 VArIABles And dAtA tyPes
There is also the boolean type (logical values true or false), array (an array),
object (an object), resource (a reference to an external resource), and NULL
(which means no value for the variable). A small example that illustrates the
situation is shown in Listing 2-2.
<?php
// An integer number:
$value=123;
// A text:
$value="text";
// A real number:
$value=12.3;
?>
31
The PHP 8 Standard When using PHP 8 and higher, you get a warning
about the unknown variable $VALUE, which appears
Here, you deal with a simple program. The $value variable gets
consequently different values, and its type is determined for each value. To
determine the type, use the gettype() function, the argument of which is the
$value variable.
variable. that is far from being the same as the $value variable since variable
names are case-sensitive (it matters whether the variable name contains
capitalized letters or small ones). therefore, $value and $VALUE are
different variables.
To display values, an instruction based on the echo keyword is used.
To the right of the instruction, comma-separated values are listed. They are
displayed in the output area. In particular, these are the current value of the
$value variable, the " => type " string, the name for the value type of the
$value variable, which is calculated by the gettype($value) statement, and
the escape sequence "\n".
32
Details
variable in the output area, although the value has not been assigned yet to
the variable. The variable has no value; in other words, the value of the
variable is the NULL reference. That confirms the call of the gettype()
function with $VALUE as an argument. When trying to display the value of
the $VALUE variable, since it is missing, nothing is displayed in the output
area. In this sense, the PHP language is more than “liberal” when a variable
has no value.
function. there is a group of functions that allow you to check if data belongs
to a specific type: is_array() (whether the variable refers 33
Details
34
Details
are used to calculate the sum, difference, product, and quotient of two
numbers, respectively. You use the ** operator (or the pow() function) to
exponentiate. The % operator calculates the remainder of a division.
In addition to these binary operators, you can use the unary increment
++ and decrement -- operators. Moreover, they have the prefix and the
postfix form.
Details
Binary operators have two operands. Unary operators have one operand. the
prefix and postfix forms of the increment and decrement operators differ in
whether the operator is placed before the operand (the prefix form) or after
the operand (the postfix form).
Regarding “action” on the operand, the postfix and prefix forms are
equivalent. The increment operator ++ increases the value of the operand by
one, and the decrement operator -- decreases the value of the operand by
one. For example, if the value of the $number variable is 100, then after
executing the $number++ statement, the variable’s value will be 101. The
result will be the same if you use ++$number instead of the $number++
statement: the $number variable gets the new value 101. However, there is a
difference between the postfix and prefix forms. The value of the expression
with the postfix form of the increment/decrement operator is the “old”
(which was before applying the operator) value of the operand.
The value of the expression with the prefix form of the increment/
35
Details
let’s say there are commands $A=100 and $B=100. After executing the
$a=$A++
and $b=++$B commands, $a has the value 100, and $b, $A, and $B have the
value 101. that is because after executing the $A++ and ++$B statements,
the $A and $B
variables increase their values by one (and get the value 101), but the value
of the $A++ expression is 100, and the value of the ++$B expression is 101.
so, the $a variable gets 100 as its value, and $b gets 101 as its value.
<?php
// Variables:
$A=5;
$B=3;
// Arithmetic operations:
$A++;
--$B;
?>
36
[1] $A = 5
[2] $B = 3
[3] $A + $B = 8
[4] $A - $B = 2
[5] $A * $B = 15
[6] $A / $B = 1.6666666666667
[7] $A ** $B = 125
[8] $A % $B = 2
[9] $A = 6
[10] $B = 2
Here, everything is quite simple, and it is believed that the result of the
program execution does not require comments.
( greater than or equal to), == ( equal to), != ( not equal to), === (
identically equal to), !== ( identically not equal to), and the <=> comparison
operator.
Most of the operators in the list are traditional and easy to understand.
Maybe the exceptions are the <=> operator, equal/not equal to operators,
and identically equal/identically not equal to operators.
It is important to know that when using the operators (including comparison
ones) with operands of different types, automatic type conversion is
performed. That means that to execute a statement, certain algorithms are
automatically applied to transform the values of the operands in the
statement. With the == and != operators, the comparison 37
involves automatic type conversion. For example, you get true if you use the
== operator to compare the boolean value true and the integer value 1
(the true==1 statement). The reason is that non-zero values are interpreted as
true, and zero values are interpreted as false. Therefore, not only the true==1
statement gives true but also the true==2, true==-10, and false==0
statements.
Details
If you try to print the boolean value true, the 1 value is printed. Moreover,
the boolean value false is not displayed at all. Instead of this value, the
empty text is printed (that is, the text without characters).
But there are also more exotic options. For example, the 123=="123"
statement, where you compare the 123 number and the "123" text for
equality, gives true. That is because, here, the automatic conversion of the
textual representation of the number "123" into the integer value 123
It depends on the context of the problem being solved. If you want the
comparison to be performed without automatic type conversion, the ===
and !== operators should be used. For example, the true===1, false===0,
and 123==="123" expressions give false.
The PHP 8 Standard In PHP 8, the rules for comparing values have
changed somewhat. the main innovation is that an empty text value is not
interpreted as equal to zero. For example, in PHP 8, the value of the 0==""
expression is false, while the value of the 0=="" expression in previous
versions of PHP is true.
38
Let’s say you have an expression like $A<=>$B. The result of such an
expression is -1, provided that the value of $A is less than that of $B. If the
value of the $A variable is greater than that of the $B variable, then the
$A<=>$B expression evaluates to 1. Finally, if the $A and $B variables have
the same value, the $A<=>$B expression gives the value 0.
Details
An operation of the form $A<=>$B can be thought of as one that returns the
sign of the difference between the values of $A and $B. Moreover, keep in
mind that the operation involves automatic type casting. therefore, for
example, the "123"<=>123 expression gives 0 since the text "123" is
automatically converted to the number 123. Accordingly, the value of "123"
<=>12 equals 1. the true<=>123 expression has the value 0 because the non-
zero integer value 123 is automatically converted to the boolean value true.
To perform the logical operations, you use the binary operators && ( logical
and) and || ( logical or), as well as the unary logical negation operator !.
39
Note simply speaking, the $A&&$B expression is true only if both operands
$A and $B in the expression are true.
The value of an expression of the form $A||$B is true if at least one of the
operands $A or $B is true or its value is cast to true due to automatic type
casting. If both operands are false, then the value of the entire expression is
false.
Note It turns out that the value of the $A||$B expression is true if at least one
of the operands in the expression is true.
Details
therefore, in these cases, the value of the second operand is not calculated.
40
Details
there exist “twins” for the operators && and ||. they are, respectively, the and
and or operators. these operators have lower precedence than the && and ||
The bitwise operations are performed at the level of the binary (bitwise)
representation of a number. Therefore, to understand the consequences of
performing such operations, it is necessary to have at least an elementary
idea of how numbers are encoded in the binary system.
Details
1…
nan−
a2a1a0
0, a 1,
to convert a positive number from the binary to the decimal system, you can
use the formula a
n−1
2.
1…
0=
0
+ 1 + 2 +…+
nan−
aaa
an−
an
Let’s take a look at the basic bitwise operators, starting with the bitwise and
operator &. Suppose an expression like $A&$B is evaluated. Its result is a
number. The binary code of that number is calculated following such a rule.
The binary codes of the operands $A and $B are compared. Namely, in those
binary codes, the corresponding bits are compared. The comparison result
gives a bit for the expression value number.
Details
41
and 10101 are compared bit by bit, and if two bits are 1, then the output is 1.
In all other cases (if at least one bit is 1), you get 0 as the output.
& 01101
10101
00101
As a result, you get the 00101 code, which corresponds to the number 5.
Note the binary representation of numbers used only five positions (bits). All
other (previous) bits are assumed to be zero.
Using the bitwise operator or | when comparing bits in numbers, you get 1 if
at least one of the bits is 1. In other words, the result of an expression like
$A|$B is a number whose binary code is obtained by comparing the binary
codes of the numbers $A and $B. In the number you get, a bit at a particular
position is 1 if at least one of the compared bits at the same position in $A
and $B is 1. If both compared bits are 0, the result is a bit with the value 0.
Thus, the result of the 13|21 expression is 29 (the binary code 11101).
| 01101
10101
11101
42
CHAPter 2 VArIABles And dAtA tyPes
^ 01101
10101
11000
The code 11000 corresponds to 24. That is the value of the 13^21
expression.
Note As you will see later, the value of the ~$A expression is the number -
($A+1). For example, the value of the ~5 expression is the number -6.
<< ( shift to the left) and >> ( shift to the right) operators. The value of an
expression of the form $A<<$n is a number whose binary code is obtained
by shifting the binary code of the number $A by $n positions to the left.
The left bits are lost, and the right bits are filled with zeros. The value of an
expression of the form $A>>$n is a number whose binary code is obtained
from the binary code of the number $A by shifting $n positions to the right.
The right bits are lost, and the left bits are filled with the sign bit’s value (the
first bit, which is 0 for positive numbers and 1 for negative numbers).
43
Details
the addition rules in the binary system are simple: 0+0=0, 1+0=1, 0+1=1,
and 1+1=10.
the last statement is 2+2=4, but only written in the binary code. so, if you
add the codes 00010011 and 11101100, you get the code 11111111,
consisting of ones.
next, add one (the code 00000001) to that code. you get 100000000. But
here, you must remember that you are dealing with a computer, assuming it
stores numbers using 8 bits. But there are nine digits in the code 100000000.
therefore, there is simply no bit at the beginning of the number to remember
the 1, which is lost. you get the code 00000000, which consists of zeros. that
number is 0.
the result will be the same if you take a different source code and a different
number of bits to remember the number. What did you get? If you take some
positive number $X, invert its code (the ~$X expression), add these codes,
and then add 1, you get 0 as a result. In other words, whatever the value of
$X is, there is the relation $X+(~$X)+1=0. It is easy to see that the (~$X)+1
expression can be identified with the code of the number -$X (the number
opposite to the value of $X).
thus, if you need to get the binary code of a negative number, you should
take the code of the opposite positive number, invert that code, and add 1.
the first bit in the binary code of a number is used to determine a sign: for
positive numbers, that bit is 0, and for negative numbers, that bit is 1.
If you need to convert the binary code of a negative number into decimal
representation, then you should follow these next steps. First, you invert the
code.
44
Let’s assume that 8 bits are used to write numbers. Then, the result of the
41<<1 expression is the number 82. The explanation is as follows.
The code of the number 41 is 00101001. After shifting by one position to the
left, you get the code 01010010, corresponding to 82. If you shift the code
00101001 by two positions to the left (the 41<<2 statement), you get the
code 10100100. Here, the first sign bit is 1. Therefore, the number is
negative. You perform a bitwise inversion to determine that number and get
the code 01011011. Then you add 1 and get the code 01011100. That is the
code for the number 92. So, the result of the 41<<2 expression is the number
-92 with the code 10100100. The result of the 41<<3 expression is the
number 72 with the code 01001000.
expression, the value of the 41<<2 expression is 164, and when calculating
the value of the 41<<3 expression, you get 328.
When the 41>>1 expression is evaluated, the code 00101001 of the number
41 is shifted by one position to the right, which gives the code 00010100. It
corresponds to the number 20. The 41>>2 expression value is 10 with the
binary code 00001010. The result of the -69>>2 expression is the number
-18. Here, you should consider that the code of the number -69
Note Once again, all these calculations are given for the case if the number
is stored using 8 bits. A different count of bits means different (in general)
results.
45
Working with text is a vast theme to discuss. Here, let’s focus only on the
basic operations with text and the features of the text that you will need in
the foreseeable future.
Note you already know that text literals can be enclosed in single or double
quotes. In the latter case, if the text contains a variable’s name, its value is
substituted instead of its name. you can also insert escape sequences into
such text, consisting of a
\\, \$, \', and \" to insert backslash \, dollar sign $, single ', and double "
quotes, respectively.
One of the basic operations often performed with text is the concatenation of
strings. In PHP, the concatenation of strings can be done by using the
. operator “dot”. For example, the result of the "Learning"." PHP" expression
is the string "Learning PHP". The same operation can be done with
variables: the value of an expression of the form $A.$B is the text calculated
by combining the text values of the $A and $B variables.
46
Details
does not use the + operator to concatenate text values. Moreover, applying
this operator to concatenate text values may lead to an error or unexpected
result. For example, the "1"+"2" expression does not give the text "12", as
you might expect, but the numeric value 3. the reason is that the + operator
is an arithmetic one, so the operands "1" and "2" are automatically converted
to the integers 1 and 2, respectively. After that, the numbers are added.
therefore, to get the text "12", you should use the "1"."2" statement.
In that case, use the strlen() function. You can compare strings for
equality/nonequality using the == and != operators. But here, you should
remember automatic type casting. Therefore, using the === and !==
Note you can also use the strcmp() (the case-sensitive comparison) and
strcasecmp() (the case-insensitive comparison) functions to compare strings.
Among them, one of the main ones is extracting a substring from a string.
To do that, use the substr() function. The function arguments are a string
(from which the substring is extracted), the index of the character from
which the substring is extracted, and, if necessary, the length of the
substring. If you do not specify the last argument, the substring is extracted
to the end of the string.
47
The function replaces the substring specified by the first argument with the
substring specified by the second argument in the string specified by the
third argument.
Note you can access a single character in a string by specifying the character
index in square brackets after the text value.
For example, if the $A variable has a text value, then the $A[$n]
Assigning Values
Details
is expression evaluated, the $B variable gets the value 100, and the
($B=100) expression has the same value. therefore, the $A variable is
assigned the sum of 100 and 1, that is, the number 101.
There also exist simplified forms of assignment operators. They allow you to
simplify the process of executing assignment statements of the 48
Operators are usually unary (they have one operand) or binary (they have
two operands). But there is one operator that has three operands. That
operator is called the ternary one. In general, if you do not focus on the
terminology, you may consider it as a specific syntactic construction that
allows you to assign a value to a variable depending on a condition that can
be true or false. The syntax for the ternary operator is as follows.
condition?value_1:value_2
First, place the condition (as usual, an expression that returns a boolean
value). Then enter a question mark (?), the value returned if the condition is
true, a colon (:), and the value returned if the condition is false. The
described construction can be assigned to a variable. For example, after
executing the $number=($x<0)?-10:10 statement, $number is set to -10 if the
value of $x is less than zero (if the condition $x<0 is true), and 10 otherwise
(if the condition $x<0 is false). A simple example that uses the ternary
operator is shown in Listing 2-4.
<?php
$number=(int)trim(fgets(STDIN));
49
$word=($number%2==0)?"even":"odd";
# The result of the test for even/odd:
?>
The program is simple, but it contains some notable instructions. First, the
$number=(int)trim(fgets(STDIN)) statement reads the integer value entered
by the user from the keyboard and writes it to the $number variable.
Then, using the ternary operator, the $number variable is tested for even/
odd, and depending on the test result, the $word variable is assigned the
value "even" or "odd". The test result is displayed on the screen.
When you run the program, you are prompted to enter a number.
The program is waiting for the user input. The user enters a number and
presses the Enter key. After that, another message appears, which contains
information about whether the number is even or odd. Depending on the
value entered by the user (highlighted in bold), the result of the program
execution can be as follows (an odd number is entered).
50
The function argument is the STDIN constant identifier for the standard
input stream (which, in this case, is associated with the console). But the
fgets() function reads any entered value as text, and, in addition, the text can
contain special escape sequences (like a break-line instruction). To remove
all “redundant” characters, use the trim() function. It removes all leading and
trailing spaces and special characters from the string passed as an argument.
Thus, if the user enters an integer, then the trim(fgets(STDIN)) expression
contains the textual representation of that number. For example, if the user
enters the number 123, then the value read (taking into account the call to
the trim() function) is "123". Frankly speaking, accounting for automatic
type conversion, calculations could be performed even with that value.
Nevertheless, for reliability, you convert the read text into a number.
To do that, place the (int) instruction before the entire expression. In addition
to the settype() function mentioned, that is another way to cast a type
explicitly.
Details
51
Summary
character.
• A variable does not have a type, but the value that the
function.
conversion system.
• Basic operations use arithmetic, logical, bitwise, and
concatenate strings.
operators.
52
CHAPTER 3
if(condition){
# commands
else{
# commands
53
Let’s discuss how the conditional statement is executed. First, the condition
after the if keyword is checked. If the condition is true, the commands after
the condition are executed. If the condition is false, the commands in the
block after the else keyword are executed.
The else block is optional. It is allowed not to use it. The syntax of the
conditional statement, in that case, is as follows.
if(condition){
# commands
First, the condition is checked; if it is true, the commands after the condition
are executed. If the condition is false, then nothing happens, and the
instruction after the conditional statement starts to execute.
Note Curly braces can be omitted if the if block or else block consists of a
single command. However, the absence of curly braces reduces the
readability of the code and leads to errors.
if(condition):
# commands
else:
# commands
endif;
54
if(condition):
# commands
endif;
A small example that uses the conditional statement is shown in Listing 3-1.
the program checks whether the number can be divided by another known
number.
<?php
# Reads a number:
$number=(integer)trim(fgets(STDIN));
# The divider:
$A=3;
if($number%$A==0){
55
else{
?>
The result of the program execution is shown next (the number entered by
the user is marked in bold).
Details
56
<?php
// Reads a number:
$number=(int)trim(fgets(STDIN));
endif;
?>
When the program is run, the user is prompted to enter a prime number
between 1 and 5. If the user enters the number 2, 3, or 5, the message You
are correct! appears. If any other number is entered, the message You are
wrong! appears. The following shows what the program’s output looks like
if the user enters a prime number from the specified range (the entered value
is marked in bold).
57
if(condition){
# commands
elseif(condition){
# commands
elseif(condition){
# commands
else{
# commands
Two elseif blocks are used here, but in principle, you can use as many elseif
blocks as you like. Let’s discuss how the conditional statement is executed.
First, the condition after the if keyword is checked, and if the condition is
true, the corresponding block of commands is executed.
58
If the condition is false, the condition in the elseif block is checked. If that
condition is true, the commands from the corresponding elseif block are
executed. If the condition is false, the condition in the next elseif block is
checked, and so on. The commands in the else block are executed if all the
checked conditions are false. The else block is optional.
# commands
elseif(condition):
# commands
elseif(condition):
# commands
else:
# commands
endif;
Namely, curly braces are not used, a colon is placed at the beginning of the
blocks, and the entire structure ends with the endif keyword (followed by a
semicolon).
Finally, and this is the third case, if A = 0 and B ≠ 0, then the equation has no
solutions. All these cases are tracked using the conditional statement in the
program shown in Listing 3-3.
59
<?php
print("Solving the equation Ax=B\n");
print("A = ");
$A=(double)trim(fgets(STDIN));
print("B = ");
$B=(double)trim(fgets(STDIN));
if($A!=0){
$x=$B/$A;
print("x = ".$x);
elseif($B==0){
else{
?>
The user is prompted to enter the parameters of the equation, and after that,
the result is calculated. Much depends on what values are entered.
The following is the result of the program execution if the equation has a
single solution (the values entered by the user are marked in bold).
A = 5.0
B = 12.6
x = 2.52
60
The following is the result of the program execution when both parameters
are set to zero.
A=0
B=0
A=0
B=1
There are no solutions
In the program, the user enters the values for the $A and $B variables.
You use the instruction (double) to cast to the double type. The search for a
solution is performed using the conditional statement. First, the $A!=0
condition is checked (the value of the $A variable is not 0). If so, the
$x=$B/$A command calculates the value for the root of the equation, which
is displayed in the console.
If the $A!=0 condition is false (that is, the value of the $A variable is 0), the
$B==0 condition in the elseif block is checked. The truth of this condition
(considering the falsity of the $A!=0 condition) means that any number can
be a solution.
Finally, the equation has no solutions if the $B==0 condition is also false.
The else block of the conditional statement handles this situation.
61
The while loop statement has perhaps the simplest syntax of all loop
statements. It begins with the while keyword, after which some condition is
placed in parentheses, and then a block of commands in curly braces
follows. In general, it looks as follows.
while(condition){
# commands
Let’s discuss how the while loop statement is executed. First, the condition is
checked. If it is true, then the commands in the body of the loop statement
are executed. Then, the condition is rechecked. If the condition is true, the
commands are executed, and the condition is checked again? and so on. That
continues until the next test of the condition is false. If so, then the loop
statement terminates.
Note If the body of the loop statement contains a single command, then
curly braces can be omitted. But that is not a good practice.
There is another form of the while loop statement, in which curly braces are
not used, a colon is placed after the condition, and the operator ends with the
endwhile instruction (and a semicolon).
while(condition):
# commands
endwhile;
62
Listing 3-4 uses the while loop statement to calculate the sum of numbers.
<?php
$n=100;
$k=1;
while($k<=$n){
print("1+2+...+$n=$s");
?>
1+2+...+100=5050
The program uses three variables: the upper limit of the sum (the count of
terms) is saved to the $n variable, the value of the sum is saved to the $s
variable (the initial value of the variable is 0), and the value for the next term
is saved to the $k variable (the initial value is 1).
The loop statement checks the $k<=$n condition, which is true if the value
of the $k variable does not exceed the value of the $n variable. In the body
of the loop statement, the $s+=$k command adds a term to the 63
CHapTer 3 THe ConTrol STaTemenTS
sum. The $k++ command increments the value of $k by one. On the next
iteration, that is the new term for the sum.
After the loop statement is terminated, the $s variable contains the sum of
numbers from 1 to the value stored in the $n variable. This result is
displayed in the console.
<?php
$number=315;
$A=1;
$A++;
if($number%$A==0){
print(" ".$A);
endwhile;
print(" ".$number)
?>
64
1 3 5 7 9 15 21 35 45 63 105 315
The number for which the program calculates divisors is stored in the
$number variable (use the value 315). It also uses the $A variable, whose
initial value is 1. You need that variable to store the value of the next divisor
for the number saved to the $number variable. Finding divisors is simple:
iterate over the numbers in a particular range and check if it is a divisor. To
do that, you use the loop statement.
Note The value of the " ".$A expression is the text resulting from the
concatenation of the space " " and the value of the $A variable. The latter is
automatically converted to the text format.
The last print(" ".$number) instruction adds the number to the list of its
divisors. That is done without checks since any number can be divided by
itself.
65
The other loop statement is the do-while statement. The following is the
syntax for the statement.
do{
# commands
}while(condition);
Note The fundamental difference between the do-while statement and the
while statement is that in the while statement, the condition is checked first,
and then the commands are executed.
at the same time, in the do-while statement, the commands are executed first,
and then the condition is checked. When using the while statement, it may
turn out that the commands in the
statement’s body are not executed at all. That happens if the condition is
false the first time it is tested. If the do-while statement is used, then the
commands in the loop statement are executed at least once.
66
Note a number is called prime if it has no divisors but one and the number
itself.
<?php
// Reads a number:
$number=(int)trim(fgets(STDIN));
do{
if($number%$A==0){
break;
$A++;
}while($A<=sqrt($number));
// The result:
print($result);
?>
67
If the user enters a prime number (marked in bold), the program’s output is
as follows.
The output of the program (from Listing 3-6)
A number to check: 37
It is a prime number
A number to check: 91
The program runs as follows. First, the user enters a number to check.
That number is stored in the $number variable. The text "It is a prime
number" is saved to the $result variable, which is displayed in the console if
it turns out that the number entered by the user is prime.
The do-while loop statement uses the conditional statement that tests the
$number%$A==0 condition. The truth of the condition means that $number
is divisible without remainder by $A (whose initial value is 2). If so, the
$result="The number can be divided by $A" command assigns a new value
to the $result variable, after which the break statement is executed. It
terminates the execution of the loop statement.
68
CHapTer 3 THe ConTrol STaTemenTS
Details
If when searching the smallest (after 1) divisor for a certain number X, some
value A is found, that means the initial number can be presented as the
product X = A · B
and here A ≤ B. That is why A 2 ≤ X. This relation gives you the upper limit
for the range where you search for divisors.
If the loop statement is terminated not due to the break instruction but
because the $A<=sqrt($number) condition becomes false, then the $result
variable remains with its original value. If so, the print($result) command
prints a message stating that the number is prime. If the break statement
“works,” then the $result variable gets a new value, and the message in the
console states that the number being checked has a divisor.
Details
# commands
69
CHapTer 3 THe ConTrol STaTemenTS
Note Curly braces can be omitted if a command block in the statement body
consists of a single command. However, it is better to have them.
Let’s discuss how the for loop statement operates. At the very beginning, the
commands from the first block are executed. They are executed once and
only once. Then, the condition in the second block is checked. If the
condition is true, then the commands from the body of the loop statement
and the commands in the third block are executed. After that, the condition is
checked. If it is true, the commands in the body of the loop statement and the
commands in the third block are executed, and after that, the condition is
checked again. And so on. The execution of the loop statement is terminated
when the condition turns out to be false during the next test.
There is also an alternative way to call the for loop statement. It does not use
curly braces. Instead of them, you place a colon after the for-instruction
(before the command block in the statement body). And all that ends with
the endif instruction (and a semicolon).
# commands
endif;
70
As an example of using the for loop statement, let’s consider a program that
calculates the sum of odd natural numbers, as shown in Listing 3-7.
<?php
$n=100;
for($s=0,$k=1;$k<=$n;$k++){
$s+=2*$k-1;
print("1+3+...+".(2*$n-1)."=$s");
?>
1+3+...+199=10000
The program is simple. It uses the $n variable that determines the count of
terms in the sum. The sum itself is calculated using the for loop statement. In
the first block, the commands $s=0 (the initial value for the sum) and $k=1
(the first term) are executed. The $k<=$n condition is checked in the loop
statement. It is true as long as the value of the $k variable (the count of terms
already added to the sum) does not exceed the value of the $n variable (the
expected count of terms in the sum). The loop statement is executed while
the $k<=$n condition is true. The commands $s+=2*$k-1 (the next term is
added to the sum) and $k++ (the term for the next iteration) are performed
for each iteration.
71
Note Here, odd numbers can be calculated using the formula 2 k − 1, where
the k variable takes the values 1, 2, 3, and so on.
Listing 3-8 is an alternative form of the for loop statement using a program
in which the Fibonacci numbers are calculated.
Note In the Fibonacci sequence, the first two numbers are equal to one, and
each subsequent number is equal to the sum of the previous two.
<?php
// How many numbers to calculate:
$n=15;
$a=$b=1;
// Prints numbers:
print("$a $b");
72
for($k=3;$k<=$n;$k++):
$b=$a+$b;
$a=$b-$a;
print(" ".$b);
endfor;
?>
In the body of the loop statement, the $b=$a+$b and $a=$b-$a commands
calculate a new number in the sequence.
73
Details
let’s discuss how to calculate the numbers. Suppose that $a and $b contain
respectively the last but one and the last number in the Fibonacci sequence.
let’s formally denote the value of the $a variable as ∆ and the value of the $b
variable as
□. You need to do the "next step": the $b variable should contain the value
∆+□, and the $a variable should contain the value □.
after executing the $b=$a+$b command, $b contains the value ∆+□, and $a
contains the original value ∆. To write the value □ to the $a variable, you
need to execute the $a=$b-$a command.
After the next number in the sequence is calculated and saved to the $b
variable, the print(" ".$b) command displays it in the console.
Note It is worth mentioning that the distribution of commands in the blocks
of the for loop statement is somewhat
statement can be moved to the third block, and commands from the third
block can be moved to the main body of the loop statement as long as the
commands are executed in the same order.
Depending on the value of some expression, the switch statement allows you
to execute one or another block of commands. In some sense, this statement
resembles nested conditional statements. But while in a conditional
statement, a condition is checked (an expression with a value of the boolean
type or a value that can be cast to the boolean type), in a selection statement,
the value of an expression is checked, whose type may differ from the
boolean.
74
switch(expression){
case value:
# commands
break;
case value:
# commands
break;
default:
# commands
Each case block contains, after the case keyword, a control value. It is
followed by a colon and a block of commands, which usually ends with the
break instruction. In the default block, if it exists, the break instruction is not
used (it simply does not make any sense to use it there).
parentheses after the switch keyword is evaluated first. The value of that
expression is sequentially compared with the control values in the case
blocks until the first match.
Details
75
switch(expression):
case value:
# commands
break;
case value:
# commands
break;
default:
# commands
endswitch;
Here, the curly braces are not used: a colon is used instead of the opening
curly brace, and the endswitch statement (followed by a semicolon) is used
instead of the closing curly brace.
Listing 3-9 shows a program illustrating how the selection statement can be
used.
<?php
$athos="Athos";
$porthos="Porthos";
$aramis="Aramis";
print("A name from \"The Three Musketeers\": "); 76
$name=trim(fgets(STDIN));
switch($name){
case $athos:
break;
case $porthos:
break;
case $aramis:
break;
default:
?>
The program prompts the user to enter the name of one of the Three
Musketeers: Athos, Porthos, or Aramis.
The program "knows" the names "Athos", "Porthos", and "Aramis".
If the user enters one of these names, the program displays the name of the
Musketeer. If the name entered by the user is "not known" to the program,
then the message "Strange. Is this a fourth Musketeer?" is printed. The
following shows the program’s output if the user enters the name "Athos".
77
The following is the result for the case when the user enters the name
"Aramis".
Finally, if the program “doesn’t recognize” the name, the result is as follows.
The program uses the $athos, $porthos, and $aramis variables to store the
names of the Three Musketeers in them. The $name variable is assigned the
name entered by the user. The switch statement is used to find matches. The
expression to be tested is the value of the $name variable.
The $athos, $porthos, and $aramis variables are used as control values in the
case blocks.
Let’s discuss how the selection statement is executed. The value of the
$name variable is sequentially compared with the values of the $athos,
$porthos, and $aramis variables. As soon as a match is found, the commands
of the corresponding case block are executed. If there are no matches, then
the commands in the default block are executed.
78
Listing 3-10 illustrates how to use the selection statement in the alternative
form. In this program, the number the user enters is checked for divisibility
by 2 and 4.
<?php
$number=(int)trim(fgets(STDIN));
switch($number%4):
case 0:
print("The number can be divided by 4");
break;
case 2:
break;
default:
endswitch;
?>
If the user enters a number that can be divided by 4, the result is as follows.
79
Enter a number: 70
Finally, if the number the user enters is not divisible by 2, the program
produces the following result.
The output of the program (from Listing 3-10)
In this case, the integer entered by the user is stored in the $number variable.
The switch statement checks the value of the $number%4
The case blocks ended with the break instructions in the considered
examples. However, that is not required. There exist situations when the
same set of commands must be executed for several control values. The
program in Listing 3-11 shows how that could be done.
<?php
$day=trim(fgets(STDIN));
80
switch($day){
case "Monday":
case "Tuesday":
case "Wednesday":
case "Thursday":
case "Friday":
break;
case "Saturday":
case "Sunday":
print("It is a holiday");
break;
default:
?>
The result of the program execution can be as follows (the value entered by
the user is marked in bold).
It is a working day
It is a holiday
81
In the program, the user enters the name of a day of the week, and the
program determines whether it is a working day or a holiday. The critical
point is that for the values "Monday", "Tuesday", "Wednesday", "Thursday",
and "Friday", the same print("It is a working day") command must be
executed. To not duplicate the code five times, create four empty case blocks
(they do not contain commands), and only the last (out of five) case block
contains the necessary command and the break instruction. If, for example,
the user enters "Wednesday", the code from the case block with the control
value "Wednesday" is executed until the first break instruction. It turns out
that the same commands are executed for each of the five control values.
A similar tactic handles the "Saturday" and "Sunday" values. The commands
in the default block are executed if the user enters a value other than one of
the controls.
PHP has the goto instruction that can be used to jump to a particular position
in a program marked with a label. Frankly speaking, using the goto
instruction is usually considered not a very good programming style.
Nevertheless, such a possibility exists, and it is better to know about it.
So, you can place a label in a program. It is an identifier that determines the
transition point in the program. Declaring a label is simple.
You specify the name of the label followed by a colon. To jump to that place
in the program, you must call the goto statement followed by the label (that
determines the place in the program to jump to). Listing 3-12 shows 82
<?php
// Variables:
$number=10;
$k=1;
// A label:
start:
print($k." ");
$k++;
if($k<=$number){
goto start;
}
?>
1 2 3 4 5 6 7 8 9 10
display) and $k (the current number). The place in the program marked with
the start label begins with the print($k." ") command (prints the value of the
$k variable and a space). After that, the $k++ command increments $k by
one. Then, the program checks the $k<=$number condition in the
conditional statement. If it is true, goto start is executed. As a result, the
program’s execution continues from the place 83
marked with the label start. Namely, the commands print($k." ") and $k++
are executed, after which the condition in the conditional statement is
checked again, and so on. It looks like a loop statement. When
$k<=$number evaluates to false, the goto start instruction is ignored, and the
program is over (since there are no other commands).
$variable=match(expression){
value=>resulr,
value=>result,
value=>result,
...
$value=>result,
default=>result
};
At the very beginning of the statement, you place the match keyword
followed by the expression (in parentheses) whose value has to be checked.
The next block is enclosed in curly braces. As mentioned, the match
statement returns a result, so the whole expression is assigned to some
variable. At the end of the statement, you put a semicolon.
In the main body of the match statement, place blocks of the form
value=>result in curly braces. These elements are separated by commas.
84
The last one can be a block like default=>result with the default keyword,
but it is optional.
Let’s discuss how the match statement is executed. First, the value of the
expression in parentheses after the match keyword is evaluated. Then, that
value is sequentially compared (up to the first match) with the values
specified in the body of the match statement. If a match is found, the result
after the corresponding => arrow is returned. If no matches are found, the
result for the block with the default keyword is returned.
Details
The match selection statement must return a result. When executing the
statement, an error occurs if it turns out that none of the blocks work (no
matches are found, and there is no default block).
The comparisons are performed until the first match. If a match is found, the
remaining values are not checked.
If the result should be the same for several values of the tested expression,
then such values can be collected (separated by commas) within one block.
Let’s look at such a situation in more detail.
The program that uses the match selection statement is shown in Listing 3-
13.
<?php
for($num=1;$num<=10;$num++){
$res=match($num){
85
1=>"one",
9=>"nine",
default=>"a great number"
};
?>
[1] one
[9] nine
The program’s core is the for loop statement, in which the $num variable
runs through the range from 1 to 10 inclusively. For each iteration, the $res
variable is assigned a value, after which that value (along with the value of
the $num variable) is displayed by the echo "[$num] ",$res,"\n"
command.
86
Use the match selection statement to assign a value to the $res variable. It
checks the value of the $num variable. If the variable’s value is 1, the string
"one" is returned as a result (the 1=>"one" block). For the values 2, 3, 5, and
7 of the $num variable, the statement returns the result "a prime number"
(the 2,3,5,7=>"a prime number" block). If $num is 4, 6, or 8, the result is the
text "an even number" (the 4,6,8=>"an even number" block).
For the value 9, the result "nine" is returned (the 9=>"nine" block). In all
other cases, the result is the string "a great number". The default=>"a great
number" block is responsible for that result.
<?php
for($num=1;$num<=10;$num++){
$res=match(true){
($num<8)=>"just a number",
};
// Prints the result:
?>
87
This example is similar to the previous one, but significant changes were
made. The keyword true is specified as the expression to be checked.
The results of the $num<=3, $num<8, and $num>=5 expressions are
compared against that value. They are checked one by one until the first
match. In particular, it first checks if the value of the $num<=3 expression is
true. If so, then the result of the match statement is "a small number". If
there is no match, then the value of the $num<8 expression is checked if it is
true.
88
Details
The conditions $num<=3, $num<8, and $num>=5 are such that at least one
of them is true. Therefore, the selection statement returns a result for any
value of the $num variable.
It is also worth mentioning that for the values 5, 6, and 7 of the $num
variable, the $num<8 and $num>=5 conditions are true at the same time. But
the $num<8
Summary
else block.
is true.
89
are found.
a colon.
90
CHAPTER 4
Arrays
—She’s broken!
Arrays are usually used when there are many values, and creating a separate
variable for each is impossible. If so, a common name is used for the entire
set of values, and specific values (array elements) are identified using an
index or indexes. In the “classic” version, the indexes are integers.
In PHP, integers and strings can be used as indexes. In that case, the term key
may be used instead of index. An array with string keys is usually called an
associative array.
For example, the term list is sometimes used along with the term array.
Instead of the associative array, the term dictionary or table is used. Let’s
name all arrays (integer indexes and string keys) as arrays. A list is an array
with integer indexes. The index is interpreted as a particular case of an
integer key.
© Alex Vasilev 2024
91
ChApTer 4 ArrAys
An array in PHP can be created differently, and all methods are acceptable.
Let’s examine the main and simplest possibilities and other tricks for
creating and using arrays. You do that step by step as you solve problems.
So, you can create an array using the array() function. If that function is
called without arguments, an empty array is created. If you pass arguments
to the array() function, they determine the values of the array elements. If so,
element indexes are integers, and indexing begins from zero. Also, there are
other ways to create arrays. A small example that creates arrays is shown in
Listing 4-1.
<?php
// An empty array:
$A=array();
print("Array \$A:\n");
print_r($A);
$A[1]="Yellow";
$A[2]="Green";
print("Array \$A:\n");
print_r($A);
$B=array(100,200,300);
print("Array \$B:\n");
92
ChApTer 4 ArrAys
print_r($B);
print("\$B = [ ");
for($k=0;$k<count($B);$k++){
print($B[$k]." ");
print("]\n");
print("Array \$C:\n");
print_r($C);
?>
Array $A:
Array
Array $A:
Array
Array $B:
Array
(
93
ChApTer 4 ArrAys
Array $C:
Array
[1] => 2
The first array is created with the $A=array() statement. The array is empty,
and a reference to it is written to the $A variable. To check the contents of an
array, you use the print_r() function, whose argument is a variable that refers
to the array.
Details
After checking the array, you see that the array is indeed empty.
ChApTer 4 ArrAys
with the 1 index, and the "Green" element with the 2 index to the $A array.
Here, to refer to an element of an array, you specify the name of the array
followed by the index in square brackets. Having displayed the array’s
contents using the print_r() function, you ensure that the elements were
added to the array.
Details
If a value is assigned to the array element that does not exist, then the
element is added to the array. If you assign a value to an already existing
element, then that element changes its value. In this case, the array is empty.
By assigning values to the elements of the array, you add elements to the
array. Moreover, there was no need to create the array first. It was enough to
assign a value to an element of the array. The array is created automatically
in that case.
Note In addition to the count() function, you can use the sizeof() function to
determine the size of an array.
95
ChApTer 4 ArrAys
Another way to create an array is to list the values of the array elements in
square brackets. That is how the $C array is created. The $C=["First",2,3.3]
statement is used to create it. It is worth mentioning that the elements of that
array have values of different types. In PHP, that is an acceptable situation.
Indexes for the array elements are determined automatically (0, 1, and 2).
It may happen that you are not satisfied with the situation when the indexes
of the array elements are determined automatically, or you want to use non-
numeric values as indexes. If so, when creating an array, you pass
constructions of the form key=>value as arguments to the array() function or
list them in square brackets. Namely, you specify the key of the element and,
after the “arrow” =>, its value. In addition, as before, you can assign values
to the elements of an array. In that case, the array is automatically created,
and elements with the corresponding keys are added to it.
Note Once again, let’s go over the terminology. Arrays contain elements.
elements have a value and a key (or keys for multidimensional arrays). For
integer keys, the term indexes is also used.
<?php
$A["Red"]=100;
$A["Yellow"]=200;
$A["Green"]=300;
96
ChApTer 4 ArrAys
print("Array \$A:\n");
print_r($A);
print("Array \$B:\n");
print_r($B);
?>
Array $A:
Array
Array $B:
Array
97
ChApTer 4 ArrAys
)
Array $C:
Array
[X] => 0
has the "X" string key. The element with the value "Last" has no specified
key. In that case, the index is calculated automatically: one greater than the
highest integer index of the elements already included in the array.
Therefore, the element with the value "Last" gets the integer key 6.
98
ChApTer 4 ArrAys
Details
you can add a new element to an array with a command like array[]=value.
To remove an element from an array, you can use the unset() function,
passing the element to be removed as an argument to the function.
suppose multiple elements with matching indexes are specified in the array
description. In that case, the array has a single element with the
corresponding index, and its value is determined by the last of the values
specified for the element with that index.
You have examined a case where the index is used the for loop statement to
iterate array elements. The inconvenience of that approach is that the indexes
must form an ordered sequence. But that may not be the case.
foreach(array as key=>value){
# commands
First comes the array name, the as keyword, and then the key=>value
expression. The keys and values are realized by employing variables. The
body of the loop statement contains statements enclosed in curly braces.
The foreach loop statement is executed as follows. The elements are iterated
sequentially in the array specified in the foreach statement.
The commands in the body of the loop statement are executed for each 99
ChApTer 4 ArrAys
An alternative syntax uses a colon instead of the opening curly brace and the
endforeach keyword (and a semicolon) instead of the closing curly brace.
foreach(array as key=>value):
# commands
endforeach;
<?php
// An array:
$A=["X"=>100,"Y"=>200,"Z"=>300];
foreach($A as $k=>$v){
?>
ChApTer 4 ArrAys
Details
For the first loop, $k is set to "X", and $v is set to 100. For the second loop,
$k is set to "Y", and $v is set to 200. For the third loop, $k is set to "Z", and
$v is set to 300.
Another example of using the foreach statement (in its alternative form) is
shown in Listing 4-4.
<?php
// An array:
$A=[5=>100,"Two hundred",300];
print("Array \$A:\n");
print_r($A);
// Iterates over the elements in the array:
foreach($A as $k=>$v):
print("\$A[$k] = $v");
if(gettype($v)=="string"){
print(" - delete\n");
unset($A[$k]);
}else{
print(" - remain\n");
101
ChApTer 4 ArrAys
endforeach;
print("Array \$A:\n");
print_r($A);
?>
Array $A:
Array
Array $A:
Array
The program creates an array and then removes the elements with text values
from the array. The array is created by the $A=[5=>100,"Two hundred",300]
command. It has three elements. The value of the element with the 5 index is
100. The indexes of the other two elements are calculated automatically.
Thus, the index of the element with the value
"Two hundred" is 6, and the index of the element with the value 300 is 7.
102
ChApTer 4 ArrAys
The foreach loop statement is used to iterate over the elements of the $A
array. The key is stored in the $k variable, and the element’s value is stored
in the $v variable. For each cycle, the print("\$A[$k] = $v") command
displays the value of the array element. Then, the conditional statement
comes into play, in which the gettype($v)=="string"
condition is checked (the element’s value is of the string type). If so, the
print(" - remove\n") command displays a message about removing the
element, and then the element is removed from the array using the
unset($A[$k]) command.
The check shows that the element with the text value is removed from the
array.
Sometimes, you do not need to know and use the keys of the array elements.
That means that you are interested only in the values of the elements. If so, a
simplified syntax can be used in the foreach loop statement.
foreach(array as variable){
# commands
Here, a variable to store the keys is not specified, and the name of the
variable follows the as keyword that sequentially, cycle by cycle, takes the
values of the elements from the array placed before the as keyword. An
example of using the foreach loop statement in a simplified form is shown in
Listing 4-5.
103
ChApTer 4 ArrAys
OceanofPDF.com
Listing 4-5. Iterating over the Array’s Elements
<?php
# An array:
foreach($A as $v){
echo "]";
?>
Here, in the loop statement, the $v variable sequentially takes the values of
the $A array elements. The keys are not used.
It is worth mentioning that within the framework described, you can access
the value of an element in a read-only mode. You cannot assign a new value
to the element since the standard scheme for iterating over array elements
assumes that a copy of the element’s value is written to the corresponding
variable. By changing the value of the copy, you do not affect the element’s
value. Nevertheless, there exists an easy way to change the situation. To do
that, in the description of the foreach loop statement, before the name of the
variable proposed for storing the values of the array elements, you should
place the & symbol. If you do so, the specified variable refers to an array
element. In other words, you get access to the element’s value and the
element itself (and you can, if necessary, change its value).
104
ChApTer 4 ArrAys
Details
& symbol. For example, the $x=100 command creates the $x variable with
the value 100.
<?php
# An array:
$A=[100,200,300];
print_r($A);
foreach($A as $v):
$v++;
endforeach;
print_r($A);
foreach($A as &$v):
$v++;
endforeach;
print_r($A);
?>
105
ChApTer 4 ArrAys
Array
(
[0] => 100
Array
Array
The program creates an array and then, using the foreach loop statement,
iterates over the elements of the array and attempts to increase the value of
the array elements by one (the $v++ command in the body of the loop
statement). In the first case, you use an ordinary variable to access the
array’s elements; in the second case, you use a reference. As you can see, in
the first case, the values of the elements do not change; in the second case,
the value is increased by one for each array element.
106
ChApTer 4 ArrAys
Multidimensional Arrays
The elements of an array can be, among other things, arrays. And the
elements of these internal arrays can also be arrays, and so on. In that case,
multiple indexes or keys must be used to access an element of the internal
array: the first key allows access to the internal array, the second key allows
access to an element of that internal array, and the chain can continue. If so,
you usually speak of multidimensional arrays. But, in the respect that in
PHP, array elements can be of different types, this concept is rather vague.
You proceed from the fact that a multidimensional array is an array among
the elements of which there are arrays.
<?php
// A multidimensional array:
print_r($A);
echo "Array \$A:\n";
for($i=0;$i<count($A);$i++){
for($j=0;$j<count($A[$i]);$j++){
107
ChApTer 4 ArrAys
echo "\n";
// A multidimensional array:
print_r($B);
foreach($B as $k1=>$v1){
foreach($v1 as $k2=>$v2){
// Displays the value of the element:
?>
Array $A:
Array
[0] => 1
[1] => 2
[2] => 3
[3] => 4
[4] => 5
108
ChApTer 4 ArrAys
[1] => Array
[0] => A
[1] => B
[2] => C
[0] => 6
[1] => 7
[2] => 8
[3] => 9
Array $A:
12345
ABC
6789
Array $B:
Array
(
[X] => 2
[Y] => 3
[0] => D
[1] => E
109
ChApTer 4 ArrAys
[2] => F
Array $B:
$B[7][X] = 2
$B[7][Y] = 3
$B[9][0] = D
$B[9][1] = E
$B[9][2] = F
array. If you specify the second index, you get access to an element of the
internal array. For example, the $A[0][1] expression refers to the element
with the 1 index in the array, which is the element with the 0 index in the
$A array (the element value is 2). The $A[1][2] instruction refers to the
element with the 2 index in the array, which is the element with index 1 in
the $A array (the value of the element is "C").
You did not specify indexes for array elements, so they are determined
automatically. You can use that fact and enumerate the array elements
employing indexes. You do that in the nested for loop statements. In the
outer statement, the loop variable $i runs from 0 to count($A) (the count of
elements in the $A) array minus one. In the inner loop statement, the loop
variable $j runs from 0 to count($A[$i]) (the number of elements in the
inner array $A[$i]) minus one. With the given values of the $i and $j
variables, the echo $A[$i][$j]," " command is executed, which displays the
value of the element $A[$i][$j] (the element with the $j index in the array,
which is the element with the $i index in the $A) array and a space.
110
ChApTer 4 ArrAys
After the inner loop statement is terminated, the echo "\n" command breaks
the line (moves the caret to the new line in the output area).
Another multidimensional array is created by the $B=array(7=>
array("X"=>2,"Y"=>3),9=>array("D","E","F")) command. Here, you use
the array() function, and for some arrays (including the outer one), you
explicitly specify the key values. Nested foreach statements are used to
iterate over elements. The outer statement iterates over the contents of the
$B array. The key of an $B array element is written to the $k1 variable, and
the value of the element of the $B array is written to the $v1 variable. But
the $B array consists of arrays, so $v1 is an array. That array is reviewed in
the inner foreach loop statement. There, the key of the element in the
internal array is written to the $k2 variable, and the value of that element is
written to the $v2 variable. The echo "\$B[$k1][$k2]
= $v2\n" command displays the keys and the value of the element in the
internal array.
Array Assignments
The basic operations performed on array elements are reading the element’s
value and assigning a value to the element. If you need to know an array
element’s value, specify the array name and element index/key in square
brackets after the array name.
Note you can use curly braces instead of square brackets when referring to
array elements, but in php 8, such syntax raises an error.
111
ChApTer 4 ArrAys
If you want to change the value of an array element, you just assign a new
value to the element. As noted earlier, if the element to which a value is
assigned does not exist in the array, such an element is created. You also
know how to iterate over the elements of an array using the foreach loop
statement. All these have been discussed. However, that is not a complete
list of operations that can be performed with arrays. Next, let’s examine
some of the most relevant issues. Let’s start with array assignments.
<?php
$A=[1,[2,[3,4]]];
print("Array \$A:\n");
print_r($A);
// Assigns an array:
$B=$A;
print("Array \$B:\n");
print_r($B);
$A[0]="A";
$A[1][0]="B";
$A[1][1][0]="C";
print("Array \$A:\n");
print_r($A);
print("Array \$B:\n");
// Checks the contents of the array:
print_r($B);
?>
112
ChApTer 4 ArrAys
Next, with the $B=$A command, the $A array is assigned as a value to the
$B
variable. Then, you change the values of some array elements $A and check
how the $A and $B arrays have changed.
Details
changes the value of the $A array element with the 0; $A[1][0]="B" index
changes the value of the element with the 0 index in the array, which is the
element with the 1 index in the $A; $A[1][1][0]="C" array changes the
element with the 0 index in the array, which is the element with the 1 index
in the array, which is the element with the 1 index in the $A array.
Array $A:
Array
(
[0] => 1
[0] => 2
[0] => 3
[1] => 4
113
ChApTer 4 ArrAys
Array $B:
Array
[0] => 1
[0] => 2
[1] => Array
[0] => 3
[1] => 4
Array $A:
Array
[0] => A
[0] => B
[0] => C
[1] => 4
)
)
114
ChApTer 4 ArrAys
Array $B:
Array
[0] => 1
[0] => 2
[0] => 3
[1] => 4
Note such an obvious conclusion might seem strange and naive. however,
this situation may surprise those familiar with Java, C#, or python.
Concatenating Arrays
ChApTer 4 ArrAys
the value presented in the first operand (the value from the first array). The
situation is illustrated in Listing 4-9.
<?php
$A=["First"=>1,2,"Last"=>3];
$B=[100,200,"Last"=>300];
$C=$A+$B;
print_r($C);
?>
Array
[First] => 1
[0] => 2
[Last] => 3
ChApTer 4 ArrAys
the value 2, and in the $B array, that is, the element with the value 100).
As noted, the first array (the $A array) takes precedence in such situations.
Thus, in the $C array, the element with the 0 index has the value 2, and the
element with the "Last" key has the value 3.
Comparing Arrays
Two arrays are considered equal if they have the same set of elements,
including the keys of those elements and their values. But here, you should
consider the automatic type casting involved when comparing arrays.
Namely, if the == and != operators are used to compare arrays, then the
comparison is performed considering the automatic type conversion. If you
want to compare arrays without involving the automatic type casting, you
should use the ===
and !== operators. Here, only the values of the elements are considered.
The keys are compared for a match involving the automatic type casting in
any case. An example of how arrays are compared is shown in Listing 4-10.
<?php
$A=["0"=>123,1=>true,2=>""];
$B=["123",10,0];
$C=[0=>123,"1"=>true,"2"=>""]; $D=[0=>123,1=>true,3=>""];
if($A==$B){
echo '$A==$B',"\n";
if($A!==$B){
echo '$A!==$B',"\n";
117
ChApTer 4 ArrAys
if($A===$C){
echo '$A===$C',"\n";
if($A!=$D){
echo '$A!=$D',"\n";
?>
$A==$B
$A!==$B
$A===$C
$A!=$D
The PHP 8 Standard In php 8, the empty string "" is not equal to the
number 0. Therefore, in php 8, $A==$B is not true.
If the automatic type conversion is not involved, then the values of the
elements of the arrays $A and $B are different, so the $A!==$B expression
is true.
118
ChApTer 4 ArrAys
In the $C array, the values of the elements are the same as in the $A array.
Although the elements’ keys in the $C array are different from those in the
$A array, the keys are interpreted as the same due to the automatic type
casting. Therefore, the $A===$C condition is true. Finally, the $D
array is compared to the $A array, and only one of the keys differs. That is
enough for the $A!=$D condition to be true.
list(variables)=array
You pass variables as arguments to the function (and these variables may
have no values at all) and assign an array to that expression. The
consequences are as follows: the variable specified as the first argument of
the list() function is assigned the first element of the array, the second
variable in the argument list of the list() function is assigned the second
element of the array, and so on. Some arguments can be skipped, and the
count may not match the count of array elements. Examples of using the
list() function are shown in Listing 4-11.
<?php
// An array:
$A=[1,2,3,4,5];
list($x,,$y,$z)=$A;
// The result:
print("\$x = $x\n");
119
ChApTer 4 ArrAys
print("\$y = $y\n");
print("\$z = $z\n");
?>
$x = 1
$y = 3
$z = 4
There are also some other functions and utilities that can be useful when
handling arrays. For example, the array_keys() function returns an array
with the keys of the array passed as an argument to the function.
The array_pop() function removes the last element from the array, and the
array_push() function adds an element (or elements) to the end of the array.
The array_slice() function allows you to get a slice of an array (that is,
extract a subarray from the array). The first argument of the function is the
array to be sliced. The second argument is the index of the element from
which the slice is to be performed. If that argument is negative, then the
index is counted from the last element of the array 120
ChApTer 4 ArrAys
(-1 means the last element, -2 means the last but one element, and so on).
<?php
$K=range(3,5);
print("Array \$K:\n");
print_r($K);
print_r($A);
$B=array_keys($A);
print("Array \$B:\n");
print_r($B);
$C=array_combine($K,$B);
print("Array \$C:\n");
print_r($C);
array_pop($C);
print("Array \$C:\n");
print_r($C);
array_push($C,"A","B");
121
ChApTer 4 ArrAys
print("Array \$C:\n");
print_r($C);
// The fifth array:
$D=array_slice($C,0,3);
print("Array \$D:\n");
print_r($D);
$E=array_slice($C,-3,2);
print("Array \$E:\n");
print_r($E);
?>
Array $K:
Array
[0] => 3
[1] => 4
[2] => 5
Array $A:
Array
(
Array $B:
Array
122
ChApTer 4 ArrAys
[0] => X
[1] => Y
[2] => Z
Array $C:
Array
[3] => X
[4] => Y
[5] => Z
)
Array $C:
Array
[3] => X
[4] => Y
Array $C:
Array
[3] => X
[4] => Y
[5] => A
[6] => B
Array $D:
Array
[0] => X
[1] => Y
[2] => A
123
ChApTer 4 ArrAys
Array $E:
Array
[0] => Y
[1] => A
124
ChApTer 4 ArrAys
Summary
automatically.
multiple keys.
125
CHAPTER 5
Functions
Creating Functions
Very often in programs, you must execute many times the same sequence of
commands. It is convenient to write such commands as a separate block of
code and then, if necessary, simply put the instruction that means the
execution of the corresponding block of commands. In general terms, that
idea underlies the use of functions.
In other words, you form a block of commands, specify a name for that
block of commands, and every time you need the block of commands
executed, you just specify its name. As usual, you use commands to process
some values or data. If you are intended to process such values
127
Chapter 5 FunCtions
during the function call, the function should be called with an argument (or
arguments). Traditionally, function arguments are specified in parentheses
after the function name. If there are multiple arguments, they are separated
by commas.
function name(arguments){
// commands
}
arguments, and the function arguments are described as variable names (the
argument names begin with the $ symbol). When a function is called and
arguments are passed to it, the commands described in its body are
executed. In that case, in those places where the arguments are put in the
code, the actual values passed to the function are used.
128
Chapter 5 FunCtions
Details
Function names are not case-sensitive. in other words, whether the function
name is in uppercase or lowercase letters doesn’t matter. For example, if
you have the show() function, then that is the same as the SHOW() or
Show() function.
<?php
function show($argument){
echo "Calling the function show()\n";
show(123);
Show(2.5);
?>
129
Chapter 5 FunCtions
The straightforward show() function has been described. It has only one
argument, which is named $argument. That means that when you call the
function, you should put some value (the function argument) in parentheses
after the function name.
You should refer to the code in the function’s body to understand what
happens when a function is called. In this case, there are only three
commands, each using the echo statement. So, three messages appear in the
output window whenever you call the function. The first message states that
the show() function has been called. The second message contains
information about the type of argument passed to the function. To determine
the type of the argument, the gettype($argument) instruction is used to
explicitly refer to the $argument argument.
130
Chapter 5 FunCtions
Note When the function is described, the type of the argument and its value
are not known. those circumstances “reveal”
when the function is called. now, you can simply describe what needs to be
done with the function argument.
$argument argument.
Note after the last message, a line break is performed twice using two \n
instructions. that is purely for aesthetic purposes so that message blocks
displayed due to different function calls are separated by a blank line.
After the function is declared, you call it with three different arguments (an
integer, a string, and a real number). To illustrate the case-insensitivity of
the function name, you specify each time the function name using a
different combination of uppercase and lowercase letters. In particular, you
write the name of the function in small letters (the show(123) command), in
capital letters (the SHOW("We learn PHP") command), and also indicate
the first capital letter in the function name (the Show(2.5) command). In all
three cases, the same show() function is called.
131
Chapter 5 FunCtions
A function can return a result. The result of a function is the value that
remains “for memory” after the function has completed its execution. If a
function returns a result, the instruction by which the function is called has
a value, which is the result of the function. Therefore, you can, for example,
assign a function call instruction to a variable or use it as an operand in a
complex statement. To understand the result of an expression containing
function call instructions, you should replace those instructions with the
values returned by the corresponding functions in the expression.
To show in the function description that the function returns a result, you
use the return instruction followed by the value the function returns.
Details
if a function does not return a result, then the return statement can be used
to terminate the execution of such a function without specifying a return
value.
Listing 5-2 shows a program in which you use several functions that return
a result.
132
Chapter 5 FunCtions
<?php
function factorial($n){
$s=1;
for($k=2;$k<=$n;$k++){
$s*=$k;
return $s;
function power($x,$n){
$s=1;
for($k=1;$k<=$n;$k++){
$s*=$x;
return $s;
function test($number){
if($number%2==0){
return "even";
}else{
return "odd";
}
// Variables:
$z=2;
$num=10;
133
Chapter 5 FunCtions
$res=power($z,$num);
?>
10! = 3628800
The number 10 is even
You use the local variable $s with the initial value 1 in the function’s body.
Then, a loop statement is executed. There, the $k variable gets values from
2 to $n inclusively. For each loop, the $s*=$k command is executed.
According to the command, the current value of the $s 134
Chapter 5 FunCtions
Details
the variables in the body of a function are called local variables. they are
the first assigned values in the function’s body. Local variables exist while
the function code is executed and are available only in the function’s body.
two important conclusions follow from that. First, it makes sense to refer to
a local variable only in the function body. second, you can use local
variables with the same names in different functions; these are different
variables since they have different scopes.
the arguments specified in the function declaration have the “power” of
local variables. they are available only in the function’s body. if you specify
the same names for the arguments in the description of different functions,
they are different variables independent of each other.
Note even though the name of the second argument $n of the power()
function is the same as the name of the argument of the factorial() function,
there is nothing in common between
these arguments. the same remark applies to the local variable $s used in the
body of the power() function.
135
Chapter 5 FunCtions
In the power() function, the local variable $s is initialized with the initial
value 1. After that, the $s*=$x command is executed in the loop statement,
which multiplies the current value of the $s variable by the first argument
$x of the power() function. The number of cycles is determined by the
second argument $n. As a result, the $s variable contains the value of $x in
the power $n. The return $s statement returns the result of the function.
string as a result, and if the number is odd, the "odd" string is the result of
the function.
The core of the function code is a conditional statement, which checks the
$number%2==0 condition (the remainder of dividing the $number
argument by 2 is 0). If the condition is true, then the result is returned by the
return "even" command. Otherwise, the result is returned by return "odd".
You use two variables to test how the functions operate: $z with the value 2
and $num with the value 10. Using the $res=power($z,$num) command,
you call the power() function with arguments $z and $num, and you store
the result, returned by the function, to the $res variable. That is the value of
the $z variable in the power determined by the $num variable.
The factorial of the number saved in the $num variable is calculated by the
factorial($num) instruction.
136
Chapter 5 FunCtions
Details
Because of that, functions do not have to be declared before they are called.
in other words, you can first place a function call instruction in a program
and only after that describe the function. however, such a style should not
be overused, especially in the practical use of php codes, since that can
increase the probability of error raising.
The Type of Arguments and Result
Note the fact that the type of the arguments or the type of the result is not
explicitly specified is not always a disadvantage; rather, it is on the
contrary. there are often situations when you need to create a function
whose argument could be values of different types. But there are also
opposite situations when you must pass a value of a strictly defined type to
a function. it all depends on the specifics of the problem being solved.
137
Chapter 5 FunCtions
Of course, you can add some code to the function to check the passed
arguments’ type. But that is not always convenient. Fortunately, there is an
easier way to “restrict” the range of allowed types for arguments. Namely,
you can explicitly specify the type of the arguments and the result of the
function in the function description. That could be done quite simply. For
arguments, the type is specified before the argument name in the function
description, and the function result type is specified, separated by a colon,
after the closing parenthesis. The function description template, in that case,
is as follows.
// commands
An error arises with such a function description if you call it and pass an
argument of a different type than the one specified in the function
description.
Details
php has a system for catching and handling exceptions (errors) of various
types.
that system allows you to create programs that operate efficiently even if
errors arise. Catching exceptions is discussed later.
Listing 5-3 uses functions with explicit type specifications for their
arguments and results.
<?php
# declare(strict_types=1);
138
Chapter 5 FunCtions
// is specified explicitly:
for($s=1,$k=1;$k<=$n;$s*=$x,$k++);
}
// Calls the function:
echo power(3,4);
echo power(1.5,2.7);
echo power("2","10.1");
?>
There are only two commands in the body of the function. The first one is a
call of the for loop statement. In the first block of that statement, the $s=1
and $k=1 commands are executed, which set the $s and $k variables to the
initial value 1. The loop statement is executed while the $k<=$n condition
is true. Two commands, $s*=$x and $k++, are executed for each loop. Both
commands are placed in the third block of the loop statement, so the body
of the loop statement is empty (there are no commands at all).
You end the instruction that calls the loop statement with a semicolon since
the command following the loop statement does not belong to it.
139
Chapter 5 FunCtions
The result of the function is returned by the "The number $x in the power
$n: ".$s."\n" statement. Thus, the result is a string formed by combining
string fragments and contains information about the results of calculations.
You test the created function using the echo power(3,4), echo
power(1.5,2.7), and echo power("2","10.1") commands. It may seem
strange, but all three commands run without errors, although the type of the
arguments passed to the power() function does not match the declared one.
The reason is that the automatic type casting comes into play by default.
For example, the second argument must be of the integer type. If a real
number is passed as the second argument, then the fractional part is
automatically discarded in that real number. If you pass a string with a
number “hidden” in it as an argument, then such a string is converted to the
number format, and so on.
If unsatisfied with such code execution, you can switch to the hard typing
mode. To do that, the declare(strict_types=1) statement should be added to
the program.
corresponding line.
140
Chapter 5 FunCtions
If so, only the first of the three instructions to test the power() function
operates correctly. Attempting to execute the other two cause an error.
Details
in php 8, the ability to define type unions is introduced. in that case, the
types are listed with the vertical bar | as a separator. For example, the
int|string|double expression means that the
also, php 8 introduces the mixed type, the broadest possible union of types.
<?php
function swap($a,$b){
141
Chapter 5 FunCtions
$x=$a;
$a=$b;
$b=$x;
// Variables:
$A=100;
$B=200;
swap($A,$B);
?>
You create the swap() function in the program with two arguments.
142
Chapter 5 FunCtions
Two variables are used, $A and $B, with the values 100 and 200
respectively. First, check the values of these variables. Then, you pass the
variables to the swap() function as arguments (the swap($A,$B) command).
Next, check the values of the variables again.
What is the program’s output? As you can see, the $A and $B variables do
not change their values. Nevertheless, the second check of the arguments in
the body of the swap() function shows that the values of the arguments are
switched. What does all that mean, and how do you understand the
situation? Indeed, everything is quite simple. You should consider that when
passing arguments to a function, the function gets copies of the variable
passed to the function as the arguments. In other words, when executing the
swap($A,$B) command, it is not the $A and $B
variables that are passed to the swap() function but their copies. So, the
copies of the variables swap values when executing the code of the swap()
function. When the function execution is over, the copies of the arguments
are removed from memory, and the $A and $B variables remain with their
previous values. Such a mechanism of passing arguments to functions is the
default one called passing arguments by value. Besides passing arguments
by value, arguments can be passed by reference. In that case, not copies of
the arguments but “originals” are passed to the function. If you want to pass
arguments by reference, you should put the & instruction before the
argument name in the function declaration. A modification of the previous
program, but this time with passing the arguments to the swap() function by
reference, is shown in Listing 5-5.
<?php
function swap(&$a,&$b){
$x=$a;
$a=$b;
143
Chapter 5 FunCtions
$b=$x;
$A=100;
$B=200;
echo "\$A = $A and \$B = $B\n";
swap($A,$B);
?>
You see that the values of the $A and $B variables have changed after these
variables were passed to the swap() function.
Note the mechanism of the argument’s passing is essential if you change the
values of the function arguments during the function’s execution. if the
argument values are not going to be changed, then the default mechanism of
passing the arguments by value is perfectly acceptable.
144
Chapter 5 FunCtions
To set a default value for an argument, you put the assignment operator and
that default value after the argument name in the function declaration. The
arguments with default values must be placed at the end of the arguments
list in the function declaration.
Note in other words, arguments without default values are described first,
followed by those with default values.
Listing 5-6 is a program with functions whose arguments (some or all) have
values by default.
<?php
function show($first="Alpha",$second="Bravo"){
function display($x,$y=200,$z=300){
145
Chapter 5 FunCtions
show(); # No arguments
?>
146
Chapter 5 FunCtions
The program uses two functions: show() with two arguments and display()
with three arguments. Both arguments of the show() function have values
by default. The last two arguments have default values in the display()
function. You call these functions and pass them a different count of
arguments each time.
When the show() command is executed, the default values are used for both
arguments to the show() function. In other words, the command is executed
as if the first argument were "Alpha" and if the second argument were
"Bravo".
The show("A") command means that the value "A" is used for the first
argument, and the default value "Bravo" is used for the second argument.
Finally, the show("A","B") statement means that the value "A" is passed as
the first argument, and the value "B" is passed as the second argument to
the function.
A similar situation takes place for the display() function. The only
difference is that since there is no default value for the first argument, the
first argument must always be specified. So, when you run the display(100)
command, the values of the arguments are 100, 200, and 300, respectively.
The display(1,2) command means that the first argument’s value is 1, the
second argument is 2, and the third is the default value 300. When
executing the display(1,2,3) command, all function arguments are explicitly
specified and have the values 1, 2, and 3.
The peculiarity of PHP is that you can pass more arguments than specified
in the function declaration without any tragic consequences when calling a
function. For example, if a function is described with two arguments, and
when you call the function, you pass five arguments, then the last three
arguments are ignored.
147
Chapter 5 FunCtions
Note You are dealing with default values for function arguments. that
makes it possible to specify a different number of arguments when calling a
function (less than indicated in the function description). But in that case,
the number of processed arguments is limited to those specified in the
function description. Contrary to that, you want all arguments to be
processed, no matter how many you pass to the function when called.
148
Chapter 5 FunCtions
Details
the first of these functions returns the count of passed arguments (meaning
the arguments of the function in whose body func_num_args() is called).
the second one returns the value of the argument (of the function in which
the func_get_
arg() function).
Listing 5-7 is a program that uses functions that accept an arbitrary number
of arguments.
Listing 5-7. An Arbitrary Number of Arguments
<?php
function sum(){
$s=0;
foreach(func_get_args() as $a){
$s+=$a;
return $s;
function count_type($type){
$num=func_num_args();
$count=0;
149
Chapter 5 FunCtions
if($num==1){
return;
for($k=1;$k<$num;$k++){
if(gettype(func_get_arg($k))==$type){
$count++;
count_type("integer",2,8,"12",3.5,2,"hello"); count_type("integer");
count_type("string",2,8,"12",3.5,2,"hello");
?>
150
Chapter 5 FunCtions
Arguments at all: 7
Arguments at all: 1
Two functions are declared in the program. The sum() function is declared
without arguments, while the count_type() function has one argument. But
in fact, the code of the functions provides the processing of all arguments
passed to the functions.
Note the
The sum() function calculates the sum of the arguments passed to the
function when called. To store the sum’s value in the function’s body, you
use the $s variable with the initial zero value. The iteration of arguments is
performed in the foreach loop statement. The func_get_args() expression is
specified as the array to iterate over it. Since the func_get_
args() function returns a list with the arguments passed to the function (in
this case, sum()), it is these values that are iterated over. The $a variable is
used to store the arguments. For each loop, the $s+=$a command 151
Chapter 5 FunCtions
increments the current value of the $s variable by the value of $a, so after
terminating the loop statement, the sum of the arguments of the sum()
function is written to the $s variable. The return $s command returns that
number as the result of the function.
Details
if you call the sum() function with no arguments, the result is zero. that is
the initial value of the $s variable, which does not change during the
execution of the function code.
The count_type() function does not return a result but only displays
messages. They contain information about how many arguments were
passed to the function in total and the count of arguments of a specific type.
The type is determined as a string by the first argument $type of the
function (for example, "integer" or "string").
Before starting the count, you use the conditional statement to check the
$num==1 condition. The true condition means that only one argument is
passed to the function, which, following the assumptions, determines the
type of the arguments, and there are no other arguments. If so, then echo
"The search is over\n" displays a message, and then the function is
terminated due to the return instruction.
If there are more arguments than one, the return statement is not executed,
and the for loop statement comes into play. There, the $k variable takes the
values from 1 and strictly less than $num. Here, you iterate over all but the
first argument: ignore the first one because it is unique.
152
Chapter 5 FunCtions
The gettype() function returns a string with the type name for the value
passed as an argument to the gettype() function. In this case, the
func_get_arg($k) expression is passed as an argument. It gives the value of
the count_type() function argument with the $k index. If the type of that
argument matches the type specified in $type, then the $count++
command increments the $count variable by one. After the loop statement is
terminated, the $count variable contains the count of arguments of the given
type passed to the count_type() function.
Note the
After creating the functions, you check how they operate. Thus, the
sum(5,9,6) expression gives the sum of the numbers 5, 9, and 6. When the
function sum() is called without arguments, the result is 0. The value of the
sum(1,3,5,7,9) expression is the sum of the numbers 1, 3, 5, 7, and 9.
Chapter 5 FunCtions
The code is shown in Listing 5-8 (the comments are removed to keep the
code short).
<?php
function sum(...$nums){
$s=0;
foreach($nums as $a){
$s+=$a;
return $s;
function count_type($type,...$args){
$num=sizeof($args)+1;
$count=0;
return;
154
Chapter 5 FunCtions
for($k=0;$k<sizeof($args);$k++){
if(gettype($args[$k])==$type){
$count++;
count_type("string",2,8,"12",3.5,2,"hello");
?>
The program’s result is the same as in the previous case. The main part of
the code has not changed either. But there are still some innovations, and
they are important ones. Let’s analyze them.
instruction. The ellipsis before $nums means that it "hides" a set of values,
which can be identified with an array of the function arguments. That
"array" is what you use in the foreach loop statement when iterating over
the arguments.
The count_type() function is declared with two arguments. The first $type
argument has the same meaning as in the previous example.
155
Chapter 5 FunCtions
The initial value of the $k variable in the for loop statement is now 0
instead of 1 as it used to be. It is taken into account here that the first
argument $type is not included in the “array” $args, and the indexes of all
elements from $args must be handled.
Recursion
There is a method of defining functions that deserves special attention. It is
about recursion. In that case, the function is declared to call itself. That can
be achieved by placing a command that calls the same function (usually
with a different argument) in the function’s body. Listing 5-9 is a program
in which several functions are defined using recursion.
<?php
function factorial($n){
if($n==0) return 1;
function sum($n){
if($n==0) return 0;
156
Chapter 5 FunCtions
// A number in a power:
function power($x,$n){
if($n==0) return 1;
else return $x*power($x,$n-1);
// Variables:
$x=2;
$n=5;
?>
5! = 120
1+2+...+5 = 15
The program uses recursion to define functions for calculating the factorial
of a number, the sum of natural numbers, and for raising a number to a
power.
157
Chapter 5 FunCtions
Details
in this case, consider that the factorial of some number n is the product of
the number n and the factorial of the number ( n − 1), that is, n ! = n · ( n −
1)!.
What happens when the function is called? If the function is called with a
zero argument, the result is 1. Let’s say the argument is non-zero; for
example, 5. Then the result is calculated as the product of the number 5, and
the result of the function call with argument 4. When the function is called
with argument 4, the product of the number 4 and the result of the function
call with argument 3 is calculated. When the function is called with
argument 3, the product of the number 3 and the result of calling the
function with argument 2 is calculated, and so on. The chain of calls ends
when the function is called with argument 0. After that, everything is
“rolled up”: the values of expressions are sequentially evaluated until the
result of calling the function with argument 5 is received.
Note For the sake of clarity and compactness of the code, curly braces were
not used in the conditional statement, although that is not very good
practice.
The function for calculating the sum of numbers sum() also has one
argument $n, and when calculating the result, the $n==0 condition in the
conditional statement is checked. If the condition is true, the result is zero
(the sum of zero terms is assumed to be zero). If the condition is false, the
result is calculated by the $n+sum($n-1) expression.
Details
the sum of the numbers from 1 to n can be thought of as the sum of the
number n and the sum of the numbers from 1 to ( n − 1).
158
Chapter 5 FunCtions
Details
In PHP, there are many features worthy to be noted. However, let’s focus on
the eval() function (more precisely, a syntax construction). It allows you to
evaluate the expression passed to it as a string argument. For example, if
you pass the '$number=2*3+4;' string as an argument to the eval() function,
10 is written to the $number variable. That result is obtained by evaluating
the 2*3+4 expression.
159
Chapter 5 FunCtions
Details
First, the commands with the eval() syntax construction are very dangerous
—so much so that the corresponding codes can be blocked by antivirus
programs (in that case, you need to “ask” the antivirus to make an
exception). the reason for the potential danger is that eval() allows you to
execute previously unknown code, which can affect the vulnerability of the
entire system. therefore, the eval() construction should not be overused.
second, it matters in which quotes (single or double) you pass the string to
eval(). the string must contain a valid php instruction (including the
semicolon at the end of the command). You should also remember that their
values are substituted in double quotes instead of variable names. therefore,
for example, an alternative to the eval('$number=2*3+4;') command is the
eval("\$number=2*3+4;") command. in the latter case, the \$ instruction is
used to include the $ character in the string. the result is the same in both
cases.
<?php
$first='$A=2*3+4;';
$second="\$B=2*\$A-5;";
// Calls eval():
eval($first);
eval($second);
eval(trim(fgets(STDIN)));
?>
160
Chapter 5 FunCtions
The result of the program’s execution could look as follows (the user input
is marked in bold).
$x = 25
Details
that is, the $A=2*3+4 and $B=2*$A-5 commands are indeed executed, as a
result of which $A is set to 10 and $B is set to 15.
Then, the expression entered by the user is read and passed as an argument
to eval() (the eval(trim(fgets(STDIN))) command). The user must enter a
command assigning a value to the $x variable. That command is executed
because the corresponding text is passed as an argument to eval(). After
that, the value of the $x variable is checked using the echo
Details
the preceding is the program’s output when the user enters the $x=$A+$B;
expression. the expression is read (subject to the transformations due to the
trim() function) as the text '$x=$A+$B;' and is passed as an argument to
eval(). as a result, the $x=$A+$B command is executed, and the $x variable
is set to 25.
161
Chapter 5 FunCtions
Anonymous Functions
Details
$variable=function(arguments){
# commands
};
<?php
$A=function($n){
for($s=0,$k=1;$k<=$n;$k++){
$s+=$k*$k;
162
Chapter 5 FunCtions
return $s;
};
// Variables:
$n=4;
$x=5;
$y=10;
$B=$A;
$A=function($x,$y){
return $x+$y;
};
?>
$A(4) -> 30
$B(4) -> 30
$A(5,10) -> 15
163
Chapter 5 FunCtions
function($n){
for($s=0,$k=1;$k<=$n;$k++){
$s+=$k*$k;
return $s;
variable also “becomes a function” and is the same as $A. The $A variable
is then assigned a new anonymous function, defined as follows.
function($x,$y){
return $x+$y;
This time, it is a function with two arguments and returns the sum of the
arguments. Therefore, the value of the $A($x,$y) expression (with the
values 5 and 10 for the $x and $y variables, respectively) is 15.
Named Arguments
When calling a function, you pass the arguments in the same order in which
they were specified in the function declaration. That way of passing
arguments is called positional one, or passing arguments by position.
164
Chapter 5 FunCtions
However, PHP 8 introduced the ability to pass arguments by name. In that
case, when the function is called, the arguments (all or some) are defined by
a name and a value. The function itself is described as usual.
Details
<?php
function show($first,$second,$third){
echo "--------------------\n";
165
Chapter 5 FunCtions
show(100,200,300);
show(second:200,third:300,first:100);
show(100,third:300,second:200);
?>
--------------------
--------------------
--------------------
In this case, an ordinary function show() with three arguments named $first,
$second, and $third is described. When you call the function, it displays the
values of the arguments passed to it.
You can call the function in the usual way, using positional argument
passing. For example, the show(100,200,300) command means that the
value 100 is passed as the $first argument, the value 200 is passed as the
$second argument, and the value 300 is passed as the $third argument.
166
Chapter 5 FunCtions
You can use the mixed argument passing scheme when some
Details
note that a default argument value is used if that argument is not explicitly
specified when the function is called. in a function declaration, the default
value is specified after the argument name through the assignment operator.
An example where function arguments have default values and are passed
by name is shown in Listing 5-13.
167
Chapter 5 FunCtions
<?php
function show($first=1,$second=2,$third=3){
echo "--------------------\n";
show(100,third:300);
show(second:200);
?>
--------------------
--------------------
Now, for the show() function, the $first, $second, and $third arguments
have the default values 1, 2, and 3 respectively. Therefore, when you call
the function with the show(100,third:300) command, the $first argument is
set to 100, the $second argument uses the default value 2, and the $third
argument is set to 300.
168
Chapter 5 FunCtions
Summary
reference symbol.
169
Chapter 5 FunCtions
an array.
argument).
were a function.
170
CHAPTER 6
Useful Tricks
and Operations
This chapter discusses topics that are essential and useful in everyday
practice.
References
If the value of a variable is assigned to another variable, then you get a copy
of the assigned variable. For example, if $B=$A is executed, the value of
$A becomes the value of $B. The important thing here is that if the value of
$A is subsequently changed, then the value of $B does not change. But
another situation is also possible when two variables refer to the same
value. In that case, you deal with a reference. A reference is, in fact, an alias
for a variable, an alternative way to refer to the corresponding value.
Note It turns out that there is one value and two variables.
171
To create a reference to a variable, you must place the symbol & after the
assignment operator in the assignment statement. Thus, the $R=&$A
command creates a reference $R to the $A variable. By changing the value
of the $A variable, you change the value of the $R reference, and vice versa
—changing the value of the $R reference means changing the value of the
$A variable.
Details
<?php
$A=100;
$B=$A;
// A reference to the variable:
$R=&$A;
172
$A=200;
unset($A);
$R=&$B;
$R=300;
?>
$A = 100
173
ChapTer 6 UsefUl TrICks and OperaTIOns
$B = 100
$R = 100
$A = 200
$B = 100
$R = 200
$B = 100
$R = 200
$B = 100
$R = 100
$B = 300
$R = 300
The program is simple. First, $A=100 sets $A to 100, and $B=$A sets $B
to the same value (the value of $A). But the $R=&$A command creates the
$R reference to the $A variable. The difference between the $B variable and
the $R reference becomes obvious after executing the $A=200 instruction,
which assigns a new value to the $A variable. At the same time, the value of
the $B variable does not change, and when checking the value of the $R
reference, you get the value 200.
In the next step, you use the unset($A) command to remove the $A variable.
That does not affect the value of the $R reference, and it still refers to the
same value as before the variable was deleted.
After executing the $R=&$B command, you “link” the reference to the $B
variable. More precisely, after executing that command, the $R
reference is associated with the same memory area as the $B variable. So,
after executing the $R=300 command, $B is set to 300.
174
References like this one are called hard references. In addition to hard
references, there are also soft references. That is a more general mechanism
for accessing variables. Let’s begin with the brief example shown in Listing
6-2.
<?php
$number=123;
// of another variable:
$reference="number";
$A="Alpha";
$$A=100;
$Alpha=200;
$A='Bravo';
$$A=300;
?>
175
$$reference = 123
$number = 321
$Alpha = 100
$$A = 200
$Alpha = 200
$Bravo = 300
Using the method described, you can get a reference to a variable that does
not yet exist. The $A="Alpha" command writes the text "Alpha" to the $A
variable. Therefore, when the $$A=100 command is executed, the $Alpha
variable is assigned the value 100, and thus such a variable appears in the
program.
176
Constants
The function’s first argument is a string with the constant’s name. The
second argument specifies the value of the constant. The $ symbol is not
used at the beginning of the constant name. Following the generally
accepted convention, the names of constants consist of capital letters (that
is, this is not necessary, but good manners oblige). For example, the
define("PI",3.141592) command defines the constant PI with the value
3.141592. After executing that command, the value of the constant PI
cannot be changed.
<?php
define("PI",3.141592);
// Using constants:
// Declares constants:
const ONE=1;
const TWO=2;
const THREE=ONE+TWO;
?>
sin(PI/6) = 0.49999990566244
ONE = 1
TWO = 2
THREE = 3
178
Note In php, there exists the built-in pi() function, which, when called,
returns the value of the “pi” number.
Three more constants are created using the const ONE=1, const TWO=2,
and const THREE=ONE+TWO commands. In the latter case, the value of
the THREE constant is calculated as the sum of the ONE and TWO
constants.
Details
In php, some built-in constants allow us to get important information about
the working document and program components. for example, using the
__LINE__
constant, you can get the current line number in the file. The __FILE__
constant allows you to get the name of the file, the value of the __DIR__
constant is the name of the directory in which the file is located, and the
name of the function (in which the constant is requested) can be obtained
using the __FUNCTION__
constant. The names of all these (and some other) constants begin and end
with a double underscore.
Global Variables
Earlier, you dealt with functions and used local variables in them. Local
variables are created in the body of a function (by assigning a value to the
variable) and exist while the function is operating. After executing the
function, the local variables are removed from memory. The next time the
function is called, local variables are created again, and everything repeats.
179
<?php
function show(){
$A=100;
echo "The local variable \$A = ",$A,"\n";
$A=200;
show();
?>
You use the show() function, which creates a local variable $A with the
value 100 in its body and displays the variable’s value in the output
window. Before calling the function, you use the $A=200 command to
create the $A global variable with the value 200. When the show() function
is called, the value 100 is displayed, while the value of the global variable
does not change. The explanation is simple: the variable created when the
show() function is called has nothing to do with the $A global variable.
<?php
// The function:
function show(){
global $A;
$A=200;
$A=100;
show();
?>
181
In the function’s body, the global $A command declares that the $A variable
is global. Next, the variable’s value is displayed, the value 200 is assigned
to it, and then the value is checked again.
In the program, the $A variable is assigned the value 100. Then, you call the
show() function and, after calling it, check the value of the $A variable.
Details
a built-in $GLOBALS array contains all global variables available in the
program. The array is accessible anywhere in the program and does not
need to be declared in any way.
Static Variables
182
<?php
function calc(){
static $value=0;
$value+=100;
return $value;
for($k=1;$k<=5;$k++){
?>
Briefly, everything is simple. You have the calc() function that is called with
no arguments. The first time the function is called, the result is 100. The
second time the function is called, the result is 200. The third time, the
function returns 300, and so on. Thus, you use the same instruction but get a
new (predicted) result each time. To understand why that happens, let’s
analyze the code of the calc() function.
183
In the function’s body, the static $value=0 command creates the static
variable $value with the value 0. Then, with the $value+=100
command, that value is incremented by 100 and returned as the result of the
function.
Let’s see what happens when the function is called for the first time.
It’s simple: the $value variable is created, it gets the value 100 after all, and
the function returns the result. That completes the execution of the function.
If the $value variable were normal (not a static one), then it would be
removed from memory, and the next time the function is called, everything
would start with creating the new variable $value. But the variable is static.
Therefore, the variable is not deleted from memory after the function is
terminated.
Moreover, the next time the calc() function is called, it is the variable that is
used, and with the value that the variable had at the last function call. That
value is incremented by 100 and returned as the result. It turns out that each
time the calc() function is called, the value of the $value variable is
increased by 100. Therefore, the function returns a new value each time.
Details
The command that initializes the static variable $value with the zero value
is executed only once, the first time the function is called. It is also worth
mentioning that the $value variable (despite being static) is available only
in the function’s body.
Multiline Strings
From a practical point of view, strings are very important when using PHP.
And often, you must deal with multiline strings. There are several ways to
create them.
184
<?php
// A variable:
$word="wind";
// A multiline string:
$text=<<<MYTEXT
MYTEXT;
echo $text;
?>
185
ChapTer 6 UsefUl TrICks and OperaTIOns
(You determine the name of the identifier.) Then, the text follows, ending
with the MYTEXT instruction and a semicolon.
Details
Notably, the name of the $word variable in the text fragment is used. As a
result, the variable’s value is inserted instead of its name. That means the
text behaves like a string literal enclosed in double quotes.
<?php
// A multiline string:
$text=<<<'MYTEXT'
MYTEXT;
echo $text;
?>
186
In this case, the MYTEXT identifier after the <<< instruction is enclosed in
single quotes, and the text itself contains commands, including variable
names. All the text content is displayed “as it is”—that is, it is similar to the
situation when a string literal is enclosed in single quotes.
Using Files
Let’s discuss the most common techniques for getting data from files and
writing data to files.
First of all, the file needs to be opened. To do that, you use the fopen()
function. The function’s first argument is a string specifying the path to the
file. The second argument is a string with special characters. That argument
determines the access mode under which you use the file.
Table 6-1 lists and describes combinations for the second argument of the
fopen() function.
187
'r'
The file is opened for reading. The pointer for reading is set at the
beginning of the file.
'r+'
The file is opened for reading and writing. The pointer for reading/
'w'
The file is opened for writing. The pointer for writing is set at the beginning
of the file. The original contents of the file are deleted. If the file does not
exist, it will be created.
'w+'
The file is opened for reading and writing. The pointer for reading/
writing is set at the beginning of the file. The original contents of the file
are deleted. If the file does not exist, it will be created.
'a'
The file is opened for writing only. The pointer for writing is set at the end
of the file. If the file does not exist, it will be created.
'a+'
The file is opened for reading and writing. The pointer for reading/
writing is set at the end of the file. If the file does not exist, it will be
created.
'x'
The file is created for writing. The pointer for writing is set at the beginning
of the file. If the file already exists, an error is raised.
'x+'
The file is created and opened for reading and writing. The pointer for
reading/writing is set at the beginning of the file. If the file already exists,
an error is raised.
'c'
The file is opened for writing only. If the file does not exist, it will be
created. If the file already exists, then the contents of the file are not
deleted. The pointer for writing is set at the beginning of the file.
'c+'
The file is opened for reading and writing. The pointer for reading/
writing is set at the beginning of the file. If the file does not exist, it will be
created. If the file exists, its contents are not deleted.
188
Details
data can be written and read in byte or character stream mode. as it is easy
to understand from the name, operating with a byte stream implies that data
is written and read byte by byte. If the stream is a character one, then
reading and writing are performed character by character. The type of the
stream (character or byte) is determined by the characters b (the byte
stream) and t (the character stream), which are placed in the string after the
instruction that specifies the file access mode.
There is a set of functions designed to work with files. The most important
among them are the following. The fgets() function reads a line starting at
the pointer in the file. The fread() function is used for byte reading. The
fwrite() function allows you to write bytes. The file() function allows you to
read a file into an array. You can use the file_
Details
In some cases, creating (for reading or writing) a file with a random name
may be necessary (so no one gets unauthorized access to it by mistake). The
tmpfile() function can be used for doing that.
189
<?php
$path="D:/books/php/myfile.txt";
$k=1;
while(!feof($h)){
$line=fgets($h);
$k++;
fclose($h);
?>
For this program to run successfully, there must be the myfile.txt file with
some text in the D:\books\php folder. In this case, the contents of the text
file are as follows.
Taras Shevchenko
190
The full path to the file is written to the $path variable. Then, the
$h=fopen($path,"rt") command attempts to open the file, and if successful,
the file identifier is written to the $h variable. Next, using that variable, you
get access to the file. In particular, you read the contents of the file line by
line and display the read string in the output area. Each line is preceded by
its number in square brackets. The $k variable is used to count the lines.
The second argument, "rt" passed to the fopen() function, means that the
file is opened for reading only under the character stream mode.
Details
an error arises if the file you are trying to open does not exist. In that case,
instead of the $h=fopen($path,"rt") command, you can use a command like
$h=fopen($path,"rt") or die("File access error"). here, the or logical
operator is used. It performs the logical or operation in a simplified form:
the second operand, die("File access error"), is evaluated only if the first
operand, $h=fopen($path,"rt"), has a value equal to false. If the file is
opened successfully, the first operand is non-zero, which is equivalent to
true. In that case, the second operand is not evaluated. If the file cannot be
opened, then the second operand die("File access error") is evaluated, and
as a result, a message about the error appears in the output area, and the
code execution stops.
To read the file’s contents, you use the while loop statement. The condition
is defined by the !feof($h) expression. The feof() function determines
whether the end of the file whose identifier is passed as an argument to the
function has been reached. Therefore, the !feof($h) expression is true if the
end of the file has not been reached.
Until the end of the file is reached, the $line=fgets($h) command writes the
line read to the $line variable using the fgets() function. Then the echo "[$k]
",$line instruction displays the read line in the output area. Finally, the $k++
command increments the counter variable $k value.
191
That process is terminated as soon as the end of the file is reached. The
fclose($h) command closes the file. The result of running the program is as
follows.
<?php
$path="D:/books/php/mytext.txt";
$h=fopen($path,"wt");
echo "Writing into the file.\n";
$k=1;
$line=trim(fgets(STDIN));
while($line!=="exit"){
fwrite($h,"[$k] ");
fwrite($h,$line."\n");
192
$k++;
$line=trim(fgets(STDIN));
fclose($h);
echo "The program is over.";
?>
The result of the program execution could be as follows (the text entered by
the user is marked in bold).
Taras Shevchenko
exit
But the most important thing is that in the D:\books\php folder, there
appears (if it was not there) the mytext.txt file with the following content.
Let’s find out why that happens. Namely, let’s analyze the program.
The $path variable, as in the previous case, stores the full path to the file
where you intend to write the text. In particular, that is the mytext.
txt file from the D:\books\php folder. You open the file using the
$h=fopen($path,"wt") instruction. The second argument, "wt", means the
file is opened for writing under the character stream mode.
Next, several messages are displayed, and then, with the help of the
$line=trim(fgets(STDIN)) command, you read the text entered by the user
(in which all leading and trailing spaces and special characters are
previously discarded). After that, the while loop statement is launched, in
which the $line!=="exit" condition is checked. The condition is true if the
user has not entered the text "exit".
Note Thus, to terminate the input process, you must enter the word exit.
The fwrite($h,"[$k] ") command writes the line number in square brackets
into the file, after which the fwrite($h,$line."\n") command adds the read
string into the file, supplemented by the instruction to move to a new line in
the file. The $k++ instruction changes the value of the counter variable $k,
and then the $line=trim(fgets(STDIN)) command reads the next line the
user enters. Finally, you close the file using the fclose($h) instruction.
Often, there is a need to include some code from another file into a
program. Next, let’s examine a small example that shows (at an elementary
level) how that could be done. The main idea is as follows. You describe
some function in a file and then call it in another. Namely, you create a file
called show.php with the following code.
194
<?php
// The function:
function show($n){
?>
Let’s create a file (see Listing 6-11) in the same folder that contains the
show.php file with the show() function code.
<?php
require_once 'show.php';
// Creates a variable:
$val=123;
show($val);
?>
The output of the program is as follows.
The code begins with the require_once 'show.php' command, which imports
the contents of the show.php file into the program. Then, you create the $val
variable and pass it to the show() function as an argument.
195
Summary
variable is created and gets its initial value the first time the function is
called. After the function is terminated,
used again.
196
function.
197
CHAPTER 7
paradigm, and how the main conceptual points are learned will largely
determine the success of using the broad features of PHP to create OOP
projects.
The study of the OOP principles often begins with their enumeration:
encapsulation, polymorphism, and inheritance. That may sound a little bit
scary. However, not everything is as scary as it seems at first glance. To
understand the concept of OOP, it makes sense to clarify what it is and why
you need it to create programs.
199
Let’s say there is a small café with a kitchen, and you need to organize the
work in the kitchen. The kitchen receives orders from visitors and prepares
dishes following those orders. If the cafe is not very large and there are not
many visitors, you need a chef to manage the process for the successful
operation of the kitchen. You also need to have several assistant chefs. Each
assistant chef is responsible for preparing a specific dish or dishes. For
example, one chef specializes in meat dishes, another in fish dishes, the
next one prepares salads, someone specializes in desserts, and so on. One or
more refrigerators can be used to store food, and all chefs store products
there and use those products to prepare meals. All chefs have access to all
refrigerators. The distribution of tasks to the assistant chefs is the
responsibility of the main chef. The main chef also controls the contents of
the refrigerators: are there all the products, and are their quantities
sufficient?
language, that means you need to define for each assistant chef the
functional responsibilities and the products they can use in their work.
Let’s say you make everything right, and the kitchen operates like a clock.
What can break the situation? One of the main reasons is the expansion of
the “enterprise.” In a programming language, an increase in the amount of
code. Imagine that there are a lot of visitors, and the 200
What is important in this new model? The important thing is that you use a
system of departments that interact with each other. Previously, in the
original scheme, individual assistant chefs interacted with each other. As
part of the new approach, the chefs also interact with each other within the
department. At the next level, there is an interaction between departments.
You can do the same with the program. Namely, you can organize it as an
interaction of some blocks which contain the data and which can process
that data. Such blocks are called objects. The scheme itself describes the
paradigm of object-oriented programming (OOP).
Note OOp principles were developed for creating large programs. a large
program usually contains several thousand lines of code or more.
Thus, writing a program within the framework of OOP implies the creation
of objects. Objects are created based on patterns called classes.
which you build (an analogy to a class). You take a plan and build a house
following the plan. Similarly, you take a class and create an object based on
the class. Several houses can be built based on the same plan. They are of
the same type but physically different. And if you build houses based on
different plans, you get different houses. As well multiple objects can also
be created based on a class. They are also of the same type (with the same
functionality), but at the same time, physically, they are different. If you
create objects based on different classes, the objects are also different. It is
also possible that there is a plan but no buildings. Similarly, you can create
a class but not create any object based on it.
That is the main idea. Next, you must learn how to declare classes and
create objects based on them.
inheritance, it is worth mentioning the following. These are the three basic
mechanisms of OOp. Encapsulation means that the data and the code for
processing it are combined into a single unit, which is an object.
polymorphism implies using generic interfaces for interacting with objects,
functions, and methods. Finally, inheritance allows you to create new
classes based on existing ones by inheriting their properties. all these
mechanisms are examined step by step in examples.
It is time to go deep into the practical issues. Let’s start by creating classes.
A class declaration begins with the class keyword followed by the class
name. Then, in a block defined by curly braces, the contents of the class are
described. The class declaration template looks as follows.
202
But the intrigue remains: what can be described in a class? The short
answer is that you can describe methods and fields there. The fields are
actually variables. Unlike ordinary variables, the fields are described in the
class. There is no need to assign values to them; it is just enough to specify
their presence in the class. Methods are the same as functions. But contrary
to the functions, the methods are described in the class.
Note The fields are sometimes also called properties or attributes. The
fields and methods of a class are called members of the class.
class MyClass{
public $number;
The class contains only one public $number statement, which means that
the class describes a field called $number. The public keyword is called an
access level specifier, meaning the field is public. The “publicity”
of the field, in turn, allows you to access the field not only inside the class
but also outside of it.
Note In addition to the public access level specifier, the private (a private
field) and protected (a protected field)
keywords can be used. how the access level specifier affects the field
properties is discussed later.
203
ChapTEr 7 ClassEs and ObjECTs
So, there is the MyClass class with a single $number field. What does that
mean? That means if you create an object based on the MyClass class, the
object has the $number field.
Details
To create an object based on a class, use the new instruction followed by the
name of the class to be the basis for creating the object. A reference to that
object is written to a variable (an object variable) identified with the object.
The template of the statement that creates an object is as follows.
$variable=new ClassName;
For example, if you want to create an object of the MyClass class, the
corresponding command could look like the following.
$obj=new MyClass;
204
In php 8, you can use the $obj::class statement to get the name of that class
based on which the $obj object was created. In the previous versions of php,
the get_class() function is used for that purpose, and the corresponding
command looks like get_
class($obj).
But an object is primarily its fields and methods. Therefore, access to the
object is access to its fields and methods. To do that, put the arrow -> after
the object variable and then place the field name without the $ symbol. In
this case, you access the $number field of the $obj object using the $obj-
>number instruction.
<?php
// Description of a class:
class MyClass{
public $number;
// Creates an object:
$obj=new MyClass;
$obj->number=123;
$obj->number=321;
205
?>
The program begins with a description of the MyClass class. Based on the
class, the $obj=new MyClass instruction creates the $obj object. It has the
$number field, assigned the value 123 using the $obj->number=123
After that, the $obj->number=321 command assigns the new value 321
to the $number field of the $obj object. The check shows that the field value
has changed.
Details
The public access level specifier in the description of the $number field in
the MyClass class makes it possible to access the field in the $obj->number
format outside the MyClass code.
206
The Methods
Note From here, you examine ordinary (non-static) fields and methods. In
addition to ordinary class members, there exist static members. Operations
with them have their own peculiarities, which are discussed later.
<?php
class MyClass{
public $number;
function show(){
207
function set($n){
$this->number=$n;
// Creates objects:
$A=new MyClass;
$B=new MyClass;
$A->set(100);
$B->set(200);
$A->show();
$B->show();
?>
The main changes are related to the MyClass code. In addition to the
$number field, the class contains the methods show() and set(). The show()
method has no arguments and allows you to display the $number field of
the object from which the method is called. The set() method assigns a
value to the $number field of the object from which the method is called.
The method’s argument (named $n) determines the value assigned to the
$number field.
208
You are faced with an essential problem in the description of these methods.
Namely, a method is called from an object. That means that to call the
method, it is necessary to specify the name of the method and the object
from which the method is called. The method, in turn, accesses the field
$number of the object. When accessing the field, you must specify the
object (which owns the field). But when you describe the method, the
object does not yet exist. In other words, you need to denote somehow the
object from which the method is called. That is what the $this identifier is
used for. The $this instruction, when used within the method code, denotes
the object from which the method is called. Therefore, for example, the
$this->number command is a reference to the $number field of the object
from which the method is called. In particular, in the body of the show()
method, use the print("The field \$number: $this-
>number\n") statement, which displays the $number field of the object from
which the method is called. In the body of the set() method, the $this-
>number=$n statement assigns the $n argument of the method to the
$number field.
In the program, create two objects, $A and $B, of the MyClass class.
to the field $number of $A, and the $B->set(200) instruction assigns 200 to
the field $number of $B. After that, using the $A->show() command,
display the $number field of the $A object, and to display the $number field
of the $B
209
Details
command, the $obj object gets the $name field with the value "php".
nevertheless, since php 8.2, that possibility is deprecated. If you still want
to use it, you should put the #[\AllowDynamicProperties] annotation before
the class description.
You can use the unset() function to remove a field from an object. For
example, to delete the $name field from the $obj object, the unset($obj-
>name) instruction could be helpful.
It is also worth mentioning that methods, like fields, can be described with
the public, private, and protected specifiers of access level. If a method is
described without a specifier of access level (as in the earlier examples),
then the method is a public one by default.
a good practice is to specify the public access level explicitly for public
methods. nevertheless, let’s use the default (public) access level (so the
public keyword is not used) for some methods to demonstrate php’s
flexibility and power.
also, you can assign values to fields in the description of a class. In that
case, when creating an object based on the class, the corresponding field of
the object has the value assigned to the field in the class.
In the php 8 version, you can use the ?-> instruction instead of -> when
accessing the fields and methods of objects. For example, you can use an
expression like $object?->method instead of the expression like $object-
>method. The former option is safer because if the value of the $object
variable is an empty null reference, then there is no fatal error.
210
In the examples, you created objects based on a class, and then the fields of
the objects were assigned values. If there are many objects and they have
many fields, then the process can become tedious. So, it is advisable to
automate it. In that sense, two special methods may be useful: the
constructor and the destructor.
Details
<?php
class MyClass{
# The field:
public $code;
# The constructor:
211
function __construct($code=123){
$this->code=$code;
# The destructor:
function __destruct(){
# Creates objects:
$A=new MyClass();
$B=new MyClass(321);
?>
The program describes the MyClass class. The class has the $code field, the
constructor, and the destructor. The constructor has a single argument
(denoted as $code) with the default value 123. In the constructor, the $this-
>code=$code command is executed, which assigns a value (the method
argument) to the $code field of the object being created.
212
ChapTEr 7 ClassEs and ObjECTs
The destructor contains only one command echo "The object is deleted:
",$this->code,"\n", which informs you that the object is deleted.
Details
213
ChapTEr 7 ClassEs and ObjECTs
When the $B object is created, the value 321 is passed to the constructor as
an argument. That is the value of the $code field of the $B object.
You create two objects, so two messages appear. Two more messages
automatically appear when objects are deleted from memory. You see that
the program ends with the commands creating objects. There are no other
commands in the program. Therefore, after the objects are created, the
program is terminated. But before the program is terminated, all created
objects are automatically deleted from memory.
OceanofPDF.com
As you already know, the destructor is called before the object is deleted.
The command executed in the destructor displays a message that the object
is deleted. Two objects were created, so two objects were also deleted.
Note Objects are deleted in the reverse order as they were created: the last
created object is deleted first.
Details
In the previous versions of php, there was another way to create the
constructor.
It differs from the one described in that the constructor’s name is not __
construct(), but its name matches the name of the class. In this case, that
would be the MyClass() method.
In php 8, a method whose name is the same as the name of its class is no
longer interpreted as the constructor.
214
The fields and methods that were described in the classes in the previous
examples were ordinary—that is, non-static. But, as noted earlier, a class
can also contain static members— static fields and static methods.
You describe it with the static keyword. But what is the difference between
a static field or method and a non-static field or method? If ordinary (non-
static) fields and methods are “attached” to an object, then static class
members do not belong to any object. They exist on their own (but in the
context of the class in which they are described).
To refer to a static field or class method, specify the class name followed by
a double colon (::), and then the name of the field or method (with
arguments in parentheses) follows. If you call a static method or refer to a
static field inside the class code, the self keyword is used instead of the
class name.
Listing 7-4 describes a class with a static field and two static methods.
<?php
class MyClass{
# A static field:
# Static methods:
self::$name=$name;
215
ChapTEr 7 ClassEs and ObjECTs
MyClass::$name="Alpha";
MyClass::hello();
MyClass::rename("Bravo");
MyClass::hello();
?>
The MyClass class has the static field $name. The rename() static method is
designed to change the value of the $name field (the method argument has
the same name). Assigning a value to the field is realized by the
self::$name=$name command in the method. There, the $name instruction
means the method’s argument, and the static field is accessed by the
self::$name instruction.
The static hello() method has no arguments. When the method is called, the
echo "The name: ",self::$name,"\n" command is executed, which displays
the value of the static field.
216
Copying Objects
<?php
class MyClass{
public $code;
function __construct($code){
$this->code=$code;
function show(){
echo "The field \$code: ",$this->code,"\n";
# Creates an object:
$A=new MyClass(100);
$A->show();
# Assigns objects:
$B=$A;
$B->show();
217
$A->code=200;
$A->show();
$B->show();
?>
The following is the result of the program execution.
The object $A
The object $B
The object $A
The object $B
The program defines the MyClass class with the $code field, the one-
argument constructor (defines the value of the $code field), and the show()
method that displays the field’s value.
creates the $A object, whose $code field gets the value 100. Using the
show() method, check the value of that field. Then, the $B=$A command is
executed. But the copying of objects, in that case, does not happen. The $A
variable does not contain the object but only refers to it. The situation can
be interpreted so that the $A variable contains the object’s address.
change the value of the $code field of the $A object (the $A->code=200
command), the check shows that the value of the $code field of the $B
object has also changed. But once again, you deal with the same object
here.
So, how can you create a copy of an object? One of the easiest ways is to
use the clone instruction in the object assignment command. In particular,
the $B=clone $A command could be used instead of the $B=$A command.
The new version of the program that copies objects is shown in Listing 7-6.
<?php
class MyClass{
public $code;
function __construct($code){
$this->code=$code;
function show(){
$A=new MyClass(100);
$A->show();
# Copies objects:
$B=clone $A;
$B->show();
$A->code=200;
$A->show();
219
$B->show();
?>
The object $A
The object $B
The object $A
The object $B
The field $code: 100
The result of the program execution proves that a copy of the object was
indeed created.
The previous examples used public fields and methods. Their “publicity”
allowed access to them outside the class code. However, making fields or
methods private is often reasonable and convenient. Such class members
are described with the private keyword and are available only inside the
class code. What does it give to us? The point is that private members of a
class are more difficult to use in an “unsupposed” manner. In other words, if
a field or method is used to solve additional routine tasks and is not
proposed for the “end user,” it is better to “hide” such a field or method.
220
<?php
// A class:
class MyClass{
private $code;
function get(){
return $this->code;
function set($code){
$this->code=$code;
$this->set($code);
// Creates an object:
$obj=MyClass::create(100);
?>
221
You describe the MyClass class with a private $code field and two public
non-static methods. The get() method returns the value of the $code field of
the object from which the method is called (the return $this->code
statement in the method body).
designed to assign a value to the $code field of the object from which the
method is called. The $this->code=$code instruction in the method’s body
solves the task.
The class has a constructor with one argument to pass when creating an
object, and the argument determines the value of the object’s $code field.
And you do that by calling the set() method. But the tricky moment is that
the constructor is described with the private keyword. That is, it is private.
So, you cannot create an object outside the class code using the new
instruction. Then how can you create objects? For that purpose, you create
the public static create() method. The method has one argument (denoted as
$code). The argument defines the value of the object’s field of the same
name, the reference to which is returned by the method as a result. The
object itself is created by the new self($code) statement in the method body.
The result of the expression is a reference to the created object. It is the
reference that is returned by the method. The self keyword is used to
identify the class from which the method is called.
Since you cannot create an object in the usual way, you use the
$obj=MyClass::create(100) command to create an object of the MyClass
class. The $code field of the created object gets the value 100. However,
222
since the $code field is private, you cannot access it directly. If you want to
get the value of the field, use the $obj->get() instruction, which calls the
public get() method from the $obj object.
To assign a value to the field of the object, call the set() method, as is done
with the $obj->set(200) command.
Note It turns out that the $code field of the object is private, so you cannot
perform operations directly with it outside the class code. but you can
access the field using public methods. In particular, use public methods to
read the field’s value and assign a value to the field.
Special Methods
There is a group of methods that solve “special” tasks. The names of those
methods begin with a double underscore. Let’s explore them next.
223
<?php
class MyClass{
// The fields:
public $name;
public $code;
// The constructor:
function __construct($name,$code){
$this->name=$name;
$this->code=$code;
return $txt;
$obj=new MyClass("Object",123);
echo $obj->__toString();
echo $obj;
print($text);
?>
224
The program describes the MyClass class, which has two fields ($name and
$code). The class also has a constructor with two arguments that define the
values of the fields. In addition, it describes the __toString() method. The
method has no arguments and returns a string as a result.
The string is formed in several steps and contains information about the
values of the object’s fields.
Based on the MyClass class, you create the $obj object. In the $obj->__
toString() statement, the __toString() method is called explicitly, like an
ordinary method. But when the echo $obj instruction is executed, the
__toString() method is called automatically from the $obj object, and the
result of the method replaces the reference to that object. The method is also
called implicitly when the $text=$obj."The program is over"
from the $obj object, and the string result of the method is concatenated
with the second string operand.
Let’s explore three more special methods: __set(), __get(), and __call().
They are used when referring to members of a class. Namely, the __call()
method is called if a call is made to the non-existing object method.
The arguments of the __call() method are the name of the called method
and the list of arguments passed to the called method.
Details
If a method is called from an object and the object does not have such a
method, then the __call() method is automatically called from the object.
The first argument of the __call() method is the name of the non-existing
method. The second argument of the __call() method is an array whose
elements are the arguments passed to the non-existing method.
<?php
class MyClass{
// The method:
226
echo $txt."\n";
if(strlen($name)>5){
}else{
for($k=0;$k<sizeof($args);$k++){
}
}
$obj=new MyClass();
$obj->display("Alpha");
$obj->hello("Bravo","Charlie","Delta");
?>
The arguments: 1
[1] Bravo
[2] Charlie
[3] Delta
227
The program uses the MyClass class, which describes the ordinary show()
method with one argument. When the method is called, the value of the
argument passed to the method is displayed. You need that method to show
that the presence of the __call() method does not affect the operation of
ordinary methods in a class.
The special __call() method is declared with two arguments. The first
argument $name means the name of the method that is called from the
object and which the object does not have. The second argument, $args, is
an array with the arguments passed to the non-existing called method.
You use a conditional statement in the method’s body that tests the
strlen($name)>5 condition. The condition is true if the name of the called
(non-existing) method consists of more than five characters. If so, echo
If the strlen($name)>5 condition is false and the name of the called method
has no more than 5 characters, a loop statement is launched that iterates
over the elements of the $args array (the arguments passed to the non-
existing method) and displays their values.
Details
The sizeof() function is used to calculate the size of an array. The length of
a string is calculated using the strlen() function.
Based on the MyClass class, create the $obj object. If you call the existing
show() method from that object, everything happens as it should, without
surprises.
The name of the method consists of more than five characters. So, when
228
The __set() and __get() methods are automatically called when accessing
the non-existing fields of an object. In particular, the __set() method is
called if you try to assign a value to the field that does not exist.
The arguments of the method __set() are the name of the field to which the
value is assigned and the assigned value itself.
Details
The __get() method is called if you try to read the value of the non-existing
field. The name of that field is passed as an argument to the method __get().
The program that illustrates how to use the __get() method is shown in
Listing 7-10.
<?php
// The class:
class MyClass{
public $number=321;
private $code=100;
return $this->code;
return 123;
// Creates objects:
$obj=new MyClass();
?>
$number: 321
$code: 50
get(): 100
$value: 123
230
The MyClass class has the public field $number with the value 321
and the $code private field with the value 100. The class has the ordinary
get() method with no arguments, which returns the value of the private field
$code.
Details
a field can be inaccessible because the object does not have it or the field is
private.
The __get() method is automatically called in both cases. You use the
conditional statement to check if the object has a private field with the
requested name.
You should also pay attention to the $this->$name instruction. here, the
$name variable contains the name of the field. In other words, this is not
about the $name field but the field whose name is the value of the $name
variable (argument).
After creating the $obj object of the MyClass class, access the fields of that
object. The result of the $obj->number expression is the value 321 of the
$number field of $obj.
The $obj->code instruction accesses the private field $code of the $obj
object. The field is there, but there is no access to it. The value of the
private $code field is 100. That is the value returned by the get() method
(the $obj->get() instruction). But the value of the $obj->code expression
231
is twice less (that is, 50). It is the value returned by the __get() method. It is
called automatically when the $obj->code expression is processed.
The $obj->value instruction accesses the non-existing $value field. In that
case, the __get() method returns the value 123.
Listing 7-11.
<?php
class MyClass{
public $number;
private $code;
return $this->code;
$this->code=$code;
}
// The special method is called when
if(isset($this->$name)) $this->$name=$arg/2;
else $this->$name=2*$arg;
232
// Creates an object:
$obj=new MyClass();
$obj->number=123;
$obj->set(321);
$obj->code=100;
?>
$number: 123
$code: 321
$code: 50
$value: 200
233
annotation for the MyClass class (put the annotation before the class
description).
The MyClass class has the public $number field, the private $code field, the
public get() method to read the value of the $code field, and the set()
method to set the value to that field.
The __set() method is described with two arguments. The first argument
$name specifies the field name to which the value is assigned.
The core of the method code is a conditional statement. You check the
isset($this->$name) condition in the conditional statement. It is true if the
object has the corresponding field. If the condition is true, the $this-
>$name=$arg/2 command is executed. In that case, the field gets half the
value passed for assigning. If the condition is false, then $this-
Note If you assign a value to the unavailable private field, that field gets
half the value you assign. If you assign a value to the non-existing field, the
field is added to the object and gets twice the value you assign.
Based on the MyClass class, create the $obj object. After that, you use the
$obj->number=123 command to assign the value 123 to the public field
$number, and the $obj->set(321) command sets the value 321 to 234
the $code private field. Here, everything happens without any intrigue.
In the next step, you try to assign a value to the private $code field with the
$obj->code=100 command. In that case, the __set() method is automatically
called. Since the $obj object has the $code field, the value of that field is
not 100 but 50. Checking it with the $obj->get() instruction confirms the
predictions.
The $obj->value=100 command attempts to assign the value 100 to the
non-existing $value field. In that case, the __set() method is also called. As
a result, the $value field is added to the object and gets the value 200. The
field’s value can be checked using the $obj->value statement.
The constructor in a class often assigns values to the fields of the object
being created. In that case, the fields are declared in the class, and the
constructor contains commands that assign values to the fields (based on the
constructor’s arguments). In practice, it looks like the following.
class MyClass{
// The field:
public $code;
// The constructor:
function __construct($code){
$this->code=$code;
235
Here, you deal with the MyClass class, which has the public $code field and
the one-argument constructor. The constructor argument specifies the value
of the field. Starting with PHP 8, combining the field declaration and field
assignment can significantly reduce the code. Considering the innovations,
the code could look like the following.
class MyClass{
Thus, if you specify an access level specifier for the argument in the
description of the constructor argument, then that means the following.
Listing 7-12 shows the class declaration with a constructor that defines two
fields (one public and one private).
236
<?php
// The declaration of a class:
class MyClass{
function show(){
// Creates an object:
$obj=new MyClass(123,"MyClass");
$obj->show();
?>
to the $code field, and the constructor’s second argument specifies the value
of the $name field. The constructor contains the echo "The object is created:
$code and $name\n" command, which displays a message with information
that the object is created and the values of the arguments passed to the
constructor.
Details
The show() method is described in the MyClass class. When the method is
called, it displays the $code and $name fields of the object from which the
method is called.
<?php
class MyClass{
private $name;
$this->name=$name;
238
function show(){
$obj=new MyClass(123,"MyClass");
$obj->show();
?>
The second argument in the constructor of the MyClass class is a regular
argument, and the private field of the same name in the class is traditionally
declared. You also added the command that assigns the constructor’s second
argument to the $name field. In all other aspects, the examples are similar.
The result of the program execution is the same as in the previous case.
Summary
and methods.
class description.
omitted.
239
to an object variable.
240
class::method(arguments) format.
241
CHAPTER 8
Inheritance
So, let’s say that you have a class that you would like to modify (add some
new properties and methods to it). In principle, you can simply modify the
code of the corresponding class. But the situation is complicated because
the programs already use the class. Therefore, the idea of modifying the
code of an already existing class is not the best one. The idea of describing
a new class from scratch, duplicating, in addition to new fragments, the
contents of the original class is also not productive. First, in that case, you
have to repeat the existing code. In programming, such a style is usually a
sign of a badly created program. Second, if you later have to make changes
to the original class (for example, by changing the code of one
243
CHaPTer 8 InHerITanCe
of the methods), you may need to make changes to the newly created class
synchronously. So, what are you going to do? In such a situation, it is
reasonable to use the inheritance mechanism.
The idea is simple: create a new class based on an existing one. In that case,
the newly created class automatically inherits all public and protected
methods from the original class. (What happens to the private members of
the class is a special case, which is discussed a little later.) The class from
which the new class is created is called the parent or base class.
A class created based on the parent class is called a child or derived class.
Note PHP allows multilevel inheritance: from a parent class, you can create
a child class, from which another child class can be created, and from it, the
next child class, and so on. Thus, child and parent classes are relative: a
class can be a child for some class and a parent for another class.
However, PHP does not allow multiple inheritance: a child class can have
one and only one parent class.
From a technical point of view, creating a child class is very simple: in the
class description, after its name, you put the extends keyword and the name
of the parent class. The description of the child class specifies only those
fields and methods that should be appended to the child class in addition to
the members from the parent class. The members of the parent class are
automatically available in the child class. The child class declaration
template looks as follows.
244
CHaPTer 8 InHerITanCe
That pattern means the Bravo class is created based on the Alpha class.
In the Bravo class, you need to describe only those members you want to
append to the inherited members from the Alpha class.
Details
The situation is as if all public and protected members of the Alpha class
were declared in the Bravo class. In the body of the Bravo class, you can
directly access those class members.
Listing 8-1 is a program that creates and uses parent and child classes.
class Alpha{
// The field:
public $number;
$this->number=$number;
// The field:
public $symbol;
$this->symbol=$symbol;
245
CHaPTer 8 InHerITanCe
// The method for assigning values
// to both fields:
$this->setSymbol($symbol);
$this->setNumber($number);
// Creates an object:
$obj=new Bravo;
// Assigns values to the fields:
$obj->setSymbol('A');
$obj->setNumber(100);
$obj->show();
$obj->setAll('B',200);
$obj->show();
?>
246
CHaPTer 8 InHerITanCe
The Alpha class has the public $number field and the public one-argument
setNumber() method for assigning a value to the field.
Since the Bravo child class is based on the Alpha class, the Bravo class also
has the $number field and the $setNumber() method, even though these
class members are not defined in the Bravo class. But they are inherited
from the Alpha class. In addition to the inherited members, you explicitly
declared the public $symbol field and three public methods in the Bravo
class. The setSymbol() method with one argument is designed to assign a
value to the $symbol field. The setAll() method has two arguments. The
method assigns values to the $number and $symbol fields.
Note In the body of the child class, you handle the fields and methods
inherited from the parent class as if they were declared directly in the child
class.
247
CHaPTer 8 InHerITanCe
The $obj=new Bravo command is used to create the $obj object based on
the Bravo class.
Note You do not create an object of the Alpha parent class since it is not
particularly interesting. It would be an ordinary object of an ordinary class.
First, the $obj->setNumber(100) and $obj->setSymbol('A') commands
assign values to the fields of the $obj object. You check the fields using the
show() method. The $obj->setAll(200,'B') command is another way to
change the fields of the $obj object.
Details
You also could directly access the $number and $symbol fields of $obj. note
that a member must be public to be accessed outside the class.
Overriding Methods
It is pretty convenient that, due to inheritance, a child class gets the fields
and methods of its parent class. However, in some cases, it is necessary for
the method inherited in a child class to be performed somewhat differently
than it is implemented in the parent class. In other words, there are
situations when an inherited method needs to be overridden. To override a
method in a child class is easy. You just need to declare it explicitly.
248
CHaPTer 8 InHerITanCe
<?php
class Alpha{
// The field:
public $number;
$this->number=$args[0];
// The field:
public $symbol;
parent::set($args[0]);
$this->symbol=$args[1];
}
// the fields:
echo "-----------------\n";
parent::show();
249
CHaPTer 8 InHerITanCe
$A=new Alpha;
$A->set(100);
$A->show();
$B=new Bravo;
// Assigns values to the fields:
$B->set(200,'B');
$B->show();
?>
-----------------
The Alpha parent class has the $number field and two public set() and
show() methods you plan to override in the child class. The show() method
has no arguments. When the method is called, it displays a 250
CHaPTer 8 InHerITanCe
message with the name of the Alpha class and the $number field of the
object from which the method is called. The set() method, which you need
for assigning a value to the $number field, is described as one that can take
an arbitrary number of arguments (formally, it is described with the $args
argument preceded by an ellipsis). To understand why you did that, it is
necessary to consider the following important circumstances. When
overriding a method in a child class, the method must be declared with the
same arguments as in the parent class. The set() method in the parent class
assigns a value to a single field. In the child class, use the method to assign
values to two fields. Therefore, use a trick: describe the method with an
arbitrary number of arguments and use only those that are needed. In the
parent class, that is the first argument accessed using the $args[0]
The Bravo child class is created by inheriting the Alpha class. The $symbol
field also appears, and the set() and show() methods are overridden.
CHaPTer 8 InHerITanCe
the parent class (that is, the Alpha class) must be called first. The first
argument of that version of the method (from the Alpha class) is defined by
the first argument passed to the set() method (from the Bravo class).
As a result, the $number field is assigned a value. To assign a value to the
$symbol field, the $this->symbol=$args[1] command is used, according to
which the second argument determines the value of the field passed to the
set() method.
line, purely aesthetic, to separate the results of different calls to the show()
method. The parent::show() command calls the version of the show()
method from the Alpha parent class, after which the echo "The class
Bravo\n" command displays a message, and then the value of the $symbol
field is displayed (by the echo "The field \$symbol: ",$this-
>symbol,"\n" command).
The $A=new Alpha command creates the $A object based on the Alpha
class. The set() and show() methods for that object are executed as
described in the Alpha class.
The $B object of the Bravo child class is created by the $B=new Bravo
command. You check directly that for the object, the show() and set()
methods are executed differently (if compared to the $A object), namely,
according to how they are overridden in the Bravo class.
Note You can disable method overriding by declaring the method with the
final keyword.
252
CHaPTer 8 InHerITanCe
class Alpha{
// The constructor:
function __construct(){
// The destructor:
function __destruct(){
$obj=new Bravo;
?>
253
CHaPTer 8 InHerITanCe
You have created a very simple Alpha parent class. The class only has the
constructor and the destructor. When you create an object, a message
appears that an object of the Alpha class is created. When an object is
removed from memory, a message appears that an object of the Alpha class
is deleted.
The Bravo child class is based on the Alpha class. The body of the Bravo
class is empty. You don’t describe anything in it at all (you may do that, but
why to do that is another question). Then, create an object based on the
Bravo class. As a result, you get messages about creating and deleting an
object of the Alpha class appearing in the output window. How is that
possible? The parent class’s constructor and the destructor of the parent
class and other public methods are inherited in the child class. In this case,
you did not describe either the constructor or the destructor for the Bravo
child class. If so, the constructor and the destructor inherited from the Alpha
parent class are used.
Finally, as with regular methods, you can call the constructor and destructor
from the parent class. To do that, use the parent keyword.
CHaPTer 8 InHerITanCe
<?php
class Alpha{
// The field:
public $number;
// The constructor:
function __construct($number){
$this->number=$number;
// The destructor:
function __destruct(){
public $symbol;
// The constructor:
function __construct($number,$symbol){
echo "----------\n";
parent::__construct($number);
$this->symbol=$symbol;
// The destructor:
function __destruct(){
echo "~~~~~~~~~~~~~~~~~~\n";
255
CHaPTer 8 InHerITanCe
parent::__destruct();
$obj=new Bravo(200,'B');
?>
----------
The character: B
~~~~~~~~~~~~~~~~~~
You have the Alpha parent class with the $number field, the constructor,
and the destructor. The constructor is passed one argument that defines the
value of the $number field. The constructor and the destructor display
messages with the $number field value.
The Bravo child class, derived from the Alpha class, adds another field,
$symbol, and overrides the constructor and the destructor. The constructor
of the Bravo class has two arguments (named as $number and $symbol).
In the destructor of the Bravo class, among other actions, the destructor
from the Alpha class is called. To do that, use the parent::__
destruct() instruction.
256
CHaPTer 8 InHerITanCe
the Bravo class, and due to that, the constructor of the child class is
automatically called. Next, the destructor is automatically called before the
program terminates.
<?php
class Alpha{
private $code;
// to the field:
$this->code=$code;
return $this->code;
// The constructor:
function __construct($code){
257
CHaPTer 8 InHerITanCe
$this->set($code);
$obj=new Bravo(123);
$obj->set(321);
The Alpha class has the private $code field and two public methods: the
set() method allows you to assign a value to the field, and the get() method
returns the field’s value. Based on the Alpha class, the Bravo class is
created by inheritance. It inherits the public set() and get() methods but does
not (according to conventional terminology) inherit the private $code field.
It turns out that the Bravo class has the set() and get() methods that require
the $code field to operate properly, but that field itself is not inherited. How
can that be? To answer the question, it is necessary to clarify what the
phrase “not inherited” means. The matter of fact is that the private field
$code is not inherited in the Bravo class because you cannot directly access
the $code field in the body of the Bravo class. You can interpret the
situation so that the class “does not know”
anything about that field, but technically, such a field exists, and the set()
and get() methods can operate with it.
258
CHaPTer 8 InHerITanCe
The set() and get() methods are used in the Bravo class constructor.
The $this->set($code) command assigns a value to the $code field, and the
$this->get() instruction is used to get the field’s value.
command. The object has public set() and get() methods. The methods, in
turn, refer to the “invisible,” even for the Bravo class, the $code field.
Thus, the $obj->set(321) command writes the value 321 to the field, and the
$obj->get() instruction is used to get its value.
Details
In addition to public and private members, a class can also have protected
class members. Protected class members are described with the protected
access level specifier. Like private members, protected members of a class
are available only within the class’s code. But unlike private members,
protected members are inherited. An example of using protected class
members is shown in Listing 8-6.
<?php
class Alpha{
259
CHaPTer 8 InHerITanCe
protected $code;
$this->code=$code;
$obj=new Bravo;
$obj->set(123);
$obj->show();
?>
CHaPTer 8 InHerITanCe
methods set() (the method for assigning a value to the field) and show() (the
method for displaying the field value), you can directly access the inherited
$code field (the instruction like $this->code).
The $obj object is created based on the Bravo class. The object has the
$code field, but it is not directly accessible. To assign a value to the field,
use the set() method (the $obj->set(123) command), and to display the field
value, use the show() method (the $obj->show() command).
Virtual Methods
<?php
class Alpha{
function hello(){
function show(){
$this->hello();
# The constructor:
function __construct(){
print("Creates an object:\n");
$this->hello();
261
CHaPTer 8 InHerITanCe
print("----------------\n");
function hello(){
$obj->show();
?>
Creates an object:
----------------
The idea behind the program is very simple. There is the Alpha parent class,
and it has the public hello() method, which, when called, displays a
message with the name of the Alpha class. The Alpha class also has the
public show() method, in the body of which the hello() method is called.
The class also has the constructor that calls the hello() method.
The Bravo child class, which is derived from the Alpha class, overrides the
hello() method. The method now displays a message with the name of the
Bravo class. What does happen? It turns out that the Bravo class 262
CHaPTer 8 InHerITanCe
inherits the show() method and the constructor from the Alpha class. Both
the show() method and the constructor call the hello() method. And that
method, in turn, is overridden in the Bravo class. The intrigue is which
version of the hello() method is called when the show() method is called
from an object of the Bravo class. The result of the program execution
demonstrates that the constructor and the show() method, despite being
described in the Alpha class, call the version of the hello() method
described in the Bravo class. Such a feature of methods is called virtuality.
The version of the called method is determined by the class of the object
from which the method is called.
That does not mean that the possible values of an object field are limited to
only those data types. In fact, the value of an object field can be almost
anything. For example, let’s investigate a situation when an anonymous
function is assigned as a value to a field.
263
CHaPTer 8 InHerITanCe
<?php
class MyClass{
public $calc;
// A variable:
$number=9;
// Creates an object:
$obj=new MyClass;
$obj->calc=function($n){
return $n*$n;
};
$obj->calc=function($n){
return sqrt($n);
};
?>
Argument 9: 81
Argument 9: 3
264
CHaPTer 8 InHerITanCe
Let’s analyze the code using the MyClass class, which has the public $calc
field. Based on the MyClass class, create the $obj object. The following
command assigns a value to the $calc field of that object.
$obj->calc=function($n){
return $n*$n;
};
The anonymous function assigned to the field returns the square of the $n
argument. To calculate the result of the function to which the $calc field of
the $obj object refers, use the ($obj->calc)($number) instruction.
$obj->calc=function($n){
return sqrt($n);
};
Now, the $calc field refers to the function that returns the square root of its
argument.
Note The
square root. If the $number argument is set to 9, the result of the function is
3 (the square root of 9).
265
CHaPTer 8 InHerITanCe
Multilevel Inheritance
<?php
protected $number;
// The constructor:
function __construct($number){
$this->number=$number;
$this->show();
function show(){
$this->drawLine();
function drawLine(){
echo "----------------\n";
266
CHaPTer 8 InHerITanCe
// The second class:
protected $symbol;
// The constructor:
function __construct($number,$symbol){
$this->symbol=$symbol;
parent::__construct($number);
function show(){
$this->drawLine();
protected $text;
// The constructor:
function __construct($name,$symbol,$text){
$this->text=$text;
parent::__construct($name,$symbol);
function show(){
267
CHaPTer 8 InHerITanCe
$this->drawLine();
// Creates objects:
$A=new Alpha(100);
$B=new Bravo(200,'B');
$C=new Charlie(300,'C',"Charlie");
?>
The result of the program execution is as follows.
Alpha: 100
----------------
Bravo: 200
Bravo: B
----------------
Charlie: 300
Charlie: C
Charlie: Charlie
----------------
The scheme is as follows: based on the Alpha class, the Bravo class is
created by inheritance, and based on the Bravo class, the Charlie class is
created. The Alpha class has the protected $number field, the one-argument
constructor, the show() method, and the drawLine() method.
In the constructor, the field is assigned a value, and then the show() method
is called, which displays the value of the object’s field and the name of the
Alpha class.
268
CHaPTer 8 InHerITanCe
Note For convenience, the drawLine() method in the
That element separates the results of calling the show() method in all three
classes. That is possible since the drawLine() method is inherited in all
child classes.
The $number field, the constructor, the show(), and the drawLine() methods
are inherited in the Bravo class. But the constructor and the show() method
in that class are overridden. The constructor now has two arguments
defining the values of the $number and $symbol fields (a protected field
described in the Bravo class). The show() method is overridden so that
when the method is called, the values of both fields and the name of the
Bravo class are displayed.
In the Charlie class, the $number and the $symbol fields, the constructor,
the show(), and the drawLine() methods are inherited from the Bravo class.
At the same time, the show() method and the constructor are overridden. In
the Charlie class, the constructor has three arguments that determine the
$number, $symbol, and $text fields (the last one is a protected field
described in the Charlie class). The show() method is overridden so that the
values of the three fields and the name of the Charlie class are displayed
when it is called.
The Alpha, Bravo, and Charlie classes are used to create objects.
269
CHaPTer 8 InHerITanCe
Executing the $B=new Bravo(200,'B') command leads to calling
the constructor described in the Bravo class. Following the code of that
constructor, the $symbol field is assigned a value, and then the parent class
constructor is called (that is, the code of the constructor described in the
Alpha class). So, the $number field gets a value, the show() method is
called, and a separator line is displayed. Here, you need to consider an
essential circumstance: due to the virtuality of the methods, the version of
the show() method is called not from the Alpha class but from the Bravo
class (since the object of that class is created). The show() method from the
Bravo class displays the name of that class and the values of the created
object’s $number and $symbol fields.
270
CHaPTer 8 InHerITanCe
Summary
class. All non-private fields and methods of a parent class are inherited in
the child class.
(or constructor/destructor).
271
CHaPTer 8 InHerITanCe
methods.
272
CHAPTER 9
Advanced OOP
Mechanisms
This chapter explores the crucial mechanisms for implementing the OOP
Abstract Classes
When you create a class, you may not describe some methods but only
declare them. In other words, you can specify that the class has some
method but not specify what that method does. Such methods are called
abstract methods.
273
Abstract methods are declared with the abstract keyword. If a class has at
least one abstract method, that class is also abstract and must be defined
with the abstract keyword. But the question remains: why do you need all
that?
In its most general form, the answer is that abstract classes are used in
inheritance. To understand the depth of the answer, you should look at the
inheritance process not in the context that you can pass fields and methods
from the parent class to the child but in a slightly different way.
The point is that the parent class defines the “structure” of the child class,
which is created based on the parent class. To be more specific, let’s look at
an example (without having to write program code yet).
Note The area is calculated using the method because this characteristic of a
geometric figure is determined by its characteristic size and must change
according to how the characteristic size of the figure changes. It is best to
use a method that, when called, refers to the field in which the characteristic
size of the figure is written.
Note that the area of a square with side R is equal to R 2. The area of a
circle of radius R is equal to πR 2. The area of an equilateral triangle 3 2
274
ChApTer 9 AdvANCed OOp MeChANIsMs
Thus, in all three cases, the objects have a similar structure. The only
difference is how the method that calculates the area is implemented. But
those are different objects, and they must be created based on different
classes. Then, you can ask yourself: how do you get the different classes to
have the same structure (the same set of fields and methods, but the
implementation of the methods should be different)? The answer could be
as follows: you can describe an abstract class and then create different
classes based on it using inheritance. Those classes have the same structure
defined by the abstract class.
<?php
// An abstract class:
// Protected fields:
protected $name;
protected $R;
// The constructor:
function __construct($R,$name){
$this->R=$R;
$this->name=$name;
275
function getName(){
return $this->name;
// An abstract method:
function getArea(){
$r=$this->R;
return $r*$r;
}
// The class to realize a circle:
function getArea(){
$r=$this->R;
$k=3.141592;
return $k*$r*$r;
function getArea(){
$r=$this->R;
$k=sqrt(3)/4;
return $k*$r*$r;
276
}
// The function displays information about an object:
function show($F){
// Creates objects:
$S=new Square(2.5,"Square");
$C=new Circle(3,"Circle");
$T=new Triangle(4,"Triangle");
show($S);
show($C);
show($T);
?>
Square: 6.25
Circle: 28.274328
Triangle: 6.9282032302755
In that case, you describe the abstract Figure class and then create the
Square, Circle, and Triangle classes based on it.
The Figure class has two protected fields: $name (for the name of the
figure) and $R (for the characteristic size of the geometric figure).
Details
On the one hand, you want the fields to be inaccessible outside the class
code, but on the other hand, you need the fields to be inheritable. That is
why you make the fields protected.
277
The Figure class has the constructor with two arguments that define the
value of the fields $R and $name.
Since the $name field is protected, to read its value, you describe the
getName() method, which returns the value of that field. You also declare
the abstract getArea() method in the Figure class. Assume that that method
should calculate the area of the figure. How exactly the area is calculated is
defined in the child classes.
Note The abstract class has an abstract method and a method described
explicitly. The child class defines the abstract method and inherits the
explicitly described method. The constructor and protected fields are also
inherited.
The Square, Circle, and Triangle classes differ only in the way they
implement the getArea() method; there is nothing else in them besides that
method.
You create objects based on each class and then use the show() function to
display information about those objects (the name and area).
The important thing here is that in the description of the show() function,
you refer to the getName() and getArea() methods of the object passed as an
argument to the function. The function is called three times, and each time,
it takes an object of a different class as an argument. But since all these
classes are child classes of the abstract class Figure, each object has the
getName() and getArea() methods.
Interfaces
Thus, abstract classes can be used as a template for creating other classes.
only one parent class. If you need to “combine” several templates into one
child class at the same time, the abstract class is of little help in that case.
Fortunately, there is another mechanism that allows you to solve the
problem. It is based on using interfaces.
To use interfaces in practice, you first need to figure out how to create an
interface and, second, how to implement it in a class.
If a class implements an interface, then all methods from the interface must
be described in the class. The fact that the class implements an interface is
stated in the class description: the name of the interface implemented in the
class is given after the class name, using the keyword implements. If the
class implements multiple interfaces, they are listed after the implements
keyword, separated by commas. How all that looks like in practice is
illustrated in Listing 9-2.
279
<?php
interface Alpha{
function show();
interface Bravo{
function set($val);
private $num;
function __construct($val){
$this->set($val);
function set($val){
$this->num=$val;
function show(){
$obj=new MyClass(100);
$obj->show();
$obj->set(200);
$obj->show();
?>
280
$num = 100
$num = 200
The program describes two interfaces, Alpha and Bravo, and the MyClass
class that implements both. The Alpha interface has the show() method
(without arguments), and the Bravo interface has the set() method with one
argument. Therefore, these methods are described in the MyClass class. In
addition, the class has the private field $num and the constructor with one
argument. When the constructor is called, it calls the set() method, which
assigns a value to the $num field. The show() method is described so that
the value of $num is displayed when it is called.
command creates the $obj object with the value 100 of the field $num. The
$obj->show() command checks the field’s value. The $obj->set(200)
command assigns a new value to the field.
Interface Inheritance
One interface can inherit another interface. Everything happens the same
way as with class inheritance: the interface description is followed by the
extends keyword, and then the name of the inherited interface follows. As a
result, all the declarations from the inherited interface are “passed” to the
interface being created. A small illustration is shown in Listing 9-3.
281
<?php
// The interface:
interface Alpha{
function show();
function set($val);
public $num;
function set($val){
$this->num=$val;
function show(){
// Creates an object:
$obj=new MyClass;
$obj->show();
?>
$num = 123
282
Accordingly, the MyClass class that implements the Bravo interface should
contain (and does contain) descriptions of the set() and show() methods.
interface and then is implemented in a class is not good. Let’s explain that
using the example. In particular, the Bravo interface only explicitly declares
the set() method. You must trace the interface inheritance chain to
understand that you must define the show() method when implementing the
interface. That is not very good. The first option, when the class implements
two different interfaces, is much more convenient since you can
immediately identify the
contents you need to implement in the class.
Implementation
In such a case, in the class description after the class name, you put the
extends keyword, the name of the inherited class, the implements keyword,
and the names of the interfaces to be implemented. An example of that is
shown in Listing 9-4.
283
<?php
class Base{
public $number;
interface Alpha{
function show();
function set($number);
function set($number){
$this->number=$number;
function show(){
// Creates an object:
$obj=new MyClass;
$obj->set(123);
$obj->show();
?>
284
ChApTer 9 AdvANCed OOp MeChANIsMs
$number = 123
The program describes the Base class with the $number field. In addition,
you describe the Alpha interface with the show() method declared and the
Bravo interface with the set() method declared. The MyClass class inherits
the Base class and implements the Alpha and Bravo interfaces. The
$number field is inherited from the Base class in the MyClass class so that
you can refer to it in the description of the set() and show() methods. The
$obj object is created based on the MyClass class, so it has the $number
field and the show() and set() methods.
Traits
Traits do not play an independent role, but you can get a class by putting
them together. A trait is described as follows. You use the trait keyword,
after which a trait block is placed in curly braces. That is the block of code
added to the class if you include the trait. To include traits in a class, you
put the use instruction in the class body, then list the traits to be included in
the class, separated by commas. Listing 9-5 shows how that looks in
practice.
285
trait First{
private $number;
function show(){
trait Second{
function set($number,$symbol){
$this->number=$number;
$this->symbol=$symbol;
class MyClass{
use First,Second;
private $symbol;
function __construct($number,$symbol){
$this->set($number,$symbol);
$this->show();
$obj=new MyClass(100,'A');
?>
286
$number = 100
$symbol = A
“assemble” that class “in parts.” In particular, you describe two traits (the
First and Second). The First trait contains the private field $number
declaration, and the show() method. When the method is called, the values
of the $number and $symbol fields are displayed (the $symbol field is not
declared in the trait).
The Second trait describes the set() method with two arguments.
When called, the method assigns values to the $number and $symbol fields
(the fields are not declared in the trait).
First,Second instruction, which adds contents of the traits First and Second
to the class.
Note The situation is as if the contents of the traits First and Second were
described directly in the body of MyClass class.
In addition to the traits, you declare the private field $symbol in the class.
You also describe the constructor with two arguments in the class.
The set() and show() methods are called in the constructor so that the
$number and $symbol fields get values, and then the values of those fields
are displayed. So, the $obj=new MyClass(100,'A') command, which creates
an object of the MyClass class, automatically displays a message.
287
The object needs to have that method. How can you guarantee that? One
way is to specify the argument type in the function description explicitly.
But if you just specify the name of the class, then you can pass objects of
that class only (or its child classes) as an argument to such a function.
There is a more “refined” approach. It consists in creating an interface in
which the needed method is declared. Then, you create a function with an
argument whose type is the interface’s name. If so, an object of any class
implementing that interface can be passed as an argument of the function.
The fact that the object implements the interface guarantees that the object
has the needed method.
Details
You can create an abstract class with a declared method. If you specify the
name of that abstract class as a function argument type, you can pass an
object of any class that inherits the abstract class as a function argument.
<?php
// The interface:
interface MyInterface{
function show();
288
function show(){
echo "The class Alpha\n";
function show(){
$obj->show();
// Creates objects:
$A=new Alpha();
$B=new Bravo();
display($A);
display($B);
?>
The program describes the MyInterface interface, in which the show()
method is declared. It also creates two classes, Alpha and Bravo,
implementing the MyInterface interface. The display() function has one
argument whose type is MyInterface. That means you can pass objects of
the classes that implement the MyInterface interface as an argument to the
function. That ensures the object being the argument has the show()
method. The method is called in the function from the object passed as an
argument.
289
Note An error arises if you try to pass an object of the class that does not
implement the MyInterface interface to the
display() function. It happens even if that class contains the show() method.
There is another way to check the type of argument, which is not as tragic
in terms of consequences. It is based on the use of the instanceof
instruction, which can be exploited to check if an object is of a specific
type. Listing 9-7 is a version of the previous program, but this time, the type
of the display() function argument is not explicitly specified. Instead, the
argument type is checked in the function’s body.
<?php
// The interface:
interface MyInterface{
function show();
290
function show(){
class Bravo{
function show(){
echo "The class Bravo\n";
function display($obj){
$obj->show();
}else{
// Creates objects:
$A=new Alpha();
$B=new Bravo();
display($A);
display($B);
?>
291
Unlike the previous example (from Listing 9-6), the Bravo class contains a
description of the show() method, but it does not implement the
MyInterface interface. Also, the display() function description does not
specify the argument type. But in the body of the function, you use a
conditional statement. It checks the $obj instanceof MyInterface condition.
It is true if the $obj argument of the function is of the type MyInterface.
That is so if the class based on which the $obj object was created
implements the MyInterface interface. In that case, the show() method is
called from the $obj object. Otherwise, the echo "The argument type
error\n" command is executed.
A Namespace
But if, for example, functions belong to different namespaces, they may
have the same names.
292
ChApTer 9 AdvANCed OOp MeChANIsMs
instruction into the program and then put the name of the namespace.
The instruction must be the first command in the code. Then, if you want to
include some utilities in another program, you have to use the require_once
instruction to add the file that contains the namespace.
When referring to classes, functions, and other utilities from the imported
namespace, you put the namespace name and the backslash \ before the
class or function name.
<?php
// Creates a namespace:
namespace MyUtils;
class MyClass{
function show(){
?>
The code begins with the namespace MyUtils instruction, which means that
the following MyClass class and the hello() function belong to the MyUtils
namespace. It is assumed that the code is written to the listing09_08.php
file.
293
The next step uses the created MyUtils namespace. The code in which that
happens is shown in Listing 9-9.
<?php
require_once "listing09_08.php";
function hello(){
$obj=new MyUtils\MyClass();
// Calls a method from the object:
$obj->show();
hello();
MyUtils\hello();
?>
294
The hello() command calls the function described directly in the program.
To call the function from the MyUtils namespace, use the MyUtils\hello()
command. The result of the program execution is as follows.
A single file may describe several namespaces (nevertheless, that is not the
best option). If so, the blocks describing the contents of the namespaces
(including the namespace instructions) are specified one after another. It is
also possible to enclose the code of the same namespace in curly braces.
Let’s look at a small example. The program in Listing 9-10
<?php
namespace Alpha{
function show(){
namespace Bravo{
function show(){
}
?>
295
Each namespace contains the show() function that displays a message with
the namespace name. The namespaces are used in Listing 9-11.
<?php
require_once "listing09_10.php";
Alpha\show();
Bravo\show();
?>
After importing the contents of the namespace file with the require_
(for functions, the use keyword is also followed by the function keyword).
Listing 9-12 is the code for the MyUtils namespace with the show() and
display() functions and the MyClass class.
<?php
// A namespace:
namespace MyUtils;
function show(){
function display(){
}
class MyClass{
function __construct(){
?>
<?php
require_once "listing09_12.php";
// Creates aliases:
297
// Uses aliases:
show();
disp();
$obj=new MyClass();
?>
listing09_12.php file, you create aliases by the use function MyUtils\ show,
use function MyUtils\display as disp, and use MyUtils\
Anonymous Classes
There are situations when you need a class to create only a single object
based on it. In such cases, it is convenient to use anonymous classes. It
means that you create an object at the same time as you create a class.
298
<?php
$obj=new class{
private $number;
return $this->number;
$this->number=$number;
};
$obj->set(100);
?>
$number = 100
In that case, you create the $obj object with the help of the following
instructions (the comments are deleted).
new class{
private $number;
return $this->number;
299
$this->number=$number;
Summary
300
by commas.
by commas.
301
302
CHAPTER 10
Error Handling
303
The idea behind exception handling is very simple. You must provide some
program code to execute when an exception occurs. In PHP, you can
implement that idea in many different ways. Let’s start with the simplest
case and then explore the problem in detail.
So, let’s say there is a code block, and you suspect an error may occur
during its execution. What do you have to do? There is a simple recipe. It
assumes putting the mentioned code (the controlled code) in a special block
that begins with the try keyword and is enclosed in curly braces.
After the try block with the controlled code, the catch block is placed,
containing the code to be executed in an error. The following is the template
for the whole try-catch.
try{
}catch(Error_type $object_name){
The catch keyword is followed by the error class name and a formal
notation in parentheses for the error object (the variable identified with the
error object).
304
Details
the point is that when an error occurs, an object that contains information
about the error is automatically created. the information can, in principle, be
used when processing the error. the catch block contains the name of the
error class (the error type) and the error object.
You can use different processing methods to handle errors of different
types. if so, then in the try-catch construction, use several catch blocks—
each one for an error of a specific type.
in PHP 8, you can (if you need to) specify only the exception class name in
the catch block description in parentheses after the catch keyword without
any variable for the exception object.
First, the controlled code is executed. If there is no error, the catch block is
ignored. If there is an error in the try block while executing the controlled
code, the try block is stopped, and the catch block is executed. Then, the
command after the try-catch construction is run. How that looks in practice
is illustrated in Listing 10-1.
<?php
try{
$input="\$x=".trim(fgets(STDIN)).";";
305
// If an error occurs:
}catch(ParseError $e){
?>
Thus, if no error of the ParseError class occurs during the code execution in
the try block, then the catch block is ignored, and the calculated value of the
$x variable is displayed. If an error occurs, the value of $x is not displayed,
and the code in the catch block is executed instead. But in any case, the
echo "The program is over\n" command is executed after the try-catch
construction.
The result of the program execution depends on what expression the user
enters. If the expression is a correct PHP statement, the result is as follows
(the user input is marked in bold).
306
$x = 23
Exception Classes
307
Method
Description
getMessage()
exception.
getCode()
getFile()
getLine()
getTrace()
the stack trace is returned (as an array).
getPrevious()
__toString()
exception object.
Note in the interface, the methods are only declared. the purpose of the
methods is given following how they are defined in the classes that
implement the interface.
308
Class
Description
ArgumentCountError
ArithmeticError
it inherits the Error class. exceptions of this class
mathematical operations.
AssertionError
CompileError
DivisionByZeroError
to divide by zero.
Error
ErrorException
Exception class.
Exception
it implements the Throwable interface and is the
ParseError
command).
( continued)
309
Class
Description
TypeError
UnhandledMatchError
ValueError
In addition to the listed exception classes, you can create your own—
usually by inheriting the Exception class. The custom class exceptions are
used for throwing exceptions artificially.
Throwing Exceptions
310
CHaPter 10 errOr Handling
Note in fact, this scheme is similar to the one used in the conditional
statement, save that throwing an exception is used instead of the condition.
You use the throw statement followed by the exception object to throw an
exception. An exception object is created the same way you create objects
of any other class: after the new statement, you put the class name and, if
necessary, the arguments passed to the class’s constructor.
Note it is worth mentioning that just creating an exception object does not
cause the exception to be thrown.
<?php
// Reads a number:
$number=(int)trim(fgets(STDIN));
try{
if($number>0){
// Throws an exception:
}
311
if($number<0){
// Throws an exception:
// if no exception is thrown:
// Displays a message:
echo $e->getMessage();
?>
During the program execution, the user is prompted to enter a number. The
number is saved to the $number variable. The following code is enclosed in
the try block and uses two conditional statements in a simplified form. The
first one checks the $number>0 condition. If it is true, the throw new
Exception("A positive number") command throws an exception of the
Exception class. The new Exception("A positive number") statement creates
an anonymous object of the Exception class.
OceanofPDF.com
The string passed to the class constructor describes the thrown exception.
312
The last command in the try block is the echo "The zero" statement.
If an exception is thrown while executing the code, the code in the try block
is terminated, and the code in the catch block starts executing. There is a
single echo $e->getMessage() command in the block, which displays a
message associated with the thrown exception (the text that was passed to
the constructor when the exception object was created). The getMessage()
method gets the message string from the $e exception object.
If no exception is thrown when executing the code in the try block, the echo
"The zero" command is eventually executed, and the catch block is ignored.
possible when the program is executed. If the user enters a positive number,
the result is like the following (the value entered by the user is marked in
bold).
Enter a number: 5
A positive number
The following is the result when the user enters a negative number.
Enter a number: -5
A negative number
Finally, if the user enters zero, the result of the program execution is as
follows.
Enter a number: 0
The zero
313
In this case, you have thrown exceptions of the Exception class. As noted,
you can create your own in addition to the built-in exception classes.
The recipe for creating your own exception class is simple: you just need to
create a child class for the Exception class. An example is shown in Listing
10-3.
<?php
private $error;
// The constructor:
function __construct($msg,$error){
parent::__construct($msg);
$this->error=$error;
function __toString(){
return $txt;
314
class Odd{
// A private field:
private $number;
// The constructor:
function __construct($number){
$this->number=$number;
function __toString(){
class Even{
// A private field:
private $number;
// The constructor:
function __construct($number){
$this->number=$number;
function __toString(){
return "The number ".$this->number." is even\n";
for($count=1;$count<=3;$count++){
// The message:
$msg="attempt ".$count;
315
$number=(int)trim(fgets(STDIN));
try{
if($number%2==0){
// Throws an exception:
}catch(MyException $e){
echo $e;
?>
The result of the program execution could be as follows (entered by the user
values are marked in bold).
316
Enter a number: 5
The message: attempt 3
inheriting the library class Exception. In that class, you declare the private
$error field. It is supposed that the field is assigned a reference to some
object.
The class has a constructor with two arguments. The first argument (denoted
as $msg) is passed as an argument to the parent class constructor (the
parent::__construct($msg) command in the constructor body).
In addition to the MyException class, you create two classes: Odd and Even.
They have a similar structure and differ in some details (namely, by the
result that the __toString() method returns). Each class has the private field
$number and the constructor with a single argument specifying that field’s
value. The __toString() method returns a string containing the value of the
$number field and information about whether the number is even or odd.
After describing the classes, you run the loop statement for three iterations
(the $count variable is used as a counter). For each loop, the $msg="attempt
".$count command generates a string with the current 317
Details
318
Details
if the catch block is designed to handle exceptions of a certain class, it also
handles exceptions of its child classes.
<?php
$A=(double)trim(fgets(STDIN));
$B=(double)trim(fgets(STDIN));
try{
if($A==0){
// If the second parameter is zero:
319
$x=$B/$A;
}catch(AnyNumberException $e){
}catch(NoRootsException $e){
?>
Depending on what values for the parameters A and B are entered by the user
(marked in bold), the following results of the program execution are
possible. The following occurs when a nonzero value is entered for the
parameter A, while the parameter B also has a nonzero value.
A = 2.4
B = 12
The root is $x = 5
The following is the result of the program execution if the parameter A has a
nonzero value and the parameter B is equal to zero.
320
A=5
B=0
The root is $x = 0
B=0
Finally, if the parameter A is zero and the parameter B is nonzero, the result
is as follows.
A=0
B=1
You have used the following strategy. The program reads the values entered
by the user for the parameters and then tries to calculate the solution of the
equation. But while executing the code, one of two custom class exceptions
can be thrown under certain conditions. Here, you have a
“general line” and two “special cases,” which are handled with the help of
exception catching.
321
You read the values of the parameters of the equation and write those values
to the $A and $B variables. The main calculations are performed in the try
block. You also use a conditional statement in a simplified form.
thrown. in both cases, it does not reach the execution of the commands
placed after the external conditional statement since handling of the thrown
exception begins.
handling blocks, and the exception class was used to identify the scenario to
implement. But you could act somewhat differently, “hiding”
322
CHaPter 10 errOr Handling
<?php
// The constructor:
function __construct(){
// The constructor:
function __construct(){
$A=(double)trim(fgets(STDIN));
try{
$x=$B/$A;
}catch(AnyNumberException|NoRootsException $e){
echo $e->getMessage();
?>
323
The result of the program execution is the same as in the previous case.
However, the execution algorithm has changed slightly. There are two main
changes. First, the message displayed when an exception is generated is
associated with the exception object. This message can be retrieved using the
getMessage() method. Second, you combined two catch blocks into one by
specifying the AnyNumberException|NoRootsE
the $A==0&$B==0 condition is true if the $A==0 and $B==0 conditions are
both true. the $A==0&$B!=0 condition is true if the $A==0 and $B!=0
conditions are both true.
324
<?php
$color=strtolower(trim(fgets(STDIN)));
// The outer block of the controlled code:
try{
try{
// Makes a selection:
switch($color){
case "red":
case "green":
case "blue":
default:
}catch(RedException $e){
}catch(GreenException $e){
}catch(BlueException $e){
echo "Blue is stylish\n";
325
catch(OtherException $e){
?>
In this program, the user is prompted to enter the name of a color, and
depending on the entered value, the program displays specific messages.
The entered by the user name of a color is written to the $color variable.
First, the symbols in the string are converted to lowercase, for which the
strtolower() function is used. Next is the outer try block with the inner try-
catch-finally construction inside. In the inner try block, the switch statement
is executed, in which the value of the $color variable is checked. If the
variable’s value is "red", then an exception of the RedException class is
thrown. The "green" value throws an exception of the GreenException class.
If the variable’s value is "blue", a BlueException exception is thrown. In all
other cases, an exception of the OtherException class is thrown.
326
Let’s discuss how the code is executed. First, the string the user enters is
read and written to the $color variable, and the variable’s value is checked in
the switch statement. As a result, one of the four classes of exceptions is
thrown. If it is an exception of the RedException, GreenException, or
BlueException class, it is handled in one of the catch blocks of the inner try-
catch-finally construction. Then, the finally block is executed, and the echo
"You have a good taste\n" instruction after that block. The outer catch block
is ignored, and the last instruction, echo "The program is over\n", is
executed.
The result of the program execution depends on the value entered by the user
(the values entered by the user are marked in bold). Symbols in the name of
a color does not matter. In particular, the result could be as follows.
Red is beautiful
Thank you for the answer
Green is wonderful
327
Blue is stylish
Once again, two things are worth mentioning. First, if the inner try-catch
construction does not handle an exception, it is passed to the outer try-catch
construction for handling. Second, the code in the finally block is always
executed, both if an exception is thrown and if no exception is thrown.
Rethrowing an Exception
An exception can be thrown after it has been thrown. In that case, the same
exception object is used multiple times. Let’s consider a problem that solves
a linear equation once again as an example of using such an approach. The
program is shown in Listing 10-7.
328
<?php
$B=(double)trim(fgets(STDIN));
try{
try{
// Throws an exception:
$x=$B/$A;
}catch(MyException $e){
?>
329
The result of the program execution is the same as in Listing 10-4. But the
code is worth analyzing.
You use the exception class MyException. After reading the values of the $A
and $B variables, the block of the controlled code is executed. It contains the
inner try block in which, if the condition $A==0 is true, an exception of the
MyException class is thrown. If the condition is false, the $x=$B/$A and
echo
"The root is \$x = $x\n" statements are executed. The first statement
calculates the root of the equation. The second statement displays the result
of the calculation. Those statements are not executed if an exception is
thrown. If it is, the exception is handled in the inner catch block. The
handling is based on checking the condition $B==0. If the condition is false,
the echo "There are no roots\n" instruction is executed. If the condition is
true, the throw $e command rethrows the previously thrown exception. Here,
$e denotes the exception object passed to the inner catch block for handling.
The exception is caught and handled in the outer catch block this time. In
particular, the echo
Details
it turns out that if one of the parameters of the equation is zero, a custom
class exception is thrown. if, while handling this exception, it turns out that
the second parameter is equal to zero, then the exception is rethrown.
rethrowing an exception means you are using the exception object thrown
earlier.
Very often, errors that occur during the execution of a program are not
critical and do not cause the program’s termination. The typical external
effect in such a case is an error or warning message. Different techniques
and schemes allow you to react to such situations adequately. But even if
330
the error is critical and is not caught in the program (using the try-catch
construction), you can still “fight” against it.
Details
function handler(){
set_exception_handler('handler');
// Displays a message:
// Throws an exception:
331
?>
In this case, you describe the handler() function, and the name of the
function (as a string) is passed as an argument to the set_exception_
Note there are other functions useful when dealing with errors and
exceptions. For example, you can use the set_error_
handler() function to define error handlers. You can throw errors using the
trigger_error() function. and the list is not complete.
332
Summary
executed.
class to be handled.
exception.
• Special functions and utilities allow you to set the error control mode.
Among them are the error message
333
CHAPTER 11
Generators
and Iterators
they mean.
That object resembles an array in its properties. But it is not really an array.
335
Details
Let’s consider the specifics of creating and using the generator functions
employing small examples. You first need to know that the object returned
by a generator function can be used to get a sequence of values.
In particular, to get the current value, you can use the current() method, and
to shift to the next value, you involve the next() method.
<?php
// A generator function:
function colors(){
yield "Red";
yield "Yellow";
yield "Green";
}
// Calls the generator function:
$color=colors();
336
for($k=1;$k<=3;$k++){
$color->next();
?>
[1] Red
[2] Yellow
[3] Green
In this case, you describe the colors() generator function, where you use the
yield "Red", yield "Yellow", and yield "Green" commands.
That means that the resulting generator object (which you get when calling
the colors() function) generates the values "Red", "Yellow", and
"Green".
Thus, the $color variable refers to an object of the Generator class. That
object has, among other things, the methods current() and next(). If you call
the current() method from the $color object, you get the value
"Red". If, after that, you call the next() method and then the current() method
again, you get the value "Yellow". Finally, another call of the next() and
current() methods gives you the value "Green". All that is illustrated by the
for loop statement, in which the current() and next() methods are called three
times from the $color object.
337
Details
If you call the current() method after three calls to the next() method (that is,
after all the values “written” to the $color object have been iterated), you get
a null reference.
There would be little use for the generator functions if two methods had to
be called each time to generate a new value. Listing 11-2 illustrates a better
way to use a generator function.
<?php
// A generator function:
function colors(){
foreach(colors() as $color){
echo $color,"\n";
?>
Red
Yellow
Green
338
The code of the colors() generator function was slightly changed. The list of
generated values is now implemented as an array, and the yield statement is
called in the foreach loop statement in the function body.
Also, you do not write the instruction with the function call into a separate
variable but directly indicate it as a collection to be iterated in the foreach
loop statement. The result is that instead of calling the color() function, you
would specify an array with values displayed when the program is executed.
<?php
function numbers($count,$start,$step=1){
for($k=1,$num=$start;$k<=$count;$k++,$num+=$step){
yield $num;
echo "[1]";
339
echo "\n[2]";
echo "\n[3]";
?>
[1] 1 3 5 7 9
[2] 3 4 5 6 7 8 9
[3] 10 9 8 7 6 5
The numbers() function is described with three arguments (the last one has a
default value). The function is designed to create an object that generates a
numeric sequence. The first argument $count specifies how many numbers
should be in the sequence. The second argument $start specifies the first
value in the sequence. The third argument, $step (with the default value 1),
specifies the increment when calculating the sequence. The core of the
function is the loop statement. The count of cycles is determined by the
$count argument. The $num variable, used in the yield $num command, gets
the initial value defined by the $start argument. For each loop, the variable’s
value is incremented by the value determined by the $step argument.
You call the number() function in the foreach loop statements used to display
the sequence of numbers. So, the numbers(5,1,2) instruction means
generating the sequence of 5 numbers, the initial value is 1, and each next
number is 2 more than the previous one. The numbers(7,3) 340
CHApTer 11 GenerATorS And ITerATorS
for($k=1;$k<=$n;$k++){
yield $k;
Then, the following command inclusively creates the array of numbers from
1 to 5, and a reference to the array is written to the $A variable.
$A=iterator_to_array(nums(5));
Listing 11-4 creates a function that duplicates the work of the built-in
iterator_to_array() function.
<?php
341
// An empty array:
$array=[];
foreach($gen as $a){
$array[]=$a;
return $array;
// A generator function:
function nums($n){
for($k=1;$k<=$n;$k++){
yield $k;
// Creates an array:
$A=generator_to_array(nums(5));
print_r($A);
?>
Array
[0] => 1
[1] => 2
[2] => 3
[3] => 4
[4] => 5
342
command creates an empty array in the function body. The foreach loop
statement then iterates over the values produced by the $gen generator
passed as an argument to the function. By the $array[]=$a command, the
next received value of $a is added to the end of the $array array, which is
eventually returned as the result of the function.
The program also describes the nums() function, which creates the generator
for a sequence of natural numbers. The argument of the function determines
how many numbers are in the sequence. Therefore, when the
$A=generator_to_array(nums(5)) command is executed, the array of 5
343
<?php
// A generator function:
function randoms($n){
for($k=1;$k<=$n;$k++){
$number=rand(1,9);
yield $number;
$sum+=$number;
return $sum;
// A generator object:
$rnd=randoms(5);
foreach($rnd as $r){
?>
A possible result of the program execution can be as follows.
49415
The sum: 23
344
Details
The built-in rand() function generates random numbers. You call this
function with two integer arguments that define the bounds of the range
within which the random number is generated.
Then, use the yield $number command to include the generated value in the
list of generated values. Then, due to the $sum+=$number command, the
value of the $number variable is added to the current value of the $sum
variable.
statement. That means that when the getReturn() method is called from the
generator object, you get the value of the $sum variable, which is the sum of
the generated random numbers.
Details
Although the return statement formally returns an integer, the randoms()
generator function returns a generator object. You can call the getReturn()
method from a generator object only after the object has been “worked
out”—
that is, after you have “looked through” the generator object in the foreach
loop statement.
345
generate five numbers), and a reference to the object is written to the $rnd
variable. Use the object in the foreach loop statement. Finally, you exploit
the $rnd->getReturn() instruction to determine the sum of the generated
numbers.
Using Generators
Namely, let’s analyze a few simple examples, starting with Listing 11-6.
<?php
// A generator function:
function nums(){
for($k=100;$k<=300;$k+=100){
yield $k;
}
// Creates a generator object:
$nums=nums();
try{
foreach($nums as $n){
346
}catch(Exception $e){
?>
Something is wrong
What is the program’s output? You get the numbers 100, 200, and 300
the first time. But then you get an exception. It happens since the generator
object is an object “for a single use.” It can be “iterated through” only once.
After that, you must create a new generator object to generate the same
sequence of values. If you try to iterate an object that has already been
iterated, you get an error. Therefore, instead of writing a reference to the
generator object into a variable, the generator function call instruction is
used directly in practice. A small variation of the previous example is shown
in Listing 11-7.
347
<?php
function nums(){
for($k=100;$k<=300;$k+=100){
yield $k;
try{
foreach(nums() as $n){
}catch(Exception $e){
?>
The result of the program execution has changed. The numbers 100, 200,
and 300 are displayed both times, and no exception is thrown. Changes to
the program code are minimal. You no longer use a variable to store a
reference to 348
the generator object, and in the foreach statements, where the $nums
variable used to be, the instruction that calls the nums() function is now
placed. What does it change? Each time the nums() function is called, a new
generator object is created, so, in this case, you do not reuse the generator
object.
<?php
// A generator function:
function gen(){
yield 123;
// A generator object:
$gen=gen();
?>
123
You use the very simple generator function gen(), which executes the echo
"A generator function is executed\n" command followed by the yield 123
statement. That means that the message is displayed first, and then the
number 123 is added to the list of the values to be generated.
349
>current(),"\n" statements are executed. You might expect that first, you get
the A generator function is executed message, followed by the A generator
object is created message. And after that, you might expect that the value
123 is displayed. However, the first two messages appear in a different order.
The reason is that executing the $gen=gen() statement does not lead to
executing the code described in gen(). The actual function code only starts
executing when the current() method is called from the $gen object.
Objects of the Generator class have the rewind() method, which allows you
to execute the part of a generator function code before the first yield
instruction. A modification of the previous program where you use the
rewind() method is shown in Listing 11-9.
<?php
function gen(){
yield 123;
$gen=gen();
$gen->rewind();
echo $gen->current(),"\n";
?>
350
123
In this case, the $gen->rewind() command is executed as soon as the
generator object is created. As a result, the message A generator function is
executed is displayed first. Then, the message A generator object is created is
also displayed.
The yield instruction can be used to form a list of generated values and pass
a value to a generator. The yield keyword is identified with the value passed
to the generator object using the send() method.
Details
You can call the send() method from a generator object and pass some
argument to the method. In the body of the corresponding generator
function, that value (the argument of the send() method) can be accessed
using the yield keyword.
<?php
// A generator function:
function nums($n){
351
// The sum:
$sum=0;
$number=yield;
$sum+=$number;
return $sum;
$n=5;
// A generator object:
$nums=nums($n);
for($k=1;$k<=$n;$k++){
// Reads a number:
$num=(double)trim(fgets(STDIN));
$nums->send($num);
// The sum:
The result of the program is as follows (the numbers entered by the user are
marked in bold).
352
The sum: 15
command returns the value of the $sum variable as the result of the
getReturn() method.
Next, that value is sent to the generator object; to do that, use the $nums-
>send($num) command. After reading all the values, using the $nums-
>getReturn() instruction, you get the result for the sum of the numbers
entered by the user.
Iterators
353
Method
Description
current()
key()
The method returns the key/index of the current value of the iterator.
next()
The method shifts to the next value of the iterator.
rewind()
The method for setting the iterator to the state to generate the first value.
valid()
Note It is not surprising that generator objects have the same methods since
the Generator class implements the
Iterator interface.
<?php
private $last;
private $previous;
private $key;
354
// The constructor:
function __construct($max){
$this->max=$max;
$this->rewind();
$this->key=1;
$this->previous=1;
$this->last=1;
return $this->previous;
return $this->key;
}
public function next(){
++$this->key;
$this->last+=$this->previous;
$this->previous=$this->last-$this->previous;
$this->max=$max;
355
$fibs=new Fibonacci(10);
foreach($fibs as $f){
echo $f," ";
echo "\n";
$fibs->resize(15);
foreach($fibs as $f){
?>
1 1 2 3 5 8 13 21 34 55
The PHP 8 Standard Versions higher than pHp 8 display a set of warnings
since the class methods that implement the Iterator
interface should be described with the return type (stated after braces with
the method’s arguments through a colon). namely, you should use the
following description of the Fibonacci class (the comments are discarded,
and the added blocks of code are marked in bold).
private $last;
private $previous;
356
private $key;
private $max;
function __construct($max){
$this->max=$max;
$this->rewind();
$this->key=1;
$this->previous=1;
$this->last=1;
return $this->previous;
return $this->key;
}
public function next(): void{
++$this->key;
$this->last+=$this->previous;
$this->previous=$this->last-$this->previous;
$this->max=$max;
357
Another solution is to precede each method (from the Iterator interface) with
the #[\ReturnTypeWillChange] attribute.
Let’s create the Fibonacci class that implements the Iterator interface. An
object of the class is designed to generate a sequence of the Fibonacci
numbers (the first two numbers are equal to one, and each next is equal to
the sum of the previous two). The class has the private $last and $previous
fields that are supposed to store the last and last but one number in the
sequence. The private field $key is used to store the key of the generated
number. The $max field contains the value that determines how many
numbers are generated in the sequence.
The constructor has a single argument that specifies the value of the $max
field. The rewind() method is called in the body of the constructor.
When the method is called, the $key, $previous, and $last fields are assigned
values.
When called, the current() method returns the value of the $previous field.
The key() method returns the value of the $key field.
statement, the value of the $key field is incremented by one. Next, the $this-
>last+=$this->previous and $this->previous=$this->last-
The valid() method is used (automatically) to check that the iterator is ready
to generate a value. The $this->key<=$this->max condition is checked in the
method’s body. It is true if the current number key does not exceed the
maximum value set for the sequence. If so, the method returns true.
Otherwise, it returns false.
358
Details
You need the valid() method to determine when the iteration of the elements
in the loop statement ends.
Summary
statement.
359
iterator into the state to generate the first value. You can
iterator is ready.
360
CHAPTER 12
Using PHP
Unlike most other popular languages, PHP is not used “on its own.” It is
used “in a context.” PHP was developed for creating web programs or
scripts. Accordingly, PHP is designed for web programming. Next, let’s look
at some simple tasks and situations that explain how PHP code can be used
in web development.
361
Let’s explore how to create (using the PHP tools) a document that contains a
list of the Fibonacci numbers (the first two numbers are equal to one, and
each subsequent number is equal to the sum of the two previous numbers).
In that case, instead of writing the numbers in the document explicitly, use
PHP code to generate the corresponding content.
Details
Documents with HTML markup usually have the .html extension. For the
browser, that is an indicator that the document contains hypertext markup. If
you want to place PHP code in a document with HTML markup, the
corresponding file should be saved with the .php extension.
<!DOCTYPE html>
<html>
<head>
<body>
<p>The first two numbers are equal to one, and each next number is equal to
the sum of the two previous ones. Here are the
numbers:</p>
<p>
<?php
$n=20;
$a=1;
$b=1;
for($k=3;$k<=$n;$k++){
362
$b=$a+$b;
$a=$b-$a;
?>
</p>
</body>
</html>
Details
so, suppose that there are two computers: a client and a server. They are
connected to each other. a browser is launched on the client computer, and
using that browser, you try to open a document hosted on the server
computer. When the client receives the document, it renders it based on the
HTML markup.
If you request a PHP document on the server through the client browser, then
that document is executed on the server as a script, and the result is returned
to the browser. If the document contains both HTML markup and PHP code,
then the already existing HTML markup remains "as it is", and instead of the
PHP code, the result of its execution is substituted. The total result is a
document with HTML
markup designed to be displayed by the browser. You may say that you deal
with dynamic documents since their contents can change due to the
execution of PHP
scripts directly while processing the document. That is how the preceding
document is organized. It contains “static” HTML code and a block of PHP
code, which “is transformed” into a block of hypertext markup during
execution.
363
In fact, after executing the PHP code, the browser receives such a document.
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<p>The first two numbers are equal to one, and each next number is equal to
the sum of the two previous ones. Here are the
numbers:</p>
<p>
1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181,
6765, and so on.</p>
</body>
</html>
This code differs from Listing 12-1 because the following HTML code is
inserted instead of the PHP block.
1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181,
6765, and so on.
<?php
$n=20;
$a=1;
$b=1;
364
for($k=3;$k<=$n;$k++){
$b=$a+$b;
$a=$b-$a;
?>
Namely, the last and the one before the last numbers in the sequence (two
ones) are stored in the $a and $b variables. A new number is calculated for
each loop. The result is displayed in the document.
Note You can imagine all that as if the program prints directly into the
document.
Viewing the document in the browser window shows the result shown in
Figure 12-1.
Figure 12-1. Displaying the document with PHP code in the browser
window
365
That is, everything is more or less simple. The only thing left is figuring out
how to get the result presented here.
all descriptors in an HTML document are enclosed in angle brackets < and
>.
Between the angle brackets, you put the descriptor’s name. Most descriptors
are paired ones: there is an opening descriptor, and there is a closing
descriptor. The closing descriptor contains a forward slash / in front of the
descriptor name. everything between the opening and closing descriptor is
the contents of the descriptor. For example, an entire HTML document is
enclosed in a block delimited by <html> and </html> tags. The beginning
instruction
The <html> block contains the <head> block and the <body> block. The
<head> block, in turn, contains the <title> block whose contents (the text
placed between the <title> and </title> tags) are displayed in the tab in the
browser window.
The <h1> and </h1> tags define the first-level heading. a paragraph is
defined using the <p> and </p> tags.
366
CHaPTer 12 UsINg PHP
Let’s consider the technical side of the issue. When dealing with the
document, you suppose that the browser on the client computer makes the
request, and the PHP code is executed on the server computer. Moreover,
even if it is possible to place the document on the server, the debugging
process is not the most pleasant in such a case. Therefore, using the same
computer as the client and server during development is natural. There are
several ways to do that. The following describes the one that seems to be the
most simple, convenient, and understandable. It is about running a local
server.
You can learn how to start a local server and use the NetBeans environment
there. Here, you refresh a little the knowledge gained earlier.
First comes the php (or php.exe) instruction, after which you put the
367
Details
Different programs and services send and receive requests when the client
and server interact. a unique numeric identifier matches a program and a
message sent for that program. It is called a port. Many services choose a
port automatically, but in this case, you need to specify the port explicitly.
That can be almost any number, but for reliability (to not specify the port
already in use), selecting a port after 5000
The port is followed by the -t option and a folder on the hard drive that is the
server’s root directory. For example, you can use the following command.
php -S localhost:6789
Details
In Windows, you can use explorer to navigate to the folder you want to use
as the root directory of the local server and enter the cmd command in the
address bar.
You may also have to specify the full path to the php.exe file. For example,
if the php.exe file is in the C:\PHP folder, the command looks like
C:\PHP\php -S
localhost:6789.
368
CHaPTer 12 UsINg PHP
After starting the local server, you can view the document in a browser
window. If the file is called listing12_01.php and is located in the D:\
Books\php\codes folder, which serves as the root directory for the local
server, then you need to enter the following request in the browser address
bar.
localhost:6789/listing12_01.php
Note The scheme described is acceptable for testing all examples discussed
next.
When you enter the page’s address into the browser’s address bar, you can
specify additional parameters and their values. That can be done quite
simply. After the address, you place the question mark (?) followed by the
parameter and its value in a parameter=value format. The & symbol is used
as a separator if there are multiple parameters.
<!DOCTYPE html>
<html lang="en">
<head>
<title>Greetings</title>
</head>
<body>
369
<h1>Welcome Page</h1>
<?php
echo $name;
?>
</p>
</body>
</html>
First, let’s look at the result of the code execution and then analyze it.
So, you start the local server; for example, using port 6789 (the php -S
localhost:6789 command from the folder with the listing12_02.php file with
the program), and enter the following request in the address bar of the
browser.
localhost:6789/listing12_02.php
Figure 12-2. The browser window if the name parameter is not passed in the
request
370
In this case, the browser renders the document with the following HTML
markup.
<!DOCTYPE html>
<html lang="en">
<head>
<title>Greetings</title>
</head>
<body>
<h1>Welcome Page</h1>
</p>
</body>
</html>
The document contains a greeting with the name Mister X marked in bold.
a pair of the <strong> and </strong> tags were used to bold the text.
Next, in the browser’s address bar, you enter another command (the
important part of the command is marked in bold).
localhost:6789/listing12_02.php?name=Mickey Mouse
Note a space in the name parameter value in the browser’s address bar is
automatically replaced with the %20 instruction.
371
Figure 12-3. The browser window if the name parameter is passed in the
request
In this case, specify the Mickey Mouse value for the name parameter in the
request. As a result, that value is displayed on the welcome page. The
document now has the following HTML markup.
<!DOCTYPE html>
<html lang="en">
<head>
<title>Greetings</title>
</head>
<body>
<h1>Welcome Page</h1>
</p>
</body>
</html>
The markup differs from the previous case only in the name (Mickey Mouse
instead of Mister X). That effect is achieved using the PHP code included in
the source document in Listing 12-2. The code is quite simple.
372
<?php
?>
The main task is solved using the conditional statement. It checks the
isset($_GET["name"]) condition. The condition is true if there is an element
in the $_GET array with the key "name". Here, you need to consider that all
parameters passed in the request are stored in the $_GET
array. The name of the parameter is the key of the element, and the value of
the parameter is the element’s value. Therefore, you can use the
$_GET["name"] instruction to get the name parameter value passed in the
request. However, the problem is that the user may not pass a value for the
name parameter in the request. Therefore, you first check if the $_GET
array contains the corresponding element. If the element exists, then the
$name=$_GET["name"] statement assigns the value of the name parameter
to the $name variable. If the required element is not in the array, the $name
variable is assigned the "Mister X" value. After that, the echo $name
instruction writes the value of the $name variable to the HTML document.
Using Buttons
Often, when working with HTML documents, use forms. Those are special
blocks with controls, such as buttons, input fields, options, radio buttons,
and drop-down lists. Next, let’s examine another example similar in
functionality to the previous one, but you use a button and an input field this
time. To understand how it works, let’s start with the result.
Assume that there is an index.html file in a folder. The file must have exactly
that name since a file with such a name is automatically downloaded when
accessing the server (unless the file is explicitly specified in the request).
373
CHaPTer 12 UsINg PHP
Details
After running the local server, you enter the request localhost:6789
into the browser’s address bar (or specify a different port, depending on
which one was indicated when running the local server). The result is shown
in Figure 12-4.
The window contains an input field with the text What is your name?
above it, as well as the Submit button. If you just click the button (without
filling in the field), then the contents of the browser window change and is
as in Figure 12-5.
374
CHaPTer 12 UsINg PHP
Figure 12-5. The result of clicking the Submit button in the case of the
empty field
You can also do otherwise – enter a name in the field and click the Submit
button, as shown in Figure 12-6.
Figure 12-6. The form with the filled field before submitting data After
pressing the Submit button, you see the result shown in Figure 12-7.
375
CHaPTer 12 UsINg PHP
Figure 12-7. The result of clicking the Submit button in the case of the filled
field
Thus, after pressing the Submit button, a greeting appears. If the field was
empty when submitting the form data, the name Mister X is displayed in the
greeting. If the field was filled in, the greeting displays the name specified in
this field. Now, let’s turn to the program code. You start with the contents of
the index.html file.
<!DOCTYPE html>
<html lang="en">
<head>
<title>Greetings</title>
</head>
<body>
<h1>Introduce yourself</h1>
<button>Submit</button>
</form>
</body>
</html>
376
It can be understood that you deal with a text field due to the type attribute
whose value is "text".
A button is created using the <button> and </button> tags. The text between
these tags is the name of the button.
It is crucial here which attributes are specified for the form and the input
field. In particular, you use three attributes for the form. The method
attribute is set to "post". It defines how the form data is submitted.
Details
There are two methods for submitting form data: geT and POsT. The
difference is in the way the data is transmitted. In general terms, the geT
method transfers data without encoding. an example of transferring data
using the geT method has already been given in the example with processing
parameters passed in the request in the address bar.
The POsT method transfers data more safely. In this example, you use it to
transfer data to the server.
The target attribute with the value "_self" means that the response sent by
the server is displayed in the same window where the form was displayed.
377
Details
Let’s talk about the scheme. The browser on the client side makes a request
to the server. The server sends a response – the page with the form. There is
the Submit button. The form data is sent to the server when the button is
clicked. The server processes the data (for doing that, a script is used that
can be explicitly specified in the form description) and then sends a response
(HTML code) to the browser.
The document, among other things, can be displayed in the window where
the document with the form was displayed initially. That is the approach you
use in the example.
Finally, the action attribute defines the script to process the form data. The
HTML code resulting from executing the program is sent back to the
browser. In this example, the value of the action attribute is the text
Details
The listing12_03.php file must be in the same folder as the index.html file. If
the file is located in another folder, then you should specify the full path to
it, starting from the root directory (in this case, that is the place where the
index.html file is located).
Submitting the form data means passing information about the state of the
form’s controls to the server. When processing the data, the controls need to
be identified somehow. For that purpose, set the name attribute for the
controls. In this case, there is only one control (however, it also needs to be
identified). You set the input field’s name attribute to "name".
Submitting the form data means that the server gets the value contained in
the input field when the Submit button is clicked.
378
So, you know now what is sent to the server. The question is how the data
received by the server is processed. According to the value of the form’s
action attribute, the program from the listing12_03.php file is responsible for
processing the form data. The program code is shown in Listing 12-3.
<!DOCTYPE html>
<html>
<head>
<title>Welcome</title>
</head>
<body>
<h1>Welcome</h1>
<?php
if(empty($_POST["name"])){
$name="Mister X";
else{
$name=$_POST["name"];
echo $name;
?>
</body>
</html>
379
You are dealing with HTML code with the following PHP block
added to it.
<?php
if(empty($_POST["name"])){
$name="Mister X";
}
else{
$name=$_POST["name"];
echo $name;
?>
A text fragment is inserted into the document when the code is executed. But
to define that text, you need to make some manipulations.
The first step is to get the value entered by the user in the form’s input field.
As noted, you use the POST method to send the data, and the field name
attribute from which to read the text has the value "name". Attributes that are
passed by the POST method are automatically stored in the $_POST
global array. The name attribute’s value (enclosed in double quotes) is the
element’s key, and the passed value (the contents of the input field) is the
array element’s value.
"name". That may cause some ambiguity. Note that the "name" key of the
$_POST["name"] element is associated with the "name"
value of the name attribute. If the input field’s name attribute had the value
"newname", then the value written to the input field would be passed as the
$_POST["newname"] element.
380
Often, you have to use several buttons in the same form. When pressing
different buttons, the reaction of the server should be different. The
following example explains how to implement such a task using PHP. Like
in the previous example, let’s start with the results.
Details
as before, the local server is launched from the folder where the index.html
file is located. In other words, you should place the index.html file in the
folder that serves as the root directory for the local server. The code for that
file is discussed later.
381
CHaPTer 12 UsINg PHP
Figure 12-8. The initial browser window with a form and two buttons
Details
To see the window, you should enter localhost, followed by a colon, and the
port number specified when running the local server in the browser’s address
bar. For example, that could be localhost:6789.
The window contains a small text and two buttons named First and Second.
You can click any of them. If you click the First button, you get the result
shown in Figure 12-9.
Figure 12-9. The result after pressing the First button 382
Now, the browser window contains a message with the name of the clicked
button. The same happens if you click the Second button in the initial
window (see Figure 12-8). But the button’s name is different in this case, as
shown in Figure 12-10.
Figure 12-10. The result after pressing the Second button Thus, when a
button is pressed in the original window, a new
document is displayed in the same window with the message containing the
name of the pressed button (displayed in capital letters and in bold).
First, analyze the HTML code for the index.html file that opens when the
browser starts.
<!DOCTYPE html>
<html lang="en">
<head>
<title>Two Buttons</title>
</head>
<body>
<h1>Two Buttons</h1>
style="width:100px">First</button>
383
style="width:100px">Second</button>
</form>
</body>
</html>
Compared to the previous case, there are not too many changes, but they are.
First, there is no input field, but there are two buttons (the elements created
by <button> and </button> tags). Each of the buttons is described with the
style="width:100px" attribute. It defines the width of the button to be 100
pixels. That is about “decoration.” The first button has the value "first" for
the name attribute. The name attribute’s value for the second button is
"second". You need that attribute to identify the buttons in the PHP code. In
addition, each button has a value for the value attribute. For the first button,
it is "FIRST", and for the second button, it is
When you click a button, since, in this case, the POsT method is used to
send data, the element associated with the clicked button is added to the
$_POST array.
The key is determined by the button’s name attribute, and the element’s
value is determined by the button’s value attribute.
php file (the value "listing12_04.php" for the form’s action attribute).
384
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<p>
<?php
if(isset($_POST["first"])) $button=$_POST["first"]; else
$button=$_POST["second"];
echo $button;
?>
</strong> button.
</p>
</body>
</html>
<?php
echo $button;
?>
As a result of executing the code, the text (the word associated with the
button’s name) is determined and entered in the document. Then, the
document is passed to the browser.
385
"FIRST".
POST["second"] command, you assign the value of the element from the
$_POST array with the "second" key to the $button variable. That is the
value "SECOND" of the value attribute of the second button.
The following example uses PHP to process data from a form with a drop-
down list and checkboxes. How the browser window looks at the initial
stage is shown in Figure 12-11.
Details
You should use the previous scheme: in the root directory for the local
server, you place the index.html file, which contains the form description.
386
CHaPTer 12 UsINg PHP
Figure 12-11. The form with a drop-down list and checkboxes The window
contains a form where the user is prompted to select a drink (from a drop-
down list). Also, the user can select to add (or not to add) milk and sugar.
The window with the expanded drop-down list is shown in Figure 12-12.
387
CHaPTer 12 UsINg PHP
Figure 12-12. The window with the expanded drop-down list There are also
two buttons in the window: Reset and Submit. Clicking the Reset button
resets the form settings. The form data is sent to the server when you click
the Submit button. Figure 12-13 shows the window with the form settings
made: the Coffee drink is selected in the drop-down list, the Add milk
checkbox is checked, and the Add sugar checkbox is not checked.
388
CHaPTer 12 UsINg PHP
If you send the data to the server, you get the result shown in Figure 12-14.
The window displays information about the order (the selected drink and the
need to add milk and sugar). Let’s analyze how the program’s execution
leads to the described result. The index.html file contains the following code.
<!DOCTYPE html>
<html lang="en">
<head>
<title>Menu</title>
</head>
<body>
<option value="TEA">Tea</option>
<option value="COFFEE">Coffee</option>
<option value="CHOCOLATE">Chocolate</option>
</select><br><br>
style="width:100px">
style="width:100px">
390
</form>
</body>
</html>
select> tags. And this time, you implement the buttons as <input> elements.
for the name attribute. When the form data is submitted to the server, there is
an element in the $_POST array with the key "drinks", and the value of that
element is determined by the value attribute of the <option> element
selected in the drop-down list.
The checkboxes are created as <input> elements, with the type attribute set
to "checkbox". For one of the checkboxes, the value and name attributes are
"add" and "milk", respectively, and for the other – "add" and
The buttons are also created as <input> elements. The type attribute for the
first button is set to "reset", and for the second button, that attribute is set to
"submit". Therefore, the first button is a reset button. If you click it, the
settings of all form elements return to their original state. The second button
is 391
a button for submitting the form data. The name attribute for buttons is equal
to "rb" and "sb", respectively, but those values are not used. The value
attribute determines the title displayed on the button.
The text labels are used for the list and checkboxes. The label elements are
created using the <label> and </label> tags. The for attribute of those
elements specifies the name (the value of the name attribute) of the element
for which the text label belongs.
As you can see from the form description, data processing is performed by
the program in the listing12_05.php file. The program code is shown in
Listing 12-5.
<!DOCTYPE html>
<html>
<head>
<title>Your order</title>
</head>
<body>
<p>You ordered:</p>
<?php
// Defines a drink:
$drink=$_POST["drinks"];
392
CHaPTer 12 UsINg PHP
$txt=<<<MYTEXT
<ul>
<li>Milk: <strong>$milk</strong></li>
<li>Sugar: <strong>$sugar</strong></li>
</ul>
MYTEXT;
echo $txt;
?>
<hr>
</body>
</html>
This HTML document contains a PHP code that generates text (based on the
form data), and then the text is added to the document. But first, the
$drink=$_POST["drinks"] command assigns the value attribute of the
element selected in the drop-down list to the $drink variable.
Note In this case, you don’t check if the $_POST array contains an element
with the key "drinks" (the value of the drop-down list’s name attribute)
because some element in the list is always selected.
393
Next, two similar conditional statements follow. In the first one, the
isset($_POST["milk"]) condition is checked. It is true if the $_POST
array contains an element with the key "milk" (the checkbox for adding milk
is checked). If so, then the $milk=$_POST["milk"] command assigns the
value attribute of the corresponding checkbox to the $milk variable.
The data associated with the checkbox “responsible” for adding sugar is
processed similarly. But now, the isset($_POST["sugar"]) condition is
checked. If the condition is true, the $sugar=$_POST["sugar"] command is
executed. If the condition is false, the $sugar="do not add" command is
executed.
After the values of the $drink, $milk, and $sugar variables are defined, the
$txt variable is created with a multi-line text value.
Use the <ul> and </ul> tags to create an unordered list. List items are
defined by the <li> and </li> tags.
The following example continues the “culinary” theme. This time, you use
controls such as a slider and radio buttons. The browser window displays the
document shown in Figure 12-15 at the initial stage.
394
395
Figure 12-16. The document is displayed after submitting the form data
Figure 12-17 shows the document in which different (compared to the initial
version) settings are made.
396
CHaPTer 12 UsINg PHP
Figure 12-17. The settings of the form are changed in the initial document
After submitting the form data, you get the result, as shown in Figure 12-18.
397
CHaPTer 12 UsINg PHP
Figure 12-18. The server response depends on the form settings Next, let’s
analyze the code. This project uses two files. One is the index.html file in the
root directory where the local server is started. The second is the
listing12_06.php file in the same directory for processing the form data sent
to the server. The following is the code for the index.
html file.
<!DOCTYPE html>
<html lang="en">
<head>
<title>Coffee</title>
</head>
<body>
<label for="espresso">Espresso</lebel>
398
<br><br>
<label for="latte">Latte</lebel>
<br><br>
value="Americano">
<label for="americano">Americano</lebel><br><br>
value="Cappuccino">
<label for="cappuccino">Cappuccino</lebel><br><br>
<br><br>
value="2">
<br><br>
style="width:100px">
style="width:100px">
</form>
</body>
</html>
The document, in general, and the form in particular, contains many familiar
elements. In addition to them, there are radio buttons and a slider.
The radio buttons and the slider are implemented as <input> elements.
399
For the radio buttons, the type attribute is set to "radio", and for the slider,
the type attribute is set to "range".
In addition to the type attribute, the following attributes are specified for the
radio buttons. The name attribute for all radio buttons is "coffee". You use
the same value for the name attribute since you need to group the radio
buttons. One and only one radio button can be selected within a group. group
the radio buttons by giving the same value to the name attribute. Individual
radio buttons can be identified using the id attribute. You use that attribute to
bind a text label and a radio button. The radio buttons also have the value
attribute. By that attribute, when processing the request, you determine
which radio button was selected when submitting the form. One of the radio
buttons has the checked attribute, which means that the corresponding radio
button is selected (checked).
For the slider, the name attribute’s value is "sugar". That attribute is used
when processing the form data to determine the slider. The state of the slider
is defined by the value attribute (initially set to "2"). The min and max
attributes are the minimum and maximum values for the slider, respectively.
The step attribute holds the increment for the positions of the slider.
<!DOCTYPE html>
<html>
<head>
<title>Coffee</title>
</head>
<body>
400
<p>
<?php
function getsugar($spoons){
switch($spoons){
// Defines a drink:
$coffee=$_POST["coffee"];
$sugar=getsugar($_POST["sugar"]);
?>
</p>
<hr>
</body>
</html>
401
The idea is quite simple. Following the form’s settings, the $txt variable is
formed, and its text value is inserted into the document that the server sends
to the browser. The text includes the values of the $coffee and $sugar
variables. The $coffee variable is determined by the
$coffee=$_POST["coffee"] command. That is the value attribute of the
selected radio button. The getsugar() function determines the $sugar
variable. The function has a text argument (assumed to be the slider’s value
attribute). Depending on the argument, the function returns a string with
information about how many spoons of sugar to put in coffee. The function
is used in the $sugar=getsugar($_POST["sugar"]) command.
Here, to get the value attribute of the slider, use the $_POST["sugar"]
The corresponding block is marked with the <em> and </em> tags to
highlight a text in italics.
Summary
• PHP code can be added to HTML documents, selected
402
403
CHAPTER 13
Afterword: What
The book discussed the most essential topics and issues related to learning
the PHP language. In addition to the actual syntax rules and constructions,
there is also such an aspect as the use of the language in practice. But to
understand how a language “works” in real life, it is vital to know what it
can do in principle. Hopefully, after reading the book and studying the
examples discussed, you now have an overall picture of PHP’s potential.
405
Chapter 13 afterword: what was and what will Be One more point is
important to be stressed. Programming languages are studied for a variety of
reasons. But the main thing, perhaps, is the desire to get a new profession, to
become a programmer. That means that programming is not limited to
learning a single language. Each language has its own characteristics, but
certain universal programming principles are common for most languages.
The presented book is to help you understand, even on an intuitive level,
those principles and make it easier for them to move ahead along your
professional path. And, of course, thank you for paying attention to the book.
406
Index
Symbols
$A++ command, 65
statement, 99
$num=func_num_args()
Associative array, 91
command, 152
$number variable, 65
$res=power($z,$num)
command, 136
Bitwise operations, 41
Array
concatenation, 115
creating, 203–206
elements, 125
loop
407
INDEX
229–232, 234
do-while statement, 89
Control statements
do-while, 66–69
echo keyword, 32
Error handling
custom exceptions,
76–78, 80–82
314–316, 318
count() function, 95
count_type() function,
151–153, 155
throwing exceptions,
try-catch constructions/finally
block, 324–327
Data types
integer type, 31
operations
arithmetic, 34–36
assignment, 48
bitwise, 41–43, 45
comparison, 37–39
logical, 39, 40
strings, 46, 48
Files
ternary, 49–51
408
INDEX
fopen(), 187
Generator function
194, 195
reading, 190
definition, 335
writing, 192
fopen() function,
foreach keyword, 99
for keyword, 70
get_class() function, 33
function_exists() function, 33
Functions
317, 324
arguments, 169
goto statement, 90
commands, 128
definition, 127
recursion, 156–158
I, J
if keyword, 53
fwrite($h,"[$k] ") command, 194
if statement, 89
409
INDEX
Inheritance
constructors, 253–256
Logical operators, 39
251, 252
match statement
258, 272
default keyword, 85
protected class members, 259,
program output, 88
261, 272
program uses, 85
selection statement, 87
Interpreter regime
syntax, 84
command, 4, 5
method_exists() function, 33
hello.php file, 4
NetBeans environment
window, 6
NetBeans environment, 13
program execution, 12, 17
runtime environment, 9
environment, 5
is_callable() function, 33
Iterators
Object-oriented programming
(OOP), 199
object, 359
OOP mechanisms
K
anonymous classes, 298, 299, 302
inheritance/interface,
410
INDEX
programming, 361
interfaces, 278–281
request parameters
288–290, 292
traits, 285–287
P, Q
401, 402
PHP program
code, 1–3
PHP
NetBeans development
buttons
environment, 25
attributes, 377
regime
interpreter, 3
example, 381–383
Server, 18
program, 381
print($result) command, 69
window, 374
print() function, 30
code, 364
port, 368
References
text, 364
example, 175
browser window, 386–388
411
INDEX
Server regime
switch keyword, 75
T, U
Ternary operator, 52
258, 281
317, 318
trim() function, 51
set_exception_handler()
function, 331
Variables
195, 298
comments, 29
creating, 28
$ symbol, 27
287, 289
Virtuality, 263
strlen() function, 47
W, X, Y, Z
str_replace() function, 48
substr() function, 47
412
OceanofPDF.com
Document Outline
Table of Contents
About the Author
About the Technical Reviewer
Acknowledgments
Introduction
Chapter 1: The First Program
The Program’s Code
The Interpreter Regime
The Server Regime
Summary
Chapter 2: Variables and Data Types
Introduction to Variables
Basic Data Types
The Arithmetic Operations
The Comparison Operations
The Logical Operations
The Bitwise Operations
The Operations with Strings
Assigning Values
The Ternary Operator
Summary
Chapter 3: The Control Statements
The if Conditional Statement
The while Loop Statement
The do-while Loop Statement
The for Loop Statement
The switch Selection Statement
The goto Instruction
The match Selection Statement
Summary
Chapter 4: Arrays
Getting Familiar with Arrays
A Loop over an Array
Multidimensional Arrays
Array Assignments
Concatenating Arrays
Comparing Arrays
Functions for Handling Arrays
Summary
Chapter 5: Functions
Creating Functions
The Function Result
The Type of Arguments and Result
The Argument Passing Mechanism
The Argument Value by Default
An Arbitrary Number of Arguments
Recursion
The eval() Function
Anonymous Functions
Named Arguments
Summary
Chapter 6: Useful Tricks and Operations
References
Constants
Global Variables
Static Variables
Multiline Strings
Using Files
Including a File in the Program
Summary
Chapter 7: Classes and Objects
The OOP Principles
Creating Classes and Objects
The Methods
The Constructor and the Destructor
Static Fields and Methods
Copying Objects
Private Fields and Methods
Special Methods
Defining Fields in the Constructor
Summary
Chapter 8: Inheritance
Creating a Child Class
Overriding Methods
Constructors and Inheritance
Inheritance and Private Members
Protected Members of a Class
Virtual Methods
A Function as a Field Value
Multilevel Inheritance
Summary
Chapter 9: Advanced OOP Mechanisms
Abstract Classes
Interfaces
Interface Inheritance
Class Inheritance and Interface Implementation
Traits
Object Type Control
A Namespace
Anonymous Classes
Summary
Chapter 10: Error Handling
Exception Handling Principles
Exception Classes
Throwing Exceptions
The Custom Exceptions
Handling Exceptions of Different Classes
Nested try-catch Constructions and the finally Block
Rethrowing an Exception
The Functions for Handling Errors
Summary
Chapter 11: Generators and Iterators
Getting Familiar with Generators
A Generator Function with Arguments
An Array Based on a Generator
The Generator Result
Using Generators
Passing a Value to a Generator
Iterators
Summary
Chapter 12: Using PHP
A Script in an HTML Document
Handling the Request Parameters
Using Buttons
Using Several Buttons
Using Lists and Checkboxes
A Slider and Radio Buttons
Summary
Chapter 13: Afterword: What Was and What Will Be
Index
OceanofPDF.com