jeroen Sat May 19 13:45:34 2001 EDT Modified files: /phpdoc/en/language types.xml Log: - added note about 'mixed' type - added boolean syntax, and some examples - changed float to double as much as possible - re-sectionized integer. added note about integer division, notes about integer-overflow (== type juggling in fact) - Noted that behaviour of converting to int is undefined in cases other than boolean and string. - Completely revised arrays (I skipped string for now) BTW: Not totally ready yet, but ready enough to include. It is properly defined, only examples and more explaination etc could be useful. - Removed ++ and -- operator for strings. It is at best very complex how it works, at worst buggy. Though in certain cases it can be useful, it will return with proper definition. - Noted (in comment for now) that copying arrays works strange when there are references to some elements. - minor layout-improvements - typo's
Index: phpdoc/en/language/types.xml diff -u phpdoc/en/language/types.xml:1.24 phpdoc/en/language/types.xml:1.25 --- phpdoc/en/language/types.xml:1.24 Thu May 17 02:25:32 2001 +++ phpdoc/en/language/types.xml Sat May 19 13:45:31 2001 @@ -39,9 +39,7 @@ </listitem> </itemizedlist> - </para> - <para> Two compound types: <itemizedlist> @@ -59,10 +57,7 @@ </listitem> </itemizedlist> - </para> - - <para> And finally two special types: <itemizedlist> @@ -81,6 +76,25 @@ </itemizedlist> </para> + + <note> + <simpara> + In this manual you'll often find <literal>mixed</literal> parameters. + This pseudo-type + indicates multiple possiblities for that parameter. + </simpara> + <!-- + + Just an idea, maybe useful for some func-defs? + (at least it is for the operator-defs) + + <simpara> + In parameter definitions you can also encouter the 'number' pseudo-type, + that indicates a parameter that is either <type>integer</type> or + <type>double</type>. + </simpara> + --> + </note> <simpara> @@ -107,44 +121,75 @@ <sect1 id="language.types.boolean"> <title>Booleans</title> - <simpara> - This is the simpelest type. A <type>boolean</type> expresses a - truth value. It can be either TRUE or FALSE. - </simpara> - <simpara> - You can use the special case-insensitive constants 'TRUE' and - 'FALSE' to specify a <type>boolean</type> value. Usually you - use some kind of <link linkend="language.operators">operator</link> - which returns a <type>boolean</type> value, and then pass it - on to a <link linkend="control-structures">control - structure</link>. + This is the easiest type. A <type>boolean</type> expresses a + truth value. It can be either true or + false. </simpara> - - <!-- TODO: example of this --> - - <!-- TODO: example to show that if ( expr == TRUE ) is not really - necessary... (i've seen this construct numerous times) - --> - <!-- TODO: how others vars are converted to boolean --> - <note> <simpara> - The boolean-type was introduced in PHP 4 + The boolean-type was introduced in PHP 4. </simpara> </note> - + + <sect2 id="language.types.boolean.syntax"> + <title>Syntax</title> + <para> + To specify a boolean-literal, use either the keyword <literal>TRUE</literal> + or <literal>FALSE</literal>. Both are case-insensitive. + <!-- technically they are just constants --> + <informalexample> + <programlisting role="php"> +$foo = True; // assign the value TRUE to $foo + </programlisting> + </informalexample> + </para> + <para> + Usually you + use some kind of <link linkend="language.operators">operator</link> + which returns a <type>boolean</type> value, and then pass it + on to a <link linkend="control-structures">control + structure</link>. + <informalexample> + <programlisting role="php"> +if ($action == "show_version") // == is an <link +linkend="language.operators">operator</link> which returns a <type>boolean</type> +{ + echo "The version is 1.23"; +} + +// this is not necessary: +if ($show_separators == true) +{ + echo "<hr>\n"; +} + +// because you can simply type this: +if ($show_separators) +{ + echo "<hr>\n"; +} + </programlisting> + </informalexample> + </para> + </sect2> + <sect2 id="language.types.boolean.casting"> <title>Converting to boolean</title> + <simpara> + To explicitely convert a value to <type>boolean</type>, use either + the <literal>(bool)</literal> or the <literal>(boolean)</literal> cast. + However, in most cases you do not need to use the cast, since a value + will be autmatically converted if an operator, function or + control-structure requires a <type>boolean</type>-argument. + </simpara> <simpara> - See <link linkend="language.types.type-juggling">type-juggling</link> - for general information about converting. + See also <link linkend="language.types.type-juggling">type-juggling</link>. </simpara> <para> When converting to <type>boolean</type>, the following values - are considered FALSE: + are considered <literal>FALSE</literal>: <itemizedlist> <listitem> @@ -156,7 +201,7 @@ > 0 (zero) </simpara> </listitem> <listitem> - <simpara>the <link linkend="language.types.double">float</link> + <simpara>the <link linkend="language.types.double">double</link> 0.0 (zero) </simpara> </listitem> <listitem> @@ -180,63 +225,143 @@ </listitem> </itemizedlist> - Every other value is considered TRUE (including any + Every other value is considered <literal>TRUE</literal> (including any <link linkend="language.types.resource">resource</link>). - <warning><simpara>-1 is considered TRUE!</simpara></warning> - <!-- and/or a few examples, for the people only looking at - the examples... </XXX> --> + <warning> + <simpara> + <literal>-1</literal> is considered + <literal>TRUE</literal>, like any other non-zero (whether negative + or positive) number! + </simpara> + </warning> + <!-- TODO: add a few examples, for the people only looking at + the examples... --> </para> - </sect2> </sect1> <sect1 id="language.types.integer"> - <title>Integers</title> - <para> - Integers can be specified using any of the following syntaxes: - <informalexample> - <programlisting role="php"> + <title>Integers</title> + + <simpara> + An <type>integer</type> is a number of the set + Z = {..., -2, -1, 0, 1, 2, ...}. + </simpara> + + <para> + See also: + <link linkend="ref.gmp">Arbitrary precision integers</link> and + <link linkend="language.types.double">Floating point numbers</link> + </para> + + <sect2 id="language.types.integer.syntax"> + <title>Syntax</title> + <simpara> + Integers can be specified in decimal (10-based), hexadecimal (16-based) + or octal (8-based) notation, optionally preceded by a sign (- or +). + </simpara> + <para> + If you use the octal notation, you must precede the number with a + <literal>0</literal> (zero), to use hexadecimal notation precede + the number with <literal>0x</literal>. + <example> + <title>Integer literals</title> + <programlisting role="php"> $a = 1234; # decimal number $a = -123; # a negative number $a = 0123; # octal number (equivalent to 83 decimal) -$a = 0x12; # hexadecimal number (equivalent to 18 decimal) - </programlisting> - </informalexample> - The size of an integer is platform-dependent, although a - maximum value of about 2 billion is the usual value - (that's 32 bits signed). - </para> +$a = 0x1A; # hexadecimal number (equivalent to 26 decimal) + </programlisting> + </example> + <!-- + + decimal : [1-9][0-9]* + | 0 + + hexadecimal : 0[xX][0-9a-fA-F]+ + + octal : 0[0-7]+ + + integer : [+-]?decimal + | [+-]?hexadecimal + | [+-]?octal + + --> + The size of an integer is platform-dependent, although a + maximum value of about two billion is the usual value + (that's 32 bits signed). + </para> + <note><!-- or warning? --> + <simpara> + In PHP there is no such thing as integer-division. <literal>1/2</literal> + yields the <type>double</type> <literal>0.5</literal>. <!-- See + ??? for more information. (with the operators, or with type-jug) --> + </simpara> + </note> + </sect2> <sect2 id="language.types.integer.overflow"> <title>Integer overflow</title> <para> - Because of the flexible type-juggling, a number - is autmatically converted to float when it is about - to overflow. + If you specify a number beyond the bounds of the <type>integer</type>-type, + it will be interpreted as a <type>double</type> instead. + <informalexample> + <programlisting role="php"> +$large_number = 2147483647; +var_dump($large_number); +// output: int(2147483647) +$large_number = 2147483648; +var_dump($large_number); +// output: float(2147483648) <!-- + +php is inconsistent here... +vardump says float, gettype says double + +--> + </programlisting> + </informalexample> + Furthermore, if some function or operator yields a number that is beyond + the boundaries of <type>integer</type>, it will also + be automatically converted to + <type>double</type>. + <informalexample> + <programlisting role="php"> +$million = 1000000; +$large_number = 50000 * $million; +var_dump($large_number); +// output: float(50000000000) + </programlisting> + </informalexample> </para> </sect2> <sect2 id="language.types.integer.casting"> <title>Converting to integer</title> + <simpara> + To explicitely convert a value to <type>integer</type>, use either + the <literal>(int)</literal> or the <literal>(integer)</literal> cast. + However, in most cases you do not need to use the cast, since a value + will be autmatically converted if an operator, function or + control-structure requires a <type>boolean</type>-argument. + </simpara> <simpara> - See <link linkend="language.types.type-juggling">type-juggling</link> for - general information about converting. + See also <link linkend="language.types.type-juggling">type-juggling</link>. </simpara> <sect3 id="language.types.integer.casting.from-boolean"> <title>From <link linkend="language.types.boolean" >booleans</link></title> <simpara> - <link linkend="language.types.boolean">False</link> will yield - 0 (zero), and <link linkend="language.types.boolean">True</link> - will yield 1 (one). + <literal>FALSE</literal> will yield + <literal>0</literal> (zero), and <literal>TRUE</literal> + will yield <literal>1</literal> (one). </simpara> </sect3> - <sect3 id="language.types.integer.casting.from-float"> + <sect3 id="language.types.integer.casting.from-double"> <title>From floating point numbers</title> <simpara> When converting from float to integer, the number will @@ -249,20 +374,18 @@ (usually <literal>+/- 2.15e+9 = 2^31</literal>), the result is undefined, since the float hasn't got enough precision to give an exact integer result. - <warning> - <simpara> - No warning, not even a notice will be issued in this - case! - </simpara> - </warning> + No warning, not even a notice will be issued in this + case! </para> <warning><para> Never cast an unknown fraction to <type>integer</type>, as this can sometimes lead to unexpected results. - <informalexample><programlisting role="php"> + <informalexample> + <programlisting role="php"> echo (int) ( (0.1+0.7) * 10 ); // echo's 7! - </programlisting></informalexample> + </programlisting> + </informalexample> See for more information the <link linkend="warn.float-precision">warning @@ -276,26 +399,43 @@ See <link linkend="language.types.string.conversion">String conversion</link> </simpara> + </sect3> - <para> - See also: - <link linkend="ref.gmp">Arbitrary precision integers</link> and - <link linkend="language.types.double">Floating point numbers</link> - </para> + <sect3 id="language.types.integer.casting.from-other"> + <title>From other types</title> + <para> + Behaviour of converting to integer is undefined for other + types. Currently, the behaviour is the same as if + the value was first <link linkend="language.types.boolean.casting" + >converted to boolean</link>. + <caution> + <simpara> + However, do <emphasis>not</emphasis> + relay on this behaviour, as it can change without notice. + </simpara> + </caution> + </para> + <!-- + + IMO, it would more sense as (int) $arr returned the + number of elements in $arr. This won't break anything, + since this behaviour was never defined before, and + (bool)(int) $arr will still behave the same. + + --> </sect3> + </sect2> </sect1> <sect1 id="language.types.double"> <title>Floating point numbers</title> <para> - Floating point numbers (aka "doubles" or "real numbers") can be + Floating point numbers (aka "doubles", "floats" or "real numbers") can be specified using any of the following syntaxes: - <informalexample> - <programlisting role="php"> + <synopsis> $a = 1.234; $a = 1.2e3; $a = 7E-10; - </programlisting> - </informalexample> + </synopsis> <!-- LNUM [0-9]+ @@ -697,18 +837,398 @@ <sect1 id="language.types.array"> <title>Arrays</title> + <para> + An array in PHP is actually an ordered map. A map is a type that + maps <emphasis>values</emphasis> to <emphasis>keys</emphasis>. + This type is optimized in several ways, + so you can use it as a real array, or a list (vector), + hashtable (which is an implementation of a map), + dictionary, <!-- is a map --> + collection, + stack, queue and probably more. Because you can have another + PHP-array as a value, you can also quite easily simulate + trees. + </para> <para> - Arrays actually act like both hash tables (associative arrays) and - indexed arrays (vectors). + Explaination of those structures is beyond the scope of this manual, + but you'll find at least one example for each of those structures. + For more information about those structures, buy a good book about + datastructures. + <!-- like goodrich&tamassia: datastructures and algorithmes. + Only, the subtitle is: in Java, and it's quite academic too --> </para> + + <sect2 id="language.types.array.syntax"> + <title>Syntax</title> + + <sect3 id="language.types.array.syntax.array-func"> + <title>Specifying with <function>array</function></title> + <para> + An <type>array</type> can be created by the <function>array</function> + language-construct. It takes a certain number of comma-separated + <literal><replaceable>key</replaceable> => <replaceable + >value</replaceable></literal> + pairs. + </para> + <para> + A <varname>key</varname> is either a nonnegative <type>integer</type> + <!-- + + Negative integers are also allowed, however, IMO it's best to not + document that, or even disencourage it. + + Why? + + First, because it is very tricky. But the real reason is that the key + '-1' will be interpreted as a string, and not as a integer. Therefore, + the usage + + "the -1'st value of \$arr is $arr[-1]" is ambigious. By the way, + it results in a parse-error anyway, which is another argument for + not documenting it. + + -Jeroen + + --> + or a <type>string</type>. + If a key is the standard representation of a non-negative + <type>integer</type>, it will + be interpreted as such (i.e. <literal>'8'</literal> will be interpreted + as <literal>8</literal>, while + <literal>'08'</literal> will be interpreted as <literal>'08'</literal>). + </para> + <para> + A value can be anything. + </para> + <formalpara id="language.types.array.omit-key"> + <title>Omitting keys</title> + <para> + If you omit a key, the maximum of the integer-indices is taken, and + the new key will be that maximum + 1. If no integer-indices yet + exist, the key will be <literal>0</literal> (zero). If you specify a key + that already has a value assigned to, that key will be overwritten. + </para> + </formalpara> + + <para> + <synopsis> +array( <optional> <replaceable>key</replaceable> => </optional> <replaceable +>value</replaceable> + , ... + ) +// <replaceable>key</replaceable> is either <type>string</type + > or nonnegative <type>integer</type> +// <replaceable>value</replaceable> can be anything + </synopsis> + </para> + </sect3> + + <sect3 id="language.types.array.syntax.modifying"> + <title>Creating/modifying with square-bracket syntax</title> + <para> + You can also modify an existing array, by explicitely setting + values. + </para> + <para> + This is done by assigning values to the array while specifying the + key in brackets. You can also + omit the key, + add an empty pair + of brackets ("<literal>[]</literal>") to the variable-name in that case. + <synopsis> +$arr[<replaceable>key</replaceable>] = <replaceable>value</replaceable>; +$arr[] = <replaceable>value</replaceable>; +// <replaceable>key</replaceable> is either <type>string</type + > or nonnegative <type>integer</type> +// <replaceable>value</replaceable> can be anything + </synopsis> + If <varname>$arr</varname> doesn't yet exist, it will be created. + So this is also + an alternative way to specify an array. + To change a certain value, just assign a new value + to it. + If you want to remove a key/value pair, you need to + <function>unset</function> it. + + </para> + + </sect3> + + + </sect2><!-- end syntax --> + + <sect2 id="language.types.array.useful-funcs"> + <title>Useful functions</title> + <para> + There are quite some useful function for working + with arrays, see the <link linkend="ref.array">array-functions</link> + section. + </para> + <para> + The <link linkend="control-structures.foreach">foreach</link> + control-structure exists specificly for arrays. It + provides an easy way to traverse an array. + </para> + </sect2> + + <sect2 id="language.types.array.examples"> + <title>Examples</title> + <para> + The array-type in PHP is very versatile, so here will be some + examples to show you the full power of arrays. + </para> + <para> + <informalexample> + <programlisting role="php"> +// this +$a = array( 'color' => 'red' + , 'taste' => 'sweet', + , 'shape' => 'round', + , 'name' => 'apple', + , 4 // key will be 0 + ); + +// is completely equivalent with +$a['color'] = 'red'; +$a['taste'] = 'sweet'; +$a['shape'] = 'round'; +$a[] = 4; // key will be 0 + +$b[] = 'a'; +$b[] = 'b'; +$b[] = 'c'; +// will result in the array array( 0 => 'a' , 1 => 'b' , 2 => 'c' ) + </programlisting> + </informalexample> + </para> + + <example> + <title>Using array()</title> + <programlisting role="php"> +// Array as (property-)map +$map = array( 'version' => 4 + , 'OS' => 'Linux' + , 'lang' => 'english' + , 'short_tags' => true + ); + +// strictly numerical keys +$array = array( 7 + , 8 + , 0 + , 156 + , -10 + ); +// this is the same as array( 0 => 7, 1 => 8, ...) + +$switching = array( 10 // key = 0 + , 5 => 6 + , 3 => 7 + , 'a' => 4 + , 11 // key = 6 (maximum of integer-indices was 5) + , '8' => 2 // key = 8 (integer!) + , '02' => 77 // key = '02' + , 0 => 12 // the value 10 will be overwritten by 12 + ); + +<!-- TODO example of +- mixed keys +- overwriting keys +- integer keys as string +- using vars/functions as key/values +- mixed skipping +--> + +// empty array +$empty = array(); + </programlisting> + </example> + + <example id="language.types.array.examples.loop"> + <title>Collection</title> + <programlisting role="php"> +$colors = array('red','blue','green','yellow'); + +foreach ( $colors as $color ) +{ + echo "Do you like $color?\n"; +} +/* output: +Do you like red? +Do you like blue? +Do you like green? +Do you like yellow? +*/ + </programlisting> + </example> + + <para> + Note that it is currently not possible to change the values of the array + directly in such a loop. + <!-- + Should be made possible, if you write: + foreach ( $colors as &$color ) + + See bug#3074 + --> + A workaround is the following: + <example id="language.types.array.examples.changeloop"> + <title>Collection</title> + <programlisting role="php"> +<link linkend="control-structures.foreach">foreach</link> ( $colors as $key => $color +) +{ + // won't work: + //$color = <link linkend="function.strtoupper">strtoupper</link>($color); + + //works: + $colors[$key] = <link linkend="function.strtoupper">strtoupper</link>($color); +} +<link linkend="function.print-r">print_r</link>($colors); + +/* output: +Array +( + [0] => RED + [1] => BLUE + [2] => GREEN + [3] => YELLOW +) +*/ + </programlisting> + </example> + </para> + <para> + This example creates a one-based array. + <example> + <title>One-based index</title> + <programlisting role="php"> +$firstquarter = array(1 => 'January', 'February', 'March'); +<link linkend="function.print-r">print_r</link>($firstquarter); + +/* output: +Array +( + [1] => 'January' + [2] => 'February' + [3] => 'March' +) +*/ + </programlisting> + </example> + </para> + <example> + <title>Filling real array</title> + <programlisting role="php"> +// fill an array with all items from a <link linkend="ref.dir">directory</link> +$handle = <link linkend="function.opendir">opendir</link>('.'); +while ( $file = <link linkend="function.readdir">readdir</link>($handle) ) +{ + $files[] = $file; +} +<link linkend="function.closedir">closedir</link>($handle); + </programlisting> + </example> + <para> + Arrays are ordered. You can also change the order using differen + sorting-functions. See <link linkend="ref.array">array-functions</link> + for more information. + </para> + <example> + <title>Sorting array</title> + <programlisting role="php"> +<link linkend="function.sort">sort</link>($files); +<link linkend="function.print-r">print_r</link>($files); + </programlisting> + </example> + <para> + Because the value of an array can be everything, it can also be + another array. This way you can make recursive arrays, and + multi-dimensional arrays. + </para> + <example> + <title>Recursive and multi-dimensional arrays</title> + <programlisting role="php"> +$fruits = array ( "fruits" => array ( "a" => "orange" + , "b" => "banana" + , "c" => "apple" + ) + , "numbers" => array ( 1 + , 2 + , 3 + , 4 + , 5 + , 6 + ) + , "holes" => array ( "first" + , 5 => "second" + , "third" + ) + ); + +<!-- quite duplicate... +$a = array( + "apple" => array( + "color" => "red", + "taste" => "sweet", + "shape" => "round" + ), + "orange" => array( + "color" => "orange", + "taste" => "tart", + "shape" => "round" + ), + "banana" => array( + "color" => "yellow", + "taste" => "paste-y", + "shape" => "banana-shaped" + ) +); +--> + </programlisting> + </example> + + </sect2> + + <!-- TODO + <sect2> + <title>Misc</title> + + <sect3 id="language.types.array.foo-bar"> + <title>Why is <literal>$foo[bar]</literal> wrong?</title> + <para> + Because it is. + + + </para> + </sect3> + </sect2> + + - example multi-dim with $arr[bla][bla] syntax + - converting to array + - warning about references + - note that assigning is copy (usually...) + + + --> + +<!-- there is no such thing as multi/singel dim arrays (at least in PHP4) <sect2 id="language.types.array.single-dim"> <title>Single Dimension Arrays</title> <para> PHP supports both scalar and associative arrays. In fact, there is no difference between the two. You can create an array using - the <function>list</function> or <function>array</function> + the + + <function>list</function> + + Nope + + + + + or <function>array</function> functions, or you can explicitly set each array element value. <informalexample> <programlisting role="php"> @@ -857,6 +1377,8 @@ </para> </sect2> + + --> </sect1> <sect1 id="language.types.object"> @@ -936,6 +1458,7 @@ </para> </sect2> + @@ -944,11 +1467,29 @@ <sect1 id="language.types.null"> <title>Null</title> + <para> + The special <literal>NULL</literal> value represents + that a variable has no value. + </para> <note> <simpara> The null-type was introduced in PHP 4 </simpara> </note> + + <sect2 id="language.types.null.syntax"> + <title>Syntax</title> + <para> + There is only one value of type null, and that is + the case-insensitive keyword + <literal>NULL</literal>. + <informalexample> + <programlisting role="php"> +$var = Null; + </programlisting> + </informalexample> + </para> + </sect2> </sect1> @@ -975,11 +1516,31 @@ <informalexample> <programlisting role="php"> $foo = "0"; // $foo is string (ASCII 48) +<!-- bad example, no real operator (must be used with variable, modifies it too) $foo++; // $foo is the string "1" (ASCII 49) -$foo += 1; // $foo is now an integer (2) +--> +$foo += 2; // $foo is now an integer (2) $foo = $foo + 1.3; // $foo is now a double (3.3) $foo = 5 + "10 Little Piggies"; // $foo is integer (15) $foo = 5 + "10 Small Pigs"; // $foo is integer (15) +<!-- + +TODO: explain ++/- - behaviour with strings + +examples: + +++'001' = '002' +++'abc' = 'abd' +++'xyz' = 'xza' +++'9.9' = '9.0' +++'-3' = '-4' +- -'9' = 8 (integer!) +- -'5.5' = '5.5' +- -'-9' = -10 (integer) +- -'09' = 8 (integer) +- -'abc' = 'abc' + +--> </programlisting> </informalexample> </para> @@ -996,13 +1557,7 @@ </simpara> <para> If you would like to test any of the examples in this section, you - can cut and paste the examples and insert the following line to - see for yourself what's going on: - <informalexample> - <programlisting role="php"> -echo "\$foo==$foo; type is " . gettype ($foo) . "<br>\n"; - </programlisting> - </informalexample> + can use the <function>var_dump</function> function. </para> <note> <para> @@ -1076,6 +1631,14 @@ </listitem> </itemizedlist> </para> + <tip> + <simpara> + Instead of casting a variable to string, you can also use enclose + the variable in double quotes. + <!-- TODO: example --> + </simpara> + </tip> + <para> Note that tabs and spaces are allowed inside the parentheses, so the following are functionally equivalent: