Exploring PHP: A Beginner's Guide to Strings, Bitwise Operations, Constructors, Constants, Namespaces, Extensions, and OpCache

Last updated Apr 24, 2024 Published Mar 20, 2018

The content here is under the Attribution 4.0 International (CC BY 4.0) license

TLDR

This blog post covers essential PHP concepts like language constructors, namespaces, and bitwise operations. While it’s a basic overview, there’s much more depth to explore beyond the book’s scope. Understanding operator precedence is crucial for mathematical operations, as detailed in PHP’s documentation.

User-defined php.ini directives allow customization, enabling PHP to read from different directories. This feature extends PHP’s flexibility beyond its default installation directory.

Lastly, control structures, not covered in this book, are vital for programming. Familiarizing oneself with PHP’s control structures is recommended for comprehensive understanding and effective coding. Explore these topics further to enhance PHP proficiency and develop robust applications.

Introduction

When searching for tutorials on basic PHP language concepts, we often encounter simple syntax issues, such as the <?php tag. These tutorials demonstrate how to use it and its purpose (we understand that PHP code will only be interpreted if there is a <?php tag, correct?). However, many tutorials fail to mention the possible variations of tags we can use. Here are some examples:

  • <?
  • <?php

As we can see, there are three variations of the tag used in PHP. Next, we will analyze each one to better understand the context in which we should use them.

The first tag we can use is <?. We must be cautious when using this opening tag because it requires a configuration in your php.ini file to work. The short_open_tag option must be set to On. It is necessary to have the short_open_tag option active to use the syntax <? echo 'Hello World!'.

Settings in php.ini to enable language features

Starting from PHP 5.4.0, it is not necessary to enable the short_open_tag option, as a modification was made in the PHP core for this syntax to always be available.

The standard PHP tag is <?php. To use it, no extra configuration is necessary, and it is recommended that you always use this form in your PHP files, as it is compatible with all versions (prior to 5.5 and most likely future ones).

Finally, we have a notation that is quite different from the common one, resembling JavaScript notation when embedding JavaScript within HTML pages. Not much different from that, this PHP notation serves the same purpose as JavaScript, that is, to execute PHP code. Unfortunately (or fortunately), this type of syntax is not very common, but it is possible to use it freely up to version 5.6.x of PHP. In version 7.0.0, this syntax will be removed. If you want to avoid difficulties in migrating to PHP 7.0.0, consider not using this type of syntax. In this book, we will use version 5.5.

The problem with PHP tags

To avoid issues with multiple files, it is recommended not to use the closing tag ?>. See the example:

<?php

// User file.php

echo 'Hello user, do you want to send an email?';

?> // Blank space

We have a file called user.php in which we accidentally left a blank space after the closing tag PHP. To make it clear, let’s use another file called email.php where we will use the header() function to redirect the user:

<?php

// Email file.php

require 'user.php';

header('Location: user.php');
exit();
?>

When running this code, we will encounter the error message: “Warning: Cannot modify header information - headers already sent,” and we will not achieve the expected result, which was to redirect the user.

This issue arises because we forgot to include a blank space after the PHP closing tag. While this oversight can occur both before the PHP opening tag and the closing tag, it is considered a good practice to avoid using the closing tag altogether to prevent conflicts with PHP functions that manipulate HTTP headers, such as header() (as used in our example), session_start(), and setcookie().

In this example, I intentionally included a space to illustrate the challenge of identifying such problems, but similar issues can arise with any form of output (HTML, images, etc.) sent before the HTTP headers.

To ensure that you do not encounter similar problems, simply omit the closing tags, as demonstrated in the examples above, but now in a more elegant and problem-free manner.

<?php

// User file.php

echo 'Hello user, do you want to send an email?';

And, of course, our email.php file:

<?php

// Email file.php

require 'user.php';

header('Location: user.php');
exit();

Variable

PHP is a weakly typed programming language, and it allows us to store any type of value, whether it be scalar, composite, or special, without declaring its type within the variable. Additionally, it is also possible to initialize the variable with a boolean value, and change its value to a numeric type. However, we must pay attention to the naming of variables when using them.

  • Every variable in PHP must start with $;
  • After the $ sign, it must be followed by a letter and not a number;
  • Every variable in PHP can have underscores, numbers, and letters.
$a      = ''; // Valid
$123abc = ''; // Invalid
$_a     = ''; // Valid
Scalar Composite Special
boolean array resource
integer objects null
float - -
scalar - -

The table shows us the official types of variables in PHP. You can check the same classification in the language’s official documentation at http://php.net/manual/language.types.intro.php.

Value variables

Like C, PHP has two types of variable passing, by value and by reference. Passing parameters by value is the default because we don’t need to use any special notation. What changes is passing parameters by reference, as we must use & to indicate that we want to pass that variable as a reference, not a copy. The only caveat here is with objects; in PHP, an object will always be passed by reference.

$a = 10;
$b = $a;
$b = 20;

echo $a; // 10
echo $b; // 20

Now we have saved the value of the variable $a in $b. If we change any value in $b, it will not affect the value of the variable $a.

Reference variables

Now let’s use the same example, but change the variable $a by reference. In PHP, to use passing by reference, it is necessary to use the & character.

$a = 'By value';
$b = &$a; // Creating the reference for $a

$a = 'And now?';

print $a; // And now?
print $b; // And now?

Contrary to passing by value, passing by reference is exactly what its name suggests: it is just a reference to the variable from where it was actually defined. In our example, the variable $b is just a reference to the variable $a, and because it is just a reference, changing its value, the value of the variable $a will also be changed.

Uppercase or lowercase? Have you ever stopped to think about what happens if we write the name of a function with uppercase letters? Or perhaps a reserved word of the language like class?

Let’s take an example using the empty constructor that we wrote in lowercase, but here we will write it in uppercase. Before proceeding, take a guess: will it work?

$a = 0;

if(EMPTY($a)) {
    print 'Hello, I am empty';
}

In PHP, no error occurs and the syntax is perfectly valid, let’s see another example now using a reserved word like class:

CLASS Dog {
    public function bark() {
        print 'woof woof woof!';
    }
}

$germanShepherd = new Dog();
$germanShepherd->bark();

And once again, the syntax is valid. Just remember that it is not recommended to use it to avoid causing confusion (and this type of usage goes against standardization). Just be aware that this type of behavior does not apply to variable names.

Variable variables

Special characters?

It is very rare in a programmer’s life to have an experience where the variables used have accents. But, in PHP, is it possible to define a variable like $mañana?

$mañana = 'Hello, $mañana';

print $mañana;

What do you think of this syntax? Is it valid? Yes, it is valid. We can define variables with special characters, such as ç, ~, ^, and so on.

The only way to invalidate the syntax of a variable is by using numbers at the beginning, remember that.

Strings

With PHP, we can use single quotes or double quotes to delimit a string.

$simple = 'Hello';
$double = "Hello";

So far, there doesn’t seem to be any difference between using one and the other, however, this becomes explicit when we use variables.

$year = 2000;

print ‘I was born in $year’; // I was born in $year As we can see, we don’t get the expected result: instead of “I was born in 2000” “I was born in $year” is displayed. This is because when we use single quotes, PHP will not interpret any type of variable and will consider anything between the quotes as plain text.

$year = 2000;

print "I was born in $year"; // I was born in 2000

Now, as expected, we get the result “I was born in 2000” because with double quotes PHP will interpret any variable that exists in the string.

HEREDOC, NOWDOC

When we come across frameworks that use MVC (Model-View-Controller), we soon realize that we must separate responsibilities for more readable and easy-to-maintain code. In other words, all our code that will be displayed to the user as HTML, for example, must be in the View, the business rule in the Model, and the Controller must act as a middle ground between the View and the Model.

But sometimes we need to use large pieces of string directly in our classes, such as returning an HTML or an SQL query. When this occurs, we typically concatenate our strings

$query = 'SELECT id, name, age FROM student ' .
            'INNER JOIN historical_student ON id = id ' .
            'INNER JOIN table 2 ' .
            'INNER JOIN table 3 ' .
            'INNER JOIN table 4 ' .
            'WHERE student status IS NOT IN (1, 2, 3) '
            ' ... ' .
            ' ... ' .
            ' ... ' .
            ' ... ' ;

To alleviate this difficulty in reading the code when we need to obtain a large text, we can use NOWDOC. In it we delimit the beginning and end so that PHP interprets a block as a string, thus making the code cleaner and easier to understand.

$text = <<<'MYUTEXT'
    SELECT id, name, age FROM student
    INNER JOIN historical_student ON id = id
    INNER JOIN table 2
    INNER JOIN table 3
    INNER JOIN table 4
    WHERE student status IS NOT IN (1, 2, 3)
     ...
     ...
     ...
     ...
MY TEXT;

At first glance, the syntax seems a little strange, but it is quite simple. The first thing to note is the use of single quotation marks (‘) indicating that this is pure text, that is, there is no variable interpretation. If any variable is entered within the block between «<’MEUTEXTO’ and MEUTEXTO, it will be displayed literally.

$text = <<<'MYUTEXT'
    This is my variable $a and this is another $b
MY TEXT;

The result of this code will be:

    This is my variable $a and this is another $b

