<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/css" href="http://commons.oreilly.com/wiki/skins/common/feed.css?97"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
		<id>http://commons.oreilly.com/wiki/index.php?title=PHP_Cookbook/Variables&amp;action=history&amp;feed=atom</id>
		<title>PHP Cookbook/Variables - Revision history</title>
		<link rel="self" type="application/atom+xml" href="http://commons.oreilly.com/wiki/index.php?title=PHP_Cookbook/Variables&amp;action=history&amp;feed=atom"/>
		<link rel="alternate" type="text/html" href="http://commons.oreilly.com/wiki/index.php?title=PHP_Cookbook/Variables&amp;action=history"/>
		<updated>2013-06-19T07:10:45Z</updated>
		<subtitle>Revision history for this page on the wiki</subtitle>
		<generator>MediaWiki 1.11.0</generator>

	<entry>
		<id>http://commons.oreilly.com/wiki/index.php?title=PHP_Cookbook/Variables&amp;diff=7317&amp;oldid=prev</id>
		<title>Docbook2Wiki: Initial conversion from Docbook</title>
		<link rel="alternate" type="text/html" href="http://commons.oreilly.com/wiki/index.php?title=PHP_Cookbook/Variables&amp;diff=7317&amp;oldid=prev"/>
				<updated>2008-03-07T13:36:04Z</updated>
		
		<summary type="html">&lt;p&gt;Initial conversion from Docbook&lt;/p&gt;

			&lt;table style=&quot;background-color: white; color:black;&quot;&gt;
			&lt;col class='diff-marker' /&gt;
			&lt;col class='diff-content' /&gt;
			&lt;col class='diff-marker' /&gt;
			&lt;col class='diff-content' /&gt;
			&lt;tr&gt;
				&lt;td colspan='2' style=&quot;background-color: white; color:black;&quot;&gt;←Older revision&lt;/td&gt;
				&lt;td colspan='2' style=&quot;background-color: white; color:black;&quot;&gt;Revision as of 13:36, 7 March 2008&lt;/td&gt;
			&lt;/tr&gt;
		&lt;/table&gt;</summary>
		<author><name>Docbook2Wiki</name></author>	</entry>

	<entry>
		<id>http://commons.oreilly.com/wiki/index.php?title=PHP_Cookbook/Variables&amp;diff=3113&amp;oldid=prev</id>
		<title>Evanlenz: 1 revision(s)</title>
		<link rel="alternate" type="text/html" href="http://commons.oreilly.com/wiki/index.php?title=PHP_Cookbook/Variables&amp;diff=3113&amp;oldid=prev"/>
				<updated>2008-03-06T22:30:01Z</updated>
		
		<summary type="html">&lt;p&gt;1 revision(s)&lt;/p&gt;

			&lt;table style=&quot;background-color: white; color:black;&quot;&gt;
			&lt;col class='diff-marker' /&gt;
			&lt;col class='diff-content' /&gt;
			&lt;col class='diff-marker' /&gt;
			&lt;col class='diff-content' /&gt;
			&lt;tr&gt;
				&lt;td colspan='2' style=&quot;background-color: white; color:black;&quot;&gt;←Older revision&lt;/td&gt;
				&lt;td colspan='2' style=&quot;background-color: white; color:black;&quot;&gt;Revision as of 22:30, 6 March 2008&lt;/td&gt;
			&lt;/tr&gt;
		&lt;/table&gt;</summary>
		<author><name>Evanlenz</name></author>	</entry>

	<entry>
		<id>http://commons.oreilly.com/wiki/index.php?title=PHP_Cookbook/Variables&amp;diff=3112&amp;oldid=prev</id>
		<title>Docbook2Wiki: Initial conversion from Docbook</title>
		<link rel="alternate" type="text/html" href="http://commons.oreilly.com/wiki/index.php?title=PHP_Cookbook/Variables&amp;diff=3112&amp;oldid=prev"/>
				<updated>2008-03-06T22:28:45Z</updated>
		
		<summary type="html">&lt;p&gt;Initial conversion from Docbook&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;{{PHP Cookbook/TOC}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
Along with conditional logic, variables are the core of what makes computer programs powerful and flexible. If you think of a variable as a bucket with a name that holds a value, PHP lets you have plain old buckets, buckets that contain the name of other buckets, buckets with numbers or strings in them, buckets holding arrays of other buckets, buckets full of objects, and just about any other variation on that analogy you can think of.&lt;br /&gt;
&lt;br /&gt;
A variable is either set or unset. A variable with any value assigned to it, &amp;lt;tt&amp;gt;true&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;false&amp;lt;/tt&amp;gt;, empty or nonempty, is set. The function &amp;lt;tt&amp;gt;isset( )&amp;lt;/tt&amp;gt; returns &amp;lt;tt&amp;gt;true&amp;lt;/tt&amp;gt; when passed a variable that's set. The only way to turn a variable that's set into one that's unset is to call &amp;lt;tt&amp;gt;unset( )&amp;lt;/tt&amp;gt; on the variable. Scalars, arrays, and objects can all be passed to &amp;lt;tt&amp;gt;unset( )&amp;lt;/tt&amp;gt;. You can also pass &amp;lt;tt&amp;gt;unset( )&amp;lt;/tt&amp;gt; multiple variables to unset them all:&lt;br /&gt;
&lt;br /&gt;
 unset($vegetables);&lt;br /&gt;
 unset($vegetables[12]);&lt;br /&gt;
 unset($earth, $moon, $stars);&lt;br /&gt;
&lt;br /&gt;
If a variable is present in the query string of a URL, even if it has no value assigned to it, it is set. Thus:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;http://www.example.com/set.php?chimps=&amp;amp;monkeys=12&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
sets &amp;lt;tt&amp;gt;$_GET['monkeys']&amp;lt;/tt&amp;gt; to &amp;lt;tt&amp;gt;12&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;$_GET['chimps']&amp;lt;/tt&amp;gt; to the empty string.&lt;br /&gt;
&lt;br /&gt;
All unset variables are also empty. Set variables may be empty or nonempty. Empty variables have values that evaluate to &amp;lt;tt&amp;gt;false&amp;lt;/tt&amp;gt; as a boolean: the integer 0, the double 0.0, the empty string, the string &amp;quot;0&amp;quot;, the boolean &amp;lt;tt&amp;gt;false&amp;lt;/tt&amp;gt;, an array with no elements, an object with no variables or methods, and &amp;lt;tt&amp;gt;NULL&amp;lt;/tt&amp;gt;. Everything else is nonempty. This includes the string &amp;quot;00&amp;quot;, and the string &amp;quot; &amp;quot;, containing just a space character.&lt;br /&gt;
&lt;br /&gt;
Variables evaluate to either &amp;lt;tt&amp;gt;true&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;false&amp;lt;/tt&amp;gt;. The values listed earlier that evaluate to &amp;lt;tt&amp;gt;false&amp;lt;/tt&amp;gt; as a boolean are the complete set of what's &amp;lt;tt&amp;gt;false&amp;lt;/tt&amp;gt; in PHP. Every other value is &amp;lt;tt&amp;gt;true&amp;lt;/tt&amp;gt;. The distinction between empty and false is that emptiness is only possible for variables. Constants and return values from functions can be &amp;lt;tt&amp;gt;false&amp;lt;/tt&amp;gt;, but they can't be empty. For example, the following is valid because &amp;lt;tt&amp;gt;$first_name&amp;lt;/tt&amp;gt; is a variable:&lt;br /&gt;
&lt;br /&gt;
 if (empty($first_name)) { .. }&lt;br /&gt;
&lt;br /&gt;
On the other hand, these two examples return parse errors because &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; (a constant) and the return value from &amp;lt;tt&amp;gt;get_first_name( )&amp;lt;/tt&amp;gt; can't be empty:&lt;br /&gt;
&lt;br /&gt;
 if (empty(0)) { .. }&lt;br /&gt;
 if (empty(get_first_name())) { .. }&lt;br /&gt;
&lt;br /&gt;
== Avoiding == Versus = Confusion ==&lt;br /&gt;
&lt;br /&gt;
=== Problem ===&lt;br /&gt;
&lt;br /&gt;
You don't want to accidentally assign values when comparing a variable and a constant.&lt;br /&gt;
&lt;br /&gt;
=== Solution ===&lt;br /&gt;
&lt;br /&gt;
Use:&lt;br /&gt;
&lt;br /&gt;
 if (12 == $dwarves) { ... }&lt;br /&gt;
&lt;br /&gt;
instead of:&lt;br /&gt;
&lt;br /&gt;
 if ($dwarves == 12) { ... }&lt;br /&gt;
&lt;br /&gt;
Putting the constant on the left triggers a parse error with the assignment operator. In other words, PHP complains when you write:&lt;br /&gt;
&lt;br /&gt;
 if (12 = $dwarves) { ... }&lt;br /&gt;
&lt;br /&gt;
but:&lt;br /&gt;
&lt;br /&gt;
 if ($dwarves = 12) { ... }&lt;br /&gt;
&lt;br /&gt;
silently executes, assigning &amp;lt;tt&amp;gt;12&amp;lt;/tt&amp;gt; to the variable &amp;lt;tt&amp;gt;$dwarves&amp;lt;/tt&amp;gt;, and then executing the code inside the block. (&amp;lt;tt&amp;gt;$dwarves = 12&amp;lt;/tt&amp;gt; evaluates to &amp;lt;tt&amp;gt;12&amp;lt;/tt&amp;gt;, which is &amp;lt;tt&amp;gt;true&amp;lt;/tt&amp;gt;.)&lt;br /&gt;
&lt;br /&gt;
=== Discussion ===&lt;br /&gt;
&lt;br /&gt;
Putting a constant on the left side of a comparison coerces the comparison to the type of the constant. This causes problems when you are comparing an integer with a variable that could be an integer or a string. &amp;lt;tt&amp;gt;0 == $dwarves&amp;lt;/tt&amp;gt; is &amp;lt;tt&amp;gt;true&amp;lt;/tt&amp;gt; when &amp;lt;tt&amp;gt;$dwarves&amp;lt;/tt&amp;gt; is &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;, but it's also true when &amp;lt;tt&amp;gt;$dwarves&amp;lt;/tt&amp;gt; is &amp;lt;tt&amp;gt;sleepy&amp;lt;/tt&amp;gt;. Since an integer (&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) is on the left side of the comparison, PHP converts what's on the right (the string &amp;lt;tt&amp;gt;sleepy&amp;lt;/tt&amp;gt;) to an integer (&amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;) before comparing. To avoid this, use the identity operator, &amp;lt;tt&amp;gt;0 === $dwarves&amp;lt;/tt&amp;gt;, instead.&lt;br /&gt;
&lt;br /&gt;
=== See Also ===&lt;br /&gt;
&lt;br /&gt;
Documentation for &amp;lt;tt&amp;gt;=&amp;lt;/tt&amp;gt; at ''http://www.php.net/language.operators.assignment.php'' and for &amp;lt;tt&amp;gt;==&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;===&amp;lt;/tt&amp;gt; at ''http://www.php.net/manual/language.operators.comparison.php''.&lt;br /&gt;
&lt;br /&gt;
== Establishing a Default Value ==&lt;br /&gt;
&lt;br /&gt;
=== Problem ===&lt;br /&gt;
&lt;br /&gt;
You want to assign a default value to a variable that doesn't already have a value. It often happens that you want a hardcoded default value for a variable that can be overridden from form input or through an environment variable.&lt;br /&gt;
&lt;br /&gt;
=== Solution ===&lt;br /&gt;
&lt;br /&gt;
Use &amp;lt;tt&amp;gt;isset( )&amp;lt;/tt&amp;gt; to assign a default to a variable that may already have a value:&lt;br /&gt;
&lt;br /&gt;
 if (! isset($cars)) { $cars = $default_cars; }&lt;br /&gt;
&lt;br /&gt;
Use the ternary (&amp;lt;tt&amp;gt;a ? b : c&amp;lt;/tt&amp;gt;) operator to give a new variable a (possibly default) value:&lt;br /&gt;
&lt;br /&gt;
 $cars = isset($_REQUEST['cars']) ? $_REQUEST['cars'] : $default_cars;&lt;br /&gt;
&lt;br /&gt;
=== Discussion ===&lt;br /&gt;
&lt;br /&gt;
Using &amp;lt;tt&amp;gt;isset( )&amp;lt;/tt&amp;gt; is essential when assigning default values. Without it, the nondefault value can't be &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; or anything else that evaluates to &amp;lt;tt&amp;gt;false&amp;lt;/tt&amp;gt;. Consider this assignment:&lt;br /&gt;
&lt;br /&gt;
 $cars = $_REQUEST['cars'] ? $_REQUEST['cars'] : $default_cars;&lt;br /&gt;
&lt;br /&gt;
If &amp;lt;tt&amp;gt;$_REQUEST['cars']&amp;lt;/tt&amp;gt; is &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;$cars&amp;lt;/tt&amp;gt; is set to &amp;lt;tt&amp;gt;$default_cars&amp;lt;/tt&amp;gt; even though &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; may be a valid value for &amp;lt;tt&amp;gt;$cars&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
You can use an array of defaults to set multiple default values easily. The keys in the defaults array are variable names, and the values in the array are the defaults for each variable:&lt;br /&gt;
&lt;br /&gt;
 $defaults = array('emperors'  =&amp;gt; array('Rudolf II','Caligula'),&lt;br /&gt;
                   'vegetable' =&amp;gt; 'celery',&lt;br /&gt;
                   'acres'     =&amp;gt; 15);&lt;br /&gt;
 &lt;br /&gt;
 foreach ($defaults as $k =&amp;gt; $v) {&lt;br /&gt;
     if (! isset($GLOBALS[$k])) { $GLOBALS[$k] = $v; }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Because the variables are set in the global namespace, the previous code doesn't work for setting function-private defaults. To do that, use variable variables:&lt;br /&gt;
&lt;br /&gt;
 foreach ($defaults as $k =&amp;gt; $v) {&lt;br /&gt;
     if (! isset($$k)) { $$k = $v; }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
=== See Also ===&lt;br /&gt;
&lt;br /&gt;
Documentation on &amp;lt;tt&amp;gt;isset( )&amp;lt;/tt&amp;gt; at ''http://www.php.net/isset''; variable variables are discussed in [[PHP Cookbook/Variables#Creating a Dynamic Variable Name|Recipe 5.5]] and at ''http://www.php.net/language.variables.variable''.&lt;br /&gt;
&lt;br /&gt;
== Exchanging Values Without Using Temporary Variables ==&lt;br /&gt;
&lt;br /&gt;
=== Problem ===&lt;br /&gt;
&lt;br /&gt;
You want to exchange the values in two variables without using additional variables for storage.&lt;br /&gt;
&lt;br /&gt;
=== Solution ===&lt;br /&gt;
&lt;br /&gt;
To swap &amp;lt;tt&amp;gt;$a&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;$b&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 list($a,$b) = array($b,$a);&lt;br /&gt;
&lt;br /&gt;
=== Discussion ===&lt;br /&gt;
&lt;br /&gt;
PHP's &amp;lt;tt&amp;gt;list( )&amp;lt;/tt&amp;gt; language construct lets you assign values from an array to individual variables. Its counterpart on the right side of the expression, &amp;lt;tt&amp;gt;array( )&amp;lt;/tt&amp;gt; , lets you construct arrays from individual values. Assigning the array that &amp;lt;tt&amp;gt;array( )&amp;lt;/tt&amp;gt; returns to the variables in the &amp;lt;tt&amp;gt;list( )&amp;lt;/tt&amp;gt; lets you juggle the order of those values. This works with more than two values, as well:&lt;br /&gt;
&lt;br /&gt;
 list($yesterday,$today,$tomorrow) = array($today,$tomorrow,$yesterday);&lt;br /&gt;
&lt;br /&gt;
This method isn't faster than using temporary variables, so you should use it for clarity, but not speed.&lt;br /&gt;
&lt;br /&gt;
=== See Also ===&lt;br /&gt;
&lt;br /&gt;
Documentation on &amp;lt;tt&amp;gt;list( )&amp;lt;/tt&amp;gt; at ''http://www.php.net/list'' and &amp;lt;tt&amp;gt;array( )&amp;lt;/tt&amp;gt; at ''http://www.php.net/array''.&lt;br /&gt;
&lt;br /&gt;
== Creating a Dynamic Variable Name ==&lt;br /&gt;
&lt;br /&gt;
=== Problem ===&lt;br /&gt;
&lt;br /&gt;
You want to construct a variable's name dynamically. For example, you want to use variable names that match the field names from a database query.&lt;br /&gt;
&lt;br /&gt;
=== Solution ===&lt;br /&gt;
&lt;br /&gt;
Use PHP's variable variable syntax by prepending a &amp;lt;tt&amp;gt;$&amp;lt;/tt&amp;gt; to a variable whose value is the variable name you want:&lt;br /&gt;
&lt;br /&gt;
 $animal = 'turtles';&lt;br /&gt;
 $turtles = 103;&lt;br /&gt;
 print $$animal;&lt;br /&gt;
 '''103'''&lt;br /&gt;
             &lt;br /&gt;
&lt;br /&gt;
=== Discussion ===&lt;br /&gt;
&lt;br /&gt;
The previous example prints &amp;lt;tt&amp;gt;103&amp;lt;/tt&amp;gt;. Because &amp;lt;tt&amp;gt;$animal&amp;lt;/tt&amp;gt; &amp;lt;tt&amp;gt;=&amp;lt;/tt&amp;gt; &amp;lt;tt&amp;gt;'turtles',&amp;lt;/tt&amp;gt; &amp;lt;tt&amp;gt;$$animal&amp;lt;/tt&amp;gt; is &amp;lt;tt&amp;gt;$turtles&amp;lt;/tt&amp;gt;, which equals 103.&lt;br /&gt;
&lt;br /&gt;
Using curly braces, you can construct more complicated expressions that indicate variable names:&lt;br /&gt;
&lt;br /&gt;
 $stooges = array('Moe','Larry','Curly');&lt;br /&gt;
 $stooge_moe = 'Moses Horwitz';&lt;br /&gt;
 $stooge_larry = 'Louis Feinberg';&lt;br /&gt;
 $stooge_curly = 'Jerome Horwitz';&lt;br /&gt;
 &lt;br /&gt;
 foreach ($stooges as $s) {&lt;br /&gt;
   print &amp;quot;$s's real name was ${'stooge_'.strtolower($s)}.\n&amp;quot;;&lt;br /&gt;
 }&lt;br /&gt;
 '''Moe's real name was Moses Horwitz.'''&lt;br /&gt;
                '''Larry's real name was Louis Feinberg.'''&lt;br /&gt;
                '''Curly's real name was Jerome Horwitz.'''&lt;br /&gt;
             &lt;br /&gt;
&lt;br /&gt;
PHP evaluates the expression between the curly braces and uses it as a variable name. That expression can even have function calls in it, such as &amp;lt;tt&amp;gt;strtolower( )&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Variable variables are also useful when iterating through similarly named variables. Say you are querying a database table that has fields named &amp;lt;tt&amp;gt;title_1&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;title_2&amp;lt;/tt&amp;gt;, etc. If you want to check if a title matches any of those values, the easiest way is to loop through them like this:&lt;br /&gt;
&lt;br /&gt;
 for ($i = 1; $i &amp;lt;= $n; $i++) {&lt;br /&gt;
     $t = &amp;quot;title_$i&amp;quot;;&lt;br /&gt;
     if ($title == $$t) { /* match */ }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Of course, it would be more straightforward to store these values in an array, but if you are maintaining old code that uses this technique (and you can't change it), variable variables are helpful.&lt;br /&gt;
&lt;br /&gt;
The curly brace syntax is also necessary in resolving ambiguity about array elements. The variable variable &amp;lt;tt&amp;gt;$$donkeys[12]&amp;lt;/tt&amp;gt; could have two meanings. The first is &amp;quot;take what's in the 12th element of the &amp;lt;tt&amp;gt;$donkeys&amp;lt;/tt&amp;gt; array and use that as a variable name.&amp;quot; Write this as: &amp;lt;tt&amp;gt;${$donkeys[12]}&amp;lt;/tt&amp;gt;. The second is, &amp;quot;use what's in the scalar &amp;lt;tt&amp;gt;$donkeys&amp;lt;/tt&amp;gt; as an array name and look in the 12th element of that array.&amp;quot; Write this as: &amp;lt;tt&amp;gt;${$donkeys}[12]&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== See Also ===&lt;br /&gt;
&lt;br /&gt;
''http://www.php.net/language.variables.variable'' for documentation on variable variables.&lt;br /&gt;
&lt;br /&gt;
== Using Static Variables ==&lt;br /&gt;
&lt;br /&gt;
=== Problem ===&lt;br /&gt;
&lt;br /&gt;
You want a local variable to retain its value between invocations of a function.&lt;br /&gt;
&lt;br /&gt;
=== Solution ===&lt;br /&gt;
&lt;br /&gt;
Declare the variable as &amp;lt;tt&amp;gt;static&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 function track_times_called( ) {&lt;br /&gt;
     static $i = 0;&lt;br /&gt;
     $i++;&lt;br /&gt;
     return $i;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
=== Discussion ===&lt;br /&gt;
&lt;br /&gt;
Declaring a variable &amp;lt;tt&amp;gt;static&amp;lt;/tt&amp;gt; causes its value to be remembered by a function. So, if there are subsequent calls to the function, you can access the value of the saved variable. The &amp;lt;tt&amp;gt;pc_check_the_count( )&amp;lt;/tt&amp;gt; function shown in [[PHP Cookbook/Variables#phpckbk-CHP-5-EX-1|Example 5-1]] uses &amp;lt;tt&amp;gt;static&amp;lt;/tt&amp;gt; variables to keep track of the strikes and balls for a baseball batter.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;phpckbk-CHP-5-EX-1&amp;quot;&amp;gt;&lt;br /&gt;
'''Example 5-1. pc_check_the_count( )'''&lt;br /&gt;
&lt;br /&gt;
 function pc_check_the_count($pitch) {&lt;br /&gt;
     static $strikes = 0;&lt;br /&gt;
     static $balls   = 0;&lt;br /&gt;
 &lt;br /&gt;
     switch ($pitch) {&lt;br /&gt;
     case 'foul':&lt;br /&gt;
         if (2 == $strikes) break; // nothing happens if 2 strikes&lt;br /&gt;
         // otherwise, act like a strike&lt;br /&gt;
     case 'strike':&lt;br /&gt;
         $strikes++;&lt;br /&gt;
         break;&lt;br /&gt;
     case 'ball':&lt;br /&gt;
         $balls++;&lt;br /&gt;
         break;&lt;br /&gt;
     }&lt;br /&gt;
 &lt;br /&gt;
     if (3 == $strikes) {&lt;br /&gt;
         $strikes = $balls = 0;&lt;br /&gt;
         return 'strike out';&lt;br /&gt;
     }&lt;br /&gt;
     if (4 == $balls) {&lt;br /&gt;
         $strikes = $balls = 0;&lt;br /&gt;
         return 'walk';&lt;br /&gt;
     }&lt;br /&gt;
     return 'at bat';&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 $what_happened = check_the_count($pitch);&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In &amp;lt;tt&amp;gt;pc_check_the_count( )&amp;lt;/tt&amp;gt;, the logic of what happens to the batter depending on the pitch count is in the &amp;lt;tt&amp;gt;switch&amp;lt;/tt&amp;gt; statement inside the function. You can instead return the number of strikes and balls, but this requires you to place the checks for striking out, walking, and staying at the plate in multiple places in the code.&lt;br /&gt;
&lt;br /&gt;
While &amp;lt;tt&amp;gt;static&amp;lt;/tt&amp;gt; variables retain their values between function calls, they do so only during one invocation of a script. A &amp;lt;tt&amp;gt;static&amp;lt;/tt&amp;gt; variable accessed in one request doesn't keep its value for the next request to the same page.&lt;br /&gt;
&lt;br /&gt;
=== See Also ===&lt;br /&gt;
&lt;br /&gt;
Documentation on &amp;lt;tt&amp;gt;static&amp;lt;/tt&amp;gt; variables at ''http://www.php.net/language.variables.scope''.&lt;br /&gt;
&lt;br /&gt;
== Sharing Variables Between Processes ==&lt;br /&gt;
&lt;br /&gt;
=== Problem ===&lt;br /&gt;
&lt;br /&gt;
You want a way to share information between processes that provides fast access to the shared data.&lt;br /&gt;
&lt;br /&gt;
=== Solution ===&lt;br /&gt;
&lt;br /&gt;
Store the data in a shared memory segment, and guarantee exclusive access to the shared memory with a semaphore:&lt;br /&gt;
&lt;br /&gt;
 $semaphore_id = 100;&lt;br /&gt;
 $segment_id   = 200;&lt;br /&gt;
 // get a handle to the semaphore associated with the shared memory&lt;br /&gt;
 // segment we want&lt;br /&gt;
 $sem = sem_get($semaphore_id,1,0600);&lt;br /&gt;
 // ensure exclusive access to the semaphore&lt;br /&gt;
 sem_acquire($sem) or die(&amp;quot;Can't acquire semaphore&amp;quot;);&lt;br /&gt;
 // get a handle to our shared memory segment&lt;br /&gt;
 $shm = shm_attach($segment_id,16384,0600);&lt;br /&gt;
 // retrieve a value from the shared memory segment&lt;br /&gt;
 $population = shm_get_var($shm,'population');&lt;br /&gt;
 // manipulate the value&lt;br /&gt;
 $population += ($births + $immigrants - $deaths - $emigrants);&lt;br /&gt;
 // store the value back in the shared memory segment&lt;br /&gt;
 shm_put_var($shm,'population',$population);&lt;br /&gt;
 // release the handle to the shared memory segment&lt;br /&gt;
 shm_detach($shm);&lt;br /&gt;
 // release the semaphore so other processes can acquire it&lt;br /&gt;
 sem_release($sem);&lt;br /&gt;
&lt;br /&gt;
=== Discussion ===&lt;br /&gt;
&lt;br /&gt;
A shared memory segment is a slice of your machine's RAM that different processes (such as the multiple web server processes that handle requests) can access. A semaphore makes sure that the different processes don't step on each other's toes when they access the shared memory segment. Before a process can use the segment, it needs to get control of the semaphore. When it's done with the segment, it releases the semaphore for another process to grab.&lt;br /&gt;
&lt;br /&gt;
To get control of a semaphore, use &amp;lt;tt&amp;gt;sem_get( )&amp;lt;/tt&amp;gt; to find the semaphore's ID. The first argument to &amp;lt;tt&amp;gt;sem_get( )&amp;lt;/tt&amp;gt; is an integer semaphore key. You can make the key any integer you want, as long as all programs that need to access this particular semaphore use the same key. If a semaphore with the specified key doesn't already exist, it's created, the maximum number of processes that can access the semaphore is set to the second argument of &amp;lt;tt&amp;gt;sem_get( )&amp;lt;/tt&amp;gt; (in this case, &amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;), and the semaphore's permissions are set to &amp;lt;tt&amp;gt;sem_get( )&amp;lt;/tt&amp;gt;'s third argument (&amp;lt;tt&amp;gt;0600&amp;lt;/tt&amp;gt;). These permissions work just like file permissions, so &amp;lt;tt&amp;gt;0600&amp;lt;/tt&amp;gt; means that the user that created the semaphore can read it and write to it. In this context, user doesn't just mean the process that created the semaphore but any process with the same user ID. Permissions of &amp;lt;tt&amp;gt;0600&amp;lt;/tt&amp;gt; should be appropriate for most uses, in which web server processes run as the same user.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;sem_get( )&amp;lt;/tt&amp;gt; returns an identifier that points to the underlying system semaphore. Use this ID to gain control of the semaphore with &amp;lt;tt&amp;gt;sem_acquire( )&amp;lt;/tt&amp;gt; . This function waits until the semaphore can be acquired (perhaps waiting until other processes release the semaphore) and then returns &amp;lt;tt&amp;gt;true&amp;lt;/tt&amp;gt;. It returns &amp;lt;tt&amp;gt;false&amp;lt;/tt&amp;gt; on error. Errors include invalid permissions or not enough memory to create the semaphore. Once the semaphore is acquired, you can read from the shared memory segment.&lt;br /&gt;
&lt;br /&gt;
First, establish a link to the particular shared memory segment with &amp;lt;tt&amp;gt;shm_attach( )&amp;lt;/tt&amp;gt; . As with &amp;lt;tt&amp;gt;sem_get( )&amp;lt;/tt&amp;gt;, the first argument to &amp;lt;tt&amp;gt;shm_attach( )&amp;lt;/tt&amp;gt; is an integer key. This time, however it identifies the desired segment, not the semaphore. If the segment with the specified key doesn't exist, the other arguments create it. The second argument (&amp;lt;tt&amp;gt;16384&amp;lt;/tt&amp;gt;) is the size in bytes of the segment, and the last argument (&amp;lt;tt&amp;gt;0600&amp;lt;/tt&amp;gt;) are the permissions on the segment. &amp;lt;tt&amp;gt;shm_attach(200,16384,0600)&amp;lt;/tt&amp;gt; creates a 16K shared memory segment that can be read from and written to only by the user who created it. The function returns the identifier you need to read from and write to the shared memory segment.&lt;br /&gt;
&lt;br /&gt;
After attaching to the segment, pull variables out of it with &amp;lt;tt&amp;gt;shm_get_var($shm, 'population')&amp;lt;/tt&amp;gt; . This looks in the shared memory segment identified by &amp;lt;tt&amp;gt;$shm&amp;lt;/tt&amp;gt; and retrieves the value of the variable called &amp;lt;tt&amp;gt;population&amp;lt;/tt&amp;gt;. You can store any type of variable in shared memory. Once the variable is retrieved, it can be operated on like other variables. &amp;lt;tt&amp;gt;shm_put_var($shm,'population',$population)&amp;lt;/tt&amp;gt; puts the value of &amp;lt;tt&amp;gt;$population&amp;lt;/tt&amp;gt; back into the shared memory segment as a variable called &amp;lt;tt&amp;gt;population&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
You're now done with the shared memory statement. Detach from it with &amp;lt;tt&amp;gt;shm_detach( )&amp;lt;/tt&amp;gt; and release the semaphore with &amp;lt;tt&amp;gt;sem_release( )&amp;lt;/tt&amp;gt; so another process can use it.&lt;br /&gt;
&lt;br /&gt;
Shared memory's chief advantage is that it's fast. But since it's stored in RAM, it can't hold too much data, and it doesn't persist when a machine is rebooted (unless you take special steps to write the information in shared memory to disk before shutdown and then load it into memory again at startup). Also, shared memory is not available on Windows.&lt;br /&gt;
&lt;br /&gt;
=== See Also ===&lt;br /&gt;
&lt;br /&gt;
[[PHP Cookbook/Web Basics#Program: Abusive User Checker|Recipe 8.28]] includes a program that uses shared memory; documentation on shared memory and semaphore functions at ''http://www.php.net/sem''.&lt;br /&gt;
&lt;br /&gt;
== Encapsulating Complex Data Types as a String ==&lt;br /&gt;
&lt;br /&gt;
=== Problem ===&lt;br /&gt;
&lt;br /&gt;
You want a string representation of an array or object for storage in a file or database. This string should be easily reconstitutable into the original array or object.&lt;br /&gt;
&lt;br /&gt;
=== Solution ===&lt;br /&gt;
&lt;br /&gt;
Use &amp;lt;tt&amp;gt;serialize( )&amp;lt;/tt&amp;gt; to encode variables and their values into a textual form:&lt;br /&gt;
&lt;br /&gt;
 $pantry = array('sugar' =&amp;gt; '2 lbs.','butter' =&amp;gt; '3 sticks');&lt;br /&gt;
 $fp = fopen('/tmp/pantry','w') or die (&amp;quot;Can't open pantry&amp;quot;);&lt;br /&gt;
 fputs($fp,serialize($pantry));&lt;br /&gt;
 fclose($fp);&lt;br /&gt;
&lt;br /&gt;
To recreate the variables, use &amp;lt;tt&amp;gt;unserialize( )&amp;lt;/tt&amp;gt; :&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;$new_pantry = unserialize(join('',file('/tmp/pantry')));&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Discussion ===&lt;br /&gt;
&lt;br /&gt;
The serialized string that is reconstituted into &amp;lt;tt&amp;gt;$pantry&amp;lt;/tt&amp;gt; looks like:&lt;br /&gt;
&lt;br /&gt;
 a:2:{s:5:&amp;quot;sugar&amp;quot;;s:6:&amp;quot;2 lbs.&amp;quot;;s:6:&amp;quot;butter&amp;quot;;s:8:&amp;quot;3 sticks&amp;quot;;}&lt;br /&gt;
&lt;br /&gt;
This stores enough information to bring back all the values in the array, but the variable name itself isn't stored in the serialized representation.&lt;br /&gt;
&lt;br /&gt;
When passing serialized data from page to page in a URL, call &amp;lt;tt&amp;gt;urlencode( )&amp;lt;/tt&amp;gt; on the data to make sure URL metacharacters are escaped in it:&lt;br /&gt;
&lt;br /&gt;
 $shopping_cart = array('Poppy Seed Bagel' =&amp;gt; 2,&lt;br /&gt;
                        'Plain Bagel' =&amp;gt; 1,&lt;br /&gt;
                        'Lox' =&amp;gt; 4);&lt;br /&gt;
 print '&amp;lt;a href=&amp;quot;next.php?cart='.urlencode(serialize($shopping_cart)).'&amp;quot;&amp;gt;Next&amp;lt;/a&amp;gt;';&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;magic_quotes_gpc&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;magic_quotes_runtime&amp;lt;/tt&amp;gt; configuration settings affect data being passed to &amp;lt;tt&amp;gt;unserialize( )&amp;lt;/tt&amp;gt;. If &amp;lt;tt&amp;gt;magic_quotes_gpc&amp;lt;/tt&amp;gt; is &amp;lt;tt&amp;gt;on&amp;lt;/tt&amp;gt;, data passed in URLs, POST variables, or cookies must be processed with &amp;lt;tt&amp;gt;stripslashes( )&amp;lt;/tt&amp;gt; before it's unserialized:&lt;br /&gt;
&lt;br /&gt;
 $new_cart = unserialize(stripslashes($cart)); // if magic_quotes_gpc is on&lt;br /&gt;
 $new_cart = unserialize($cart);               // if magic_quotes_gpc is off&lt;br /&gt;
&lt;br /&gt;
If &amp;lt;tt&amp;gt;magic_quotes_runtime&amp;lt;/tt&amp;gt; is &amp;lt;tt&amp;gt;on&amp;lt;/tt&amp;gt;, serialized data stored in a file must be processed with &amp;lt;tt&amp;gt;addslashes( )&amp;lt;/tt&amp;gt; when writing and &amp;lt;tt&amp;gt;stripslashes()&amp;lt;/tt&amp;gt; when reading:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;$fp = fopen('/tmp/cart,'w');&lt;br /&gt;
fputs($fp,addslashes(serialize($a)));&lt;br /&gt;
fclose($fp);&lt;br /&gt;
&lt;br /&gt;
// if magic_quotes_runtime is on&lt;br /&gt;
$new_cart = unserialize(stripslashes(join('',file('/tmp/cart'))));&lt;br /&gt;
// if magic_quotes_runtime is off&lt;br /&gt;
$new_cart = unserialize(join('',file('/tmp/cart')));&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Serialized data read from a database must also be processed with &amp;lt;tt&amp;gt;stripslashes( )&amp;lt;/tt&amp;gt; when &amp;lt;tt&amp;gt;magic_quotes_runtime&amp;lt;/tt&amp;gt; is &amp;lt;tt&amp;gt;on&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 mysql_query(&lt;br /&gt;
     &amp;quot;INSERT INTO cart (id,data) VALUES (1,'&amp;quot;.addslashes(serialize($cart)).&amp;quot;')&amp;quot;);&lt;br /&gt;
 &lt;br /&gt;
 $r = mysql_query('SELECT data FROM cart WHERE id = 1');&lt;br /&gt;
 $ob = mysql_fetch_object($r);&lt;br /&gt;
 // if magic_quotes_runtime is on&lt;br /&gt;
 $new_cart = unserialize(stripslashes($ob-&amp;gt;data));&lt;br /&gt;
 // if magic_quotes_runtime is off&lt;br /&gt;
 $new_cart = unserialize($ob-&amp;gt;data);&lt;br /&gt;
&lt;br /&gt;
Serialized data going into a database always needs to have &amp;lt;tt&amp;gt;addslashes( )&amp;lt;/tt&amp;gt; called on it (or another database-appropriate escaping method) to ensure it's saved properly.&lt;br /&gt;
&lt;br /&gt;
=== See Also ===&lt;br /&gt;
&lt;br /&gt;
[[PHP Cookbook/Database Access#Repeating Queries Efficiently|Recipe 10.8]] for information on escaping data for a database.&lt;br /&gt;
&lt;br /&gt;
== Dumping Variable Contents as Strings ==&lt;br /&gt;
&lt;br /&gt;
=== Problem ===&lt;br /&gt;
&lt;br /&gt;
You want to inspect the values stored in a variable. It may be a complicated nested array or object, so you can't just print it out or loop through it.&lt;br /&gt;
&lt;br /&gt;
=== Solution ===&lt;br /&gt;
&lt;br /&gt;
Use &amp;lt;tt&amp;gt;print_r( )&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;var_dump( )&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 $array = array(&amp;quot;name&amp;quot; =&amp;gt; &amp;quot;frank&amp;quot;, 12, array(3, 4));&lt;br /&gt;
 &lt;br /&gt;
 print_r($array);&lt;br /&gt;
 '''Array'''&lt;br /&gt;
                '''('''&lt;br /&gt;
                '''    [name] =&amp;gt; frank'''&lt;br /&gt;
                '''    [0] =&amp;gt; 12'''&lt;br /&gt;
                '''    [1] =&amp;gt; Array'''&lt;br /&gt;
                '''        ('''&lt;br /&gt;
                '''            [0] =&amp;gt; 3'''&lt;br /&gt;
                '''            [1] =&amp;gt; 4'''&lt;br /&gt;
                '''        )'''&lt;br /&gt;
                ''')'''&lt;br /&gt;
 var_dump($array);&lt;br /&gt;
 '''array(3) {'''&lt;br /&gt;
                '''  [&amp;quot;name&amp;quot;]=&amp;gt;'''&lt;br /&gt;
                '''  string(5) &amp;quot;frank&amp;quot;'''&lt;br /&gt;
                '''  [0]=&amp;gt;'''&lt;br /&gt;
                '''  int(12)'''&lt;br /&gt;
                '''  [1]=&amp;gt;'''&lt;br /&gt;
                '''  array(2) {'''&lt;br /&gt;
                '''    [0]=&amp;gt;'''&lt;br /&gt;
                '''    int(3)'''&lt;br /&gt;
                '''    [1]=&amp;gt;'''&lt;br /&gt;
                '''    int(4)'''&lt;br /&gt;
                '''  }'''&lt;br /&gt;
                '''}'''&lt;br /&gt;
             &lt;br /&gt;
&lt;br /&gt;
=== Discussion ===&lt;br /&gt;
&lt;br /&gt;
The output of &amp;lt;tt&amp;gt;print_r( )&amp;lt;/tt&amp;gt; is more concise and easier to read. The output of &amp;lt;tt&amp;gt;var_dump( )&amp;lt;/tt&amp;gt;, however, gives data types and lengths for each variable.&lt;br /&gt;
&lt;br /&gt;
Since these functions recursively work their way through variables, if you have references within a variable pointing back to the variable itself, you can end up with an infinite loop. Both functions stop themselves from printing variable information forever, though. Once &amp;lt;tt&amp;gt;print_r( )&amp;lt;/tt&amp;gt; has seen a variable once, it prints &amp;lt;tt&amp;gt;*RECURSION*&amp;lt;/tt&amp;gt; instead of printing information about the variable again and continues iterating through the rest of the information it has to print. When &amp;lt;tt&amp;gt;var_dump( )&amp;lt;/tt&amp;gt; sees a variable more than three times, it throws a fatal error and ends script execution. Consider the arrays &amp;lt;tt&amp;gt;$user_1&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;$user_2&amp;lt;/tt&amp;gt;, which reference each other through their &amp;lt;tt&amp;gt;friend&amp;lt;/tt&amp;gt; elements:&lt;br /&gt;
&lt;br /&gt;
 $user_1 = array('name' =&amp;gt; 'Max Bialystock',&lt;br /&gt;
                 'username' =&amp;gt; 'max');&lt;br /&gt;
 &lt;br /&gt;
 $user_2 = array('name' =&amp;gt; 'Leo Bloom',&lt;br /&gt;
                 'username' =&amp;gt; 'leo');&lt;br /&gt;
 &lt;br /&gt;
 // Max and Leo are friends&lt;br /&gt;
 $user_2['friend'] = &amp;amp;$user_1;&lt;br /&gt;
 $user_1['friend'] = &amp;amp;$user_2;&lt;br /&gt;
 &lt;br /&gt;
 // Max and Leo have jobs&lt;br /&gt;
 $user_1['job'] = 'Swindler';&lt;br /&gt;
 $user_2['job'] = 'Accountant';&lt;br /&gt;
&lt;br /&gt;
The output of &amp;lt;tt&amp;gt;print_r($user_2)&amp;lt;/tt&amp;gt; is:&lt;br /&gt;
&lt;br /&gt;
 Array&lt;br /&gt;
 (&lt;br /&gt;
     [name] =&amp;gt; Leo Bloom&lt;br /&gt;
     [username] =&amp;gt; leo&lt;br /&gt;
     [friend] =&amp;gt; Array&lt;br /&gt;
         (&lt;br /&gt;
             [name] =&amp;gt; Max Bialystock&lt;br /&gt;
             [username] =&amp;gt; max&lt;br /&gt;
             [friend] =&amp;gt; Array&lt;br /&gt;
                 (&lt;br /&gt;
                     [name] =&amp;gt; Leo Bloom&lt;br /&gt;
                     [username] =&amp;gt; leo&lt;br /&gt;
                     [friend] =&amp;gt; Array&lt;br /&gt;
  *RECURSION*&lt;br /&gt;
                     [job] =&amp;gt; Accountant&lt;br /&gt;
                 )&lt;br /&gt;
 &lt;br /&gt;
             [job] =&amp;gt; Swindler&lt;br /&gt;
         )&lt;br /&gt;
 &lt;br /&gt;
     [job] =&amp;gt; Accountant&lt;br /&gt;
 )&lt;br /&gt;
&lt;br /&gt;
When &amp;lt;tt&amp;gt;print_r( )&amp;lt;/tt&amp;gt; sees the reference to &amp;lt;tt&amp;gt;$user_1&amp;lt;/tt&amp;gt; the second time, it prints &amp;lt;tt&amp;gt;*RECURSION*&amp;lt;/tt&amp;gt; instead of descending into the array. It then continues on its way, printing the remaining elements of &amp;lt;tt&amp;gt;$user_1&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;$user_2&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Confronted with recursion, &amp;lt;tt&amp;gt;var_dump( )&amp;lt;/tt&amp;gt; behaves differently:&lt;br /&gt;
&lt;br /&gt;
 array(4) {&lt;br /&gt;
   [&amp;quot;name&amp;quot;]=&amp;gt;&lt;br /&gt;
   string(9) &amp;quot;Leo Bloom&amp;quot;&lt;br /&gt;
   [&amp;quot;username&amp;quot;]=&amp;gt;&lt;br /&gt;
   string(3) &amp;quot;leo&amp;quot;&lt;br /&gt;
   [&amp;quot;friend&amp;quot;]=&amp;gt;&lt;br /&gt;
   &amp;amp;array(4) {&lt;br /&gt;
     [&amp;quot;name&amp;quot;]=&amp;gt;&lt;br /&gt;
     string(14) &amp;quot;Max Bialystock&amp;quot;&lt;br /&gt;
     [&amp;quot;username&amp;quot;]=&amp;gt;&lt;br /&gt;
     string(3) &amp;quot;max&amp;quot;&lt;br /&gt;
     [&amp;quot;friend&amp;quot;]=&amp;gt;&lt;br /&gt;
     &amp;amp;array(4) {&lt;br /&gt;
       [&amp;quot;name&amp;quot;]=&amp;gt;&lt;br /&gt;
       string(9) &amp;quot;Leo Bloom&amp;quot;&lt;br /&gt;
       [&amp;quot;username&amp;quot;]=&amp;gt;&lt;br /&gt;
       string(3) &amp;quot;leo&amp;quot;&lt;br /&gt;
       [&amp;quot;friend&amp;quot;]=&amp;gt;&lt;br /&gt;
       &amp;amp;array(4) {&lt;br /&gt;
         [&amp;quot;name&amp;quot;]=&amp;gt;&lt;br /&gt;
         string(14) &amp;quot;Max Bialystock&amp;quot;&lt;br /&gt;
         [&amp;quot;username&amp;quot;]=&amp;gt;&lt;br /&gt;
         string(3) &amp;quot;max&amp;quot;&lt;br /&gt;
         [&amp;quot;friend&amp;quot;]=&amp;gt;&lt;br /&gt;
         &amp;amp;array(4) {&lt;br /&gt;
           [&amp;quot;name&amp;quot;]=&amp;gt;&lt;br /&gt;
           string(9) &amp;quot;Leo Bloom&amp;quot;&lt;br /&gt;
           [&amp;quot;username&amp;quot;]=&amp;gt;&lt;br /&gt;
           string(3) &amp;quot;leo&amp;quot;&lt;br /&gt;
           [&amp;quot;friend&amp;quot;]=&amp;gt;&lt;br /&gt;
           &amp;amp;array(4) {&lt;br /&gt;
             [&amp;quot;name&amp;quot;]=&amp;gt;&lt;br /&gt;
             string(14) &amp;quot;Max Bialystock&amp;quot;&lt;br /&gt;
             [&amp;quot;username&amp;quot;]=&amp;gt;&lt;br /&gt;
             string(3) &amp;quot;max&amp;quot;&lt;br /&gt;
             [&amp;quot;friend&amp;quot;]=&amp;gt;&lt;br /&gt;
             &amp;amp;array(4) {&lt;br /&gt;
               [&amp;quot;name&amp;quot;]=&amp;gt;&lt;br /&gt;
               string(9) &amp;quot;Leo Bloom&amp;quot;&lt;br /&gt;
               [&amp;quot;username&amp;quot;]=&amp;gt;&lt;br /&gt;
               string(3) &amp;quot;leo&amp;quot;&lt;br /&gt;
               [&amp;quot;friend&amp;quot;]=&amp;gt;&lt;br /&gt;
               &amp;amp;array(4) {&lt;br /&gt;
 &amp;amp;lt;br /&amp;gt;&lt;br /&gt;
 &amp;amp;lt;b&amp;gt;Fatal error&amp;amp;lt;/b&amp;gt;:  Nesting level too deep - recursive dependency? in &lt;br /&gt;
 &amp;amp;lt;b&amp;gt;var-dump.php&amp;amp;lt;/b&amp;gt; on line &amp;amp;lt;b&amp;gt;15&amp;amp;lt;/b&amp;gt;&amp;amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It's not until the fourth appearance of the reference to &amp;lt;tt&amp;gt;$user_1&amp;lt;/tt&amp;gt; that &amp;lt;tt&amp;gt;var_dump( )&amp;lt;/tt&amp;gt; stops recursing. When it does, it throws a fatal error, and no more variable dumping (or script execution) occurs.&lt;br /&gt;
&lt;br /&gt;
Even though &amp;lt;tt&amp;gt;print_r( )&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;var_dump( )&amp;lt;/tt&amp;gt; print their results instead of returning them, you can capture the data without printing it using output buffering:&lt;br /&gt;
&lt;br /&gt;
 ob_start();&lt;br /&gt;
 var_dump($user);&lt;br /&gt;
 $dump = ob_get_contents();&lt;br /&gt;
 ob_end_clean();&lt;br /&gt;
&lt;br /&gt;
This puts the results of &amp;lt;tt&amp;gt;var_dump($user)&amp;lt;/tt&amp;gt; in &amp;lt;tt&amp;gt;$dump&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== See Also ===&lt;br /&gt;
&lt;br /&gt;
Output buffering is discussed in [[PHP Cookbook/Web Basics#Buffering Output to the Browser|Recipe 8.13]]; error handling with PEAR's DB module, shown in [[PHP Cookbook/Database Access#Finding the Number of Rows Returned by a Query|Recipe 10.9]], uses output buffering with &amp;lt;tt&amp;gt;print_r( )&amp;lt;/tt&amp;gt; to save error messages; documentation on &amp;lt;tt&amp;gt;print_r( )&amp;lt;/tt&amp;gt; at ''http://www.php.net/print-r'' and &amp;lt;tt&amp;gt;var_dump( )&amp;lt;/tt&amp;gt; at ''http://www.php.net/var-dump'' .&lt;/div&gt;</summary>
		<author><name>Docbook2Wiki</name></author>	</entry>

	</feed>