Thursday, May 28, 2009

Defining a Function

Defining a Function

To define a function, use the following syntax:

function [&] function_name ( [ parameter [, ... ] ] )
{
statement list
}
The statement list can include HTML. You can declare a PHP function that doesn't contain any PHP code. For instance, the column( ) function simply gives a convenient short name to HTML code that may be needed many times throughout the page:




The function name can be any string that starts with a letter or underscore followed by zero or more letters, underscores, and digits. Function names are case-insensitive; that is, you can call the sin( ) function as sin(1), SIN(1), SiN(1), and so on, because all these names refer to the same function.

Typically, functions return some value. To return a value from a function, use the return statement: put return expr inside your function. When a return statement is encountered during execution, control reverts to the calling statement, and the evaluated results of expr will be returned as the value of the function. Although it can make for messy code, you can actually include multiple return statements in a function if it makes sense (for example, if you have a switch statement to determine which of several values to return).

If you define your function with the optional ampersand before the name, the function returns a reference to the returned data rather than a copy of the data.

Let's take a look at a simple function. Example 3-1 takes two strings, concatenates them, and then returns the result (in this case, we've created a slightly slower equivalent to the concatenation operator, but bear with us for the sake of example).

Example 3-1. String concatenation
function strcat($left, $right) {
$combined_string = $left . $right;
return $combined_string;
}
The function takes two arguments, $left and $right. Using the concatenation operator, the function creates a combined string in the variable $combined_string. Finally, in order to cause the function to have a value when it's evaluated with our arguments, we return the value $combined_string.

Because the return statement can accept any expression, even complex ones, we can simplify the program as shown in Example 3-2.

Example 3-2. String concatenation redux
function strcat($left, $right) {
return $left . $right;
}
If we put this function on a PHP page, we can call it from anywhere within the page. Take a look at Example 3-3.

Example 3-3. Using our concatenation function
php
function strcat($left, $right) {
return $left . $right;
}

$first = "This is a ";
$second = " complete sentence!";

echo strcat($first, $second);
?>
When this page is displayed, the full sentence is shown.

This function takes in an integer, doubles it, and returns the result:

function doubler($value) {
return $value << 1;
}
Once the function is defined, you can use it anywhere on the page. For example:


You can nest function declarations, but with limited effect. Nested declarations do not limit the visibility of the inner-defined function, which may be called from anywhere in your program. The inner function does not automatically get the outer function's arguments. And, finally, the inner function cannot be called until the outer function has been called.

function outer ($a) {
function inner ($b) {
echo "there $b";
}
echo "$a, hello ";
}
outer("well");
inner("reader");
well, hello there reader

More >>>>>> Defining a Function

Variable Scope

Variable Scope

Up to this point, if you don't use functions, any variable you create can be used anywhere in a page. With functions, this is no longer always true. Functions keep their own sets of variables that are distinct from those of the page and of other functions.

The variables defined in a function, including its parameters, are not accessible outside the function, and, by default, variables defined outside a function are not accessible inside the function. The following example illustrates this:

$a = 3;

function foo( ) {
$a += 2;
}

foo( );
echo $a;
The variable $a inside the function foo( ) is a different variable than the variable $a outside the variable; even though foo( ) uses the add-and-assign operator, the value of the outer $a remains 3 throughout the life of the page. Inside the function, $a has the value 2.

As we discussed in Chapter 2, the extent to which a variable can be seen in a program is called the scope of the variable. Variables created within a function are inside the scope of the function (i.e., have function-level scope). Variables created outside of functions and objects have global scope and exist anywhere outside of those functions and objects. A few variables provided by PHP have both function-level and global scope.

At first glance, even an experienced programmer may think that in the previous example $a will be 5 by the time the echo statement is reached, so keep that in mind when choosing names for your variables.

Global Variables
If you want a variable in the global scope to be accessible from within a function, you can use the global keyword. Its syntax is:

global var1, var2, ...
Changing the previous example to include a global keyword, we get:

$a = 3;

function foo( ) {
global $a;
$a += 2;
}

foo( );
echo $a;
Instead of creating a new variable called $a with function-level scope, PHP uses the global $a within the function. Now, when the value of $a is displayed, it will be 5.

You must include the global keyword in a function before any uses of the global variable or variables you want to access. Because they are declared before the body of the function, function parameters can never be global variables.

Using global is equivalent to creating a reference to the variable in the $GLOBALS variable. That is, the following declarations:

global $var;
$var = &$GLOBALS['var'];
both create a variable in the function's scope that is a reference to the same value as the variable $var in the global scope.

Static Variables
Like C, PHP supports declaring function variables static. A static variable is shared between all calls to the function and is initialized during a script's execution only the first time the function is called. To declare a function variable static, use the static keyword at the variable's first use. Typically, the first use of a static variable is to assign an initial value:

static var [= value][, ... ];
In Example 3-4, the variable $count is incremented by one each time the function is called.

Example 3-4. Static variable counter
function counter( ) {
static $count = 0;
return $count++;
}

for ($i = 1; $i <= 5; $i++) {
print counter( );
}
When the function is called for the first time, the static variable $count is assigned a value of 0. The value is returned and $count is incremented. When the function ends, $count is not destroyed like a non-static variable, and its value remains the same until the next time counter( ) is called. The for loop displays the numbers from 0 to 4.

More >>>>>> Variable Scope

Function Parameters

Function Parameters

Functions can expect, by declaring them in the function definition, an arbitrary number of arguments.

There are two different ways of passing parameters to a function. The first, and more common, is by value. The other is by reference.

Passing Parameters by Value
In most cases, you pass parameters by value. The argument is any valid expression. That expression is evaluated, and the resulting value is assigned to the appropriate variable in the function. In all of the examples so far, we've been passing arguments by value.

Passing Parameters by Reference
Passing by reference allows you to override the normal scoping rules and give a function direct access to a variable. To be passed by reference, the argument must be a variable; you indicate that a particular argument of a function will be passed by reference by preceding the variable name in the parameter list with an ampersand (&). Example 3-5 revisits our doubler( ) function with a slight change.

Doubler redux
function doubler(&$value) {
$value = $value << 1;
}

$a = 3;
doubler($a);
echo $a;
Because the function's $value parameter is passed by reference, the actual value of $a, rather than a copy of that value, is modified by the function. Before, we had to return the doubled value, but now we change the caller's variable to be the doubled value.

Here's another place where a function contains side effects: since we passed the variable $a into doubler( ) by reference, the value of $a is at the mercy of the function. In this case, doubler( ) assigns a new value to it.

A parameter that is declared as being passed by reference can only be a variable. Thus, if we included the statement in the previous example, it would issue an error.

Even in cases where your function does affect the given value, you may want a parameter to be passed by reference. When passing by value, PHP must copy the value. Particularly for large strings and objects, this can be an expensive operation. Passing by reference removes the need to copy the value.

Default Parameters
Sometimes, a function may need to accept a particular parameter in some cases. For example, when you call a function to get the preferences for a site, the function may take in a parameter with the name of the preference to retrieve. If you want to retrieve all the preferences, rather than using some special keyword, you can just not supply an argument. This behavior works by using default arguments.

To specify a default parameter, assign the parameter value in the function declaration. The value assigned to a parameter as a default value cannot be a complex expression; it can only be a constant.

function get_preferences($which_preference = "all" ) {
// if $which_preference is "all", return all prefs;
// otherwise, get the specific preference requested...
}
When you call get_preferences( ), you can choose to supply an argument. If you do, it returns the preference matching the string you give it; if not, it returns all preferences.

A function may have any number of parameters with default values. However, they must be listed after all the parameters that do not have default values.

Variable Parameters
A function may require a variable number of arguments. For example, the get_preferences( ) example in the previous section might return the preferences for any number of names, rather than for just one. To declare a function with a variable number of arguments, leave out the parameter block entirely.