We must also pay attention to the NOWDOC closing tag, as it must be the first instruction on the line that ends the block, without tabs and spaces.

Invalid way to close the NOWDOC block:

$text = <<<'MYUTEXT'
    My text
    MY TEXT;

A valid way to close the NOWDOC block:

$text = <<<'MYUTEXT'
    My text
MY TEXT;

NOWDOC, as we saw, is used for pure text, and we cannot interpret variables. That’s where HEREDOC comes into the picture. With it, we follow the same rules applied with NOWDOC, but we do not use single quotes and we can use variables.

$a = 10;
$text = <<<MYTEMPLATE
    Now we can use the variable, and 5 + 5 is $a
MYTEMPLATE;

The result is:

Now we can use the variable, and 5 + 5 is 10

Manipulating strings

PHP provides us with numerous functions for manipulating strings. Unfortunately, we still don’t have anything object-oriented like in Java, but the functions provided are very powerful. However, although PHP is not a typed language, we must be very careful when using the strpos function, as it returns the position of the first occurrence of a character in a string.

$texto = 'abcde';

print strpos($text, 'b'); //1

The result will be 1 because the corresponding character in that position was found in the text string. With this, we can do the following check:

 $texto = 'abcde';
 
 if(strpos($text, 'b')) {
    print 'Hello I exist';
 }

No news so far. The result will be the phrase Hello, I exist. Now let’s analyze the following code and apply the same rule:

$texto = 'abcde';

print strpos($text, 'a'); //0

We return zero, but we find the desired character in the string. And if we apply the same comparison, what will we get as a result?

$texto = 'abcde';

if(strpos($text, 'a')) {
  print 'Hello I exist';
}

This time, the desired result will not be obtained, as we found the character in position 0 (zero), and PHP understands that 0 converted to Boolean is FALSE. In this case, to achieve the desired result, we must compare values and types to make sure that no occurrences were found.

$texto = 'abcde';

if(false === strpos($text, 'a')) {
    print 'Hello I exist';
}

However, we must understand how to use this type of behavior, as we can take advantage of it too. Let’s imagine that you need to search for a character in a string, but the first letter should not be considered.

In this context, strpos fits perfectly and we can use it without fear. For more information about how PHP manages values ​​and types, we can access the official documentation. The strpos function also offers us a third parameter, where we can specify from which point in the string the search will begin.

$texto = 'abcde';

if(false === strpos($texto, 'a', 1)) {
    print 'Hello I exist';
}

We will not have any output when running this example, as we are starting from the second character of the string, that is, the letter b, as shown in the following table.

A B C D E
0 1 2 3 4

An important detail is that, with the strpos function, it is not allowed to use negative values ​​in the third parameter.

...
$start = -1;

if(false === strpos($texto, 'a', $start)) {
    ...
}

When using a negative value, a WARNING is displayed and the function will return false.

PHP Warning: strpos(): Offset not contained in string in /my_dir/strpos.php on line 5
PHP stack trace:
PHP 1. {main}() /my_dir/strpos.php:0
PHP 2. strpos() /my_dir/strpos.php:5

Now that we understand strpos, we can move on to the stripos function, which has the same behavior as the strpos function, but with a small difference. stripos does not take into account uppercase or lowercase letters, that is, the PHP string is the same as PHP.

$text = 'ABCDE';

if(false === stripos($texto, 'a')) {
  print 'Hello I exist';
}

See in the previous example that, although the $texto variable is all uppercase, we are looking for a lowercase letter string in it, which makes our search valid, because, with stripos, this check will be ignored and the letter A will be the same than the letter a.

Hello I exist

Are strings also arrays?

As PHP is a language written in C, we obtain some behaviors from this language that are fully applicable in PHP. And one of them is that we can iterate over strings because strings are nothing more than arrays.

$text = 'Engineer';

for ($i = 0; $i < strlen($text); $i++)
{
  print $text[$i];
}

At the end of the script execution, we obtain the Engineer result.

strstr

We use the strstr function to return a portion of text starting from the first occurrence of the letter we are trying to find. To make it easier to understand, imagine that we only need to return the email domain (the part of the email after the @ sign, such as @gmail.com, @outlook.com)

$email = '[email protected]';

print strstr($email, '@');

With the strstr function, this task becomes easy, as we only need to specify which string the text should be returned from. See the following result when running the previous script:

@php.net

It is also possible to have the opposite behavior, that is, instead of returning the email domain, return your signature:

$email = '[email protected]';

print strstr($email, '@', true);

And when we run the script, we have our email signature, as expected.

php

substr

A common task in PHP applications is the need to extract a portion of the string. To do this, we use the substr function, which allows us to achieve exactly this type of behavior. For our example, let’s assume we have a code (A3-99812.FFGD) and we must extract the first two characters that correspond to its category.

$code = 'A3-99812.FFGD';

print substr($code, 0, 2); // A3

With this code, we arrive at the expected result, which is A3, finding the category. To do this, we use substr and pass 3 arguments:

The desired string (from where we will extract). Where will we start cutting from, and which which position. In this case, let’s start with the first existing character. We inform you what size portion we are going to extract. In this case, we will only extract 2 characters that represent the category. Once again, it is worth mentioning that the official PHP documentation has numerous examples of how to use the function.

trim, ltrim and rtrim

A well-known function is the trim function, which removes whitespace at the beginning and end of the string.

$book = ' PHP ';

print trim($liter); //PHP

However, we can use the trim function to not only remove spaces at the beginning and end of the string, but also specify a character (or a string) to be removed.

$name = 'aPHPa';

print trim($name, 'a');

Here we have a simple example of where we want to remove the letter a from the beginning and end of the string. This is easily accomplished by the trim function by specifying the character we want.

PHP

Now that we understand how to use the trim function, it is easier to understand the functions that derive from it, such as ltrim, which removes white spaces (by default) from a string or removes the desired string. Let’s use the same value as the $nome variable to make it easier.

$name = 'aPHPa';

print ltrim($name, 'a');

Unlike the previous result, in this example, we have the letter a at the end of our string.

PHPa

And of course, we can remove just the characters at the end (or the white space if no characters are specified) from the string. To do this, we use the rtrim function.

$name = 'aPHPa';

print rtrim($name, 'a');

Still, with the same example, we will obtain a different result. Now the letter a has been removed from the end of the string only.

aPHP

PHP has a function called chop, which is just a shortcut for the rtrim function. So, remember: when you see the chop function, it will have the same behavior as the rtrim function.

str_replace

A common task to be performed in applications is replacing texts. PHP has the str_replace function for this purpose.

$texto = 'I bought a blue book';

print str_replace('blue', 'orange', $text);

The simplest way to use the str_replace function is by informing the three basic parameters: the text to be searched for, the text that will replace the searched text, and the text that will be replaced.

I bought an orange book

We can also specify an array for both: the text to be replaced and the text to be searched. If the arrays match, the swap is made in the order of the elements.

$texto = 'I bought a blue and yellow book';

print str_replace(['blue', 'yellow'], ['orange', 'black'], $text);

In our example, we have the blue color at position zero, which will be replaced by the orange color, which is at position zero as well. The same occurs with items in position 1 of the array.

I bought an orange and black book

However, that’s not all we achieve with the str_replace function. Furthermore, we have some very dynamic behaviors:

$texto = 'I bought a blue and yellow book';

print str_replace(['blue', 'yellow'], 'lilac', $text);

We can use an array with the text to be replaced by the same text entered as a string in the second parameter. In our example, we replaced the blue and yellow text with lavender.

I bought a lilac and lilac color book

And finally, the str_replace function gives us the total number of replacements made in the text:

$texto = 'I bought a blue and yellow book';
$substitutions = 0;

str_replace(['azul', 'yellow'], 'lilac', $texto, $substituicoes);

print $substitutions;

In this example, we are using the same text as the previous example, in which we made two substitutions. However, now we are interested in the number of substitutions made that we are storing in the $substituicoes variable:

two

An important detail is that the parameter used to count the total number of replacements performed is passed by reference, and not by value, which does not make it possible to pass a static value.

...

str_replace(['blue', 'yellow'], 'lilac', $text, 0);

...

If you try to pass a static value, such as the zero value in the previous example, a FATAL ERROR is displayed:

PHP Fatal error: Only variables can be passed by reference in /my_dir/str_replace.php on line 5

Fatal error: Only variables can be passed by reference in /my_dir/str_replace.php on line 5

The previous error tells us that it is not possible to pass a static value by reference, only variables.

Similarity between strings

So far, we’ve seen how to compare strings in a strict way, where we want to know if one string is exactly the same as another. However, with PHP, we can also use functions like similar_text to determine how closely one string matches another. Imagine that we need to find an address, but we don’t know if the location is a street or an avenue. We can use similar_text to determine this type of similarity.

$string1 = 'Av. PHP Introduction Book';
$string2 = 'Street, PHP Introduction';

print similar_text($string1, $string2);

In the previous example, similar_text will return the number of characters that exist in both strings, which in this case is 19, as the corresponding part in both strings is the text PHP Introduction. Note that there is a blank space before the word Introduction, which is why the result in question is 19, not 18.

Often, just knowing which characters are the same in both strings doesn’t provide us with much flexibility. With similar_text, we can pass a third parameter to know the percentage of similarity between the strings.

$percentage = 0;
$string1 = 'Av. PHP Introduction Book';
$string2 = 'Street, PHP Introduction';

print similar_text($string1, $string2, $percentage);

Adding the third parameter, we have the percentage value (which in this case is 70.37037037037) of the text similarity. This value is passed by reference, and the function’s return value is not modified.

Continuing in this world of similarities between strings, we have the levenshtein function, which returns the number of characters we must replace to have two identical strings.

$string1 = 'Av. PHP Introduction Book';
$string2 = 'Street, PHP Introduction';

print levenshtein($string1, $string2);

The order of the strings passed to the function is very important, as the levenshtein function will calculate how many characters we need to change in $string1 to transform it into $string2. And if we change the order of the parameters, we will get different results.

The levenshtein function has a few more parameters to be used. For more information about this function, see the official PHP documentation at http://php.net/manual/en/function.levenshtein.php.

Counting characters

We often want to count the total number of characters a given string has. For this, PHP relies on the strlen function. With it, it is possible to count the number of characters in a string, but we must be careful with its behavior.

Before moving on to the answer, try to interpret the following code:

print strlen(‘1\n2’); If you were unsure about the \n line break character, don’t worry, you weren’t the only one. The correct answer is 4. This is the result obtained exactly by using single quotes. With this, PHP will always interpret the string as plain text.

Now that we understand how it works with single quotes, we can assume what will happen with double quotes. Again, before seeing the answer, try interpreting the following code:

print strlen("1\n2\t");

If you answered 4, you got it right. This time, with double quotes, PHP will interpret the special formatting characters \n and \t before counting, that is, for each of the special characters, we count 1. After that, we are left with only the characters 1 and 2, which we normally count, which brings us to 4.

Even though it’s a very logical thing, we need to stop and analyze the syntax to avoid falling for this trick in the test.

explodes

$parameters = '1,2,3,4';

$array = explode(',', $parameters);

We can use this type of manipulation when we want to have stricter treatment of data sent by the user. The global $_GET is the perfect example for this. Let’s imagine that the user will provide us via URL with the type of category they want to search on any website.

$_GET['category'] = 'notebook-pen-case-eraser';

$category = $_GET['category'];

$categories = explode('-', $category);

We can also limit the size returned by the explode function, passing the maximum desired number. Let’s continue with our example, and now we will limit it so that it only returns the first two categories entered by the user.

$_GET['category'] = 'notebook-pen-case-eraser';

$category = $_GET['category'];

$categories = explode('-', $category, 2);

This example will return only two elements within an array with the first element containing notebook, and the second the rest of the string pencil case, pen, eraser.

Array
(
    [0] => notebook
    [1] => case,pen,eraser
)

When using the third parameter of the explode function, we must pay attention to its behavior, as we expect the return of the array to be limited, and not limited to its application to the string.

implodes

We often want to do the opposite of the explode function, transforming an array into a string. For this, there is the implode function.

$categories = array(
    'case',
    'pen',
    'rubber'
);

print implode(',', $categories);

Unlike explode, the implode function does not have a third parameter, making it easier to understand and manipulate. In this example, we provide as the first parameter which “glue” we want to use to join the positions of the array and transform it into a string.

Using the implode function, only the values ​​of the arrays are taken into account, the keys are ignored, regardless of whether they are associative or numeric.

$categories = array(
    'case' => 'a',
    'pen' => 'b',
    'eraser' => 'c'
);

print implode(',', $categories); //a,b,c
$categories = array(
    0 => 'a',
    1 => 'b',
    2 => 'c'
);

print implode(',', $categories); //a,b,c

The official PHP documentation has some examples using these functions, which you can consult at http://php.net/manual/pt_BR/function.explode.php and http://php.net/manual/pt_BR/function. implode.php.

Assignment Operators

PHP has a series of assignment operators, such as = that we use to assign a value to a variable.

$a = 'Random string';

To assign a value to an index in an array with PHP, we use the => operator.

$a = [
  0 => 1,
  1 => 2
];

Comparisons

As we already know that PHP is not a typed language, we should be careful when comparing values.

$a = 0;
$b = '0';

if ($a == $b) {
  print 'They are the same!';
}

When we run this code, we get the answer “They are equal!”, because with a double equal sign, PHP only compares the value. In other words, here we only compare 0 of variable $a with 0 of variable $b.

$a = 0;
$b = '0';

if ($a === $b) {
  print 'They are the same!';
}

Now, with triple equal signs, we have different behavior, and when executing the previous script we do not get any response. With this type of syntax, PHP will check, in addition to the value of the variables (which in this case are the same), also their type, which in this example are different, as the variable $a is an integer and $b is a string.

