FreeBSD Programming Primer – Part 3

}

March 28, 2013

In the third part of our series on programming, we will look at code structure, program flow and how to embed CSS and Javascript in out pages. We will also start using SQL to dynamically generate web pages.

  • What you will learn in this series:
  • How to to configure a development environment and write HTML, CSS, PHP and SQL code
  • What you need to know:
  • BSD and general PC administration skills

Before we start coding in earnest, we will look at the basic construction of our programming language (PHP), the directory and functional structure of our CMS and how this all fits together. Our CMS will be designed to be as extensible as possible, and will follow the design as detailed in Figure 1. Pages will be stored in the MySQL database, merged with the header, templates, CSS and Javascript and returned to the client browser. This will allow us to separate design from content efficiently.

Key Command line instructions
Alterations to configuration files
MySQL prompt / SQL
HTML / XHTML / PHP / CSS / Javascript code
Part 1. PHP fundamentals
Any language – both verbal and programming – comprises of separate elements that fit together in a logical structure that communicates meaning to the recipient. For language to be effective, rules are strictly defined, not only to preserve efficiency but to prevent misunderstanding. For example, a written sentence will comprise of nouns, verbs and adjectives – likewise computer code will consist of variables, expressions and control structures. The main functional difference between a human language such as English and a programming language is flexibility and interpretation – as humans we adaptable enough to interpret a missing full stop or misspelled word correctly, whereas a computer will fail miserably.

Here will will look at some of the the basic building blocks of PHP.
The following code examples can be created in the examples directory using your favorite editor (in this case I am using VI). Login to the webserver using SSH or from the console, switch to the DEV account from root and create the files:
dev# su
dev# su dev
dev# cd /home/dev/data/
dev# mkdir examples
dev# cd examples
dev# vi example1.php
The example can then be run from:
http://yourserveripaddress/examples/example1.php (see Figure 2)

