topiniskala.com

PHP programming tutorial

Page index:

Introduction to PHP


Even with all of it's faults, PHP still might be my favourite programming language, at least when it come to web development. Unlike Java or .NET, PHP is very easy and effortless to deploy and you can get going with your project as soon as inspiration hits. This of course can be a double edged sword as the ease of coding makes it also easy to write bad code and ignore good practices. Having worked quite a bit with legacy PHP apps you can imagine the horrors I have witnessed...
But anyway, as PHP is my favourite language and I have been itching for some kind of easy and casual coding project outside of work, might as well go through a PHP tutorial book I found from flea market and write some kind of guide for the language based on it. Of course there are much better resources on PHP all over the internet, so if you stumble upon this and are interested in PHP, maybe explore the other ones first. This is just a casual hobby project, not a proper learning resource.

To get started with PHP, I recommend using Linux. I won't recommend any IDEs or editors as I personally enjoy programming most in a pure command line enviroment with Nano or Vi, but that might be too excentric for most. As for any specific flavour of Linux, Ubuntu (or more lightweight Xubuntu) is an easy recommendation as it is propably the most used and thus most documented, but personally I prefer CentOS for server use. On top of Linux you will propably need a server, a database system and of course the PHP engine to run your code. I will cover the basics of setting up a full LAMP stack (Linux, Apache, MySQL, PHP) at some point later and also cover some basic server hardening to take care of security, but for now i'll focus on programming.

PHP is a scripting language which means that instead of compiling your code to binary, you need a php run time enviroment to run your code, which is written as script files with .php extension. These files must start with <?php tag for the PHP engine to recognize them as proper scripts. You can test and run your scripts on the command line with the command php [SCRIPT NAME]. As PHP is a very web oriented language you almost never see any actual php programs that are run with the php command, but instead you place your PHP code into a web server and run it by accessing it on browser or programs like cURL.

In the following chapters I will go through the basics of programming in PHP before moving to the server and database stuff, but for now I end with two "Hello World" examples in PHP; the first to be run in command line and the next built into a website to be accessed by browser from server.

Command Line Hello World
<?php
echo "Hello World";
?>
Web page Hello World
<!DOCTYPE html>
<html>
<head>
    <title>Hello World</title>
</head>
<body>
    <?php echo "Hello World!"; ?>
</body>
</html>

Variables and text


Strings

In the previous chapter we used the "echo" command to print text, so let's start this chapter with how to create text, either to command line or the web page. In programming a line of text is called a "string". A single character data type is called a 'char', so a line of text is therefore a 'string' of 'chars'. To print strings PHP has two main options, either the aforementioned "echo" or "print". These two have some differences between them, but for us these differences are not important for now, so i'm not going to go deeper into them, but for now we will focus on "print".

strings.php
<?php
print "This is a line.";
print "This is another line.";
?>

