Difference between revisions of "PHP"
(41 intermediate revisions by 8 users not shown) | |||
Line 1: | Line 1: | ||
− | PHP is an open-source language used widely for writing server-side code for web servers. PHP is a good starting point for web developers, as it is straightforward to learn and yet powerful at the same time. Indeed, some of the internet's most popular web sites are written using PHP as their language of choice! This article introduces the syntax of PHP and how to make a | + | PHP is an open-source language used widely for writing server-side code for web servers. PHP is a good starting point for web developers, as it is straightforward to learn and yet powerful at the same time. Indeed, some of the internet's most popular web sites (including Facebook and Wikipedia) are written using PHP as their language of choice! This article introduces the syntax of PHP and how to make a basic PHP web application. |
− | == | + | {{XKCD |
+ | |name=mac_pc | ||
+ | |id=934 | ||
+ | }} | ||
− | + | == What is PHP? == | |
+ | |||
+ | PHP is a server-side scripting language widely used in web development. PHP is what turns your web site from a static fileserver into a dynamic web application. | ||
By default, Apache only knows how to serve static HTML pages to the client. You can write as many HTML pages as you want, which is fine for basic web sites. But if you want to have users post to a forum, or process credit card transactions, or make your own online calendar, a server-side language like PHP is what you need. | By default, Apache only knows how to serve static HTML pages to the client. You can write as many HTML pages as you want, which is fine for basic web sites. But if you want to have users post to a forum, or process credit card transactions, or make your own online calendar, a server-side language like PHP is what you need. | ||
+ | |||
+ | === Document Generation Language === | ||
+ | |||
+ | If PHP's original core purpose had to be described in three words, it would be this: '''document generation language'''. Unlike languages including Java, Ruby, Python, and Perl, which consist of classes in a strict program layout, PHP code is most often embedded inside a template document. When the PHP interpreter runs, it "fills in the gaps" and generates a finished product document. | ||
+ | |||
+ | This isn't to say that PHP can ''only'' be a document generating language, because this is certainly not true. However, for the purposes of Module 2, it is safe to think of it this way when you are learning the concepts behind a web server. | ||
+ | |||
+ | ==== MIME Types ==== | ||
+ | |||
+ | By default, PHP generates HTML documents. (Recall that an HTML document is simply a block of text consisting of markup conforming to the HTML standard.) | ||
+ | |||
+ | However, PHP does not need to generate HTML documents. It can also generate images, PDFs, or any other type of document. Each of these document types has its own unique markup language. The markup language used by a certain document is defined by its ''MIME Type''. | ||
+ | |||
+ | The HTML MIME Type is '''text/html'''. Other MIME Types include '''image/jpeg''', '''image/png''', and '''application/xml'''. | ||
+ | |||
+ | To change the MIME Type of the document generated by PHP, use the statement: | ||
+ | |||
+ | <source lang="php"> | ||
+ | header("Content-Type: image/jpeg"); | ||
+ | </source> | ||
+ | |||
+ | Since PHP generates HTML documents by default, you can think of there being an implicit <code>header("Content-Type: text/html");</code> at the top of every PHP script. | ||
+ | |||
+ | === PHP and Apache === | ||
+ | |||
+ | When you request a PHP file over Apache, the file is ''not'' sent verbatim. Instead, it is first sent through the PHP interpreter. Here is an oversimplified schematic of the process: | ||
+ | |||
+ | [[File:PHP-Apache_Flowchart.png]] | ||
+ | |||
+ | In summary, here are some points to keep in mind. | ||
+ | |||
+ | # A PHP file on your server is not an HTML document. It is a PHP script. | ||
+ | # PHP generates documents. By default, it generates HTML documents. | ||
+ | # PHP can generate other document types by changing the MIME Type in the Content-Type HTTP Header. | ||
+ | # Apache runs the PHP interpreter on your PHP script before transmitting it to the browser. The content that is generated after the PHP interpreter runs is expected to match the MIME type: by default, an HTML document. | ||
+ | # The W3C Validator checks for valid markup in an HTML document. Everywhere that PHP generates an HTML document, that HTML document should be valid. | ||
== Installing PHP == | == Installing PHP == | ||
− | To install PHP, | + | {{RequiredInstructions|content= |
+ | |||
+ | To install PHP 8.2, run the following commands. | ||
+ | |||
+ | sudo yum install php | ||
+ | sudo service php-fpm start | ||
+ | |||
+ | Once you install the required packages, [[Web Server Configuration#Restarting Apache and Testing|restart Apache]] for the changes to take effect. | ||
− | + | }} | |
== PHP Configurations == | == PHP Configurations == | ||
− | The PHP configuration file is called ''php.ini''. In RHEL, it is located at ''/etc | + | {{RequiredInstructions|content= |
+ | |||
+ | The PHP configuration file is called ''php.ini''. In RHEL, it is located at ''/etc/php.ini''. | ||
The configuration file is largely self-documenting as to what the different options mean. There is one value in particular that we want to change for the purposes of CSE330. Open php.ini in your favorite text editor, find the '''display_errors''' option, and set it to '''On''': | The configuration file is largely self-documenting as to what the different options mean. There is one value in particular that we want to change for the purposes of CSE330. Open php.ini in your favorite text editor, find the '''display_errors''' option, and set it to '''On''': | ||
Line 25: | Line 75: | ||
'''Note:''' You can turn errors on or off for a certain PHP script by using the '''error_reporting()''' and/or '''ini_set()''' functions. | '''Note:''' You can turn errors on or off for a certain PHP script by using the '''error_reporting()''' and/or '''ini_set()''' functions. | ||
− | '''Note:''' If you tell PHP to log its errors, they will be stored in the Apache error log file, at ''/var/log/ | + | '''Note:''' If you tell PHP to log its errors, they will be stored in the Apache error log file, at ''/var/log/php-fpm/www-error.log''. |
+ | |||
+ | }} | ||
== Your First PHP Script == | == Your First PHP Script == | ||
− | By default, all files that have the *.php extension will be interpreted as containing PHP code. Here is the most basic PHP script: | + | By default, all files that have the *.php extension will be interpreted as containing PHP code. |
+ | All files with PHP need to be saved as '.php'; not '.html'. | ||
+ | Here is the most basic PHP script: | ||
<source lang="php"> | <source lang="php"> | ||
Line 37: | Line 91: | ||
</source> | </source> | ||
− | Save that code into a file named phpinfo.php, and save it in your web server directory. Load it up in your browser like this: ''http://ec2-blah-blah.compute-1.amazonaws.com/phpinfo.php'' | + | Save that code into a file named phpinfo.php, and save it in your web server directory (/var/www/html/). Load it up in your browser like this: ''http://ec2-blah-blah.compute-1.amazonaws.com/phpinfo.php'' |
If you see something like this, your PHP installation is working! | If you see something like this, your PHP installation is working! | ||
Line 166: | Line 220: | ||
$fruits["g"] = "Grapefruit"; | $fruits["g"] = "Grapefruit"; | ||
− | echo $fruits[" | + | echo $fruits["c"]; # displays Cherry |
$keys = array_keys($fruits); # get an array containing indexed values of the fruits' keys | $keys = array_keys($fruits); # get an array containing indexed values of the fruits' keys | ||
Line 197: | Line 251: | ||
</source> | </source> | ||
− | PHP also supports switch statements, which are convenient for simplifying long if/ | + | PHP also supports switch statements, which are convenient for simplifying long if/elseif/else blocks: |
<source lang="php"> | <source lang="php"> | ||
Line 234: | Line 288: | ||
while ($i < 5) { | while ($i < 5) { | ||
$mystring .= "Blah"; | $mystring .= "Blah"; | ||
+ | $i++; | ||
} | } | ||
echo $mystring; # displays BlahBlahBlahBlahBlah | echo $mystring; # displays BlahBlahBlahBlahBlah | ||
Line 306: | Line 361: | ||
} | } | ||
− | function | + | function formatName(){ |
− | return $this->name; | + | return "Gotta love to eat " . $this->name; |
} | } | ||
} | } | ||
class Fruit extends Food { | class Fruit extends Food { | ||
− | function | + | function formatName(){ |
− | return | + | return Food::formatName() . " (fruit)"; |
} | } | ||
} | } | ||
Line 319: | Line 374: | ||
$fruit = new Fruit("Cherry"); | $fruit = new Fruit("Cherry"); | ||
− | echo $fruit-> | + | echo $fruit->formatName() . "\n"; # displays: Gotta love to eat Cherry (fruit) |
− | echo Fruit::getDefinition(); # displays Food is nourishment for carbon-based lifeforms. | + | echo Fruit::getDefinition() . "\n"; # displays: Food is nourishment for carbon-based lifeforms. |
?> | ?> | ||
Line 352: | Line 407: | ||
?> | ?> | ||
</source> | </source> | ||
+ | |||
+ | === Content Type === | ||
+ | |||
+ | PHP is just a factory for generating documents. We've so far seen it create HTML documents, but it can just as easily create images, PDFs, or any other type of interpreted file format. Each of these files formats has a '''MIME Type''' associated with it. To specify a MIME type for a page served over HTTP, the <code>Content-Type</code> header must be set. | ||
+ | |||
+ | This brings up an important point. '''Every PHP document has an implicit <code>Content-Type: text/html</code> header.''' This means that by default, PHP will generate HTML documents. '''The MIME type for a document can be changed using the header() function:''' | ||
+ | |||
+ | <source lang="php"> | ||
+ | <?php | ||
+ | header("Content-Type: text/plain"); | ||
+ | echo time(); | ||
+ | ?> | ||
+ | </source> | ||
+ | |||
+ | The above example creates a plain text file containing the current timestamp (number of seconds since January 1, 1970). | ||
+ | |||
+ | For another application of the Content-Type header, see [[#Sending a File to the Browser]] | ||
=== sprintf() === | === sprintf() === | ||
Line 458: | Line 530: | ||
For more detail on sprintf formats, refer to [http://us.php.net/sprintf the PHP documentation]. | For more detail on sprintf formats, refer to [http://us.php.net/sprintf the PHP documentation]. | ||
− | The remaining arguments are the data that are inserted into each of the conversion specifications. In the example above, there are four conversion specifications ('''%s''', '''%d''', '''%d''', and ''%d'''), so '''sprintf()''' takes 4 additional arguments after the format string. | + | The remaining arguments are the data that are inserted into each of the conversion specifications. In the example above, there are four conversion specifications ('''%s''', '''%d''', '''%d''', and '''%d'''), so '''sprintf()''' takes 4 additional arguments after the format string. |
Note that we still need to sanitize string output (using '''htmlentities()''' ) when we are using '''sprintf()'''. However, since our format string specifies integers for the remaining three arguments, '''sprintf()''' will take care of type casting, so we no longer need to worry about sanitizing the integers. | Note that we still need to sanitize string output (using '''htmlentities()''' ) when we are using '''sprintf()'''. However, since our format string specifies integers for the remaining three arguments, '''sprintf()''' will take care of type casting, so we no longer need to worry about sanitizing the integers. | ||
Line 530: | Line 602: | ||
<p> | <p> | ||
<strong>Gender:</strong> | <strong>Gender:</strong> | ||
− | <input type=" | + | <input type="radio" name="gender" value="male" id="maleinput" /> <label for="maleinput">Male</label> |
− | <input type=" | + | <input type="radio" name="gender" value="female" id="femaleinput" /> <label for="femaleinput">Female</label> |
</p> | </p> | ||
<p> | <p> | ||
Line 559: | Line 631: | ||
$age = 2012 - $birthyear; | $age = 2012 - $birthyear; | ||
− | printf("<p>Hello, %s %s! You were born in %d, so you are %d years old. You are % | + | printf("<p>Hello, %s %s! You were born in %d, so you are %d years old. You are %s.</p>\n", |
htmlentities($first), | htmlentities($first), | ||
htmlentities($last), | htmlentities($last), | ||
Line 618: | Line 690: | ||
<?php | <?php | ||
session_start(); | session_start(); | ||
− | + | ||
− | $oldnum = (int) $_SESSION['inc_num'] | + | $oldnum = (int) $_SESSION['inc_num']; |
+ | if($oldnum<1) $oldnum=1; | ||
$newnum = $oldnum*2; | $newnum = $oldnum*2; | ||
− | + | ||
echo $newnum; | echo $newnum; | ||
$_SESSION['inc_num'] = $newnum; | $_SESSION['inc_num'] = $newnum; | ||
Line 628: | Line 701: | ||
Sessions also work across different pages, as long as they are on the same web server. | Sessions also work across different pages, as long as they are on the same web server. | ||
+ | |||
+ | '''Tip:''' To log out a user, you can call '''session_destroy()''' after '''session_start()''' on the logout page. | ||
== Other PHP Tips == | == Other PHP Tips == | ||
Line 670: | Line 745: | ||
</source> | </source> | ||
− | '''Note:''' If you want to read an entire file, PHP provides the '''file_get_contents()''' function, which is basically a shortcut for '''fopen()''', '''fread()''', and '''fclose()'''. | + | '''Note:''' Most files in Linux end with an empty line, so the very last iteration of the above loop will output an empty bullet point. |
+ | |||
+ | '''Note:''' The function '''fgets()''' reads the contents of a line ''in addition to the line feed at the end of the line''. If you want to compare a string to the line that was read by '''fgets()''', you need to pass the value returned by '''fgets()''' to a function like '''[http://php.net/trim trim()]'''. | ||
+ | |||
+ | '''Note:''' If you want to read an entire file, PHP provides the '''file_get_contents()''' function, which is basically a shortcut for '''fopen()''', '''fread()''', and '''fclose()'''. ('''fread()''' is similar to '''fgets()''', except it reads the entire file instead of just one line.) | ||
=== Sending a File to the Browser === | === Sending a File to the Browser === | ||
− | Another useful function to know is the '''readfile''' function. It takes a file on the webserver's file system and sends it to the web browser. A simple example is given below | + | Another useful function to know is the '''readfile''' function. It takes a file on the webserver's file system and sends it to the web browser. A simple example is given below. |
The following example loads a file associated with a certain username and displays it. | The following example loads a file associated with a certain username and displays it. | ||
Line 708: | Line 787: | ||
// Finally, set the Content-Type header to the MIME type of the file, and display the file. | // Finally, set the Content-Type header to the MIME type of the file, and display the file. | ||
header("Content-Type: ".$mime); | header("Content-Type: ".$mime); | ||
+ | header('content-disposition: inline; filename="'.$filename.'";'); | ||
readfile($full_path); | readfile($full_path); | ||
Line 775: | Line 855: | ||
'''Note:''' By default, PHP will not allow a file upload of more than 2 MB. SitePoint has an excellent tutorial for how to increase this limit: http://www.sitepoint.com/upload-large-files-in-php/ | '''Note:''' By default, PHP will not allow a file upload of more than 2 MB. SitePoint has an excellent tutorial for how to increase this limit: http://www.sitepoint.com/upload-large-files-in-php/ | ||
+ | |||
+ | == PEAR == | ||
+ | |||
+ | The PHP Extension and Application Repository, or '''PEAR''', is a package manager that enables you to install classes and/or extensions to PHP. In other words, it is a yum/apt for PHP. You can think of PEAR as PHP's analog of ''gem'' in Ruby or ''pip'' in Python. | ||
+ | |||
+ | === Configuration === | ||
+ | |||
+ | PEAR is available through both the yum and apt repositories under the package name '''php-pear'''. | ||
+ | |||
+ | <source lang="bash"> | ||
+ | $ sudo yum install php-pear # in RHEL | ||
+ | </source> | ||
+ | |||
+ | === Installing PHP Extensions === | ||
+ | |||
+ | Using PEAR to install PHP extensions is just as easy as yum, apt, gem, and pip. Just run '''sudo pear install xxx'''. | ||
+ | |||
+ | <source lang="bash"> | ||
+ | $ sudo pear install Archive_Tar | ||
+ | </source> | ||
+ | |||
+ | Go here for a list of available packages in PEAR: http://pear.php.net/packages.php | ||
+ | |||
+ | === Using PHP Extensions === | ||
+ | |||
+ | To make use an extension installed in PEAR, you must '''include''' or '''require''' it into the PHP file of interest. For example, if you wanted to use the Archive_Tar class from the above example in a PHP file, you would do: | ||
+ | |||
+ | <source lang="php"> | ||
+ | <?php | ||
+ | require "Archive/Tar.php"; | ||
+ | |||
+ | // your code here | ||
+ | ?> | ||
+ | </source> | ||
+ | |||
+ | By convention, the filepath you need to specify is the name of the PEAR package with underscores replaced with slashes and a .php extension at the end. For example, the package ''Console_Getargs'' becomes <code>require "Console/Getargs.php";</code> | ||
+ | |||
+ | === PECL === | ||
+ | |||
+ | The PHP Extension Community Library, or '''PECL''', is a repository for additional PHP extensions, the difference being that PECL extensions are written in compiled C code rather than PHP. | ||
+ | |||
+ | PECL is installed automatically when you install PEAR from yum or apt-get. | ||
+ | |||
+ | Installing an extension using PECL is almost identical to PEAR, except that you use '''pecl''' instead of '''pear''' on the command prompt: | ||
+ | |||
+ | <source lang="bash"> | ||
+ | $ sudo pecl install imagick | ||
+ | </source> | ||
+ | |||
+ | You do not need to '''require''' or '''include''' PECL extensions since they are already compiled into PHP. | ||
== PHP Reference == | == PHP Reference == |
Latest revision as of 15:26, 5 June 2024
PHP is an open-source language used widely for writing server-side code for web servers. PHP is a good starting point for web developers, as it is straightforward to learn and yet powerful at the same time. Indeed, some of the internet's most popular web sites (including Facebook and Wikipedia) are written using PHP as their language of choice! This article introduces the syntax of PHP and how to make a basic PHP web application.
Contents
What is PHP?
PHP is a server-side scripting language widely used in web development. PHP is what turns your web site from a static fileserver into a dynamic web application.
By default, Apache only knows how to serve static HTML pages to the client. You can write as many HTML pages as you want, which is fine for basic web sites. But if you want to have users post to a forum, or process credit card transactions, or make your own online calendar, a server-side language like PHP is what you need.
Document Generation Language
If PHP's original core purpose had to be described in three words, it would be this: document generation language. Unlike languages including Java, Ruby, Python, and Perl, which consist of classes in a strict program layout, PHP code is most often embedded inside a template document. When the PHP interpreter runs, it "fills in the gaps" and generates a finished product document.
This isn't to say that PHP can only be a document generating language, because this is certainly not true. However, for the purposes of Module 2, it is safe to think of it this way when you are learning the concepts behind a web server.
MIME Types
By default, PHP generates HTML documents. (Recall that an HTML document is simply a block of text consisting of markup conforming to the HTML standard.)
However, PHP does not need to generate HTML documents. It can also generate images, PDFs, or any other type of document. Each of these document types has its own unique markup language. The markup language used by a certain document is defined by its MIME Type.
The HTML MIME Type is text/html. Other MIME Types include image/jpeg, image/png, and application/xml.
To change the MIME Type of the document generated by PHP, use the statement:
header("Content-Type: image/jpeg");
Since PHP generates HTML documents by default, you can think of there being an implicit header("Content-Type: text/html");
at the top of every PHP script.
PHP and Apache
When you request a PHP file over Apache, the file is not sent verbatim. Instead, it is first sent through the PHP interpreter. Here is an oversimplified schematic of the process:
In summary, here are some points to keep in mind.
- A PHP file on your server is not an HTML document. It is a PHP script.
- PHP generates documents. By default, it generates HTML documents.
- PHP can generate other document types by changing the MIME Type in the Content-Type HTTP Header.
- Apache runs the PHP interpreter on your PHP script before transmitting it to the browser. The content that is generated after the PHP interpreter runs is expected to match the MIME type: by default, an HTML document.
- The W3C Validator checks for valid markup in an HTML document. Everywhere that PHP generates an HTML document, that HTML document should be valid.
Installing PHP
To install PHP 8.2, run the following commands.
sudo yum install php sudo service php-fpm start
Once you install the required packages, restart Apache for the changes to take effect.
PHP Configurations
The PHP configuration file is called php.ini. In RHEL, it is located at /etc/php.ini.
The configuration file is largely self-documenting as to what the different options mean. There is one value in particular that we want to change for the purposes of CSE330. Open php.ini in your favorite text editor, find the display_errors option, and set it to On:
display_errors = On
You will need to restart Apache for any php.ini changes to take effect.
Note: You can turn errors on or off for a certain PHP script by using the error_reporting() and/or ini_set() functions.
Note: If you tell PHP to log its errors, they will be stored in the Apache error log file, at /var/log/php-fpm/www-error.log.
Your First PHP Script
By default, all files that have the *.php extension will be interpreted as containing PHP code. All files with PHP need to be saved as '.php'; not '.html'. Here is the most basic PHP script:
<?php
phpinfo();
?>
Save that code into a file named phpinfo.php, and save it in your web server directory (/var/www/html/). Load it up in your browser like this: http://ec2-blah-blah.compute-1.amazonaws.com/phpinfo.php
If you see something like this, your PHP installation is working!
Look at the source code of that page. Notice that even though there were only three lines of code in our PHP file, PHP filled it up with hundreds of lines of HTML!
Your own PHP scripts will probably look something more like this:
<!DOCTYPE html>
<html>
<head>
<title>My First PHP Script</title>
</head>
<body>
<?php
echo "\t<p>Hello World!</p>\n";
?>
</body>
</html>
The above code will send the following HTML to the browser:
<!DOCTYPE html>
<html>
<head>
<title>My First PHP Script</title>
</head>
<body>
<p>Hello World!</p>
</body>
</html>
Here's the take-home message of this section. To run PHP code, enclose it in <?php ?>
tags; HTML code can be used in a PHP file (although not inside the PHP code block!); and just a few lines of code can generate an arbitrary amount of HTML.
PHP Language Components
PHP is a programming language much like others you have learned: it has variables, arrays, functions, objects etc. However, the syntax for PHP and the way PHP handles variables may be new to you. This section gives an overview of PHP the language.
Variables
All variables start with the currency $ symbol. The $ is necessary for both setting and accessing.
PHP is a weak-typed language; that is, you can set any type of value to a variable (string, array, number, etc), and PHP will accept it, even if that variable previously contained a different data type. In some ways this is convenient, but in others it can lead to hard-to-detect bugs, so be careful.
<?php
$i = 5; # Set the integer 5 to the variable $i
$msg = "Hello World"; # Set the string Hello World to the variable $msg
?>
Notice that all lines in PHP necessarily end with a semicolon. If you forget a semicolon, the PHP will fail to parse!
Strings
Strings in PHP can be either single-quoted or double-quoted. Single-quoted strings are always taken literally; double-quoted strings allow for additional elements.
<?php
$a = "Apple";
$b = "Banana";
$fruits_double = "$a\n$b"; # $fruits_double now contains the string Apple (line break) Banana
$fruits_single = '$a\n$b'; # $fruits_single now contains the string $a\n$b
?>
If you want to use special characters in a double-quoted strings, escape them using the backslash operator:
<?php
$a = "Apple";
$b = "Banana";
$fruits = "\$a\\n$b"; # $fruits now contains the string $a\nBanana
?>
You can concatenate multiple strings together using the concatenation operator, which in php is a period:
<?php
$c = "Cherry";
$g = "Grapefruit";
$fruits = $c."\n".$g; # $fruits contains the string Cherry (line break) Grapefruit
?>
Arrays
Declaring arrays is very simple in PHP.
<?php
$fruits = array("Apple", "Banana", "Cherry", "Grapefruit"); # $arr now contains an array with 4 items
echo $fruits[1]; # displays Banana
echo count($fruits); # displays 4
array_shift($fruits); # remove the first element of the array
echo $fruits[1]; # displays Cherry
echo count($fruits); # displays 3
?>
Note: echo outputs a string to the browser. We will see more ways to output data later in this guide.
PHP also supports associative arrays. Associative arrays are arrays whose keys are strings rather than numbers; in some languages, they are called Dictionaries.
<?php
$fruits["a"] = "Apple";
$fruits["b"] = "Banana";
$fruits["c"] = "Cherry";
$fruits["g"] = "Grapefruit";
echo $fruits["c"]; # displays Cherry
$keys = array_keys($fruits); # get an array containing indexed values of the fruits' keys
echo $keys[3]; # displays g
?>
Conditional Statements
Conditional statements work similarly to how they do in other languages.
<?php
$grade = 85;
if ($grade < 60) {
echo "F";
} elseif ($grade < 70) {
echo "D";
} elseif ($grade < 80) {
echo "C";
} elseif ($grade < 90) {
echo "B";
} else {
echo "A";
}
?>
PHP also supports switch statements, which are convenient for simplifying long if/elseif/else blocks:
<?php
$food = "Apple";
switch ($food) {
case "Apple":
case "Banana":
case "Cherry":
case "Grapefruit":
echo "You must like fruit!";
break;
case "Broccoli":
case "Spinach":
echo "You must like vegetables!";
break;
default:
echo "You don't like fruits or vegetables!";
break;
}
?>
Loops
PHP supports several different kinds of loops, including while, for, and foreach:
<?php
$mystring = "";
$i = 0;
while ($i < 5) {
$mystring .= "Blah";
$i++;
}
echo $mystring; # displays BlahBlahBlahBlahBlah
$myarray = array("Apple", "Banana", "Cherry", "Grapefruit");
# The following two loops are functionally equivalent.
$mystring = "";
for($i=0; $i<count($myarray); $i++){
$mystring .= $i.": ".$myarray[$i].", ";
}
echo $mystring; # displays 0: Apple, 1: Banana, 2: Cherry, 3: Grapefruit
$mystring = "";
foreach($myarray as $key => $value){
$mystring .= $key.": ".$value;
}
echo $mystring; #displays 0: Apple, 1: Banana, 2: Cherry, 3: Grapefruit
?>
Functions
Just like with all modern programming languages, you can define your own functions with PHP.
<?php
function add($x, $y){
return $x + $y;
}
echo add(3, 5); # displays 8
?>
A neat shortcut for PHP is that you can specify default parameter values directly in the argument list:
<?php
function sayHello($name="John Doe"){
return "Hello, $name... how do you do?";
}
echo sayHello("Todd"); # displays Hello, Todd... how do you do?
echo sayHello(); # displays Hello, John Doe... how do you do?
?>
Object-Oriented Programming
PHP5 supports object-oriented programming, and many new libraries come as classes rather than simple functions. Here is an example class definition:
<?php
class Food {
protected $name;
function __construct($name){
$this->name = $name;
}
static function getDefinition(){
return "Food is nourishment for carbon-based lifeforms.";
}
function formatName(){
return "Gotta love to eat " . $this->name;
}
}
class Fruit extends Food {
function formatName(){
return Food::formatName() . " (fruit)";
}
}
$fruit = new Fruit("Cherry");
echo $fruit->formatName() . "\n"; # displays: Gotta love to eat Cherry (fruit)
echo Fruit::getDefinition() . "\n"; # displays: Food is nourishment for carbon-based lifeforms.
?>
Things to notice:
- All methods in a class must be preceded by the function keyword.
- Static methods require the static keyword
- Instance methods can refer to the current instance through the implicit variable $this
- To access properties and methods from an instance, use an arrow: $instance->property
- To access static properties and methods from a class, use two colons: ClassName::StaticPropertyOrMethod
- Instances of classes are defined using the syntax $instance = new ClassName(); like in Java
Outputting Data
What's the point of a web language if we can't output data? The most basic method for outputting data is using either the echo or print statement:
<?php
echo "Hello World"; # outputs Hello World to the browser
?>
You often find yourself wanting to print all information associated with a variable for debugging purposes. PHP provides the handy var_dump function for that:
<?php
var_dump($myvar);
?>
Content Type
PHP is just a factory for generating documents. We've so far seen it create HTML documents, but it can just as easily create images, PDFs, or any other type of interpreted file format. Each of these files formats has a MIME Type associated with it. To specify a MIME type for a page served over HTTP, the Content-Type
header must be set.
This brings up an important point. Every PHP document has an implicit Content-Type: text/html
header. This means that by default, PHP will generate HTML documents. The MIME type for a document can be changed using the header() function:
<?php
header("Content-Type: text/plain");
echo time();
?>
The above example creates a plain text file containing the current timestamp (number of seconds since January 1, 1970).
For another application of the Content-Type header, see #Sending a File to the Browser
sprintf()
Code in PHP that outputs information can get very ugly. Consider, for example, the following snippet:
<?php
$medals = array(
"United States" => array(46, 29, 29),
"China" => array(38, 27, 23),
"Russia" => array(24, 26, 32)
);
?>
<table>
<tr>
<th>Country</th>
<th>Gold Medals</th>
<th>Silver Medals</th>
<th>Bronze Medals</th>
</tr>
<?php
foreach($medals as $country => $counts){
echo "\t<tr>\n\t\t<td>".htmlentities($country)."</td>\n\t\t<td>".htmlentities($counts[0])."</td>\n\t\t<td>".htmlentities($counts[1])."</td>\n\t\t<td>".htmlentities($counts[2])."</td>\n\t</tr>\n";
}
?>
</table>
This code will generate the following HTML:
<table>
<tr>
<th>Country</th>
<th>Gold Medals</th>
<th>Silver Medals</th>
<th>Bronze Medals</th>
</tr>
<tr>
<td>United States</td>
<td>46</td>
<td>29</td>
<td>29</td>
</tr>
<tr>
<td>China</td>
<td>38</td>
<td>27</td>
<td>23</td>
</tr>
<tr>
<td>Russia</td>
<td>24</td>
<td>26</td>
<td>32</td>
</tr>
</table>
It's not very clear, though, that this is what the PHP code is going to generate. In particular, the echo line inside the foreach loop is 196 jumbled characters!
sprintf() is a nifty PHP function (with roots in C) that allows us to clean up that code. We get the same output as above if we use the following PHP instead:
<?php
$medals = array(
"United States" => array(46, 29, 29),
"China" => array(38, 27, 23),
"Russia" => array(24, 26, 32)
);
?>
<table>
<tr>
<th>Country</th>
<th>Gold Medals</th>
<th>Silver Medals</th>
<th>Bronze Medals</th>
</tr>
<?php
foreach($medals as $country => $counts){
echo sprintf("\t<tr>\n\t\t<td>%s</td>\n\t\t<td>%d</td>\n\t\t<td>%d</td>\n\t\t<td>%d</td>\n\t</tr>\n",
htmlentities($country),
$counts[0],
$counts[1],
$counts[2]
);
}
?>
</table>
The above code is more straightforward and self-explanatory than the first example, and it is also easier to edit and maintain.
Here's how sprintf() works. The first argument is a format string. A format string can contain conversion specifications for additional data that will be inserted into the format string. The most common conversion specifications are:
- %s for a string
- %d for a signed integer
- %u for an unsigned integer
- %f for a floating-point number
- %.2f for a floating-point number with 2 decimal places
- %% for a literal percentage sign
For more detail on sprintf formats, refer to the PHP documentation.
The remaining arguments are the data that are inserted into each of the conversion specifications. In the example above, there are four conversion specifications (%s, %d, %d, and %d), so sprintf() takes 4 additional arguments after the format string.
Note that we still need to sanitize string output (using htmlentities() ) when we are using sprintf(). However, since our format string specifies integers for the remaining three arguments, sprintf() will take care of type casting, so we no longer need to worry about sanitizing the integers.
An additional tip: printf() is a shortcut for echo sprintf(). That is, the following lines are functionally equivalent:
<?php
$n = 12345.678;
printf("%.2f\n", $n); // prints 12345.68
echo sprintf("%.2f\n", $n); // also prints 12345.68
?>
Passing Variables
Input values can be passed to a script either through the URL request line or through data submitted by a form. Built in arrays $_GET['var'] and $_POST['var'] return the value of var depending on the access method. As we will see in the next section, values can also be passed through session variables. Finally, you can use cookies to store and retrieve values.
Note that upon submitting a form, the page specified in the form tag's action attribute is loaded (with variables sent via post or get).
GET: Passing Variables via URL
If you want to pass values in a URL, the format is ''http://example.com/yourphpfile.php?var1=value1&var2=value2.....''
PHP saves URL variables in the associative array $_GET.
For example, the following PHP document would print a hello message according to a name given in the URL.
<!DOCTYPE html>
<head><title>Hello World</title></head>
<body>
<?php
$name = $_GET['name'];
printf("<p>Hello, %s; how do you do?</p>\n",
htmlentities($name)
);
?>
</body>
</html>
If you access the URL like this: greeting.php?name=Alice, it will show Hello, Alice; how do you do?
Note: Before we output the name, we pass it through htmlentities(), which sanitizes it for output to the HTML document. This is necessary because if we displayed the name verbatim from the URL, the name could be anything: that includes malicious code that could be run on a victim's computer! You will learn more about this type of cyberattack, called Cross-Site Scripting, in Module 4. For now, just know that whenever you display anything to the end user, you need to pass it through htmlentities().
POST: Passing Variables via Form
Another method for passing variables from page to page is by sending it via POST variables. Like with GET, POST variables are saved in an associative array, this time named $_POST.
Consider the following form:
<!DOCTYPE html>
<head><title>Hello World</title></head>
<body>
<form action="info.php" method="POST">
<p>
<label for="firstnameinput">First Name:</label>
<input type="text" name="firstname" id="firstnameinput" />
</p>
<p>
<label for="lastnameinput">Last Name:</label>
<input type="text" name="lastname" id="lastnameinput" />
</p>
<p>
<label for="birthyearinput">Birth Year:</label>
<input type="number" name="birthyear" id="birthyearinput" />
</p>
<p>
<strong>Gender:</strong>
<input type="radio" name="gender" value="male" id="maleinput" /> <label for="maleinput">Male</label>
<input type="radio" name="gender" value="female" id="femaleinput" /> <label for="femaleinput">Female</label>
</p>
<p>
<input type="submit" value="Send" />
<input type="reset" />
</p>
</form>
</body>
</html>
For more information on the HTML markup in the above example, refer to the HTML and CSS guide.
This submits a form with POST data to info.php. Inside info.php, the provided values will be available in the associative $_POST array under the keys firstname, lastname, birthyear, and gender.
To display the submitted input on a target page, info.php could contain:
<!DOCTYPE html>
<head><title>Person Information</title></head>
<body>
<?php
$first = $_POST['firstname'];
$last = $_POST['lastname'];
$birthyear = (int) $_POST['birthyear'];
$gender = $_POST['gender'];
$age = 2012 - $birthyear;
printf("<p>Hello, %s %s! You were born in %d, so you are %d years old. You are %s.</p>\n",
htmlentities($first),
htmlentities($last),
$birthyear,
$age,
htmlentities($gender)
);
?>
</body>
</html>
Note: It is very important that you always sanitize strings that you output to the browser using htmlentities() or a similar function. If you don't, your site will be vulnerable to all sorts of malware. For more information, refer to the Web Application Security guide.
For further help with using HTML forms with PHP, we recommend this tutorial.
Self-Submitting Forms
Oftentimes we don't want to pass form values to a different page, but rather to the same page as contains the form so that we can process the information and display output on that same page. To do this, you can simply omit the action parameter from the form. Alternatively, you can use a PHP environment variable like $_SERVER['PHP_SELF'].
The following example simply takes the data input from a form and, via POST variables, echoes it back to the user as bold text on the same page:
<!DOCTYPE html>
<html>
<head><title>Bold Printer</title></head>
<body>
<form action="<?php echo htmlentities($_SERVER['PHP_SELF']); ?>" method="POST">
<p>
<label for="name">Name:</label>
<input type="text" name="name" id="name" />
</p>
<p>
<input type="submit" value="Print in Bold" />
</p>
</form>
<?php
if(isset($_POST['name'])){
printf("<p><strong>%s</strong></p>\n",
htmlentities($_POST['name'])
);
}
?>
</body>
</html>
Sessions
If you need to keep track of information associated with a user between page loads, you should use a session. Sessions are excellent for keeping track of the currently-logged-in user, for example.
PHP makes session management dirt simple. Whenever you need to use session variables, simply call session_start(). Then, you may interact with the $_SESSION associative array, and PHP will take care of accessing and saving all session variables for you!
For example, the following page will display a number, and then double that number on each page reload:
<?php
session_start();
$oldnum = (int) $_SESSION['inc_num'];
if($oldnum<1) $oldnum=1;
$newnum = $oldnum*2;
echo $newnum;
$_SESSION['inc_num'] = $newnum;
?>
Sessions also work across different pages, as long as they are on the same web server.
Tip: To log out a user, you can call session_destroy() after session_start() on the logout page.
Other PHP Tips
Redirecting to a Different Page
If you want to redirect the user to a different page, you need to send a Location header. For example, a page containing only this code would redirect the user to the login.php file:
<?php
header("Location: login.php");
exit; // we call exit here so that the script will stop executing before the connection is broken
?>
It is often useful to perform redirects after you perform server-side operations.
Important: You should generally not leave a user sitting on a page that has POST data, because if they refresh the page, their POST data will be submitted again, causing your server to perform an action twice. Rather, you should perform the operation, and then redirect them to another page that does not contain POST data in the header.
Reading a File Line-by-Line
If you want to read a file line-by-line, open a file handler using fopen(), use fgets() to read lines until you've reached the end, and then close the file using fclose().
The following example reads file_with_lines.txt and outputs its content in an unordered list, where each list item is a line in the file:
<?php
$h = fopen("file_with_lines.txt", "r");
$linenum = 1;
echo "<ul>\n";
while( !feof($h) ){
printf("\t<li>Line %d: %s</li>\n",
$linenum++,
fgets($h)
);
}
echo "</ul>\n";
fclose($h);
?>
Note: Most files in Linux end with an empty line, so the very last iteration of the above loop will output an empty bullet point.
Note: The function fgets() reads the contents of a line in addition to the line feed at the end of the line. If you want to compare a string to the line that was read by fgets(), you need to pass the value returned by fgets() to a function like trim().
Note: If you want to read an entire file, PHP provides the file_get_contents() function, which is basically a shortcut for fopen(), fread(), and fclose(). (fread() is similar to fgets(), except it reads the entire file instead of just one line.)
Sending a File to the Browser
Another useful function to know is the readfile function. It takes a file on the webserver's file system and sends it to the web browser. A simple example is given below.
The following example loads a file associated with a certain username and displays it.
<?php
session_start();
$filename = $_GET['file'];
// We need to make sure that the filename is in a valid format; if it's not, display an error and leave the script.
// To perform the check, we will use a regular expression.
if( !preg_match('/^[\w_\.\-]+$/', $filename) ){
echo "Invalid filename";
exit;
}
// Get the username and make sure that it is alphanumeric with limited other characters.
// You shouldn't allow usernames with unusual characters anyway, but it's always best to perform a sanity check
// since we will be concatenating the string to load files from the filesystem.
$username = $_SESSION['username'];
if( !preg_match('/^[\w_\-]+$/', $username) ){
echo "Invalid username";
exit;
}
$full_path = sprintf("/srv/uploads/%s/%s", $username, $filename);
// Now we need to get the MIME type (e.g., image/jpeg). PHP provides a neat little interface to do this called finfo.
$finfo = new finfo(FILEINFO_MIME_TYPE);
$mime = $finfo->file($full_path);
// Finally, set the Content-Type header to the MIME type of the file, and display the file.
header("Content-Type: ".$mime);
header('content-disposition: inline; filename="'.$filename.'";');
readfile($full_path);
?>
Uploading a File
Uploading files is similar to submitting data in forms. For starters, you need a form that submits to your uploading script:
<form enctype="multipart/form-data" action="uploader.php" method="POST">
<p>
<input type="hidden" name="MAX_FILE_SIZE" value="20000000" />
<label for="uploadfile_input">Choose a file to upload:</label> <input name="uploadedfile" type="file" id="uploadfile_input" />
</p>
<p>
<input type="submit" value="Upload File" />
</p>
</form>
Note that we need to specify enctype="multipart/form-data"
on the form. This is to enable files to be uploaded and recognized by PHP.
PHP puts all files submitted with a form into the $_FILES superglobal array. Each entry in the $_FILES array contains the following information:
- $_FILES['uploadedfile']['name'] is the original name of the file on the client's machine
- $_FILES['uploadedfile']['type'] is the MIME type of the file according to the browser (don't take it for granted)
- $_FILES['uploadedfile']['size'] is the size, in bytes, of the uploaded file
- $_FILES['uploadedfile']['tmp_name'] is the temporary location on your filesystem where Apache saved the uploaded file
- $_FILES['uploadedfile']['error'] is the error code associated with the file upload (if applicable)
To upload the file submitted by the form above in a user's special folder, we could use the following PHP code:
<?php
session_start();
// Get the filename and make sure it is valid
$filename = basename($_FILES['uploadedfile']['name']);
if( !preg_match('/^[\w_\.\-]+$/', $filename) ){
echo "Invalid filename";
exit;
}
// Get the username and make sure it is valid
$username = $_SESSION['username'];
if( !preg_match('/^[\w_\-]+$/', $username) ){
echo "Invalid username";
exit;
}
$full_path = sprintf("/srv/uploads/%s/%s", $username, $filename);
if( move_uploaded_file($_FILES['uploadedfile']['tmp_name'], $full_path) ){
header("Location: upload_success.html");
exit;
}else{
header("Location: upload_failure.html");
exit;
}
?>
Note: A lot of the code above is the same as the code in the file download example. In your project, you should save the logic of generating the file path (in a function) in a third file that you include into the upload and download scripts.
Note: By default, PHP will not allow a file upload of more than 2 MB. SitePoint has an excellent tutorial for how to increase this limit: http://www.sitepoint.com/upload-large-files-in-php/
PEAR
The PHP Extension and Application Repository, or PEAR, is a package manager that enables you to install classes and/or extensions to PHP. In other words, it is a yum/apt for PHP. You can think of PEAR as PHP's analog of gem in Ruby or pip in Python.
Configuration
PEAR is available through both the yum and apt repositories under the package name php-pear.
$ sudo yum install php-pear # in RHEL
Installing PHP Extensions
Using PEAR to install PHP extensions is just as easy as yum, apt, gem, and pip. Just run sudo pear install xxx.
$ sudo pear install Archive_Tar
Go here for a list of available packages in PEAR: http://pear.php.net/packages.php
Using PHP Extensions
To make use an extension installed in PEAR, you must include or require it into the PHP file of interest. For example, if you wanted to use the Archive_Tar class from the above example in a PHP file, you would do:
<?php
require "Archive/Tar.php";
// your code here
?>
By convention, the filepath you need to specify is the name of the PEAR package with underscores replaced with slashes and a .php extension at the end. For example, the package Console_Getargs becomes require "Console/Getargs.php";
PECL
The PHP Extension Community Library, or PECL, is a repository for additional PHP extensions, the difference being that PECL extensions are written in compiled C code rather than PHP.
PECL is installed automatically when you install PEAR from yum or apt-get.
Installing an extension using PECL is almost identical to PEAR, except that you use pecl instead of pear on the command prompt:
$ sudo pecl install imagick
You do not need to require or include PECL extensions since they are already compiled into PHP.
PHP Reference
If you ever have a question about PHP, first check the well-written documentation. To skip immediately to the documentation on any function, simply visit http://php.net/functionname. For example: http://php.net/var_dump