You do not need to run the examples to develop a working CMS, but they are useful to experiment with. Change values and experiment.
PHP tags
All PHP code requires an opening tag is only necessary when combining PHP with Javascript, HTML etc.
Comments
In PHP comments are denoted with // . A block of comments can also be with a block using /* …. */.
Expressions
To quote the PHP website “Expressions are the most important building stones of PHP. In PHP, almost anything you write is an expression. The simplest yet most accurate way to define an expression is “anything that has a value”.
For instance, if the server has 3 disk drives this could be written as:
<!–?php
$disk_drives = 3;
Constants
A constant is useful where the the value will not change across the execution of the script. Unlike variables, constants are accessible within function calls and throughout the script, whereas variables may be local only to that particular function. This aids program readability.
The circumference of a circle is calculated by multiplying the diameter by PI (3.14). As PI is a constant and will not change, we can define PI as a constant. See Listing 1)
Listing 1. xxxxxxx
<?php
/*
* example1.php
* Constants
* Define PI as the constant 3.14 and output the result.
*
*/
define(“PI”, 3.14);
echo PI;
Variables
A variable holds the result of an expression or statement. As the name implies, the value of the variable will change over the life of the program. The variable name is defined on the left hand side of the = sign and the value of the variable is defined on the right hand side. (See Listing 2).
Listing 2. xxxxxxx
<?php
/*
* example2.php
* Variables
* Define circumference as the variable $circumference with the value
* 12.775 and output the result
*
*/
$circumference = 12.775;
echo $circumference;
Data types
Data types, as the name suggests, define what type of data we can hold in a variable or constant. The basic types are booleans, integers, floats, strings, and arrays.
Booleans
A boolean is used where a dual state is useful. A boolean has one of two values, TRUE or FALSE. For instance, we can define the constant DEBUG and act accordingly depending on how DEBUG evaluated by the “if” control structure: see Listing 3.
Listing 3. xxxxxxx
<?php
/*
* example3.php
* Booleans
* Define DEBUG as a boolean, and print our status.
* Change TRUE to FALSE to change the output message.
*
*/
define(“DEBUG”, TRUE);
if (DEBUG) {
echo ‘We are in Debug mode’;
} else {
echo ‘We are not in Debug mode’;
}
Integers
An integer is a whole number of the set Z = {…, -2, -1, 0, 1, 2, …}. As the maximum and minimum value is platform independent, we can access this value via the constant PHP_INT_MAX. If PHP encounters a number larger than PHP_INT_MAX, the number will be converted to a float. See Listing 4.
Listing 4. xxxxxxx
<?php
/*
* example4.php
* Integers
* Check the maximum integer size available on your platform.
* For a 32 bit system this will be 2147483647.
*
*/
echo PHP_INT_MAX;
Floats
The maximum size of a floating point number, like Integers, is platform dependent. However, all sorts of rounding and logic errors can be introduced into code with floats as they behave differently from integers so particular care should be used. For instance, 1/3 is equal to 0.33333 with 3 recurring to infinity, but as we have limited space it is impossible to represent this fully. If accuracy is critical, various libraries are available to improve float functionality. See Listing 5.
Listing 5. xxxxxxx
<?php
/*
* example5.php
* Floats
* Calculate PI as a float using the more accurate formula 22 / 7.
* This should return 3.1428571428571.
*
*/
$pi = 22 / 7;
echo $pi;
Strings
A PHP string can contain up to 2Gb of characters. A string is limited to 256 ASCII characters, and does not internally store strings in Unicode format unlike some other languages.
A string can be surrounded either by single or double quotes. If surrounded by double quotes, PHP will endeavor to evaluate any variables contained within. A single quoted string is called a string literal as the string is interpreted literally rather than expanding any variables contained within it. Like the Vi versus Emacs discussion, the use of single or double quotes is very much a question of what you want to achieve. While single quotes may be considered quicker than double quotes, other coding factors have a greater impact on speed. See Listing 6.
Listing 6. xxxxxxx
<?php
/*
* example6.php
* Strings
* Demonstration of the PHP string type.
* Note that the last line is functionally identical to the previous
* line and we are separating each line with a HTML
.
*
*/
define(“BR”, ‘
‘);
$pi = 22 / 7;
echo ‘The value of PI is: $pi’ . BR;
echo ‘The value of PI is: ‘ . $pi . BR;
echo “The value of PI is: $pi” . BR;
Arrays
An array is a list with a key and value pair. For instance, we can list the major BSD distributions as an array variable, rather than multiple separate variables. We can then perform operations on the list by looping through the key / value pairs.
Arrays are useful where we have to keep records in sync. For instance if the records from a database table were dumped into an array it would be easy to manage using the record ID as key. If separate variables were used, it would be difficult to manage and the potential for errors would be great.
Arrays do not need to have sequential keys, indeed PHP supports the mixing of numeric and string values as keys within arrays. You can even define another array as the value of an array
The first array example is the traditional PHP method for defining arrays, the second version onwards is available in > PHP 5.4. See Listing 7.
Listing 7. xxxxxxx
<!–?php
/*
* example7.php
* Arrays
* All of these examples are functionally equivalent
*
*/
define(“BR”, ‘
‘);
// Define the array then print it out using the function print_r()
// Use BR to separate each line
$array_1 = array(
“0” => “FreeBSD”,
“1” => “OpenBSD”,
“2” => “NetBSD”,
);
print_r($array_1);
echo BR;
$array_2 = [
“0” => “FreeBSD”,
“1” => “OpenBSD”,
“2” => “NetBSD”,
];
print_r($array_2);
echo BR;
// Arrays can use mixed key values – they do not have to start at 0
$array_3[5] = “FreeBSD”;
$array_3[“This is key 6”] = “OpenBSD”;
$array_3[7] = “NetBSD”;
print_r($array_3);
echo BR;
// Let PHP assign the key values
$array_4[] = “FreeBSD”;
$array_4[] = “OpenBSD”;
$array_4[] = “NetBSD”;
print_r($array_4);
echo BR;
Operators
Operators are used to compare values (Comparison / Logical) or change values (Arithmetic / Assignment / Increment / Decrement / String). Care has to be taken with operator precedence, as certain operators will fire first. For example, the multiplication operator * takes precedence over the addition operator + unless the addition portion of the equation is wrapped in brackets: see Listing 8.
Listing 8. xxxxxxx
<!–?php
/*
* example8.php
* Demonstration of operator precedence
*
*/
define(“BR”, ‘
‘);
$a = 1 + 5 * 3;
$b = (1 + 5) * 3;
echo ‘$a will evaluate to 16: ‘ . $a . BR;
echo ‘$b will evaluate to 18: ‘ . $b . BR;
See Table 1 for the full list of of the most common operators.
Functions
Functions are small blocks of code that can act as effectively as a “black box” to the code that is calling it. As functions can be called repeatedly from anywhere within code – and if written properly – will provide a consistent result. Functions can act independently of the code that is calling them, or can return a result that can be manipulated by the main body of the program. An important point to realize is that variables defined inside a function are generally out of scope of the main body – that is to say $a in the main body of a program cannot be accessed by the function unless it is either passed as a parameter or accessed via some other method.
(PHP has a rich library of internal functions, if you do not recognize a function call in the later CMS sample code the script will be using a built in PHP function. The same apples to the javascript sample). See Listing 9.
Listing 9. xxxxxxx
<!–?php
/*
* example9.php
* Demonstration of a function call
*
*/
// As BR is a constant, this is available to our function directly
define(“BR”, ‘
‘);
// $pi is not available to our function, we will need to access it by
// other methods
$pi = 22 / 7;
echo “Circumference with a diameter 5: ” . print_circ1(5);
echo “Circumference with a diameter 10: ” . print_circ2(10,$pi);
function print_circ1($diameter) {
// print_circ1() will display $pi * $diameter
// Define $pi as a global variable
global $pi;
// As BR is a global constant we can access it directly
// Return our result to the main body of the program
return $pi * $diameter . BR;
}
function print_circ2($diameter, $pi) {
// print_circ2() will display $pi * $diameter
// As BR is a global constant and $pi has been passed to our
// function we can access them directly.
// Return our result to the main body of the program
return $pi * $diameter . BR;
}
Control structures
Control structures, along with Comparison / Logical operators provide the logic for our program.
Example 3 is a good example of the if/else control structure.
These are only a very small subset and the most common of the extensive features available with PHP. To see the full list, please visit the PHP language guide at http://www.php.net/manual/en/langref.php.
Part 2. CMS structure
See Table 2 – CMS directory structure. Create the directories and files as per the instructions for the example code under Part 1 – PHP fundamentals.
Before we can start coding in earnest, we need to populate our MySQL database. Create the following files, and create the database, table and our first page stored in the database: see Listings 10-12.
Listing 10. createdb.sql
create database freebsdcms;
grant usage on *.* to bsduser@localhost identified by ‘cmsdbpassword’;
grant all privileges on freebsdcms.* to bsduser@localhost;
Listing 11. createpagetbl.sql
CREATE TABLE if not exists pages (
id INT NOT NULL AUTO_INCREMENT,
PRIMARY KEY(id),
title VARCHAR(50) NOT NULL,
h1 VARCHAR(50),
body TEXT
);
Listing 12. createpage.sql
USE freebsdcms;
INSERT INTO pages
VALUES (
”,
‘My first page’,
‘Page header’,
‘Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris
interdum auctor tellus sed dignissim. Phasellus non orci massa,
nec feugiat sem. Vestibulum molestie interdum
bibendum. Nunc quis elit nulla, sit amet rutrum lorem. Quisque
odio est, sagittis nec accumsan ut, placerat sit
amet lectus. Curabitur aliquam dignissim felis, a malesuada leo
fringilla at. Sed ornare aliquet lacus, quis
imperdiet augue mattis eu. Nulla porta odio ut erat consectetur at
molestie justo suscipit. Aenean convallis
pellentesque nisl, vitae posuere mauris facilisis vitae. Morbi in
tellus nisl, vel facilisis diam.’
);
Note that the Ipsum Lorem test should be on one line with no carriage returns or line feeds. Your editor may wrap this very long line.
Create the the database, table and page as follows in Listing 13.
Listing 13. xxxxxx
#dev mysql -u root password ‘cms-password’ < createdb.sql
#dev mysql -u root password ‘cms-password’ < createpagetbl.sql
#dev mysql -u root password ‘cms-password’ < createpage.sql
Part 3. The code
The following PHP files contain the code for out website. Create each file as per Table 2. See Listing 14.
Listing 14. xxxxxx
<!–?php
/*
* index.php
* Index page for FreeBSD CMS
*
*/
// Get required files
// Our global settings – Note need full path
require_once ‘includes/cms.inc’;
// Core functions
require_once INCLUDES.’core.inc’;
// HTML functions
require_once INCLUDES.’html.inc’;
// MySQL functions
require_once INCLUDES.’mysql.inc’;
// Turn full debug functionality on if enabled
if(DEBUG){
// Turn on full PHP error reporting
error_reporting(E_ALL);
}else{
// Hide all error messages
error_reporting(0);
}
// Build page – use first record in database
$page[‘id’] = 1;
buildpage($page);
<?php
/*
*
* cms.inc
* Contains default settings for our CMS
*
* NOTE: ¶ denotes a line wrapped – all code should be on one line
*
*/
// Set our timezone
date_default_timezone_set(‘Europe/London’);
// Copyright details
define(“LICENCE”, ‘licence.txt’);
define(“COPYRIGHT”, ‘Copyright © 2013 Rob Somerville ¶ me@merville.co.uk’);
define(“COPYYEAR”, date(‘Y’));
define(“COPYAUTH”, ‘Rob Somerville’);
define(“COPYEMAIL”, ‘me@merville.co.uk’);
// Version
define(“VERSION”, ‘Version 1.0 not for production use’);
// Mode – If DEBUG is set to true, show errors and debug info
define(“DEBUG”, TRUE);
// Where to find our files
define(“TEMPLATES”, ‘templates/’);
define(“INCLUDES”, ‘includes/’);
define(“SQL”, ‘sql/’);
// HTML tags that are orphaned and not defined in out template files
define(“BODY”, ”);
define(“HEAD”, ”);
// MySQL details
define(“DBSERVER”, ‘localhost’);
define(“DBUSER”, ‘bsduser’);
define(“DBPASSWORD”, ‘cmsdbpassword’);
define(“CMSDB”, ‘freebsdcms’);
<!–?php
/*
*
* core.inc
* Contains core functions for our CMS
*
*/
function buildpage($page) {
// Builds a standard page
$id = $page[‘id’];
// Build the SQL and get the result
$sql = “SELECT * FROM pages WHERE id=’$id’ LIMIT 1″;
$result = mysql_select($sql);
// Output our page header
outfile(TEMPLATES . ‘header.inc’);
// Create our body
$markup = ”;
$markup .= wraptag(‘title’, $result[4]);
$markup .= HEAD;
$markup .= BODY;
// If we are in debug mode, show an alert
if(DEBUG){
$debug = ‘¶ ‘;
}else{
$debug = ”;
}
// Add to markup
$markup .= wraptag(‘h1’,$debug . $result[3]);
$markup .= wraptag(‘p’,$result[5]);
$markup .= divclass(ahref(COPYRIGHT, LICENCE, ‘Copyright and ¶
licence details’),’licence’);
// Output all our markup
echo $markup;
// Output our HTML page footer
outfile(TEMPLATES . ‘footer.inc’);
}
function outfile($file) {
// Outputs template file to browser e.g header, footer, license etc.
$fh = fopen($file, ‘r’);
while (!feof($fh)) {
echo fgets($fh);
}
fclose($fh);
<?php
/*
*
* html.inc
* Contains core html functions for our CMS
*
*/
function wraptag($tag, $text) {
// Wraps $text with compliant tags
// wraptag(‘p’,sometext)
//

sometext

return ‘<‘ . $tag . ‘>’ . $text . ‘‘; } function divclass($divcontent, $class, $id = ”) { // Generates a div tag $text with compliant tags // divclass(‘content’,’class’) //

content

// divclass(‘content’,’class’,’id’) //

content

if ($id != ”) { $id = ‘id=”‘ . $id . ‘”‘; } return ‘

Click here // ahref(‘Click here’,freebsd.org,’Link title’) // Click here if ($title == ”) { $title = $text; } $ahref = ” . ¶ $text . ”; return $ahref; connect_errno > 0){ die(‘Unable to connect to database [‘ . $db->connect_error . ‘]’); } if(!$result = $db->query($sql)){ if(DEBUG){ die(‘There was an error running the query [‘ . $db->error . ‘]’); }else{ die(”); } } // Pass our results to an array to be returned $r = array(); $r[] = $result->num_rows; // No of rows returned $r[] = $db->affected_rows; // No of rows affected e.g. ¶ update /delete while($row = $result->fetch_assoc()){ $r[] = $row[‘id’]; $r[] = $row[‘h1’]; $r[] = $row[‘title’]; $r[] = $row[‘body’]; } // Free the result $result->free(); return $r; } global.css holds the style information for our site. Experiment with the font sizes, line spacing etc. to style the site to your liking. If you use Firefox, install the Firebug plugin to dynamically change the values, but if you want to make them pernanet you will need to edit this file. Also try renaming global.css and refreshing your browservs cache to see the effect of the styling on the site. See Listing 15. Listing 15. xxxxxx /* global.css – the site global stylesheet */ h1 { background-color: teal; float: left; color: white; padding: 21px; text-transform: uppercase; } p { float: left; } body { line-height: 160%; text-align: justify; float: left; } html { background: none repeat scroll 0 0 #F9F8F2; border: 1px solid; color: teal; font-family: Verdana; margin: 10px; padding: 20px; } .jstime, .licence { background: none repeat scroll 0 0 #EDEAC6; border: 1px solid #DADADA; color: slategrey; float: right; font-family: Verdana; font-size: x-small; margin-bottom: 5px; margin-right: 10px; margin-top: 10px; padding: 3px 10px; } The include files build our basic HTML header and footers, add the CSS and load the Javascript. See Listings 16-20. Listing 16. header.inc

Listing 17. footer.incListing 18. template.inc This can be empty, but needs to be created. The javascript files are split into 2. Preload.js provides the date and time on each page, postload.js is just an empty file which provides hooks we will use later on in the series. Listing 19. preload.js /* preload.js Provides Javascript support */ // Call the function displaydate() displaydate() function displaydate(){ // Displays the date and time in AM/PM format. var currentTime = new Date() var hours = currentTime.getHours() var minutes = currentTime.getMinutes() var month = currentTime.getMonth() + 1 var day = currentTime.getDate() var year = currentTime.getFullYear() if (minutes < 10){ minutes = “0” + minutes } var ampm = “”; if(hours > 11){ ampm = “PM” } else { ampm = “AM” } document.write(”

” + day + “/” + month + “/” + year + ” ” + hours + “:” + minutes + ampm + “

“) Listing 20. postload.js /* postload.js Just an empty file with comments */ Part 4. Out simple CMS Once you have entered the code as per table 2, point your browser at httP;//yourserveripaddress/index.php. You should see a page similar to Screenshot 3. Turn debug off and on in cms.inc, and the paragraph mark should disappear. If you copy the HTML source from the page (In you browser view source, select all, copy and paste into the W3C validator) the page should validate.So what is our code doing? The unformatted text is stored as plain text in our database table. Index.php forms the first page of our website, and loads our settings and functions from the include files. The first stage is to load our header from a plain text file, which is the HTML at the start of our page. The header file in turn loads the CSS and javascript, and returns control to index.php. We then query the database, wrap the text in the relevant HTML tags and output to our browser. We then close the HTML with our footer HTML. In the next part of our series we will develop the CMS further, passing parameters via our browser to load different pages, We will also start using our template file so that we can design our site the way we want it with separate blocks and regions.

Bio
Rob Somerville has been passionate about technology since his early teens. A keen advocate of open systems since the mid eighties, he has worked in many corporate sectors including finance, automotive, airlines, government and media in a variety of roles from technical support, system administrator, developer, systems integrator and IT manager. He has moved on from CP/M and nixie tubes but keeps a soldering iron handy just in case.

Join iX Newsletter

iXsystems values privacy for all visitors. Learn more about how we use cookies and how you can control them by reading our Privacy Policy.
π