-
Notifications
You must be signed in to change notification settings - Fork 16
/
functions.html
486 lines (469 loc) · 22.2 KB
/
functions.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
---
title: Functionally yours
---
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="chrome=1">
<title>PHP101 - {{ page.title }}</title>
<link rel="stylesheet" href="stylesheets/styles.css">
<link rel="stylesheet" href="stylesheets/pygment_trac.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script src="javascripts/main.js"></script>
<!--[if lt IE 9]>
<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
</head>
<body>
<header>
<h1>PHP101</h1>
<p>For the absolute beginner</p>
</header>
<div id="banner">
<span id="logo"></span>
<a href="https://github.com/ss23/php-tutorial" class="button fork"><strong>View On GitHub</strong></a>
</div><!-- end banner -->
<div class="wrapper">
{% include nav.html %}
<section>
<h2>A little knowledge</h2>
<p>If you’ve been taking your regular dose of PHP 101, you know now enough about PHP to write
simple programs of your own. However, these programs will be “procedural” or linear – the
statements in them will be executed sequentially, one after another – simply because that’s
the only programming style I’ve used so far.</p>
<p>You know what they say about a little knowledge being a dangerous thing… as your PHP
scripts become more and more complex, it’s only a matter of time before you bump your head
against the constraints of the procedural method, and begin looking for a more efficient
way of structuring your PHP programs.</p>
<p>That’s where Part Six of PHP 101 comes in. In this tutorial I’m going to introduce you to
a new way of doing things, where code doesn’t run in a straight line, but twists, leaps
and bounds across the landscape of your script. Most of this activity is accomplished
through a programming construct called a “function”, and this tutorial teaches you how to
build them (once), use them (many times), pass them arguments and have them return values,
and generally make your scripts more compact, efficient and maintainable.</p>
<h2>In plain English</h2>
<p>Ask a geek to define the term “function”, and he’ll probably mumble something about a
function being “a block of statements that can be grouped together as a named entity.”
Since this is a tutorial on PHP, not an introductory course in Greek, I’ll translate that
for you: a function is simply a set of program statements which perform a specific task,
and which can be “called”, or executed, from anywhere in your program.</p>
<p>Every programming language comes with its own built-in functions, and typically also allows
developers to define their own functions. For example, if I had a profit statement for the
year on my desk, and I wanted to inflate each number by 35%, I could call my neighborhood
accounting firm and get them to do it for me… or I could write a simple PHP function called
cheatTheShareholders() and have it do the work for me (it’s faster, plus PHP
doesn’t bill by the hour).</p>
<p>There are three important reasons why functions are a Good Thing™. First: user-defined
functions allow you to separate your code into easily identifiable subsections – which are
easier to understand and debug. Second: functions make your program modular, allowing you
to write a piece of code once and then re-use it multiple times within the same program. And
third: functions simplify code updates or changes, because the change needs only to be
implemented in a single place (the function definition). Functions thus save time, money
and electrons… and I know the electrons at least will thank you!</p>
<h2>Monday morning blues</h2>
<p>To see how a function works, look at the following example:</p>
{% highlight php %}<?php
// define a function
function myStandardResponse() {
echo "Get lost, jerk!<br /><br />";
}
// on the bus
echo "Hey lady, can you spare a dime? <br />";
myStandardResponse();
// at the office
echo "Can you handle Joe's workload, in addition to your own, while he's in Tahiti for a month? You'll probably need to come in early and work till midnight, but we are confident you can handle it. Oh, and we can't pay you extra because of budgetary constraints...<br />";
myStandardResponse();
// at the party
echo "Hi, haven't I seen you somewhere before?<br />";
myStandardResponse();
?>{% endhighlight %}
<p>Here’s what the output might look like:</p>
<pre>
Hey lady, can you spare a dime?
Get lost, jerk!
Can you handle Joe's workload, in addition to your own, while he's in Tahiti for a month?
You'll probably need to come in early and work till midnight, but we are confident you can
handle it. Oh, and we can't pay you extra because of budgetary constraints...
Get lost, jerk!
Hi, haven't I seen you somewhere before?
Get lost, jerk!
</pre>
<p>(Sure it’s rude, but it does demonstrate how a function allows you to reuse pieces of code.)</p>
<p>The first thing I’ve done in the script above is define a new function, with the
function keyword. This keyword is followed by the name of the function, which
in this case is myStandardResponse(). All the program code attached to that
function is then placed within a pair of curly braces – and this program code can contain
loops, conditional statements, calls to other user-defined functions, or calls to other
PHP functions.</p>
<p>Of course, defining a function is only half of the puzzle; for it to be of any use at all,
you need to “invoke” it. In PHP, as in a million other languages, this is accomplished
by calling the function by its name, as I’ve done in the example above. Calling a
user-defined function is identical to calling a built-in PHP function like echo()
or explode().</p>
<p>Here’s the typical format for a function:</p>
{% highlight php %}<?php
function function_name(optional arguments) {
// Do things
}
?>{% endhighlight %}
<h2>Having an argument or two</h2>
<p>Functions like the one you saw in the previous section print the same value every time
you invoke them. While this is interesting the first six times, it can get boring on the
seventh. What we need to do, to make these boring, unintelligent functions a little more
exciting, is get them to return a different value each time they are invoked.</p>
<p>Enter arguments.</p>
<p>Arguments work by using a placeholder to represent a certain variable within a function.
Values for this variable are provided to the function at run-time from the main program.
Since the input to the function will differ at each invocation, so will the output.</p>
<p>To see how this works, look at the following function, which accepts a single argument
and then prints it back after a calculation:</p>
{% highlight php %}<?php
// define a function
function getCircumference($radius) {
echo "Circumference of a circle with radius $radius is ".sprintf("%4.2f", (2 * $radius * pi()))."<br />";
}
// call a function with an argument
getCircumference(10);
// call the same function with another argument
getCircumference(20);
?>{% endhighlight %}
<p>In this example, when the getCircumference() function is called with an
argument, the argument is assigned to the placeholder variable $radius within
the function, and then acted upon by the code within the function definition.</p>
<p>It’s also possible to pass more than one argument to a function. This is done using a
comma-separated list, as the following example shows:</p>
{% highlight php %}<?php
// define a function
function changeCase($str, $flag) {
/* check the flag variable and branch the code */
switch($flag) {
case 'U':
print strtoupper($str)."<br />";
break;
case 'L':
print strtolower($str)."<br />";
break;
default:
print $str."<br />";
break;
}
}
// call the function
changeCase("The cow jumped over the moon", "U");
changeCase("Hello Sam", "L");
?>{% endhighlight %}
<p>Here, depending on the value of the second argument, program flow within the function
moves to the appropriate branch and manipulates the first argument.</p>
<p>Note that there is no requirement to specify the data type of the argument being passed
to a function. Since PHP is a dynamically-typed language, it automatically identifies
the variable type and acts on it appropriately.</p>
<h2>Circles in the sand</h2>
<p>The functions on the previous page simply printed their output to the screen. But what
if you want the function to do something else with the result? Well, in PHP, you can
have a function return a value, such as the result of a calculation, to the statement
that called it. This is done using a return statement within the function,
as shown below:</p>
{% highlight php %}<?php
// define a function
function getCircumference($radius) {
// return value
return (2 * $radius * pi());
}
/* call a function with an argument and store the result in a variable */
$result = getCircumference(10);
/* call the same function with another argument and print the return value */
print getCircumference(20);
?>{% endhighlight %}
<p>Here, the argument passed to the getCircumference() function is processed, and
the result is returned to the main program, where it may be captured in a variable, printed,
or dealt with in other ways.</p>
<p>You can even use the result of a function inside another function, as illustrated in this
minor revision of the example above:</p>
{% highlight php %}<?php
// define a function
function getCircumference($radius) {
// return value
return (2 * $radius * pi());
}
// print the return value after formatting it
print "The answer is ".sprintf("%4.2f", getCircumference(20));
?>{% endhighlight %}
<p>Return values need not be numbers or strings alone: a function can just as easily return
an array (remember them?), as demonstrated in the following example:</p>
{% highlight php %}<?php
/* define a function that can accept a list of email addresses */
function getUniqueDomains($list) {
/* iterate over the list, split addresses and add domain part to another array */
$domains = array();
foreach ($list as $l) {
$arr = explode("@", $l);
$domains[] = trim($arr[1]);
}
// remove duplicates and return
return array_unique($domains);
}
// read email addresses from a file into an array
$fileContents = file("data.txt");
/* pass the file contents to the function and retrieve the result array */
$returnArray = getUniqueDomains($fileContents);
// process the return array
foreach ($returnArray as $d) {
print "$d, ";
}
?>{% endhighlight %}
<p>Assuming the file looked like this,</p>
<pre>
</pre>
<p>the output of the script would look like:</p>
<pre>test.com, x.com, deeply.bored.org, where.ami.net,</pre>
<p>Note that the return statement terminates program execution inside a function.</p>
<h2>Matching order</h2>
<p>The order in which arguments are passed to a function can be important. The following example
requires that the name is passed as the first argument, and the place as the second.</p>
{% highlight php %}<?php
// define a function
function introduce($name, $place) {
print "Hello, I am $name from $place";
}
// call function
introduce("Moonface", "The Faraway Tree");
?>{% endhighlight %}
<p>This is the output:</p>
<pre>Hello, I am Moonface from The Faraway Tree</pre>
<p>In this example, if you reversed the order in which arguments were passed to the function,
this is what you’d see:</p>
<pre>Hello, I am The Faraway Tree from Moonface</pre>
<p>And look what happens if you forget to pass a required argument altogether:</p>
<pre>Warning: Missing argument 2 for introduce() in xx.php on line 3
Hello, I am Moonface from </pre>
<p>In order to avoid such errors, PHP allows you to specify default values for all the
arguments in a user-defined function. These default values are used if the function
invocation is missing some arguments. Here’s an example:</p>
{% highlight php %}<?php
// define a function
function introduce($name="John Doe", $place="London") {
print "Hello, I am $name from $place";
}
// call function
introduce("Moonface");
?>{% endhighlight %}
<p>In this case the output would be:</p>
<pre>Hello, I am Moonface from London</pre>
<p>Notice that the function has been called with only a single argument, even though the function
definition requires two. However, since default values are present for each argument in the
function, the missing argument is replaced by the default value for that argument, and no
error is generated.</p>
<h2>The amazing shrinking argument list</h2>
<p>All the examples on the previous page have one thing in common: the number of arguments
in the function definition is fixed. However, PHP 4.x also supports variable-length
argument lists, by using the func_num_args() and func_get_args()
commands. For want of a better name, these functions are called “function functions”.
Try wrapping your tongue around that while you look at the next example, which
demonstrates how they can be used:</p>
{% highlight php %}<?php
// define a function
function someFunc() {
// get the arguments
$args = func_get_args();
// print the arguments
print "You sent me the following arguments:";
foreach ($args as $arg) {
print " $arg ";
}
print "<br />";
}
// call a function with different arguments
someFunc("red", "green", "blue");
someFunc(1, "soap");
?>{% endhighlight %}
<p>Hmmm… if you’re sneaky, you might have tried to pass someFunc() an array, and
found that instead of displaying the elements of the array, it simply said “Array”. You can
fix this by adding a quick test for array arguments inside the function, as in this rewrite:</p>
{% highlight php %}<?php
// define a function
function someFunc() {
// get the number of arguments passed
$numArgs = func_num_args();
// get the arguments
$args = func_get_args();
// print the arguments
print "You sent me the following arguments: ";
for ($x = 0; $x < $numArgs; $x++) {
print "<br />Argument $x: ";
/* check if an array was passed and, if so, iterate and print contents */
if (is_array($args[$x])) {
print " ARRAY ";
foreach ($args[$x] as $index => $element) {
print " $index => $element ";
}
} else {
print " $args[$x] ";
}
}
}
// call a function with different arguments
someFunc("red", "green", "blue", array(4,5), "yellow");
?>{% endhighlight %}
<h2>Going global</h2>
<p>Let’s now talk a little bit about the variables used within a function, and their
relationship with variables in the outside world. Usually, the variables used within
a function are “local” – meaning that the values assigned to them, and the changes made
to them, are restricted to the function space alone.</p>
<p>Consider this simple example:</p>
{% highlight php %}<?php
// define a variable in the main program
$today = "Tuesday";
// define a function
function getDay() {
// define a variable inside the function
$today = "Saturday";
// print the variable
print "It is $today inside the function<br />";
}
// call the function
getDay();
// print the variable
print "It is $today outside the function";
?>{% endhighlight %}
<p>When you run this script, here is what you will see:</p>
<pre>It is Saturday inside the function
It is Tuesday outside the function</pre>
<p>In other words, the variable inside the function is insulated from the identically-named
variable in the main program. Variables inside a function are thus aptly called “local”
variables because they only exist within the function in which they are defined.</p>
<p>The reverse is also true: variables defined inside a function cannot be “seen” outside
it. To illustrate, take a look at the next example and its output (or the lack of it):</p>
{% highlight php %}<?php
// define a function
function getDay() {
// define a variable inside the function
$today = "Saturday";
}
getDay();
print "Today is $today";
?>{% endhighlight %}
<p>Here is the output:</p>
<pre>Today is </pre>
<p>Depending on the error_reporting you have set up in php.ini, you might also see an error
message:</p>
<pre>Notice: Undefined variable: today in x1.php on line 10</pre>
<p>However, I didn’t say this can’t be overcome. To have variables within a function accessible
from outside it (and vice-versa), all you need to do is first declare them “global” with
the – you guessed it! – global keyword.</p>
<p>Here is a rewrite of the earlier example, this time declaring the $today
variable global:</p>
{% highlight php %}<?php
// define a variable in the main program
$today = "Tuesday";
// define a function
function getDay() {
// make the variable global
global $today;
// define a variable inside the function
$today = "Saturday";
// print the variable
print "It is $today inside the function<br />";
}
// print the variable
print "It is $today before running the function<br />";
// call the function
getDay();
// print the variable
print "It is $today after running the function";
?>{% endhighlight %}
<p>And here is the output:</p>
<pre>It is Tuesday before running the function
It is Saturday inside the function
It is Saturday after running the function</pre>
<p>Thus, once a variable is declared global, it is available at the global level, and can be
manipulated both inside and outside a function.</p>
<p>PHP also comes with so-called superglobal variables – variables that are always available,
regardless of whether you’re inside a function or outside it. You’ve already seen some of
these special variables in action: the $_SERVER, $_POST and $_GET variables are all superglobals, which is why you can access things
like the currently-executing script’s name or form values even inside a function.</p>
<p>Superglobals are a Good Thing™, because they’re always there when you need them,
and you don’t need to jump through any hoops to use the data stored inside them. Read more
about superglobals and variable scope at <a href="http://www.php.net/manual/en/language.variables.predefined.php">http://www.php.net/manual/en/language.variables.predefined.php</a> and
<a href="http://www.php.net/manual/en/language.variables.scope.php">http://www.php.net/manual/en/language.variables.scope.php</a>.
<h2>Checking references</h2>
<p>Any discussion about variables in and out of functions would be incomplete without some
mention of the difference between “passing by reference” and “passing by value”. So far,
all the examples you’ve seen have involved passing arguments to a function “by value” -
meaning that a copy of the variable was passed to the function, while the original
variable remained untouched. However, PHP also allows you to pass “by reference” – meaning
that instead of passing a value to a function, you pass a reference to the original
variable, and have the function act on that instead of a copy.</p>
<p>Confusing? Well, this is probably easier to understand with an example. Let’s start with this:</p>
{% highlight php %}<?php
// create a variable
$today = "Saturday";
// function to print the value of the variable
function setDay($day) {
$day = "Tuesday";
print "It is $day inside the function<br />";
}
// call function
setDay($today);
// print the value of the variable
print "It is $today outside the function";
?>{% endhighlight %}
<p>You’ve already seen this before, and you already know what the output is going to say:</p>
<pre>It is Tuesday inside the function
It is Saturday outside the function</pre>
<p>This is because when the getDay() function is invoked, it passes the value
“Saturday” to the function (“passing by value”). The original variable remains untouched;
only its content is sent to the function. The function then acts on the content, modifying
and displaying it.</p>
<p>Now, look at how “passing by reference” works:</p>
{% highlight php %}<?php
// create a variable
$today = "Saturday";
// function to print the value of the variable
function setDay(&$day) {
$day = "Tuesday";
print "It is $day inside the function<br />";
}
// call function
setDay($today);
// print the value of the variable
print "It is $today outside the function";
?>{% endhighlight %}
<p>Notice the ampersand (&) before the argument in the function definition. This tells
PHP to use the variable reference instead of the variable value. When such a reference
is passed to a function, the code inside the function acts on the reference, and modifies
the content of the original variable (which the reference is pointing to) rather than a
copy. If you then try retrieving the value of the original variable outside the function,
it returns the modified value:</p>
<pre>It is Tuesday inside the function
It is Tuesday outside the function</pre>
<p>Now you understand why I said no discussion about variables would be complete without
mentioning the two ways of passing variables. This, of course, is what the
global keyword does inside a function: use a reference to ensure that changes
to the variable inside the function also reflect outside it. The PHP manual puts it best
when it says “…when you declare a variable as global $var you are in fact
creating a reference to a global variable”. For more examples, read all about references
at <a href="http://www.php.net/manual/en/language.references.php">http://www.php.net/manual/en/language.references.php</a>.</p>
<p>And that just about concludes this tutorial. This time you’ve taken a big step towards
better software design by learning how to abstract parts of your PHP code into reusable
functions. You now know how to add flexibility to your functions by allowing them to accept
different arguments, and how to obtain one (or more) return values from them. Finally, you’ve
learned a little bit about how PHP treats variables inside and outside functions.</p>
<p>In <a href="part7.html">Part Seven</a>, I’ll be showing you how to group related
functions together into classes, and also telling you all about the cool new features
in the PHP 5 object model. You definitely don’t want to miss that one!</p>
</section>
<footer>
<p><small>Hosted on GitHub Pages — Theme by <a href="http://twitter.com/#!/michigangraham">mattgraham</a></small></p>
</footer>
</div>
<!--[if !IE]><script>fixScale(document);</script><!--<![endif]-->
</body>
</html>