function get_preferences( ) {
// some code
}
PHP provides three functions you can use in the function to retrieve the parameters passed to it. func_get_args( ) returns an array of all parameters provided to the function, func_num_args( ) returns the number of parameters provided to the function, and func_get_arg( ) returns a specific argument from the parameters.

$array = func_get_args( );
$count = func_num_args( );
$value = func_get_arg(argument_number);
In Example 3-6, the count_list( ) function takes in any number of arguments. It loops over those arguments and returns the total of all the values. If no parameters are given, it returns false.

Argument counter
function count_list( ) {
if(func_num_args( ) == 0) {
return false;
}
else {
for($i = 0; $i < func_num_args( ); $i++) {
$count += func_get_arg($i);
}
return $count;
}
}

echo count_list(1, 5, 9);
The result of any of these functions cannot directly be used as a parameter to another function. To use the result of one of these functions as a parameter, you must first set a variable to the result of the function, then use that in the function call. The following expression will not work:

foo(func_num_args( ));
Instead, use:

$count = func_num_args( );
foo($count);
3.4.5 Missing Parameters
PHP lets you be as lazy as you want—when you call a function, you can pass any number of arguments to the function. Any parameters the function expects that are not passed to it remain unset, and a warning is issued for each of them:

function takes_two( $a, $b ) {
if (isset($a)) { echo " a is set\n"; }
if (isset($b)) { echo " b is set\n"; }
}
echo "With two arguments:\n";
takes_two(1, 2);
echo "With one argument:\n";
takes_two(1);
With two arguments:
a is set
b is set
With one argument:
Warning: Missing argument 2 for takes_two( )
in /path/to/script.php on line 6
a is set

More >>>>>> Function Parameters

Return Values

Return Values

PHP functions can return only a single value with the return keyword:

function return_one() {
return 42;
}
To return multiple values, return an array:

function return_two ( ) {
return array("Fred", 35);
}
By default, values are copied out of the function. A function declared with an & before its name returns a reference (alias) to its return value:

$names = array("Fred", "Barney", "Wilma", "Betty");
function & find_one($n) {
return $names[$n];
}
$person =& find_one(1); // Barney
$person = "Barnetta"; // changes $names[1]
In this code, the find_one( ) function returns an alias for $names[1], instead of a copy of its value. Because we assign by reference, $person is an alias for $names[1], and the second assignment changes the value in $names[1].

This technique is sometimes used to return large string or array values efficiently from a function. However, PHP's copy-on-write/shallow-copy mechanism usually means that returning a reference from a function is not necessary. There is no point in returning a reference to some large piece of data unless you know you are likely to change that data. The drawback of returning the reference is that it is slower than returning the value and relying on the shallow-copy mechanism to ensure that a copy of that data is not made unless it is changed.

Who's Online

Now 1 guest online
More >>> Return Values

Variable Functions

Variable Functions

As with variable variables, you can call a function based on the value of a variable. For example, consider this situation, where a variable is used to determine which of three functions to call:

switch($which) {
case 'first':
first( );
break;

case 'second':
second( );
break;

case 'third':
third( );
break;
}
In this case, we could use a variable function call to call the appropriate function. To make a variable function call, include the parameters for a function in parentheses after the variable. To rewrite the previous example:

$which(); // if $which is "first" the function first( ) is called, etc...
If no function exists for the variable, a runtime error occurs when the code is evaluated. To prevent this, you can use the built-in function function_exists( ) to determine whether a function exists for the value of the variable before calling the function:

$yes_or_no = function_exists(function_name);
For example:

if(function_exists($which)) {
$which(); // if $which is "first" the function first( ) is called, etc...
}
Language constructs such as echo( ) and isset( ) cannot be called through variable functions:

$f = 'echo';
$f('hello, world'); // does not work

more >>>>>>> Variable Functions

Monday, May 25, 2009

Embedding PHP in Web Pages

Embedding PHP in Web Pages

Although it is possible to write and run standalone PHP programs, most PHP code is embedded in HTML or XML files. This is, after all, why it was created in the first place. Processing such documents involves replacing each chunk of PHP source code with the output it produces when executed.

Because a single file contains PHP and non-PHP source code, we need a way to identify the regions of PHP code to be executed. PHP provides four different ways to do this.

As you'll see, the first, and preferred, method looks like XML. The second method looks like SGML. The third method is based on ASP tags. The fourth method uses the standard HTML tag; this makes it easy to edit pages with enabled PHP using a regular HTML editor.

XML Style
Because of the advent of the eXtensible Markup Language (XML) and the migration of HTML to an XML language (XHTML), the currently preferred technique for embedding PHP uses XML-compliant tags to denote PHP instructions.

Coming up with tags to demark PHP commands in XML was easy, because XML allows the definition of new tags. To use this style, surround your PHP code with . Everything between these markers is interpreted as PHP, and everything outside the markers is not. Although it is not necessary to include spaces between the markers and the enclosed text, doing so improves readability. For example, to get PHP to print "Hello, world", you can insert the following line in a web page:


The trailing semicolon on the statement is optional, because the end of the block also forces the end of the expression. Embedded in a complete HTML file, this looks like:




This is my first PHP program!



Look, ma! It's my first PHP program:



How cool is that?




Of course, this isn't very exciting—we could have done it without PHP. The real value of PHP comes when we put dynamic information from sources such as databases and form values into the web page. That's for a later chapter, though. Let's get back to our "Hello, world" example. When a user visits this page and views its source, it looks like this:




This is my first PHP program!



Look, ma! It's my first PHP program:

Hello, world!

How cool is that?




Notice that there's no trace of the PHP source code from the original file. The user sees only its output.

Also notice that we switched between PHP and non-PHP, all in the space of a single line. PHP instructions can be put anywhere in a file, even within valid HTML tags. For example:

" />
When PHP is done with this text, it will read:


The PHP code within the opening and closing markers does not have to be on the same line. If the closing marker of a PHP instruction is the last thing on a line, the line break following the closing tag is removed as well. Thus, we can replace the PHP instructions in the "Hello, world" example with:




with no change in the resulting HTML.

SGML Style
The "classic" style of embedding PHP comes from SGML instruction processing tags. To use this method, simply enclose the PHP in . Here's the "Hello world" example again:


This style, known as short tags, is the shortest and least intrusive, and it can be turned off so as to not clash with the XML PI (Process Instruction) tag in the php.ini initialization file. Consequently, if you want to write fully portable PHP code that you are going to distribute to other people (who might have short tags turned off ), you should use the longer style, which cannot be turned off. If you have no intention of distributing your code, you don't have an issue with telling people who want to use your code to turn on short tags, and you are not planning on mixing XML in with your PHP code, then using this tag style is okay.

ASP Style
Because neither the SGML nor XML tag style is strictly legal HTML,[3] some HTML editors do not parse it correctly for color syntax highlighting, context-sensitive help, and other such niceties. Some will even go so far as to helpfully remove the "offending" code for you.

[3] Mostly because you are not allowed to use a > inside your tags if you wish to be compliant, but who wants to write code like if( $a > 5 )...?

However, many of these same HTML editors recognize another mechanism (no more legal than PHP's) for embedding code—that of Microsoft's Active Server Pages (ASP). Like PHP, ASP is a method for embedding server-side scripts within documents.

If you want to use ASP-aware tools to edit files that contain embedded PHP, you can use ASP-style tags to identify PHP regions. The ASP-style tag is the same as the SGML-style tag, but with % instead of ?:

<% echo "Hello, world"; %>
In all other ways, the ASP-style tag works the same as the SGML-style tag.

ASP-style tags are not enabled by default. To use these tags, either build PHP with the --enable-asp-tags option or enable asp_tags in the PHP configuration file.

Script Style
The final method of distinguishing PHP from HTML involves a tag invented to allow client-side scripting within HTML pages, the tag. You might recognize it as the tag in which JavaScript is embedded. Since PHP is processed and removed from the file before it reaches the browser, you can use the tag to surround PHP code. To use this method, simply specify "php" as the value of the language attribute of the tag:


This method is most useful with HTML editors that work only on strictly legal HTML files and don't yet support XML processing commands.

Echoing Content Directly
Perhaps the single most common operation within a PHP application is displaying data to the user. In the context of a web application, this means inserting into the HTML document information that will become HTML when viewed by the user.

To simplify this operation, PHP provides special versions of the SGML and ASP tags that automatically take the value inside the tag and insert it into the HTML page. To use this feature, add an equals sign (=) to the opening tag. With this technique, we can rewrite our form example as:

">
If you have ASP-style tags enabled, you can do the same with your ASP tags:

This number (<%= 2 + 2 %>)

and this number (<% echo (2 + 2); %>)

Are the same.


After processing, the resulting HTML is:

This number (4)

and this number (4)

are the same.

Programming PHP

Including Code


PHP provides two constructs to load code and HTML from another module: require and include. They both load a file as the PHP script runs, work in conditionals and loops, and complain if the file being loaded can't be found. The main difference is that attempting to require a nonexistent file is a fatal error, while attempting to include such a file produces a warning but does not stop script execution.

A common use of include is to separate page-specific content from general site design. Common elements such as headers and footers go in separate HTML files, and each page then looks like:


content

We use include because it allows PHP to continue to process the page even if there's an error in the site design file(s). The require construct is less forgiving and is more suited to loading code libraries, where the page can't be displayed if the libraries don't load. For example:

require 'codelib.inc';
mysub( ); // defined in codelib.inc
A marginally more efficient way to handle headers and footers is to load a single file and then call functions to generate the standardized site elements:

header( );
?>
content

If PHP cannot parse some part of a file included by include or require, a warning is printed and execution continues. You can silence the warning by prepending the call with the silence operator; for example, @include.

If the allow_url_fopen option is enabled through PHP's configuration file, php.ini, you can include files from a remote site by providing a URL instead of a simple local path:

include 'http://www.example.com/codelib.inc';
If the filename begins with "http://" or "ftp://", the file is retrieved from a remote site and then loaded.

Files included with include and require can be arbitrarily named. Common extensions are .php, .inc, and .html. Note that remotelyfetching a file that ends in .php from a web server that has PHP enabled fetches the output of that PHP script. For this reason, we recommend you use .inc for library files that primarily contain code and .html for library files that primarily contain HTML.

If a program uses include or require to include the same file twice, the file is loaded and the code is run or the HTML is printed twice. This can result in errors about the redefinition of functions or multiple copies of headers or HTML being sent. To prevent these errors from occurring, use the include_once and require_once constructs. They behave the same as include and require the first time a file is loaded, but quietly ignore subsequent attempts to load the same file. For example, many page elements, each stored in separate files, need to know the current user's preferences. The element libraries should load the user preferences library with require_once. The page designer can then include a page element without worrying about whether the user preference code has already been loaded.

Code in an included file is imported at the scope that is in effect where the include statement is found, so the included code can see and alter your code's variables. This can be useful—for instance, a user-tracking library might store the current user's name in the global $user variable:

// main page
include 'userprefs.inc';
echo "Hello, $user.";
The ability of libraries to see and change your variables can also be a problem. You have to know every global variable used by a library to ensure that you don't accidentally try to use one of them for your own purposes, thereby overwriting the library's value and disrupting how it works.

If the include or require construct is in a function, the variables in the included file become function-scope variables for that function.

Because include and require are keywords, not real statements, you must always enclose them in curly braces in conditional and loop statements:

for ($i=0; $i < 10; $i++) {
include "repeated_element.html";
}
Use the get_included_files( ) function to learn which files your script has included or required. It returns an array containing the full system path filenames of each included or required file. Files that did not parse are not included in this array.

Programming PHP