As a rule of thumb, just understand that with a double equal sign, PHP will only compare value, and with a triple equal sign, it will compare value and type.

Bitwise

Converting hexadecimal

Language constructors

Output Constructors

  • exit() – Used to display an exit and then end the execution of the script.
exit('PHP');
  • die() – Used to display an output and then finish executing the script.
die('PHP');
  • echo() – Used to display an output.
echo 'PHP'; // Or echo ('PHP');
  • return() – Used to return a value and end the execution of the script, or return the desired value to whoever is executing the script.
echo 'Code house';

return;

echo 'PHP'; // This line will never be executed

Or the most common way to use return, inside a function:

function add() {
return 1 + 1; // Or return(1 + 1)
}

echo add(); // two

print() – Used to display an output.

print 'PHP 5.5'; // Or print('PHP 5.5');

Assessment Builders

  • empty() – Used to check whether a variable is empty, that is, a variable with no value.
  • eval() – Used to evaluate the content of a string in PHP.
  • include() and include_once – Used to include and evaluate a PHP file, however using include, only a warning is displayed if PHP does not find the desired file.
  • require() and require_once() – Used to include and evaluate a PHP file, however, using require, it displays a fatal error if it cannot find the desired file.

In PHP, we have different types of errors at different levels. The three most common are:

  • E_ERROR – These are fatal errors that are not possible to recover from or continue executing the script. They can be used by PHP when there is a memory allocation problem, or even by the functions/constructors themselves, such as require and require_once.

  • E_WARNING – Similar behavior to E_ERROR, but it is a type of error that does not terminate the execution of the script.

  • E_NOTICE – Used to indicate a possible error during script execution. Generally, they are easily found when trying to access an array position that does not exist.

Others

  • isset() – Used to check whether a variable has been defined and does not have a null value.
  • unset() – Used to remove a variable.
  • list() – Used to assign an array to a group of variables.
  • PHP Basics (Language constructs) - Others

Constants

Constants in PHP are, by convention, all in upper case (but it is perfectly valid for PHP to define constants in lower case), and follow the same naming rule as variables. That is, constants cannot start with a number, but they can start with an underscore.

define('1CONSTANT', 'value'); // Invalid
define('_CONSTANT', 'value'); // Valid
define('myconstant', 'value'); // Valid
define('$CONSTANT', 'value'); // Invalid

In the last example, it is interesting how PHP behaves, as defining the constant with the dollar sign is valid syntax and therefore we do not have any errors displayed. But the interesting part comes when we try to access this constant that, in fact, PHP will understand that we are trying to access a variable, not a constant.

Another feature of the PHP language are the magic constants that are accessed using two underscores at the beginning and end of the constant name: __CONSTANTE__.

  • __LINE__ – Informs the line number of the file in which it is used.
  • __FILE__ – The full path of the file in which it is used.
  • __DIR__ – The directory where the file is located.
  • __FUNCTION__ – The name of the function.
  • __CLASS__ – The name of the class and, if the class is within a namespace, the name of the class is returned along with its full namespace. For example, if the Autenticacao class is in the namespace Usuario\Seguranca, the class name returned by the magic constant __CLASS__ will be Usuario\Seguranca\Autenticacao.
  • __TRAIT__ – It has the same behavior as the magic constant __CLASS__, but we must use it with traits.
  • __METHOD__ – The name of the called class method.
  • __NAMESPACE__ – The name of the current namespace.

Namespaces

Namespaces were introduced in PHP in version 5.3.0, since then, it became a key feature of the language. They are an excellent way to avoid name collisions between third-party libraries that you may use in your project and your code.

When namespaces did not exist, it was usually easy to find underscores separating the class name to avoid collisions and, as a consequence, class names became absurdly long. The pattern followed before the namespace was always the project name (or library name) followed by an underscore and the actual class name.

<?php
Root namespace;

It is also possible to define namespace sublevels within a single namespace, using the backslash ().

<?php
namespace Root\Subnivel;

To better understand namespaces, we can think of them as a hierarchical file structure:

|-- Root
    |-- Sublevel

One detail that we must take into consideration is that the namespace declaration must be right after the opening <?php tag, and no other function can be executed before that. This makes the following example invalid because the namespace declaration must be the first expression used.

<?php
require 'MyClass.php';

namespace Root\Example;

By convention, we use namespaces with the camel case pattern, however it is completely valid to use namespaces without this convention. The rules for naming namespaces follow the same principle as variables.

<?php
mySpace namespace; // Valid
namespace 1mySpace; // Invalid
namespace _mySpace_; // Valid

The interesting thing about using namespaces is that it is possible to declare more than one namespace per file. Although it is not a good practice, it is valid to use this syntax.

<?php
namespace Root\Namespace1;

class Hello {}

namespace Root\Namespace2;

class Hello {}

To alleviate the confusion between multiple namespaces in a single file, we can use square brackets to encapsulate all the code in a namespace.

namespace Root\Namespace1 {

  class Hello {}

}

namespace Root\Namespace2 {

  class Hello {}

}

You can already imagine why it is not recommended to use multiple namespaces in a single file, right? Using this, maintenance, reading and understanding of the code are impaired. A good practice is to use only one namespace per file.

To use namespaces, we use the reserved word use followed by the desired namespace.

<?php
require 'Root.php';

use Root\Sublevel;

When using namespaces, we need to be careful when using global classes, such as PDO (PHP Data Object). First, PHP will look for the desired class in the current namespace. Let’s imagine the following scenario: we will create a database connection class using PDO within the Root\Db namespace.

<?php
Root namespace;

class Connection
{
  public function getConexao()
  {
    $dsn = 'mysql:dbname=my_db;host=localhost';
    $user = 'user';
    $password = 123456;
    
    return new PDO($dsn, $user, $password);
  }
}

Executing this code, a fatal error is displayed, saying that the PDO class could not be found. This happens because PHP first looks for classes used within the current namespace, and since we don’t really have any PDO classes, the error is thrown. To use the PDO class or any other PHP class, we must use the backslash at the beginning of the class name.

<?php
  public function getConexao()
  {
    return new \PDO($dsn, $user, $password);
  }
}

Extensions

PHP allows us to use extensions for features that PHP itself does not have in its core. We can use extensions written natively for PHP by enabling them through the php.ini configuration file, or even through PECL (PHP Extension Community Library). It is important to understand how to use extensions and how to configure them. In this section, we will focus on understanding how an extension works and how to configure it.

The php.ini configuration file offers us the Dynamic Extensions section where we can change to add new extensions in PHP. You can enter just the name of the desired extension or enter the full path. By providing only the name of the extension, PHP will search in the default extension directory, defined in the extension_dir directive. For Linux, extension files are of type .so, and for Windows it is .dll.

Entering only the name of the extension:

extensions=name.so

Entering the full path of the extension:

extensions=/home/ext/name.so

Now that we know where to enable the extensions, we can install them through PECL (PHP Extension Community Library). I will assume that you already have all the necessary packages for this. Installing PEAR (PECL extensions are distributed via PEAR) is beyond this book, but it is easy to find how to proceed with the installation on the official PHP website. PECL helps us, as there are many extensions available to be used, such as: APC, cassandra, bz2, among others. We can easily install PECL extensions from the command line on Linux:

sudo pecl install extension_name

After the extension installation is complete, you will need to change php.ini in the Dynamic Extensions section and enable the installed extension. You will not need to worry about where the extension was installed, as installations through PEAR use the default extension directory.

opCache

Before we get into the details of opCache, we first need to understand what opCode is, as opCache is nothing more than caching opCodes. As with most items related to computing, opCode is an abbreviation for operation code, which is nothing more than the code that the machine understands (code that the machine will actually execute), that is, opCache performs a cache of that code.

In version 5.5 of PHP, opCache was added, which uses the low-level caching technique, creating a cache of code that the machine understands right after PHP analyzes and compiles the script.

As of PHP 5.5, opCache comes with the PHP core, but for previous versions (such as 5.2, 5.3 or 5.4), it is possible to use opCache through PECL. See the following PHP execution flow without using opCache, the normal flow:

Syntax analysis (parser) --> Compilation --> Execution

In the PHP world, we know that we don’t need to compile our code to run it like the Java and C++ typed languages ​​do. However, PHP actually compiles the code before executing it internally by the Zend Engine. Firstly, PHP performs syntax analysis, compiles and obtains a bytecode as a result (bytecodes generated by PHP are similar to those generated by Java, which are executed by the JVM), and finally we have the execution phase.

With each request made, this cycle is repeated and the entire result of the process is discarded. In other words, request X has no relationship with the request made previously, and no cache was created for it. But if we stop to think about it, a file hardly changes between one request and another, and that’s where opCache comes in. See the new flow with opCache active:

Syntax analysis (parser) --> Compilation --> OpCode Cache (OpCache) --> Execution

Prior to opCache, APC played this role. However, it is not possible to use both at the same time, which is why opCache is disabled by default.

But in case you want to enable the extension, all you need to do is add the following line to your PHP configuration file (php.ini):

zend_extension = opcache.so After enabling the extension, the first thing is to know if opCache is actually being used, and it is through the opcache_get_status function that we find out what is happening.

