Home
Our Services:
Web Portfolio
E-Commerce
Database Application
Search Engine
Placement

Compass Point Bio
Compass Point Philosophy

Resources:
Knowledge Base
Internet Primer
Web Projects Workflow
Sample Site Features
Sample Applications


Advanced Projects:
Web Services
Universal Database

News:
Newsletter
Internet Updates
Press

Site Map
Contact Us

 


 

Approach to Writing Functions in PHP
------------------------------------------------------------


 

Back to Knowledge Base
I'm a believer in simplicity. One of the great features of PHP is that there are several ways to pass variables to a function. However, one of the problems you'll encounter when your function specifically calls for variables is that it expects EXACTLY that number of variables.

For example, if your function is this:

Function do_something($variable1, $variable2){
//do something here
}

and you call it with 1 variables,

do_something('hello')

you're going to get a nasty message saying Warning: "Warning: Missing argument 2 for do_something()."

I also believe that a function should be flexible and be able to 'inspect' the surrounding environment to amplify the actual information passed. It should always be a goal to pass different quantities and combinations of variables to a function.

For this reason, I've gravitated to a standard way of expecting NO variables in the function (the function parentheses are blank), and handling any number of passed variables gracefully. I'd like to show you one method I call the "lutz method" (only because I'm into figure skating), which goes something like this:


Function do_something (){
     $fmode = func_num_args();
     $arg_list = func_get_args();
     $vorder = array( "username", "password", "comments");
     for($i=0; $i < $fmode; $i++){
          eval('$'. $vorder[$i] . '=$arg_list[$i];');
     }
     //do something in the function
          echo 'hello'; //etc.....
}

In these six lines of code I have allowed a variable number of arguments to be passed to the function, which will then be available inside the function. First I call func_num_args(), which tells me the number of arguments passed, then I simply get the arguments into an array using func_get_args().

Now, inside the function, I have created a list of the order I expect the variables to be listed in, called $vorder. I'll talk more about the order of the variables in a moment. Of course, I may or may not use any of these variables, possibly even none of them, but if variables ARE passed, I expect them to be passed passed in a specific order. In this case I can handle three variables, "username", "password", and "comments".

Finally, I use a for() loop to assign the arguments passed to preset variable names.

What I have done is allow a function to receive 1, 2, 4, or perhaps 0 variables, but to assign the variables to appropriate variables if they are passed.

"OK," you say, "why would I want to do this?" Well, I'll refer you to the php manual (www.php.net). Let's go, for example to:

http://www.php.net/manual/en/function.mysql-connect.php

and see what they have to say about the mysql_connect function. The syntax listed is as follows:

resource mysql_connect ( [string server [, string username [, string password [, bool new_link]]]])

All of those square brackets indicate OPTIONAL strings, and the folks at PHP have given a lot of thought to the order of those brackets. It is really saying, "you don't have to put anything in the parenthesis, and if the resources are already there, it will work." But, evaluating critically what is being accomplished, it's also saying, "each additional piece of information lets you do a more specific task. If you don't give me the 2nd or 3rd thing, I'll get it myself-if you've done your coding well, it should work." So, for example, there could be a real situation where you specify a username that has no password (not very smart though), but obviously you'd never specify a password without username. And PHP will assume that you want a new resource link unless you specify otherwise.

Having a physics background, I like to think of these variables as modes-kind of like modes of a wave which can vary from simple to complex. This php function (mysql_connect()) has five modes -- 0, 1, 2, 3, and 4. If a username always had to have a password associated with it, this function really only has 4 modes - 0, 1, 3 and 4, because mode2 doesn't make any sense.

Ideally, each mode is a little bit more complex, but allows me to do more-something that makes sense based on the purpose of the function. But, if I design it right, the smallest mode should let me do the most fundamental task of the function in the most elegant way. This is where real genius can shine.

Finally, each larger mode should allow me to OVERRIDE something that's already in the environment. That way, for example, if there's already a database connection, I can use it, but if I want to make a different one, I specify the connection settings, and my function creates a connection.

To give an oversimplified example, here's a function using my technique that allows someone to concatenate a string:


Function join_string (){
$fmode = func_num_args();
$arg_list = func_get_args();
$vorder = array( "string1", "string2", "string3");
for($i=0; $i < $fmode; $i++){
eval('$'. $vorder[$i] . '=$arg_list[$i];');
}
//write the strings out
if($fmode==1){
return $string1;
}elseif(($fmode==2){
return $string1 . $string2;
}elseif(($fmode==3){
return $string1 . $string2 . $string3;
}
}
//call the function
join_string("Hello everyone" , "," , "how are you doing");

This is really a simple example, since you would never do something like this, but when dealing with database connections, reading and writing files, using shopping carts, you'll find yourself wanting to create functions that will do either a little or a lot, based upon the site or the particular page. This forces you to ask the questions, "what do I want to minimally accomplish?" and "what is the minimum amount of information I need to achieve this?" and "what additional things should it be able to do?"

I hope this helps you think your design strategy out. An overview of some of the things you should think about when coding are:

1. Determine what you want the function to do, and what is the minimal level of performance you expect, and what variables are required. For example, if you create a shopping cart function, you could just create an array listing quantity and item number in a session variable.

2. Determine additional features that might be required, and the added input needed to accomplish this. For example, could the shopping cart also connect to a database and get the name and price of the item in an array? And even more complex, could it handle multiple carts?

3. Once you have thought that out, write out a comment line in the function for each 'mode' of the function, and then set out to make each mode work as efficiently as possible.

4. Standardize what you put in and what you get out. My biggies are database connection resources (I always use $db_cnx as the name), connection settings (I use $settings['hostname'], $settings['username'], etc.), file pointers (I use $fp), and on and on. If you decide on these rules and use them on all your sites, you're going to be a much better coder.

5. Write this all down so you or anyone else can review this in the future. Notes at the beginning of a function have saved me several times.