PHP Basics for templater

Written by Max Milbers on .

I decided to write a chapter about the basics of php programming. This tutorial is for people who want to be able todo simpler layouting tasks. PHP has a quite normal coding syntax and can be read quite easily with some tips and hints. This tutorial focusses on coding format and technics of the VirtueMart code.

PHP is space insensitive like html. A ; ends a line. The = sets a value to a variable. The () indicate a function call, the content of functions is wrapped in {}.

Variables are declared with a $ sign, for example $myVariable. Variables are case sensitive! PHP automatically casts a variable to the right datatype if possible. What are datatypes?

int integer numbers for example -2, -1, 0, 1, 2
float float numbers for example 1234.56789 or -834753.23414
string strings, chars, words for example hello or Ipsum loru... or also numbers like 1234.56789 or -834753.23414
boolean Important a real boolean is only "false" or "true"

Strings are written with " or '. The datatypes as Example

$myVariable = 2;
The variable $myVariable is now an integer with value 2 (not 2.0!)
$myVariable = "2";
The variable is now a string! And can be converted to 2 or 2.0, but the string "2" has not an higher value as "a" or "i".
$myVariable = 2.34;
The variable $myVariable is now a float with value 2.34
$myVariable = true;
the variable is now a real boolean with the value true.

But php has a simple datatype handling compared to most other programming languages. Datatypes are often automatically converted, but failing explains sometimes unexpected results. Strings a concatenated (chained, combined) with a dot, number are summed with a plus. Here some examples how php works with mixed datatypes.

$a = "2"; $b = 4; echo $a.$b;

Results in "24"

echo $a+$b

Results in 6

There are also two special "datatypes". Arrays and objects. Arrays can just keep other variables. Usually you can access this values by a key. A new array is created with the function array. So $myArray = new array('here' => 'yes', 'there' => 'no') creates a new array. $myArray['here'] returns "yes" and $myArray['there'] returns "no". Arrays are very handy to store data. Arrays can be also multidimensional, for example array[key1][key2] = value.

An object is for the enduser almost the same, but it can handle functions too. Objects use the -> to access a property or function of the object. Objects are defined in classes. Some objects provide static functions which are access with ::

The next thing are operators. The arithmetic operators are quite common +, -, *, / and so on, here is a complete list

More important are the comparison operators. Here are some examples

== is equal by value
!= is not equal
< strictly less than
>= greater or equal

This operators are used to create expressions or in other words "questions". The ! is used to "invert" the question. The if construction is used very often to controll the program flow. The if is the function call and within the () is the parameter and the content of the function is in {}. The question or better said value is always converted to a boolean.

if(question){ //When the questions results not in false or 0, execute this code } else if (question2){ //When question 1 resulted in false or 0, but question 2 is true (not false or 0), then execute this code } else { //When no question was answerd with true, execute this code }

There can be as many elseif as you like. When the expression is very short, layouts use sometimes the ternary operator

$a = question? $b:$c 

When the question is answered with yes, set $a = $b, else set $a = $c.

So how does this look like in a real program code?

// Calculating Manufacturers Per Row
$manufacturerPerRow = VmConfig::get ('manufacturer_per_row', 3);
if ($manufacturerPerRow > 1) {
	$manufacturerCellWidth = ' width'.floor ( 100 / $manufacturerPerRow );
} else {
	$manufacturerCellWidth = '';

The first line is just a comment. The second line sets the value of $manufacturerPerRow to the returned value of the function get of the class VmConfig. The function get just returns the value of VmConfig::params['manufacturerPerRow'] and returns the second parameter, when the property is not set. The next line just checks if the $manufacturerPerRow is bigger than one. Lets assume the value in the class VmConfig is empty, then it takes as default the second parameter 3, so $manufacturerPerRow is set to 3. 
The variable $manufacturerCellWidth is set to a string, because the code executes the line directly after the if ( 3 is bigger than 1). The string starts with " width" and the result of floor ( 100 / $manufacturerPerRow) is concatenated. Floor is just a function which down rounds a normal number to an integer. So we get for the default value the string " width33". Assuming $manufacturerPerRow is set to 1, then the else case is executed and $manufacturerPerRow set to an empty string "".

Now we come to the first obstacle. An empty string "" is not the same as as string, wich is just not set. When we just create a variable without initialising it with a value, then we get a variable pointing to null. Beware! "null" is NOT null! null is also not NULL and not 0 and not an empty string "".

Lets assume we want to echo a value, if it has a "visible" value. This sounds very easy, but it can be very hard for a beginner. We start with a very simple if construction.

if ( $var!="" ){
  echo $var;

This can work, but it can create errors very likely. When the variable is not initialised, it throws an error. When the variable is the type boolean then it is never executed. When it is NULL it is not executed and so on. To avoid this, php has a very nice function called empty

if ( ! empty( $var) ) {
	echo $var;

The ! inverts the result. So the $var is echoed if $var is not empty. The command empty is true for 0, 0.0, "0", null, NULL, false, FALSE, array() (empty array). When you want to check if a variable is set, but can be also empty, then use isset. Lets take a look on real code example

if (!empty($this->vendor->images[0])) {
	echo $this->vendor->images[0]->displayMediaThumb('',false);

Here you can see the real magic of the command empty. It checks if the first image of the array images is available, but be aware that it does not check if $this->vendor exists. It would be safer to write

if (!empty($this->vendor) and !empty($this->vendor->images[0])) {
	echo $this->vendor->images[0]->displayMediaThumb('',false);

This way both must be not empty. When a condition returns false, the next conditions are not checked. So if $this-vendor is empty already, then "$this->vendor->images[0]" is not checked. 

The code sample above contains the special variable $this. When the code is executed within a dynamic object, then the object itself is accessed by $this. This is a lot used within the layouts, because prepared data is assigned as property to the view object and accessible within the layout by $this.

Lets take a look on our virtuemart views. The view productdetails usually shows only one product. Therefore the product object is prepared in the view object and provided as property "product". The product is just accessible by $this->product. Plain and simple. But some people are confused, because in the category view, they find the variable $product. Of course a category view shows a lot productS and therefore the products are provided by $this->products. The variable $this->products is a multi dimensional array, which holds different groups of products, the keys are products, topten, featured, latest,...

So how we come to our $product? The answer are loops. Loops are used very often to process the data in arrays. Almost any loop in the vm layouts are foreach loops. The syntax is very easy. It takes an array, does for each data in the array something, which is defined in the {} after. Lets take a look on the products.php in sublayouts

foreach ($viewData['products'] as $type => $products ) {
	//Prepare the rows
	foreach ( $products as $product ) {
		//here is our product
		vmdebug("lets take a look on our product",$product);

Sublayouts are an own chapter. It is just important to understand that the data is delivered by $viewData, not by $this. This sublayout renders the different product types in the category browse view. The function vmdebug('Write your note here',$var1,[$var2], ...) just prints the first parameter as note and any variable added as parameter (seperated by comma).