print_r(opcache_get_status()); The script returns a series of information within the array:

Array
(
    [opcache_enabled] => 1
    [cache_full] => 
    [restart_pending] => 
    [restart_in_progress] => 
    [memory_usage] => Array
        (
            [used_memory] => 5466464
            [free_memory] => 61642400
            [wasted_memory] => 0
            [current_wasted_percentage] => 0
        )

    [opcache_statistics] => Array
        (
            [num_cached_scripts] => 1
            [num_cached_keys] => 1
            [max_cached_keys] => 3907
            [hits] => 0
            [start_time] => 1452556026
            [last_restart_time] => 0
            [oom_restarts] => 0
            [hash_restarts] => 0
            [manual_restarts] => 0
            [misses] => 1
            [blacklist_misses] => 0
            [blacklist_miss_ratio] => 0
            [opcache_hit_rate] => 0
        )

    [scripts] => Array
        (
            [/my_dir/opcache/status.php] => Array
                (
                    [full_path] => /my_dir/opcache/status.php
                    [hits] => 0
                    [memory_consumption] => 1400
                    [last_used] => Mon Jan 11 21:47:18 2016
                    [last_used_timestamp] => 1452556038
                    [timestamp] => 1452555995
                )
        )
)

In addition to the opCache status, we can also check which configurations are being used by PHP through the opcache_get_configuration function:

print_r(opcache_get_configuration());

This function also returns an array with various information, but with information about the configuration used by opCache:

Array
(
    [directives] => Array
        (
            [opcache.enable] => 1
            [opcache.enable_cli] => 
            [opcache.use_cwd] => 1
            [opcache.validate_timestamps] => 1
            [opcache.inherited_hack] => 1
            [opcache.dups_fix] => 
            [opcache.revalidate_path] => 
            [opcache.log_verbosity_level] => 1
            [opcache.memory_consumption] => 67108864
            [opcache.interned_strings_buffer] => 4
            [opcache.max_accelerated_files] => 2000
            [opcache.max_wasted_percentage] => 0.05
            [opcache.consistency_checks] => 0
            [opcache.force_restart_timeout] => 180
            [opcache.revalidate_freq] => 2
            [opcache.preferred_memory_model] => 
            [opcache.blacklist_filename] => 
            [opcache.max_file_size] => 0
            [opcache.error_log] => 
            [opcache.protect_memory] => 
            [opcache.save_comments] => 1
            [opcache.load_comments] => 1
            [opcache.fast_shutdown] => 
            [opcache.enable_file_override] => 
            [opcache.optimization_level] => 4294967295
        )
    [version] => Array
        (
            [version] => 7.0.3
            [opcache_product_name] => Zend OPcache
        )
    [blacklist] => Array
        (
        )
)

As we are dealing with cache at some point, we will need to reset this cache, that is, delete it to be generated again. For this, PHP’s opCache provides us with a completely simple way to do this through the opcache_reset function.

opcache_reset();

With this simple call, all stored opCode will be deleted and recached in the next request. The return of this function is a boolean value that will return true when successfully resetting the cache, or false if opCache is disabled.

Last but not least, we have the opcache_compile_file function that compiles and caches the file without executing it. Its use is very intuitive, just call the function passing the file name. You can see all the configuration options for opCache on the official PHP website.

opcache_compile_file('my_file.php');

And it is possible to pass the full path along with the file name too:

opcache_compile_file('/local/do/arquivo/meu_arquivo.php');

It is only necessary to note that a NOTICE is generated if you try to execute this function in your PHP script with opCache disabled.

PHP Notice: Zend OPcache seems to be disabled, can't compile file in /my_dir/opcache/compile.php on line 3
PHP stack trace:
PHP 1. {main}() /my_dir/opcache/compile.php:0
PHP 2. opcache_compile_file() /my_dir/opcache/compile.php:3

Summary

Although this chapter is called basic, there are many details about the language that we must take into consideration. We gave examples of language constructors, use of namespaces and even use of bitwise, among others.

But of course we can always delve deeper into the topics presented, or go beyond. Don’t limit yourself to what was covered in this book. And if you don’t know where to go from here, we’ll have some tips.

The first of these is the use of operator precedence (http://php.net/manual/language.operators.precedence.php), which is basically the definition of which operator has priority over the other. This proves to be very important when doing mathematical operations.

The user-defined php.ini directives (http://php.net/manual/configuration.file.per-user.php). We can use these settings to have PHP read from different directories in addition to the default installation directory. It is worth taking a look.

And last but not least, are the control structures (http://php.net/manual/language.control-structures.php), which were not covered in this book, but it is also important to have them all fresh in the head.

Resources