If you run the program above (with php strings.php on command line) you can propably see a problem with the code. Everything is printed into one row without any line changes. This is because print considers the text to be just a line of characters and does not assume anything about the text. Thus we need to add line changes in text form and this is done with "\n". Just add that to the end of each of the print lines to get line changes after each of the strings. But why the "\n" marker? The backlash ("\") character is used as an "escape marker". It basically means that the character coming after the escape marker is something special and should be treated differently. Thus when we type "\n" the letter n should not be treated as a character "n" but instead as a line change marker. This is also how we can add quotations to our text without them cutting off a string like this: print "Be mindful of using "quotations" in strings";. By adding escape markers before the two double quotes within the string makes them regular double quote characters. You can also use single quote strings and they behave differently to normal ones:

strings.php
<?php
print "\nThis is a line.\n";
print "This is another line.\n";
print 'This is not a new line\n, this is
a new line';
?>

As you can see, single quote strings treat the print statement as is and ignores things like escape markers. Also you can insert variables (we get to these soon) directly inside the string with double quotes, but not single quotes. We can also use "print" to print out a block of html for web pages. This can be done by using "Here Document" syntax like in the next example. You can use all of the same escape markers in "Here Documents" as with double quotes.

here_document.php
<?php
print <<<HTMLBLOCK
<html>
<head>
    <title>Example</title>
</head>
<body>
    This is a "Here document" example.
</body>
</html>
HTMLBLOCK;
?>

Final basic concept regarding string we explore is combining strings together. This is done with period, or "." key like this: print "This is a string" . " and this is another string.";. Again remember that print does not assume anything about the string and thus you have to place the whitespace on either side of the combination. Now that we have basics of strings under control, we can move on to validating and formatting them with built-in PHP functions.

String functions

Here i'll list some basic PHP string functions that are commonly used in many programs. These can be used for example in input validation, which we'll go through more extensively in the future.

strlen(string $string) : int

This function returns the length of the string given as the parameter. You can use this for example to check if the input given by the user is of correct length when validating it. Here's an example:

<?php
//This should return: 16
print strlen("Length of string");
?>

trim(string $string, string $characters = " \n\r\t\v\0") : string

This function takes a string as a parameter and returns the given string with whitespace characters from the beginning and end removed. If you give a second parameter you can define which types of whitespaces are left in the return. So, for example if you give " \t" as the second parameter the regular whitespaces and tabs are left, but rest of the whitespace characters are removed. It is usually good practice to remove whitespaces from user inputs. Here's a basic example:

<?php
//This should return: Trim the string
print trim("\n        Trim the string          \n");
?>

strcmp(string $str1, string $str2) : int

This function takes two string as parameters and returns 0 if the two are equal. If the first is less than second, it returns "<0" and if the second is less ">0". By far the most common way to use this is to make an if statement of two values if they are equal. This comparison is case sensitive. If you need a non case sensitive comparison you can use the similarly functioning strcasecmp() function. Here's an example:

<?php
//This should return: 0
print strcmp("String", "String");
?>

strtolower(string $string) : string

This function takes a string as a parameter and returns the string with all alphabetic characters in lowercase. You can also use similar strtoupper() function to make strings all uppercase. You can also use the function ucwords() to make the first letter of every word capitalized. This is a great way make all of the user inputted names in same format no matter how they are inputted. Here's an example:

<?php
//This should return: Firstname Lastname
print ucwords(strtolower("FIRSTNAME LASTNAME"));
?>

substr(string $string, int $offset, int|null $length = null) : string

This is a slightly more complex function and it is used to cut out a part of the string. The first parameter of the function is the string we want to cut from, the second parameter is the offset point integer and the third is the length integer. So, if we give the offset as 0, we start cutting from the beginning of the string and if it were 3, we would start after the third character of the string. If you give a negative offset, the offset is counted back from the end of the string. Here's an example:

<?php
//This should return: long
print substr("Very long string", 5, 4);
?>

str_replace(array|string $search, array|string $replace, string|array $subject, int &$count = null) : string|array

This another somewhat complex function and it is used to replace instances of one string with another string inside a bigger string. The first parameter of this function is the string we are searching for, while the second is the replacement string. The third string is the one we are modifying. The fourth optional parameter is an integer, which contains the amount of replacements. So if you have a replacement that will change three instances, the optional fourth parameter will be 3. You only need to name the fourth parameter, don't give it a value. Here's an example:

<?php
//This should return: This is a word, this is a word and this is a word.
print str_replace("sentence", "word", "This is a sentence, this is a sentence and this is a sentence.");
?>

This is just a small taste of different PHP string functions for now and more can be found from PHP manual online. Next we'll move on to variables...

Variables

Variables are basically packages of data, that can be modified and used in various ways. You could imagine variables as kind of labelled boxes, where you put data into. Variables are signed with the dollar symbol ("$") and declared with the equals sign ("="). So for example we can store a string into a variable like this: $name = "Some program";. In this example we have a box labelled "name" which contains the text "Some program" and we can now use it in our code with print or within functions. We can also store other values within that variable but this will erase the previously stored value. A variable can also be a number and you can perform math with variable just like with regular numbers. You can also use these variables as function parameters with the string functions above. Here's some examples with math and variables:

math.php
<?php
$a = 15;
$b = 10;
print $a + $b . "\n"; //Gives: 25
print $a - $b . "\n"; //Gives: 5
print $a * $b . "\n"; //Gives: 150
print $a / $b . "\n"; //Gives: 1.5
print $a % $b . "\n"; //Gives: 5
?>

When naming variables you have to follow some rules. Variables names can only contain upper- and lowercase letters, digits (0-9) and underscores ("_"). You can also use various UTF-8 encoding characters but usually its good practice to stick to the ones I mentioned before. To use multiple words in a variable name people usually often use either underscores for whitespaces or so-called camelwriting ($thisIsSomething = "Something"). Also you cannot have a digit as the first letter of a variable name.

You can also insert variables into printed strings but if you need to add letters to the end of the variable content inside the string you need to separate it with the curly brackets. This is maybe easier to explain with an example so here we go:

variables.php
<?php
$word = "cat";
print "\nThis is a $word";           //Prints "This is a cat"
print "\nAll {$word}s are cute\n\n"; //Prints "All cats are cute"
?>

Finally let's also go quickly through the increment and decrement operators for variables. So lets assume that we have a variable $number = 5; and we wan't to increment or decrement it by one. To increment it by one we can just write $number++; or to decrement $number--;. This might not seem like much now, but we will be using these in the next chapter with loops.

Conditionals and loops


Conditionals

Before we can start working through conditional statements. With conditionals we often have statements that ask if a sentence is true or not. True and false are marked in PHP just like that, true and false$condition = false;. Now that we got that out of the way, next conditional statements!

Conditionals are written using the if(){} statement. You write the conditional statement within the parenthesis and the code to run if condition is met within the curly brackets. You can also use the else{} statement after the if statement to add code to run if condition is not met. You can also add multiple conditions with the else if(){} statement. It's usually not good practice to have a huge list of if/else statements in one conditional, but instead you should use switch statements in those situations, which we'll go through later. Here is an example of if/else:

ifelse.php
<?php
$value1 = 100;
$value2 = 200;
if ($value1 > $value2) {
    print "\nValue 1 ({$value1}) is greater.\n\n";
} else if ($value1 < $value2) {
    print "\nValue 2 ({$value2}) is greater.\n\n";
} else {
    print "\nThe values are equal\n\n";
}
?>

As we can see from the example above, we can compare values with the greater than ($value1 > $value2) and the lesser than ($value1 < $value2) symbols. If we want to test if two values are equal we can use two equal to ($value1 == $value2) symbols. One equal to symbol declares, two symbols compare. You can also combine the > or < and = ($value1 <= $value2) to compare lesser/greater OR equal to. You can also test for if values are NOT equal by adding in an exclamation mark to the statement ($value1 != $value2). You can also do math or use functions within the conditional. The functions and variables also work with the NOT equal sign, so you can use if statements also like this: if (!function()){}. In this example the conditional would trigger if the function returns false. Here is a bigger example of string validation in a conditional:

ifelse2.php
<?php
$name = "    HACKER MAN    ";
//Remember strcmp() returns 0 if values are equal and 0 -> false
if (strcmp("Hacker Man", ucwords(strtolower(trim($name))))) {
    print "\nThe values are equal\n\n";
} else {
    print "\nThe values are not equal\n\n";
}
?>

Conditional are one of the most basic parts of programming, as just about any program you make has to contain conditional statements at some point and of course they are essential for stuff like input validation. Just be careful with the amount of conditions you add in your code, as excessive use of them can easily lead to hard to read spaghetti code. Now that we have mastered the basics of conditionals, let's move on to loops!

Loops

Loops follow the same format as conditionals, with a loop statement within the parenthesis and the code to run within the curly brackets. There are multiple kinds of loops in programming, but the two most common ones are while(){} and for(){} loops, with the while loop being the easier one so let's start with that one.

The while loop is basically a repeated conditional statement that keeps on looping until a true value is reached. For example if you want to carry on repeating a process until a certain value is given you can do it easily with a while loop. This means that the code to run within the while loop must contain a way to reach the condition to break the loop. Otherwise the loop might run forever and eventually crash your server. Here's a while loop example:

while.php
<?php
//This should list numbers from 0 to 100
$number = 0;
print "\n" . $number;
while ($number < 100) {
    $number++;
    print "\n" . $number;
}
print "\n\n";
?>

The for loop is a bit more complex to write, but gives you much more control on how the loop is run. Unlike with while loop the way the loop runs and where it stops is written within the conditional statement and not in the code to run. The for loop thus takes three parameters in the conditional statement like this: for ($i = 0; $i < 10; $i++){} The previous for loop thus starts with variable i being 0 (first parameter) and increases by one with each iteration (third parameter) and ends when the condition (second parameter) is reached. This way you can decide where the loop starts, when it ends and how the iterations work. While for loops require less chance of having the loop run forever you still have to be careful with them as running long loops and especially nested loops (loops within loops) can task the processor when done excessively. Here's a bigger example of a for loop:

for.php
<?php
//This should list numbers from 0 to 100
for ($i = 0; $i <= 100; $i++) {
    print "\n" . $i;
}
print "\n\n";
?>

Now that we have mastered the conditionals and loops we can already write very simple programs. We can store values in variables, make all kinds of decicions and loop various operations. We can also print and modify strings and do math. All of this can already create web services when combined with html, but let's no get ahead of ourselves. Just storing data in variables can get messy very quickly, as we would have a different variable for each value we store and we often have to store data in series. To make this easier we'll next move on to arrays, which are lists of data within a single variable and are thus more efficient for mass data storing.

Arrays


When we talked about variables I explained variables as labelled boxes, which contain individual units of data. Following that example we can then describe arrays as labelled shelfs of boxes. An array is a variable with square brackets within it and inside the square brackets list of data as key/value pairs ($list = ["key1" => "value1", "key2" => "value2"];). The keys are used to access the data value that's linked to the key (print $list["key1"];). You can also add more value into an array through keys ($list["key3"] = "value3"). You can also create an array without keys ($list = ["value1", "value2"];) but then the PHP Engine assigns numeric keys to the values starting from 0 and incrementing by one for each next value. Also when adding data into the array if you do not give the added data a key, the PHP engine looks for the biggest key in array and makes the key that incremented by one.

In older versions of PHP (older than 5.4) the arrays are created with different syntax and the old way also works with new versions of PHP if you find it preferable ($list = array("key1" => "value1", "key2" => "value2");). Also be mindful of array names, because if you first declare an array, but then declare a variable of the same name all of the data in the array is wiped and it becomes a regular variable. If you then try to add in data the array way it will cause an error.

Array functions

Arrays have dedicated function just like strings are here is a list of some of the more common ones.

count(Countable|array $value, int $mode = COUNT_NORMAL) : int

This function counts the elements in a parameter array and returns an integer. You can also add in a second parameter set to COUNT_RECURSIVE (or 1) to make the count recursive, if you need to count multidimensional arrays (arrays within arrays). Here's an example:

<?php
//This should return: 5
print count(["value1", "value2", "value3", "value4", "value5"]);
?>

array_key_exists(string|int $key, array $array) : bool

This function checks if a certain key (given as a string) exists within an array. If it finds the key, the function returns true and if not, false. Here's an example:

<?php
//This should return: true
if (array_key_exists(2, [1 => "first", 2 => "second", 3 => "third"])) {
    print "true";
} else {
    print "false";
}
?>

in_array(mixed $needle, array $haystack, bool $strict = false) : bool

This function searches for a needle in a haystack, with the needle being a value string and the haystack an array. If you set the third optional parameter as true, the search will be type strict, which means that if you are searching for integer 1, it will not find the string "1". If needle is found a true is returned and if not, false. You can also use the function array_search() instead but instead of true or false it returns the key to the searched value. Here's an example:

<?php
//This should return: true
if (in_array("second", [1 => "first", 2 => "second", 3 => "third"])) {
    print "true";
} else {
    print "false";
}
?>

is_array(mixed $value) : bool

This function checks wether the given parameter is an array and returns a true or false based on findings. Very simple but surprisingly useful function. Here's an example:

<?php
//This should return: true
if (is_array([1 => "first", 2 => "second", 3 => "third"])) {
    print "true";
} else {
    print "false";
}
?>

explode(string $separator, string $string, int $limit = PHP_INT_MAX) : array

This function is a bit more complex. It takes two strings as parameters, the separator and the string to be exploded. The string to be exploded is broken into a numeric array with each value of the array being a part of the string cut accodring to separator. There is also an optional third parameter which is an integer and declares how many elements we want to explode out of the string with the rest of the string being in the final value of the array. This might be easier to explain with an example so here goes:

<?php
//This should return: explode
$arr = explode(" ", "Let's explode this string");
print $arr[1];
?>

implode(string $separator, array $array) : string

Implode is pretty much the opposite of explode. It take a separator string and an array as parameters and implodes the array into a string with the separator between the values. Unlike explode implode does not have a third parameter.

<?php
//This should return: Let's implode this array
$str = implode(" ", ["Let's", "implode", "this", "array"]);
print $str;
?>

sort(array &$array, int $flags = SORT_REGULAR) : bool

Thus function sorts the elements in the array according to values, from lowest to highest. The second parameter of the function contains various flags, which you can use to change the sorting rules. The function then returns a true or false based on if the sorting succeeded or not. Just be mindful that sort only touches the values and leaves the keys alone, so it should only be used on arrays with numeric keyes where the keyes are not important. If you want to keep the key/value pairs intact during sort use similarly functioning asort() function. If you want to sort by keyes instead of values there's the ksort() function.
Here's an example and a list of some of the flags you can use as the second parameter:

Flag Effect
SORT_REGULAR Default. Compare items normally.
SORT_NUMERIC Compare items numerically.
SORT_STRING Compare items as strings.
<?php
//This should return: 5
$arr = [6, 8, 5, 9];
sort($arr);
print $arr[0];
?>

Just like with strings there is also bunch more functions for arrays in the PHP manual online, but next we move to other array related stuff.

Looping through arrays

There is special loop in PHP for looping though arrays. This is very useful, as this loop is a kind of a for loop built specifically for arrays and gives a great way to go through lists of data and run repeated processes on each of the values. This loop is called foreach loop and it is written like this: foreach($arr as $key => $value){}. In that example the array we want to loop through is the $arr and each of the key/value pairs in the array is sent into the code to run as $key and $value variables. After all of the array elements have been looped through, the loop ends. If you do not need the keyes from the looped array you can only get the values by using foreach like this: foreach($arr as $value){}. If you want to access the original array when looping through it, you can add the keyes into the foreach loop and then use those on the original array. Let's do a quick example.

foreach.php
<?php
//This program loops through an array, prints each value and changes them on the original array.
$arr = ["key1" => "value1", "key2" => "value2", "key3" => "value3", "key4" => "value4", "key5" => "value5"];
foreach ($arr as $key => $value) {
    print "\n" . $value;
    $arr[$key] = "changed";
}
foreach ($arr as $value) {
    print "\n" . $value;
}
print "\n\n";
?>

Just like with other types of loops be mindfull that your loop does not become infinite.

Multidimensional arrays

Finally for arrays we'll go through the multidimensional arrays, which are basically arrays containing arrays. You declare them pretty much the same way as regular arrays but accessing data within them is a bit different. So let's say you have an array with three elements, with each of the elements being an array with three elements. This is basically a 3x3 grid! So to access the second element from the second array, we would use: $arr[1][1];. Having multiple layers of arrays within arrays again makes the code a nightmare to read and too heavy to run, so usually that is a point where you propably need to work on your code more rather than start running three+ nested foreach loops. Here's a better example for multidimensional arrays:

multi_d.php
<?php
$arr = [
    "array1" => ["key1" => "value1", "key2" => "value2", "key3" => "value3"],
    "array2" => ["key4" => "value4", "key5" => "value5", "key6" => "value6"],
    "array3" => ["key7" => "value7", "key8" => "value8", "key9" => "value9"]
];
foreach ($arr as $key => $value) {
    print "\n" . $key;
    foreach ($value as $key2 => $value2) {
        print "\n\t" . $value2;
    }
}
print "\n\n";
?>

We are getting closer and closer to the point where we can start to create actual proper programs. A big problem with a lot of the stuff we have been working with is that we cannot really write proper programs without lots of repetition and bunch of ugly, unwieldy code. Wouldn't it be awesome to be able to have functions like with arrays or strings to do most of the tasks in our code? Well, that is the next subject of the next chapter: How to write your own functions!

Functions


Before we start to explore how to build our own functions let's first go through why this is a good idea. So, let's say we have a piece of code in our program that we need to run multiple times. Instead of writing that piece of code multiple times and worry about syntax errors, we could just write a function for the code and call it multiple times throughout our code. This makes the code much more easy to keep clean and debug. Just don't overdo them and especially with functions that call other functions that call even more functions. Makes the code undebuggable spaghetti.

But let's move on to how to write functions. First, we need to declare a function with the word 'function'. Then we name the function and add opening and closing parenthesis after it. Finally we write the code to run between two curly brackets (function someName(){}). Now we can call this function with just the name and the two parenthesis (someName();). Let's make an example:

function.php
<?php
text();

//text()
function text() {
    print "\nThis piece of text would be very long and tedious to write multiple times...\n\n";
}
?>

As you can see in the above example, we could call the text() function multiple times and we would only have to write that long sentence just once. This is of course very efficient, but such simple functions have only very limited usability, so let's add parameters into the mix. We already used parameters in previous chapters with the built-in functions and they are basically various forms of data placed between the two parenthesis after the function name and separated by a comma. These parameters are now sent into the function and are a way to pass data from the main program into the function. But be mindful that you cannot just send randomly data to functions and expect it to work. For the function to be able to take parameters they need to be initialized in the function declaration. You can also set default values for parameters so that if the parameter is not set in function call, it uses the default value (function someFunc($num = 0){}). Here's an example:

function2.php
<?php
doMath(75);
doMath(80);
doMath(85);

//doMath(int $num)
function doMath($num) {
    print "\n";
    print $num + 5 . "\n";
    print $num - 5 . "\n";
    print $num * 5 . "\n";
    print $num / 5 . "\n";
    print "\n";
}
?>

Now that we are able to send data into a function, let's also learn how to return data from functions. As you can see from the many functions in the strings or arrays sections a lot of them return some data back. Once you are able to send data to and back from functions they become really powerful tools for your programming. Returning data from functions is really easy, just write return $item; and make sure you have a variable to return your value to ($stuff = someFunction($param);). Next let's have an example of full function with parameters and returns:

function3.php
<?php
for ($i = 0; $i < 25; $i++) {
    print "\n" . randMath($i);
}
print "\n\n";

//randMath(int $num) : int
function randMath($num) {
    return $num + rand(1, 100);
}
?>

Some stuff here

Links: