Projects Are About Humans. Deal With That!

Archive for October, 2007

Future of PHP

The fact that PHP is an open source programming language makes a great case against its competitors. It has a cheap, fast, reliable and widely supported environment to run in, therefore it is mainly used in standard web deployment, not only large enterprises. PHP became the most popular language on the Internet in 2002, and that with next to $0 marketing costs. None of PHP's main competitors - ASP, Perl and JavaScript – have such a great community to support them. On the other hand, commercial languages such as ColdFusion offer a lot more components, tools and support, but that comes with a lot of money also.

Why should you choose PHP? If you're a beginner, PHP is excellent for you. It is really easy to understand, and you can figure out most things on your own. PHP documentation isn't the most detailed one, but it can give you some information on what you're trying to find out. If you still cannot find what you're looking for, a search on the Internet will be worthwhile. There are a lot of tutorials and code examples, and most certainly you will find out more than you expected. Other languages, on the other hand, have a detailed documentation – even though it is sometimes too detailed and you can't understand anything from it - so you probably won't have to do any additional research on the Internet.

If you're an intermediate or advanced programmer, you may like PHP because there are a lot of things you can do with it. Flexibility and portability are two essential attributes of PHP. You can run it or almost every operating system in the world, and you can modify it as you wish. Besides, at the end of the day, you will not have spent any money into doing so. Other languages rely on the fact that having a lot of components and tools cover for their lack of versatility towards new ones.

When it comes to support, PHP is known for its excellent global community, which helps out people looking for answers. Alternatively, commercial languages provide support from well-trained personal who will answer you quickly, but then again the costs are much higher.

You will find both praises and critics to PHP. The best way to go is to try it for yourself. Just start fresh without taking into consideration other people's comments, and figure it out on your own.

7 comments

Debugging PHP Scripts

Probably the most frustrating part of the development process is debugging. Even the most experienced programmers take their time to debug and improve their applications; if you're a beginner, this should be an essential step in your learning. Remember that a computer application doesn't do what you want it to do, it does what you tell it to do.

PHP's error messages always give you more or less information on what's wrong with your script. But first thing you need to do is check your configuration file. You can do this using the "phpinfo()" function, which outputs a lot of information in friendly-reading style, including the configuration in "php.ini". Give it a try:

<?php phpinfo() ?>

A very important setting in PHP's configuration is "display_errors". If you disable this setting, you will not see any errors from PHP, so if your script isn't working from various reasons you will just see what has been outputted so far, and that's it. Enabling this setting will make PHP output error messages, according to another setting called "error_reporting". You can choose to have displayed fatal errors, warnings (non-fatal errors), notices (potential problems), user errors, etc. These settings only report the problem to the browser, they have absolutely no effect on the action taken when an error is found. You can also do this from a script, using a function called "error_reporting()":

error_reporting(E_ERROR); //displays only the errors, no warnings or notices

While this type of debugging is suitable for development purposes, you will have to handle bugs or errors in public web-sites. Simple actions like renaming a file or directory can cause major problems if you don't take into consideration all of the web-site's structure. For these unfortunate cases, PHP provides a built-in function which is used to log errors to the server's error log file or another file of your choosing: "error_log()". This function requires as arguments the error message itself and an integer representing the message type, saying where the message should go (the system logger, email, remote connection or a file). If you want to write an error message to an error log, a destination must be set for the "error_log" option in "php.ini".

Sometimes you can define the error string yourself, but what about when an error is caught by PHP? To read the error message, you must first set the "track_errors" in your PHP configuration file to "On", then you can access the most recent error in the variable "$php_errormsg":

fopen( "important_file.txt", "a" ) or

error_log(__FILE__ . " line " . __LINE__ . ": $php_errormsg", 0);

There isn't really a technique for minimizing errors and bugs, all you can do is stay vigilant and try not to do multiple things at the same time. Don't write functions that do a lot of things at the same time, and try to separate the pieces in your code, so you will be able to better isolate and repair an error. Also, try to test your application as often as possible. Write one or two functions, and then see if they work properly. It's one thing to track an error from within a dozen functions, and another thing to find an error in the last function you wrote. Always be prepared for the worst, and try to consider all the possible aspects, not just the ones of the intended action. For example, if you need to write something to a file, always test if the file exists, and weather you have the appropriate permissions to write to the file.

No comments

PHP Database Manipulation

One of the defining features of PHP is the ease with which you can connect to and manipulate databases. PHP implements functions for connecting to a wide range of databases systems: MySQL, Oracle, MSSQL, Interbase, dBase, and many more. While there are many commercial database systems which cost thousands of dollars and provide thousands of components, the Internet community provides solutions for low-budget users as well. MySQL, for example, doesn't require you to purchase a license if you don't use it for commercial activities.

Most of the manipulating of any database is done while using SQL, which stands for Structured Query Language. This provides standard syntaxes by which different types of database can be queried. While there are a lot of extensions to SQL implemented by database systems, and some queries could work on a system but fail on another one, all of them incorporate some standard manipulating statements.

The way PHP talks to the database is simple. First you need to connect to the database system, which runs as a daemon (service for Windows) in the background. In order to do this, you must have appropriate permissions to connect to the database server from its owner. While you can always install and configure a database system on your own computer for starters, when it comes to hosting a web-site you must talk to a hosting company. They will open an account for you, and give you the information on how to connect to the database server.

Many hosting companies use MySQL, so we'll focus on using this database system. First, you must use the "mysql_connect()" function along with the server's IP, the username and the password required to connect to the server. After you connect, you can start running SQL statements as you like. Don't forget that to close the connection using "mysql_close()". You either must do this everytime you want to manipulate the database, or you use a persistent connection. This kind of connection is implemented when using the Apache web-server, and tells Apache not to terminate the connection after your script stops executing even if you call "mysql_close()". Instead, the connection is left active, waiting for another process to call mysql_pconnect(). So, using this function, you will skip the time required for your computer to connect to the database server.

if(!mysql_connect("localhost", "bob", "secret")) //tries to connect to the database server

die("Unable to connect to the database server!"); //terminates the script, and outputs the error

Depending on the hosting services, you can have access to one or more databases. But before you start changing data, you must also connect to the database of your choice. Selecting a database to work with is also accomplished using a simple function:

mysql_select_db("test_db") or die("Error when selecting the database!");

While we can treat the errors using the "die()" function, and stop the script if something bad happens, sometimes we might want to output more detailed information on the error. Whenever an operation fails, MySQL sets an error number and an error string, so we just have to read it:

if(!mysql_connect($db_ip, $db_user, $db_pass))

die("MySQL Error: " . mysql_error()); //stops the script if unable to connect to the database, and outputs the MySQL error message

All of the database manipulation is done thru SQL statements (also known as queries), which range from basic statements used to insert, modify or delete data in a table to complex statements used to retrieve some particular data using specified filters. You can find a lot of documentation on SQL on the Internet. Here are some of the most important statements:

//creates a table using the specified fields

CREATE TABLE users

(id INT NOT NULL AUTO_INCREMENT,

PRIMARY KEY(id),

username VARCHAR(20),

password VARCHAR(12),

email VARCHAR(20)

)

//adds a new record into the database

INSERT INTO my_table(id, username, password, email) VALUES (NULL, "bob", "secret", "bob@softwareprojects.org")

//modifies the password of the user "bob"

UPDATE my_table SET password = "very secret" WHERE username = "bobo"

//retrieves the email address of the user "bob"

SELECT email FROM users WHERE username = "bob"

To execute these queries, you must call the "mysql_query()" function. The result of this function is a resource that will be used with other functions, in order to access the information returned by the query.

$sql_result = mysql_query("SELECT password FROM users WHERE username='Bob'")

or die("Error or running query: " .$mysql_error())

$row = mysql_fetch_array($sql_result, MYSQL_NUM);

While it may seem that "mysql_fetch_array()" retrieves all the results from the query, you should know that it only returns one row at a time. After a call to this function, the internal index of $sql_result will be incremented by one, so the next time the next row will be retrieved, if there is any.

There are a lot of other built-in functions for MySQL, for a detailed explication of each one you should consult the PHP documentation.

No comments

PHP Sessions

Besides cookies, there is another way to pass information to different web-pages: sessions. A session-enabled page allocates unique identifiers to users the first time they access the page, and then reassociates them with the previously allocated ones when they return to the page. Any global variables that were associated with the session will then become available to your code. The difference between sessions and cookies is that a session can hold multiple variables, and you don't have to set cookies for every variable. By default, the session data is stored in a cookie with an expiry date of zero, which means that the session only remains active as long as the browser. When you close the browser, all the stored information is lost. You can modify this behavior by changing the "session.cookie_lifetime" setting in "php.ini" from zero to whatever you want the cookie lifetime to be.

PHP uses several functions to deal with sessions. Before you start the actual work with sessions, you must explicitly start a session with "session_start()". If you want sessions to start automatically, you must enable the "session.auto_start" setting in PHP's configuration file. This way a session will be initiated for every PHP document. After you have started a session, you have access to the session ID via the "session_id()" function. After you're done with the session, you can destroy it using "session_destroy()". The following script always assigns a new session ID:

session_start(); //starts or resumes a function

print "Your session ID is: " . session_id(); //displays the session ID

session_destroy(); //ends the session; comment this line and the browser will output the same session ID as before

While accessing the unique identifier is a good start, the main objective of a session is to hold the values of variables. You must register variables to a session using the "session_register()" function before you try to read them on a session-enabled page. Also, you should remember that when you register a variable to a session, and then change the variable's value, the altered value will be reflected in the session file. Finally, remember that "session_register()" requires you to pass as an argument the variable name, not the variable itself:

session_start();

if(isset($stored_var))

{

print $stored_var; //this will not be displayed the first time you load the page, because you haven't registered the variable yet!

}

else

{

$stored_var = "Hello from a stored variable!";

session_register("stored_var"); //don't do this: session_register($session_var)

}

As you can seen, you can test if a variable is assigned using the "isset()" function. While this works with all of the script's variables, to only check variables registered with a session you should use "session_is_registered()" function. You must again pass as an argument a string containing the variable name, and the function will return TRUE if the variable has been registered within the session.

session_start();

if(session_is_registered("stored_var"))

{

print $stored_var;

}

else

{

$stored_var = "Hello from a stored
variable!";

session_register("stored_var"); //don't do this: session_register($session_var)

}

As you've read before, "session_destroy()" is used to clean up the session variables, and end the session. However, "session_destroy()" does not destroy the session's variables, and they will remain accessible to the rest of the script in which "session_destroy()" is called.

session_start();

session_register("test");

$test = 12;

session_destroy();

print $test; // outputs 12

If you want to remove the registered variables, you need to use the session_unset() function. This destroys all variables associated with a session, both in the session file and within the script.

session_start();

session_register("test");

$test = 12;

session_unset(); //$test is destroyed

session_destroy();

print $test; //outputs nothing

No comments

PHP Cookies

During a complex project, there are times when you want to send data from one web-page to another. For example, in an e-commerce web-site, it is essential that you store the contents of a shopping cart while the user is browsing your site. In order to do this, there are two easy ways: you either use cookies or sessions.

Cookies are small amounts of data stored by the user's browser after a request from a server or script. While they are excellent from passing information from page to page, or even from visit to visit, cookies do have some limitations. For example, the maximum number of cookies from a host that can be stored by a browser is 20, and the maximum cookie size is 4KB. The main thing about cookies is that only the originating host can read the stored data, so the user's privacy is respected. Not only that, but the user can choose to be notified by the browser when accepting a cookie, and can even refuse some, or all of them. This is why you shouldn't rely on cookies to be an essential part of your web-site without first warning the user that you are using cookies.

Cookies consist of a name, value, expiry date, host and path information, and they end up to the user because they are send from the server thru an HTTP header. There are 3 ways a PHP script can access the cookie: using the environmental variable "$HTTP-COOKIE" - which holds all cookie names and values -, in a global variable "$cookie_name" (replace with the name, of course), or in the global array variable "HTTP_COOKIE_VARS["cookie_name"]" (again, replace "cookie_name" with the actual name of the cookie). Let's say we have a cookie called "visits" which holds the value 23, this is how you can output it to the web-browser:

print $HTTP_COOKIE; //outputs "visits=23"

print getenv("HTTP_COOKIER"); //outputs "visits=23"

print $visits; //outputs "23"

print $HTTP_COOKIE_VARS[visits]; //outputs "23"

To set a cookie with PHP, you can use the "header()" function, or the "setcookie()" function. While "header()" has a larger scope, and its main purpose is not to set a cookie, it will work just like "setcookie()". Using "header()", you write the cookie header yourself, while "setcookie()" is much more automated. If you don't know this already, always remember that the HTTP headers are automatically sent to the browser, so you must set a cookie before any output is sent to the browser:

//don't output anything before this…

header("visits=23; expires=Friday, 20-Aug-04 03:27:21 GMT; path=/; domain=softwareprojects.org");

setcookie("hits", 23, time() + 3600, "/","softwareprojects.org", 0); //notice this last extra argument

Both statements are used to send a cookie to the user's web-browser, and if you're wondering what's with that last argument we passed to "setcookie()", that tells the web-browser weather the cookies will be send only over a secure connection (0 means no, 1 means yes).

You may think that the "$visits" variable will be created after we send the header, and the first time we run PHP we will be able to read it. That is not true. The web-server reads the information only when the browser sends it the cookie, and this will not happen until the user revisits the web-page.

Setting an expiry date of zero will make the browser use the cookie until the user closes it; the browser will not remember the cookie the next time it's started. This can be useful for scripts that validate a user using cookies, and allow continued access to personal information on multiple pages after a password or other sensitive information has been submitted. It's not ok for the browser to have continued access to these pages after it has been restarted, because you cannot be sure if it's you who is using the browser, or some other user. So it would be better to allow the user to choose weather he wants to have more privacy, or he is the only user of that computer and nobody else accesses it.

Deleting cookies is also very easy, you should set the cookie you want to delete a date that has already expired. Remember to include the same path, domain and secure parameters you originally used when setting the cookie:

setcookie("visits", 23, time() - 60, "/", "softwareprojects.org", 0)

No comments

File Handling PHP

PHP includes a lot of built-in functions for handling files and directories. You can read, write, delete, and get lots of information on files thru the use of these functions. Note that before you start working with files, you have to make sure that you have the right permissions that will allow you to manipulate them. So while you're trying to figure out why you can't delete a file, it may be because the server doesn't allow you to do that.

The creation and removal of files are completed with two functions: "touch()" and "unlink()". "touch()" searches if a file exists, and if it doesn't, it creates one, according to the specified filename; "unlink()" is used to remove the file passed on as an argument:

touch("newinfo.txt"); //create a new file, if it doesn't already exist

unlink("oldinfo.txt"); //delete a file

Now that you know how to create a file, you should learn how to access it. This is done using the "fopen()" function, with requires a string containing the file path and a string containing the mode in which the file is about to be opened, which tells "fopen()" to open a file for reading, writing, or both. The complete list of the available modes can be found in the PHP documentation. "fopen()" return an integer, also known as a file pointer, which should be assigned to a variable. This will be used later on to work with the opened file. If a file cannot be open for whatever reason, "fopen()" returns FALSE. After you're done with the file, you should remember to close it with "fclose()", passing as an argument the file pointer.

$oldfp = fopen("oldinfo.txt", "r"); //opens a file for reading

if(!$fp = fopen("newinfo.txt", "w")) //tries to open a file for writing

die("Error on opening file!"); //terminates the execution of the script if it cannot open the file

fclose($oldfp);

Reading from files is done with "fgets()", which reads data from a file until it reaches a new line "\n", an EOF (end-of-file), or a specified length, in this order. So if you specify 4096 bytes but "fgets()" first reaches a new line, it stops further reading. You should know that after each reading or writing to a file, PHP automatically increments an index which holds the current position in the file. So if you have just opened a file, and then read 100 bytes, the next time you will want to read something else using the same file pointer, PHP will continue from where the 101st byte. The "fgetc()" is similar to "fgets()", except that it returns only a single character from a file every time it is called. Because a character is always 1 byte in size, "fgetc()" doesn't require a length argument.

$text = fgets($fp, 2000); //reads 2000 bytes at most

$chr = fgetc($fp); //reads 1 byte only

While you can read lines using "fgets()", you need a way of telling when you have reached the end-of-file, so you won't continue reading without any results. This is accomplished with the "feof()" functions, which returns "TRUE" or "FALSE", weather the position of a file pointer is at the end of it. You now have enough information to read a file line by line:

$filename = "test.txt";

$fp = fopen($filename, "r") or die("Couldn't open $filename");

while(!feof($fp))

{

$line = fgets($fp);

print "$line<br>";

}

fclose($fp);

While "fgets()" works well around text files, you may sometimes want more functionality for your script. The "fread()" functions returns the specified amount of data from a file, and doesn't take into consideration the end-of-line "\n", like "fgets()". "fread()" also starts from the current file position, but if you're not happy with it, you can always change it using the "fseek()" function.

fseek($fp, 100); //moves the file pointer to the 100th byte

print(fread($fp, 15)); //outputs 15 bytes

Any writing to a file is done with the use of "fwrite()" or "fputs()" functions, which both use a file pointer and a string to perform the writing:

fwrite($fp, "Hello from PHP!");

fputs($fp, "Hello again from PHP!");

So far, these functions were great with a single user. However, on public web-sites, with many users accessing your scripts at the same time, your files could quickly become corrupt. PHP offers the "flock()" function, which will lock a file and won't allow other processes to write or read the file while the current process is running. "flock()" requires a file pointer and an integer to do this:

flock($fp1, 1); //shared lock – allows read, doesn't allow write

flock($fp2, 2); //exclusive lock – doesn't allow neither read, nor write

flock($fp3, 3); //release lock – releases a shared or exclusive lock

There are a lot of other functions that you can use with files like: testing functions – "file_exists()", "is_file()", "is_dir()", "is_readable()", "is_writeable()", "is_executable()"; functions that return information on files: "filesize()", "fileatime()", "filemtime()", "filectime()". You can figure out what the function does by just reading its name; more information about them can be found in the PHP documentation.

7 comments

Expanding PHP Classes

While you can always modify a class to add more properties and methods, there is a better way to create a more complex class based on a simple one. Extending existing classes by creating new classes which inherit their parent class properties and methods may come in handy when you need to create more classes based on the initial one. This is also called a "parent-child" relationship, the reasons are obvious. Know that the parent class must be defined before the child class, so the order in which the classes are defined is important. Let's get back to our automobile class, and create a new class based on the original one:

class used_automobile_class extends automobile_class

{

var $owner;

var $is_price_negotiable;

function write_negotiable()

{

if ($this->is_price_negotiable)

{

print "The price is negotiable!";

}

else

{

print "The price is NOT negotiable!";

}

}

}

We have created a new class that inherits the all of the properties and methods of "automobile_class", and adds some new ones. While you can always add new properties and methods, it is not possible to remove any of the properties or methods defined in the parent class. You can override them, though. This means that a child class can redefine a method of its parent class, and any new objects created based on the child class will use the child's redefined method.

After reading this, you may wonder why you should expand existing classes, and not just rewrite the class and adapt it to the new requirements. The answer lies in flexibility. There are times when you start writing a class from scratch, add some more properties as needed and create this large class, but then you want to get back to one of the initial structures and redefine it some other way. This would not have happened if you had created children classes that expanded the original class.

If you have worked with OOP before on other programming languages, you may be wondering "how about the constructors and destructors?" If you don't know what I'm talking about, you should be interested to know that PHP allows you to automatically call a special method (also known as a constructor) when you create a new instance of the class using "new". Destructors, on the other hand, are special methods that are automatically called when an object is destroyed. Unfortunately, there are no destructors in PHP, but you may use "register_shutdown_function()" instead to simulate most effects of a destructor.

Creating a constructor is easy, you only have to create a method with the same name as the class. In the following example, we output a string and set a variable when an object is created based on this class:

class automobile_class

{

var $negotiable_price;

var $price; //the price of the car, in dollars

function automobile_class()

{

print "Object created!";

this->$negotiable_price = FALSE;

}

}

Please take notice of the fact that in PHP there are some class and methods names that are reserved to language. A small constraint is that you cannot name a class "stdClass", because this is internally used by PHP. Also, it is recommended that you don't use function names beginning with "__", they are "magical" to PHP.

4 comments

Object Oriented Programming In PHP

One of the most common programming concepts in the world is OOP, which stands for Object-Oriented Programming. Using this technique, programmers manipulate objects, which are made of functions and variables, instead of manipulating the functions and variables themselves. Let's say that you develop an e-commerce web-site. You could use an object to manage a shopping cart, and assign the object different properties and methods, based on what you want it to do. Properties stand for variables holding the information about the object (for example: the name, items in the cart, total value of the items, etc.), and methods stand for the functions that can be used with the object (for example: add an item into the cart, remove an item, empty cart, etc.)

It sounds simple, doesn't it? Well, it really is. But for an object to be defined, you have to have a template on which you will define the object. This is where classes come in. A class is a blueprint for one or more objects. Therefore, an object is to a class what a variable is to a type. A class is a set of characteristics, and an object is entity that is defined based on those characteristics. Another example: let's think about an automobile class. Such a class could have a characteristic (property) called "color". All objects created based on this class would have such a characteristic, but some objects would initialize this property to "red", others to "blue", and so on. This means that the class only holds a definition, and the object holds the actual value.

You can declare a class by using the "class" keyword. Let's define a simple class:

class automobile_class

{

var $color; //the color of the car

var $max_speed; //the maximum speed

var $price; //the price of the car, in dollars

function is_cheap()

{

return ($this->price < 5000); //returns TRUE if the price is smaller than 5000 dollars

}

}

In this small example you can notice some of the most important aspects of a class. After the declaration of the class, you can see the variables used within the class, which are called properties. These are declared using the "var" statement. While they can be defined anywhere within the class, you should really define them at the very top, so you can better see the class' properties. The functions within the class are called methods; they're used to manipulate the class' properties and produce results. In that simple method you can see that when we use a class method or property, we must use the "->" operator. The keyword "this" tells PHP that the property of method belongs to the class being defined.

An object is a special variable that contains a bundle of other variables and functions; you always have to use a class upon which to create an object. But, unlike a class, you won't need to write any code, nor you will see how the class actually works. While you may first think that this isn't so great, in fact this is one of the main concepts of object-oriented programming. You only have to create the class once, then you can create a zillion objects, in a zillion other projects.

While a class only exists in code and is considered to be a blueprint, an object exists in memory and is a working instance of a class. An instance of an object is created using the "new" statement along with the name of the class the object is based on. Let's return to our automobile class:

$car_object = new automobile_class();

$car_object->color = "red";

$car_object->price = 6000;

if($car_object->is_cheap())

{

print "This car is cheap!";

}

else

{

print "This car is expensive!";

}

You can see that we use the "->" operator to access and modify object's properties. After that, we use the same operator to call a method.

Perhaps the greatest benefit of object-oriented code is its reusability. Because the classes used to create objects are self-enclosed, they can be easily pulled from one project and inserted into another. Additionally, it is possible to create child classes that inherit and/or override the characteristics of their parents. This technique allows you to create more complex and specialized objects. Even if you start with a small class, you can develop it to a complex class by time, with adding more properties and objects to its children classes.

21 comments

PHP Functions

Functions are the most important part of any programming language, PHP included. You can say in a few words that functions are pieces of code that accept values and produce results. While there are functions that you don't need to supply any values to, a function which does nothing is pointless. Functions come in handy when you're writing repetitive code, and you're looking to use the same code in other scripts.

print "Welcome to my web-page!";

