Functions........
Moderator: General Moderators
-
malcolmboston
- DevNet Resident
- Posts: 1826
- Joined: Tue Nov 18, 2003 1:09 pm
- Location: Middlesbrough, UK
Functions........
i have been hearing and reading alot of things aboutn functions lately and would just like to ask some questions
1) what is the main purpose of functions?
2) recycleable functions, how?
3) creating and retrieving functions scripts, how?
theyre just some Q's of the top of my head, as i am moving towards gearing up myself to use them
also a few other questions
4) pear? what the hell is it?
5) whats OOPS? (dont try and be funny!)
6 ) HEREDOC, why is it useful?
any questions you can be arsed answering will be fine
1) what is the main purpose of functions?
2) recycleable functions, how?
3) creating and retrieving functions scripts, how?
theyre just some Q's of the top of my head, as i am moving towards gearing up myself to use them
also a few other questions
4) pear? what the hell is it?
5) whats OOPS? (dont try and be funny!)
6 ) HEREDOC, why is it useful?
any questions you can be arsed answering will be fine
Re: Functions........
modularizing your code and make it more readablemalcolmboston wrote: 1) what is the main purpose of functions?
Did you mean 'recursive functions'? If so, it looks like:malcolmboston wrote: 2) recycleable functions, how?
Code: Select all
function traverse_tree($node){
//do something with node
foreach($node->childs as $child)
traverse_tree($child);
}I'm not sure what do you mean by that.malcolmboston wrote: 3) creating and retrieving functions scripts, how?
AFAIK, pear is collection of... hmm... useful packages, or you can call it 'libraries'...malcolmboston wrote: 4) pear? what the hell is it?
Do you mean OOP? It stands for Object Oriented Programming.malcolmboston wrote: 5) whats OOPS? (dont try and be funny!)
It's useful if you need to include large chunk of text, in which variables should be parsed, but don't want to escape the double quotes.malcolmboston wrote: 6 ) HEREDOC, why is it useful?
-
malcolmboston
- DevNet Resident
- Posts: 1826
- Joined: Tue Nov 18, 2003 1:09 pm
- Location: Middlesbrough, UK
When you create a function with the function something() {} syntax, it is automatically available to you throughout that script.
Example (declare the function like this):
Then, every time in your code that you want to do the things contained in the function, you simply do this:
Example (declare the function like this):
Code: Select all
<?php
function dostuff($parameter) {
//Do stuff to the parameter
}
?>Code: Select all
<?php
dostuff($something);
?>A function encapsulates a bunch of actions. Eg:
This could be convenient for basic debugging, if you need to check the values in an array/object. In a script, just type:
Fns create "chapters" in the script: ie a single fn call can replace several lines of "bare" code and so the script becomes much easier to read.
Choice of function names are important in this respect. For example something like:
.. is easy to understand (if just a touch too verbose - always better to err on the side of clarity though).
Always watch out for repeated code and try to encapsulate it in a function or object if you can. For example:
Notice that, if you wish to change the error reporting level, you just need to edit one function def rather than many scripts throughout the site (swap the commented/uncommented lines around). This is one of the main benefits of encapsulation.
Fns can also encapsulate a repeated "pattern" such as looping through a db query to build table rows (products and creators are objects; I don't like Smarty):
Kind of abstract: but that's the whole point. The same function can be used to build posts in a forum, topics in a board, or what have you. It's got issues but maybe illustrates the point.
Functions have their own variable scope. It's best practice to reduce variable scope as much as possible since that makes code easier to debug (fewer parts of the script might influence a var's value). Without fns, everything exists in the global scope. There are potential security issues with this (if have uninitialised vars & register globals on).
You might want to customise the behaviour of a native php fn for some reason. For example, count() can produce misleading results (try count($array) where $array === false). This is more robust:
Keep fns short and sharp: 6-7 lines is usually ample. Every fn should do just one thing.
I'd pay good money if all php'ers would organise spaghetti code into fns. It's often difficult to hunt down the problem in a posted script - probably the problem wouldn't even have arisen in better-organised code. If it's easier to read, it's less likely mistakes will be made.
Pretty much all the above applies to objects. OOP is all about making things simple. Once again, a whole bunch of stuff is encapsulated - this time behind a class interface. For example, I've been working all day on a set of form validation classes which (hopefully) will handle any shape or colour of form. The interface will provide just what I need to know, hiding the actual mechanics (this isn't functioning code just showing some of the public methods):
With OOP, just think of what sort of API you'd like, then go and write it. Find out more at phppatterns.com. Don't worry - it takes a while to sink in. First, get comfortable with functions.
Code: Select all
<?php
function printR(&$array)
{
echo '<pre>';
print_r($array);
echo '</pre>';
}
?>Code: Select all
<?php
printR($array);
?>Choice of function names are important in this respect. For example something like:
Code: Select all
<?php
if(isModerator())
{
displayMovePostButton();
}
?>Always watch out for repeated code and try to encapsulate it in a function or object if you can. For example:
Code: Select all
<?php
function dbConnect()
{
$db_connection = @mysql_connect(DB_SERVER, DB_USERNAME, DB_PASS);
if ($db_connection === false)
{
#die ('Error: could not connect to server.<br />');
die('DEV ONLY: ' . mysql_errno() . ' - ' . mysql_error());
}
if (@mysql_select_db(DATABASE, $db_connection) === false)
{
#die('Cannot find database.<br />');
die('DEV ONLY: ' . mysql_errno() . ' - ' . mysql_error());
}
return $db_connection;
}
?>Fns can also encapsulate a repeated "pattern" such as looping through a db query to build table rows (products and creators are objects; I don't like Smarty):
Code: Select all
<?php
function stuffSmarty($product_name, &$creator)
{
$html = '';
$creator->i = 0;
$product =& new $product_name($creator);
while ($result = mysql_fetch_assoc($creator->getProductQuery()))
{
$product->nextRow($result);
$html .= $product->getHtml(); // return a complete html string eg a product post within creator topic
$creator->i++;
}
return $html;
}
?>Functions have their own variable scope. It's best practice to reduce variable scope as much as possible since that makes code easier to debug (fewer parts of the script might influence a var's value). Without fns, everything exists in the global scope. There are potential security issues with this (if have uninitialised vars & register globals on).
You might want to customise the behaviour of a native php fn for some reason. For example, count() can produce misleading results (try count($array) where $array === false). This is more robust:
Code: Select all
<?php
function cleverCount($array)
{
if(isset($array) and is_array($array) and count($array) != 0)
{
return count($array);
} else {
return false;
}
}
?>I'd pay good money if all php'ers would organise spaghetti code into fns. It's often difficult to hunt down the problem in a posted script - probably the problem wouldn't even have arisen in better-organised code. If it's easier to read, it's less likely mistakes will be made.
Pretty much all the above applies to objects. OOP is all about making things simple. Once again, a whole bunch of stuff is encapsulated - this time behind a class interface. For example, I've been working all day on a set of form validation classes which (hopefully) will handle any shape or colour of form. The interface will provide just what I need to know, hiding the actual mechanics (this isn't functioning code just showing some of the public methods):
Code: Select all
<?php
$validator->matchKeys(); // returns true or false
$validator->getVar($key); // "firewall": returns validated value or null if it failed to validate
$validator->errorsExist(); // returns true (redisplay the form) or false (process submitted data)
?>
Last edited by McGruff on Tue Aug 09, 2005 7:41 pm, edited 2 times in total.
PS: heredoc is often used to dump chunks of html mixed with vars in php scripts. Normally, html shouldn't be allowed to get within a thousand yards of a php script: define a bunch of vars (model) and then include an html template (view) where they get echo'd out instead. There's a bit more that could be said about templating systems, but that's a good option.
In OOP this could be summarised with an abstract base class, extended by all printer classes (which overide all the methods):
In OOP this could be summarised with an abstract base class, extended by all printer classes (which overide all the methods):
Code: Select all
<?php
class PrintStuff
{
function loadModel()
{
die('Method not implemented. .' . __LINE__ . ' | ' . __FILE__);
}
function loadView()
{
die('Method not implemented. ' . __LINE__ . ' | ' . __FILE__);
}
function printPage()
{
die('Method not implemented. ' . __LINE__ . ' | ' . __FILE__);
}
}
?>
Last edited by McGruff on Tue Aug 09, 2005 7:41 pm, edited 1 time in total.
-
mahara
- Forum Commoner
- Posts: 37
- Joined: Wed Nov 13, 2002 1:08 am
- Location: Bandung, Jawa Barat, Indonesia
Off topic too...Nay wrote:Off topic, but McGruff, could you clarify on seperating HTML and PHP? I mean even for a simple form or tiny bits of HTML, would you make a seperate template file and parse it?
-Nay
Well, template is interesting. This forum was actually created by using template (separating between HTML and PHP code).
There are different approaches to the use of templates, but yes that's exactly what I do.Nay wrote:Off topic, but McGruff, could you clarify on seperating HTML and PHP? I mean even for a simple form or tiny bits of HTML, would you make a seperate template file and parse it?
-Nay
For example, in my own forum, a page such as this would have separate template files for:
<head> html
page header
searchbar
topic header
post
footer
.. and a simple container for the topic header & posts
Some people don't like lots of separate files but it's a simple system which is easy for designers to work with (as long as they don't take fright at the <?php echo $var; ?> tags in the html). It might be a good way to start, introducing you to the general thrust of template systems.
Once you've got a separate model & view you can always send the model vars to a different system such as the Smarty template engine (not that I'm recommending it - imho it's appalling). This is one of the benefits of well-organised code (using fns or OOP): code starts to become much more modular so that you can swap bits in and out to try a different approach.
Check out hotscripts.com sometime for other approaches using custom tags, regex, template logic etc. Personally I dismissed all that long ago but not everyone would agree.
Also see this article at phppatterns.
If you use OOP, take a look at the PrintStuff class, above. It's something I started using recently so still a bit experimental. The class simply defines a template for all printer classes, helping to keep me on the straight and narrow.
Incidentally, it's meant to encapsulate the MVC pattern in web apps (my motto is embed MVC in the app, not the app in MVC).