A function is a block of code that is not immediately executed, but can be called by your scripts when needed. Functions can either be built-in or defined by the user. PHP has a lot of built-in functions; one of them is "print()". In the previous examples we used it to output strings to the web-browser. The values used along with the function are called arguments. Arguments are included in the parentheses of a function call, but this doesn't always apply. For some build-in functions, for example "print()", you can choose to use them or not use them, PHP will accept it either way.

Different functions require different arguments; functions may ask for multiple arguments (which are separated by commas), but on the other hand, they could also be executed without any arguments, in which case you only include the parenthesis after the function name. It all depends on the function and what it does. For example, a function that calculates the values of a purchase based on the price and the number of purchased items will require two values. Let's assign the result to a variable:

$value = calculate_value($item_price, $number_of_items); //calls the "calculate_value()" function with two arguments

As you can see, functions require data to be passed to them, and then return a result based on that data. Most functions give you some information after their completion, even if that only tells you if their mission was successful (a boolean type result). This is not always the case. You don't have to use any arguments when you use a simple function that outputs the same message everytime it is called, for example "Thanks for visiting our web-site", and it also doesn't return any result. When declaring a function, note that you must not add a semicolon after the function statement:

function display_goodbye_message() //no semicolon here!

{

print "<h1>Thanks for visiting our web-site</h1>";

}

This will create a function that, whenever called, will output the same string. It requires no arguments, and it doesn't return anything. This isn't so useful, and you probably won't see many similar functions. Let's get back to our value calculating function. As you can see, you can use the "return" statement to assign a result to the function – in this case, the result will be the calculated value of the purchase (the price multiplied by the number of items purchased). This is how you define it:

function calculate_value($price, $items)

{

return ($price * $items); //returns a result

}

We can call functions dynamically the same way you can access dynamic variables. This means that you can treat an expression's name as a function name, and thus call it.

$function_name = "calculate_value";

$function_name(40, 5);

This is identical to:

calculate_value(40, 5);

When a function uses a variable, there are several issues you should be aware of. It's important to know that if you declare a variable inside a function, that variable will only be available to the rest of that function's code. This is called a local variable. If you try to use this variable in another function, it will not hold any value.

But sometimes you want to access some important information outside the function, without using an argument. One way to do this, you must the "global" statement.

$exchange_rate = 1.27;

function calculate_value_from_foreign($price, $items)

{

global $exchange_rate; //make "$exchange_rate" available to the function

return ($price * $items * $exchange_rate);

}

We expanded the previous script a little bit. You can see how we use "global" to inform the function that the "$exchange_rate" variable has been declared outside it. If we have hadn't done this (try to comment the line), the function would have returned zero, because "$exchange_rate" would have been "NULL". The function simply doesn't know the value of "$exchange_rate" if you don't tell it that it was assigned outside the function. Be careful, because if you modify the value of a variable within a function, that value will be changed for the following code after the call to the function; PHP uses the variable itself, and not a copy.

Another way to access the data outside the function, without using an argument is by using a reference to a variable as an argument. You can do this by placing an ampersand "&" in front of the argument, when you define the function. This way, the function will directly access the variable through the reference, and the variable can be assigned and read at the same time.

$exchange_rate = 1.27;

function add_tax_and_calculate_value_from_foreign($price,
$items, &$rate) //notice the ampersand "&", telling
PHP to treat the variable "$rate" as a reference

{

$rate .= 0.01; //adds a 0.01 tax

return ($price * $items * $exchange_rate);

}

add_tax_and_calculate_value_from_foreign(15, 4, $exchange_rate)

print $exchange_rate; //the new exchange rate is 1.28, because the function has incremented it

As you can see, PHP is very versatile. You can define functions within other functions, you can define a function based on a condition, you can use a variable number of arguments, you can use a default argument, and many more. Functions don't act like variables; that is, you don't have to first declare it then use it. You can declare a function and the very end of your script, and use it at the beginning, even though this is really not recommended. Before starting the actual execution of the script, PHP searches the script for functions, so it will know where to look for if you call one.

No comments

PHP Loop Structures

The ability to perform repetitive tasks is a very important aspect of any programming language. Imagine an array with 500 elements. You wouldn't want to write 500 statements to read 500 elements. Instead, you can write a single loop statement that will perform an action to all 500 elements. A loop will continue to operate until a condition is achieved, or you choose to exit the loop. According to our 500 example, you can create a loop structure that will continue to read elements from an array until it has reached the last element (500).

You can define a simple loop structure in PHP using the "while" statement, which at first may look similar to the "if" statement:

while(expression)

(statements)

As long as the expression evaluates to true, the statements are executed over and over again. You wouldn't want your loop to go on forever, so you should change something within the block of statements that will affect the expression. For example:

$counter = 1; //this is out counter variable

while($counter < 10) //keep running the following statements as long as "$counter" holds a value that is smaller than 10

{

print $counter; //output the "$counter" value

$counter++; //increment "$counter"

}

This will output "123456789". The counter variable will start from 1; its value will be outputted, then the variable will be incremented by 1. The loop continues as long as the variable's value is smaller than 10; once it reaches 10, the loop structure will stop, so "10" will not be outputted.

The "do…while" statement is similar to the "while" statement. The only difference between the two is that when using the "do…while" statement the block of statements is executed before the truth test and not after it. This way the block of statements will be executed at least once, even if the expression evaluates to "FALSE":

do

(statements)

while(expression);

A much neater and safer way to implement a loop structure is using the "for" statement. This isn't much different from a while statement, in fact there is nothing you cannot achieve when using for statement that you cannot do with a while statement. It only requires you to write a smaller amount of code:

for(variable assignment; test expression; variable increment)

(statements)

Whereas in order to properly use a "while" statement you must initialize a variable outside the statement, then increment it and test it, all of these in different parts of the structure, using "for" you can do that using a single statement. This makes your code more compact and also makes it less likely that you will forget to increment a counter variable, thus creating an infinite loop. So here is how we can rewrite the previous counter example:

for($counter = 1; $counter < 10; $counter++)

{

print $counter;

}

Well, this looks a lot better. It's more compact, and you can see how the loop variable will perform at a glance. You probably have figured out on your own that this will output "123456789".

While all of this looks very fine, there are times when you need more control over a loop. PHP includes two useful functions for this: "break" and "continue". "break" does exactly what its name says: it just breaks out of the loop. This way you can take care of any unexpected actions that the loop might stumble upon. Let's say you have to sum up a list of prices. If someone has added a negative price to the list by mistake, this could really make a mess out of your calculations. On the other hand, you can use "continue" is used to skip the current iteration, but don't end the loop. "continue" just passes on to the next iteration, without running the following statements in the group. In our price list example, this could come in handy when you want to skip certain prices, so you can create a sub-total.

for($num = 0; $num < 20; $num++)

{

if($prices[$num] < 0) //if we encounter a negative price…

{

print "Error: You have negative prices!";
//output an error message

break; //exit the loop!

}

if($prices[$num] > 1000) //if we encounter prices higher than $1000, we apply a discount

continue; //don't continue to the next statement that will add them to the total sum, we have to perform discount calculations

$total += prices[$num];

}

PHP also implements a loop structure that works only on arrays, called "foreach". It will return an error when you try to use it on a variable with a different data type or an uninitialized variable.

foreach(array_expression as $value) statement

foreach(array_expression as $key => $value) statement

The first syntax is used to loop over an array, while assigning the value of the current element of the array to $value. PHP keeps count of the current index, so you don't have to worry about that, it will continue to assign elements starting from the first one until the last one, with no exceptions. The second syntax does the same thing, except that the current element key will be assigned to the variable "$key" on each loop. It's good to know that "foreach" operates on a copy of the array, not the array itself. Returning to our previous script, we can rewrite the code like this:

foreach($prices as $num) //assigns the value of each element in the "$prices" array to "$num", then does the following…

{

if($num < 0)

{

print "Error: You have negative prices!";

break;

}

if($num > 1000)

continue;

$total += $num;

}

While it may look confusing at first, just keep in mind that "$num" now holds the actual value of the array's element, not its index in the array.

1 comment

« Previous PageNext Page »