<orderedlist>
  <listitem>
   <para>
    Obtain the Apache HTTP server from the location listed above,
    and unpack it:
   </para>

   <informalexample>
    <screen>
<![CDATA[
tar -xzf httpd-2.x.NN.tar.gz
]]>
    </screen>
   </informalexample>
  </listitem>

  <listitem>
   <para>
    Likewise, obtain and unpack the PHP source:
   </para>

   <informalexample>
    <screen>
<![CDATA[
tar -xzf php-NN.tar.gz
]]>
    </screen>
   </informalexample>
  </listitem>

  <listitem>
   <para>
    Build and install Apache. Consult the Apache install documentation for
    more details on building Apache.
   </para>

   <informalexample>
    <screen>
<![CDATA[
cd httpd-2_x_NN
./configure --enable-so
make
make install
]]>
    </screen>
   </informalexample>
  </listitem>

  <listitem>
   <para>
    Now you have Apache 2.x.NN available under /usr/local/apache2,
    configured with loadable module support and the standard MPM prefork.
    To test the installation use your normal procedure for starting
    the Apache server, e.g.:

    <informalexample>
     <screen>
<![CDATA[
/usr/local/apache2/bin/apachectl start
]]>
     </screen>
    </informalexample>

    and stop the server to go on with the configuration for PHP:

    <informalexample>
     <screen>
<![CDATA[
/usr/local/apache2/bin/apachectl stop
]]>
     </screen>
    </informalexample>
   </para>
  </listitem>

  <listitem>
   <para>
    Now, configure and build PHP. This is where you customize PHP
    with various options, like which extensions will be enabled. Run
    <command>./configure --help</command> for a list of available options. In our example
    we'll do a simple configure with Apache 2 and MySQL support.
   </para>

   <para>
    If you built Apache from source, as described above, the below example will
    match your path for <command>apxs</command>, but if you installed Apache some other way, you'll
    need to adjust the path to <command>apxs</command> accordingly. Note that some distros may rename
    <command>apxs</command> to <command>apxs2</command>.
   </para>

   <informalexample>
    <screen>
<![CDATA[
cd ../php-NN
./configure --with-apxs2=/usr/local/apache2/bin/apxs --with-pdo-mysql
make
make install
]]>
    </screen>
   </informalexample>

   <para>
    If you decide to change your configure options after installation,
    you'll need to re-run the <command>configure</command>, <command>make</command>,
    and <command>make install</command> steps.
    You only need to restart apache for the new module to take effect.
    A recompile of Apache is not needed.
   </para>

   <para>
    Note that unless told otherwise, <command>make install</command> will also install
    <link xlink:href="&url.php.pear;">PEAR</link>,
    various PHP tools such as <link linkend="install.pecl.phpize">phpize</link>,
    install the PHP CLI, and more.
   </para>
  </listitem>

  <listitem>
   <para>
    Setup your <filename>php.ini</filename>.
   </para>

   <informalexample>
    <screen>
<![CDATA[
cp php.ini-development /usr/local/lib/php.ini
]]>
    </screen>
   </informalexample>

   <para>
    You may edit your <literal>.ini</literal> file to set PHP options. If you prefer having
    <filename>php.ini</filename> in another location,
    use <literal>--with-config-file-path=/some/path</literal> in step 5.
   </para>

   <para>
    If you instead choose <filename>php.ini-production</filename>, be certain to read the list
    of changes within, as they affect how PHP behaves.
   </para>
  </listitem>

  <listitem>
   <para>
    Edit your <filename>httpd.conf</filename> to load the PHP module. The path on the right hand
    side of the <literal>LoadModule</literal> statement must point to the path of the PHP
    module on your system. The <command>make install</command> from above may have already
    added this for you, but be sure to check.
   </para>

   <informalexample>
    <para>
     For PHP 8:
    </para>

    <programlisting role="apache-conf">
<![CDATA[
LoadModule php_module modules/libphp.so
]]>
    </programlisting>
   </informalexample>

   <informalexample>
    <para>
     For PHP 7:
    </para>

    <programlisting role="apache-conf">
<![CDATA[
LoadModule php7_module modules/libphp7.so
]]>
    </programlisting>
   </informalexample>
  </listitem>

  <listitem>
   <para>
    Tell Apache to parse certain extensions as PHP. For example, let's have
    Apache parse <literal>.php</literal> files as PHP. Instead of only using the Apache <literal>AddType</literal>
    directive, we want to avoid potentially dangerous uploads and created
    files such as <filename>exploit.php.jpg</filename> from being executed as PHP. Using this
    example, you could have any extension(s) parse as PHP by simply adding
    them. We'll add <literal>.php</literal> to demonstrate.
   </para>

   <informalexample>
    <programlisting role="apache-conf">
<![CDATA[
<FilesMatch \.php$>
    SetHandler application/x-httpd-php
</FilesMatch>
]]>
    </programlisting>
   </informalexample>

   <para>
    Or, if we wanted to allow <literal>.php</literal>, <literal>.php2</literal>,
    <literal>.php3</literal>, <literal>.php4</literal>, <literal>.php5</literal>,
    <literal>.php6</literal>, and <literal>.phtml</literal> files to be
    executed as PHP, but nothing else, we'd use this:
   </para>

   <informalexample>
    <programlisting role="apache-conf">
<![CDATA[
<FilesMatch "\.ph(p[2-6]?|tml)$">
    SetHandler application/x-httpd-php
</FilesMatch>
]]>
    </programlisting>
   </informalexample>

   <para>
    And to allow <literal>.phps</literal> files to be handled by the php source filter, and
    displayed as syntax-highlighted source code, use this:
   </para>

   <informalexample>
    <programlisting role="apache-conf">
<![CDATA[
<FilesMatch "\.phps$">
    SetHandler application/x-httpd-php-source
</FilesMatch>
]]>
    </programlisting>
   </informalexample>

   <para>
    <literal>mod_rewrite</literal> may be used to allow any arbitrary <literal>.php</literal> file to be displayed
    as syntax-highlighted source code, without having to rename or copy it
    to a <literal>.phps</literal> file:
   </para>

   <informalexample>
    <programlisting role="apache-conf">
<![CDATA[
RewriteEngine On
RewriteRule (.*\.php)s$ $1 [H=application/x-httpd-php-source]
]]>
    </programlisting>
   </informalexample>

   <para>
    The php source filter should not be enabled on production systems, where
    it may expose confidential or otherwise sensitive information embedded in
    source code.
   </para>
  </listitem>

  <listitem>
   <para>
    Use your normal procedure for starting the Apache server, e.g.:
   </para>

   <informalexample>
    <screen>
<![CDATA[
/usr/local/apache2/bin/apachectl start
]]>
    </screen>
   </informalexample>

   <para>OR</para>

   <informalexample>
    <screen>
<![CDATA[
service httpd restart
]]>
    </screen>
   </informalexample>
  </listitem>
 </orderedlist>

 <para>
  Following the steps above you will have a running Apache2 web server with
  support for PHP as a <literal>SAPI</literal> module. Of course, there are
  many more configuration options available for Apache and PHP. For more
  information type <command>./configure --help</command> in the corresponding
  source tree.
 </para>


<sect1 xml:id="features.file-upload.post-method">
   <title>POST method uploads</title>
   <simpara>
    This feature lets people upload both text and binary files.
    With PHP's authentication and file manipulation functions,
    you have full control over who is allowed to upload and
    what is to be done with the file once it has been uploaded.
   </simpara>
   <simpara>
    PHP is capable of receiving file uploads from any RFC-1867
    compliant browser.
   </simpara>

   <note>
    <title>Related Configurations Note</title>
    <para>
     See also the <link linkend="ini.file-uploads">file_uploads</link>,
     <link linkend="ini.upload-max-filesize">upload_max_filesize</link>,
     <link linkend="ini.upload-tmp-dir">upload_tmp_dir</link>,
     <link linkend="ini.post-max-size">post_max_size</link> and
     <link linkend="ini.max-input-time">max_input_time</link> directives
     in &php.ini;
    </para>
   </note>

   <para>
    PHP also supports PUT-method file uploads as used by
    <productname>Netscape Composer</productname> and W3C's
    <productname>Amaya</productname> clients.  See the <link
    linkend="features.file-upload.put-method">PUT Method
    Support</link> for more details.
   </para>

   <para>
    <example>
     <title>File Upload Form</title>
     <para>
      A file upload screen can be built by creating a special form which
      looks something like this:
     </para>
     <programlisting role="html">
<![CDATA[
<!-- The data encoding type, enctype, MUST be specified as below -->
<form enctype="multipart/form-data" action="__URL__" method="POST">
    <!-- MAX_FILE_SIZE must precede the file input field -->
    <input type="hidden" name="MAX_FILE_SIZE" value="30000" />
    <!-- Name of input element determines name in $_FILES array -->
    Send this file: <input name="userfile" type="file" />
    <input type="submit" value="Send File" />
</form>
]]>
     </programlisting>
     <para>
      The <literal>__URL__</literal> in the above example should be replaced,
      and point to a PHP file.
     </para>
     <para>
      The <literal>MAX_FILE_SIZE</literal> hidden field (measured in bytes) must
      precede the file input field, and its value is the maximum filesize accepted by PHP.
      This form element should always be used as it saves users the trouble of
      waiting for a big file being transferred only to find that it was too
      large and the transfer failed.  Keep in mind: fooling this setting on the
      browser side is quite easy, so never rely on files with a greater size
      being blocked by this feature. It is merely a convenience feature for
      users on the client side of the application. The PHP settings (on the server
      side) for maximum-size, however, cannot be fooled.
     </para>
    </example>
   </para>

   <note>
    <para>
     Be sure your file upload form has attribute <literal>enctype="multipart/form-data"</literal>
     otherwise the file upload will not work.
    </para>
   </note>

   <para>
    The global <varname>$_FILES</varname> will contain all the uploaded file information.
    Its contents from the example form is as follows. Note that this assumes the use of
    the file upload name <emphasis>userfile</emphasis>, as used in the example
    script above. This can be any name.
    <variablelist>
     <varlistentry>
      <term><varname>$_FILES['userfile']['name']</varname></term>
      <listitem>
       <para>
        The original name of the file on the client machine.
       </para>
      </listitem>
     </varlistentry>
     <varlistentry>
      <term><varname>$_FILES['userfile']['type']</varname></term>
      <listitem>
       <para>
        The mime type of the file, if the browser provided this
        information.  An example would be
        <literal>"image/gif"</literal>. This mime type is however
        not checked on the PHP side and therefore don't take its value
        for granted.
       </para>
      </listitem>
     </varlistentry>
     <varlistentry>
      <term><varname>$_FILES['userfile']['size']</varname></term>
      <listitem>
       <para>
        The size, in bytes, of the uploaded file.
       </para>
      </listitem>
     </varlistentry>
     <varlistentry>
      <term><varname>$_FILES['userfile']['tmp_name']</varname></term>
      <listitem>
       <para>
        The temporary filename of the file in which the uploaded file
        was stored on the server.
       </para>
      </listitem>
     </varlistentry>
     <varlistentry>
      <term><varname>$_FILES['userfile']['error']</varname></term>
      <listitem>
       <para>
        The <link linkend="features.file-upload.errors">error code</link>
        associated with this file upload.
       </para>
      </listitem>
     </varlistentry>
     <varlistentry>
      <term><varname>$_FILES['userfile']['full_path']</varname></term>
      <listitem>
       <para>
        The full path as submitted by the browser. This value does not always contain a real directory structure, and cannot be trusted.
        Available as of PHP 8.1.0.
       </para>
      </listitem>
     </varlistentry>
    </variablelist>
   </para>

   <para>
    Files will, by default be stored in the server's default temporary
    directory, unless another location has been given with the <link
    linkend="ini.upload-tmp-dir">upload_tmp_dir</link> directive in
    &php.ini;. The server's default directory can
    be changed by setting the environment variable
    <envar>TMPDIR</envar> in the environment in which PHP runs.
    Setting it using <function>putenv</function> from within a PHP
    script will not work. This environment variable can also be used
    to make sure that other operations are working on uploaded files,
    as well.
    <example>
     <title>Validating file uploads</title>
     <para>
      See also the function entries for <function>is_uploaded_file</function>
      and <function>move_uploaded_file</function> for further information. The
      following example will process the file upload that came from a form.
     </para>
     <programlisting role="php">
<![CDATA[
<?php
$uploaddir = '/var/www/uploads/';
$uploadfile = $uploaddir . basename($_FILES['userfile']['name']);

echo '<pre>';
if (move_uploaded_file($_FILES['userfile']['tmp_name'], $uploadfile)) {
    echo "File is valid, and was successfully uploaded.\n";
} else {
    echo "Possible file upload attack!\n";
}

echo 'Here is some more debugging info:';
print_r($_FILES);

print "</pre>";

?>
]]>
     </programlisting>
    </example>
   </para>
   <simpara>
    The PHP script which receives the uploaded file should implement
    whatever logic is necessary for determining what should be done
    with the uploaded file. You can, for example, use the
    <varname>$_FILES['userfile']['size']</varname> variable
    to throw away any files that are either too small or too big.  You
    could use the
    <varname>$_FILES['userfile']['type']</varname> variable
    to throw away any files that didn't match a certain type criteria, but
    use this only as first of a series of checks, because this value
    is completely under the control of the client and not checked on the PHP
    side.
    Also, you could use <varname>$_FILES['userfile']['error']</varname>
    and plan your logic according to the <link
    linkend="features.file-upload.errors">error codes</link>.
    Whatever the logic, you should either delete the file from the
    temporary directory or move it elsewhere.
   </simpara>
   <simpara>
    If no file is selected for upload in your form, PHP will return
    <varname>$_FILES['userfile']['size']</varname> as 0, and
    <varname>$_FILES['userfile']['tmp_name']</varname> as none.
   </simpara>
   <simpara>
    The file will be deleted from the temporary directory at the end
    of the request if it has not been moved away or renamed.
   </simpara>


<sect1 xml:id="functions.anonymous">
   <title>Anonymous functions</title>

   <simpara>
    Anonymous functions, also known as <literal>closures</literal>, allow the
    creation of functions which have no specified name. They are most useful as
    the value of <type>callable</type>
    parameters, but they have many other uses.
   </simpara>
   <simpara>
    Anonymous functions are implemented using the <link linkend="class.closure">
    <classname>Closure</classname></link> class.
   </simpara>

   <example>
    <title>Anonymous function example</title>
    <programlisting role="php">
<![CDATA[
<?php
echo preg_replace_callback('~-([a-z])~', function ($match) {
    return strtoupper($match[1]);
}, 'hello-world');
// outputs helloWorld
?>
]]>
    </programlisting>
   </example>

   <simpara>
    Closures can also be used as the values of variables; PHP automatically
    converts such expressions into instances of the
    <classname>Closure</classname> internal class. Assigning a closure to a
    variable uses the same syntax as any other assignment, including the
    trailing semicolon:
   </simpara>

   <example>
    <title>Anonymous function variable assignment example</title>
    <programlisting role="php">
<![CDATA[
<?php
$greet = function($name) {
    printf("Hello %s\r\n", $name);
};

$greet('World');
$greet('PHP');
?>
]]>
    </programlisting>
   </example>

   <simpara>
    Closures may also inherit variables from the parent scope. Any such
    variables must be passed to the <literal>use</literal> language construct.
    As of PHP 7.1, these variables must not include &link.superglobals;,
    <varname>$this</varname>, or variables with the same name as a parameter.
    A return type declaration of the function has to be placed
    <emphasis>after</emphasis> the <literal>use</literal> clause.
   </simpara>

   <example>
    <title>Inheriting variables from the parent scope</title>
    <programlisting role="php">
<![CDATA[
<?php
$message = 'hello';

// No "use"
$example = function () {
    var_dump($message);
};
$example();

// Inherit $message
$example = function () use ($message) {
    var_dump($message);
};
$example();

// Inherited variable's value is from when the function
// is defined, not when called
$message = 'world';
$example();

// Reset message
$message = 'hello';

// Inherit by-reference
$example = function () use (&$message) {
    var_dump($message);
};
$example();

// The changed value in the parent scope
// is reflected inside the function call
$message = 'world';
$example();

// Closures can also accept regular arguments
$example = function ($arg) use ($message) {
    var_dump($arg . ' ' . $message);
};
$example("hello");

// Return type declaration comes after the use clause
$example = function () use ($message): string {
    return "hello $message";
};
var_dump($example());
?>
]]>
    </programlisting>
    &example.outputs.similar;
    <screen>
<![CDATA[
Notice: Undefined variable: message in /example.php on line 6
NULL
string(5) "hello"
string(5) "hello"
string(5) "hello"
string(5) "world"
string(11) "hello world"
string(11) "hello world"
]]>
    </screen>
   </example>

   <para>
    As of PHP 8.0.0, the list of scope-inherited variables may include a trailing
    comma, which will be ignored.
   </para>
   <simpara>
    Inheriting variables from the parent scope is <emphasis>not</emphasis>
    the same as using global variables.
    Global variables exist in the global scope, which is the same no
    matter what function is executing. The parent scope of a closure is the
    function in which the closure was declared (not necessarily the function it
    was called from). See the following example:
   </simpara>

   <example>
    <title>Closures and scoping</title>
    <programlisting role="php">
<![CDATA[
<?php
// A basic shopping cart which contains a list of added products
// and the quantity of each product. Includes a method which
// calculates the total price of the items in the cart using a
// closure as a callback.
class Cart
{
    const PRICE_BUTTER  = 1.00;
    const PRICE_MILK    = 3.00;
    const PRICE_EGGS    = 6.95;

    protected $products = array();

    public function add($product, $quantity)
    {
        $this->products[$product] = $quantity;
    }

    public function getQuantity($product)
    {
        return isset($this->products[$product]) ? $this->products[$product] :
               FALSE;
    }

    public function getTotal($tax)
    {
        $total = 0.00;

        $callback =
            function ($quantity, $product) use ($tax, &$total)
            {
                $pricePerItem = constant(__CLASS__ . "::PRICE_" .
                    strtoupper($product));
                $total += ($pricePerItem * $quantity) * ($tax + 1.0);
            };

        array_walk($this->products, $callback);
        return round($total, 2);
    }
}

$my_cart = new Cart;

// Add some items to the cart
$my_cart->add('butter', 1);
$my_cart->add('milk', 3);
$my_cart->add('eggs', 6);

// Print the total with a 5% sales tax.
print $my_cart->getTotal(0.05) . "\n";
// The result is 54.29
?>
]]>
    </programlisting>
   </example>

   <example>
    <title>Automatic binding of <literal>$this</literal></title>
    <programlisting role="php">
<![CDATA[
<?php

class Test
{
    public function testing()
    {
        return function() {
            var_dump($this);
        };
    }
}

$object = new Test;
$function = $object->testing();
$function();

?>
]]>
    </programlisting>
    &example.outputs;
    <screen>
<![CDATA[
object(Test)#1 (0) {
}
]]>
    </screen>
   </example>

   <para>
    When declared in the context of a class, the current class is
    automatically bound to it, making <literal>$this</literal> available
    inside of the function's scope. If this automatic binding of the current
    class is not wanted, then
    <link linkend="functions.anonymous-functions.static">static anonymous
    functions</link> may be used instead.
   </para>

   <sect2 xml:id="functions.anonymous-functions.static">
    <title>Static anonymous functions</title>
    <para>
     Anonymous functions may be declared statically. This
     prevents them from having the current class automatically bound to
     them. Objects may also not be bound to them at runtime.
    </para>
    <para>
     <example>
      <title>Attempting to use <literal>$this</literal> inside a static anonymous function</title>
      <programlisting role="php">
<![CDATA[
<?php

class Foo
{
    function __construct()
    {
        $func = static function() {
            var_dump($this);
        };
        $func();
    }
};
new Foo();

?>
]]>
      </programlisting>
      &example.outputs;
      <screen>
<![CDATA[
Notice: Undefined variable: this in %s on line %d
NULL
]]>
      </screen>
     </example>
    </para>

    <para>
     <example>
      <title>Attempting to bind an object to a static anonymous function</title>
      <programlisting role="php">
<![CDATA[
<?php

$func = static function() {
    // function body
};
$func = $func->bindTo(new stdClass);
$func();

?>
]]>
      </programlisting>
      &example.outputs;
      <screen>
<![CDATA[
Warning: Cannot bind an instance to a static closure in %s on line %d
]]>
      </screen>
     </example>
    </para>
   </sect2>


<sect2 role="changelog">
    &reftitle.changelog;
    <para>
     <informaltable>
      <tgroup cols="2">

        <row>
         <entry>&Version;</entry>
         <entry>&Description;</entry>
        </row>

        <row>
         <entry>7.1.0</entry>
         <entry>
          Anonymous functions may not close over &link.superglobals;,
          <varname>$this</varname>, or any variable with the same name as a
          parameter.
         </entry>
        </row>

      </tgroup>
     </informaltable>
    </para>
   </sect2>

   <sect2 role="notes">
    &reftitle.notes;
    <note>
     <simpara>
      It is possible to use <function>func_num_args</function>,
      <function>func_get_arg</function>, and <function>func_get_args</function>
      from within a closure.
     </simpara>
    </note>
   </sect2>

  </sect1>
  <sect1 xml:id="functions.arrow">
   <title>Arrow Functions</title>

   <simpara>
    Arrow functions were introduced in PHP 7.4 as a more concise syntax for
    <link linkend="functions.anonymous">anonymous functions</link>.
   </simpara>
   <simpara>
    Both anonymous functions and arrow functions are implemented using the
    <link linkend="class.closure"><classname>Closure</classname></link> class.
   </simpara>

   <simpara>
    Arrow functions have the basic form
    fn (argument_list) => expr.
   </simpara>

   <simpara>
    Arrow functions support the same features as
    <link linkend="functions.anonymous">anonymous functions</link>,
    except that using variables from the parent scope is always automatic.
   </simpara>

   <simpara>
    When a variable used in the expression is defined in the parent scope
    it will be implicitly captured by-value.
    In the following example, the functions <varname>$fn1</varname> and
    <varname>$fn2</varname> behave the same way.
   </simpara>

   <para>
    <example>
     <title>Arrow functions capture variables by value automatically</title>
     <programlisting role="php">
<![CDATA[
<?php

$y = 1;

$fn1 = fn($x) => $x + $y;
// equivalent to using $y by value:
$fn2 = function ($x) use ($y) {
    return $x + $y;
};

var_export($fn1(3));
?>
]]>
     </programlisting>
     &example.outputs;
     <screen>
<![CDATA[
4
]]>
      </screen>
    </example>
   </para>
   <simpara>
    This also works if the arrow functions are nested:
   </simpara>
   <para>
    <example>
     <title>Arrow functions capture variables by value automatically, even when nested</title>
     <programlisting role="php">
<![CDATA[
<?php

$z = 1;
$fn = fn($x) => fn($y) => $x * $y + $z;
// Outputs 51
var_export($fn(5)(10));
?>
]]>
     </programlisting>
    </example>
   </para>
   <simpara>
    Similarly to anonymous functions,
    the arrow function syntax allows arbitrary function signatures,
    including parameter and return types, default values, variadics,
    as well as by-reference passing and returning.
    All of the following are valid examples of arrow functions:
   </simpara>
   <para>
    <example>
     <title>Examples of arrow functions</title>
     <programlisting role="php">
<![CDATA[
<?php

fn(array $x) => $x;
static fn($x): int => $x;
fn($x = 42) => $x;
fn(&$x) => $x;
fn&($x) => $x;
fn($x, ...$rest) => $rest;

?>
]]>
     </programlisting>
    </example>
   </para>
   <simpara>
    Arrow functions use by-value variable binding.
    This is roughly equivalent to performing a use($x) for every
    variable <varname>$x</varname> used inside the arrow function.
    A by-value binding means that it is not possible to modify any values
    from the outer scope.
    <link linkend="functions.anonymous">Anonymous functions</link>
    can be used instead for by-ref bindings.
   </simpara>
   <para>
    <example>
     <title>Values from the outer scope cannot be modified by arrow functions</title>
     <programlisting role="php">
<![CDATA[
<?php

$x = 1;
$fn = fn() => $x++; // Has no effect
$fn();
var_export($x);  // Outputs 1

?>
]]>
     </programlisting>
    </example>
   </para>

   <sect2 role="changelog">
    &reftitle.changelog;
    <para>
     <informaltable>
      <tgroup cols="2">

        <row>
         <entry>&Version;</entry>
         <entry>&Description;</entry>
        </row>

        <row>
         <entry>7.4.0</entry>
         <entry>
          Arrow functions became available.
         </entry>
        </row>

      </tgroup>
     </informaltable>
    </para>
   </sect2>

   <sect2 role="notes">
    &reftitle.notes;
    <note>
     <simpara>
      It is possible to use <function>func_num_args</function>,
      <function>func_get_arg</function>, and <function>func_get_args</function>
      from within an arrow function.
     </simpara>
    </note>
   </sect2>
  </sect1>


<title>Basic syntax</title>
  <sect1 xml:id="language.basic-syntax.phptags">
   <title>PHP tags</title>
   <para>
    When PHP parses a file, it looks for opening and closing tags, which are
    <literal><?php</literal> and <literal>?></literal> which tell PHP to
    start and stop interpreting the code between them. Parsing in this manner
    allows PHP to be embedded in all sorts of different documents, as
    everything outside of a pair of opening and closing tags is ignored by the
    PHP parser.
   </para>

   <para>
    PHP includes a short echo tag <literal><?=</literal> which is a
    short-hand to the more verbose <?php echo.
   </para>

   <para>
    <example>
     <title>PHP Opening and Closing Tags</title>
     <programlisting role="php">
<![CDATA[
1.  <?php echo 'if you want to serve PHP code in XHTML or XML documents,
                use these tags'; ?>

2.  You can use the short echo tag to <?= 'print this string' ?>.
    It's equivalent to <?php echo 'print this string' ?>.

3.  <? echo 'this code is within short tags, but will only work '.
            'if short_open_tag is enabled'; ?>
]]>
     </programlisting>
    </example>
   </para>

   <para>
    Short tags (example three) are available by default but can be disabled
    either via the <link linkend="ini.short-open-tag">short_open_tag</link>
    &php.ini; configuration file directive, or are disabled by default if
    PHP is built with the <option>--disable-short-tags</option> configuration.
   </para>
   <para>
    <note>
     <para>
      As short tags can be disabled it is recommended to only use the normal
      tags (<?php ?> and <?= ?>) to
      maximise compatibility.
     </para>
    </note>
   </para>

   <para>
    If a file contains only PHP code, it is preferable to omit the PHP closing tag
    at the end of the file.  This prevents accidental whitespace or new lines
    being added after the PHP closing tag, which may cause unwanted effects
    because PHP will start output buffering when there is no intention from
    the programmer to send any output at that point in the script.
    <informalexample>
     <programlisting role="php">
<![CDATA[
<?php
echo "Hello world";

// ... more code

echo "Last statement";

// the script ends here with no PHP closing tag
]]>
     </programlisting>
    </informalexample>
   </para>
  </sect1>

  <sect1 xml:id="language.basic-syntax.phpmode">
   <title>Escaping from HTML</title>
   <para>
    Everything outside of a pair of opening and closing tags is ignored by the
    PHP parser which allows PHP files to have mixed content.  This allows PHP
    to be embedded in HTML documents, for example to create templates.
    <informalexample>
     <programlisting role="php">
<![CDATA[

This is going to be ignored by PHP and displayed by the browser.

<?php echo 'While this is going to be parsed.'; ?>

This will also be ignored by PHP and displayed by the browser.

]]>
     </programlisting>
    </informalexample>
    This works as expected, because when the PHP interpreter hits the ?> closing
    tags, it simply starts outputting whatever it finds (except for the
    immediately following newline - see
    <link linkend="language.basic-syntax.instruction-separation">instruction separation</link>)
    until it hits another opening tag unless in the middle of a conditional
    statement in which case the interpreter will determine the outcome of the
    conditional before making a decision of what to skip over.
    See the next example.
   </para>
   <para>
    Using structures with conditions
    <example>
     <title>Advanced escaping using conditions</title>
     <programlisting role="php">
<![CDATA[
<?php if ($expression == true): ?>
  This will show if the expression is true.
<?php else: ?>
  Otherwise this will show.
<?php endif; ?>
]]>
     </programlisting>
    </example>
    In this example PHP will skip the blocks where the condition is not met, even
    though they are outside of the PHP open/close tags; PHP skips them according
    to the condition since the PHP interpreter will jump over blocks contained
    within a condition that is not met.
   </para>
   <para>
    For outputting large blocks of text, dropping out of PHP parsing mode is
    generally more efficient than sending all of the text through
    <function>echo</function> or <function>print</function>.
   </para>
   <para>
    <note>
     <para>
      If PHP is embeded within XML or XHTML the normal PHP
      <?php ?> must be used to remain compliant
      with the standards.
     </para>
    </note>
   </para>
  </sect1>

  <sect1 xml:id="language.basic-syntax.instruction-separation">
   <title>Instruction separation</title>
   <para>
    As in C or Perl, PHP requires instructions to be terminated
    with a semicolon at the end of each statement. The closing tag
    of a block of PHP code automatically implies a semicolon; you
    do not need to have a semicolon terminating the last line of a
    PHP block. The closing tag for the block will include the immediately
    trailing newline if one is present.
   </para>

   <para>
    <example>
     <title>Example showing the closing tag encompassing the trailing newline</title>
     <programlisting role="php">
<![CDATA[
<?php echo "Some text"; ?>
No newline
<?= "But newline now" ?>
]]>
     </programlisting>
     &example.outputs;
     <screen>
<![CDATA[
Some textNo newline
But newline now
]]>
     </screen>
    </example>
   </para>

   <para>
    Examples of entering and exiting the PHP parser:

    <informalexample>
     <programlisting role="php">
<![CDATA[
<?php
    echo 'This is a test';
?>

<?php echo 'This is a test' ?>

<?php echo 'We omitted the last closing tag';
]]>
     </programlisting>
    </informalexample>
    <note>
     <para>
      The closing tag of a PHP block at the end of a file is optional,
      and in some cases omitting it is helpful when using <function>include</function>
      or <function>require</function>, so unwanted whitespace will
      not occur at the end of files, and you will still be able to add
      headers to the response later. It is also handy if you use output
      buffering, and would not like to see added unwanted whitespace
      at the end of the parts generated by the included files.
     </para>
    </note>
   </para>
  </sect1>
  <sect1 xml:id="language.basic-syntax.comments">
   <title>Comments</title>
   <para>
    PHP supports 'C', 'C++' and Unix shell-style (Perl style) comments. For example:

    <informalexample>
     <programlisting role="php">
<![CDATA[
<?php
    echo 'This is a test'; // This is a one-line c++ style comment
    /* This is a multi line comment
       yet another line of comment */
    echo 'This is yet another test';
    echo 'One Final Test'; # This is a one-line shell-style comment
?>
]]>
     </programlisting>
    </informalexample>
   </para>
   <simpara>
    The "one-line" comment styles only comment to the end of
    the line or the current block of PHP code, whichever comes first.
    This means that HTML code after <literal>// ... ?></literal>
    or <literal># ...  ?></literal> WILL be printed:
    ?> breaks out of PHP mode and returns to HTML mode, and
    <literal>//</literal> or <literal>#</literal> cannot influence that.
   </simpara>
   <para>
    <informalexample>
     <programlisting role="php">
<![CDATA[

This is an <?php # echo 'simple';?> example

The header above will say 'This is an  example'.

]]>
     </programlisting>
    </informalexample>
   </para>
   <simpara>
    'C' style comments end at the first <literal>*/</literal> encountered.
    Make sure you don't nest 'C' style comments.  It is easy to make this
    mistake if you are trying to comment out a large block of code.
   </simpara>
   <para>
    <informalexample>
     <programlisting role="php">
<![CDATA[
<?php
 /*
    echo 'This is a test'; /* This comment will cause a problem */
 */
?>
]]>
     </programlisting>
    </informalexample>
   </para>
  </sect1>


<sect1 xml:id="language.generators.syntax">
  <title>Generator syntax</title>

  <para>
   A generator function looks just like a normal function, except that instead
   of returning a value, a generator &yield;s as many values as it needs to.
   Any function containing &yield; is a generator function.
  </para>

  <para>
   When a generator function is called, it returns an object that can be
   iterated over. When you iterate over that object (for instance, via a
   &foreach; loop), PHP will call the object's iteration methods each time it needs a
   value, then saves the state of the generator when the generator yields a
   value so that it can be resumed when the next value is required.
  </para>

  <para>
   Once there are no more values to be yielded, then the generator
   can simply return, and the calling code continues just as if an array has run
   out of values.
  </para>

  <note>
   <para>
    A generator can return values, which can be retrieved using
    <methodname>Generator::getReturn</methodname>.
   </para>
  </note>

  <sect2 xml:id="control-structures.yield">
   <title><command>yield</command> keyword</title>

   <para>
    The heart of a generator function is the <command>yield</command> keyword.
    In its simplest form, a yield statement looks much like a return
    statement, except that instead of stopping execution of the function and
    returning, yield instead provides a value to the code looping over the
    generator and pauses execution of the generator function.
   </para>

   <example>
    <title>A simple example of yielding values</title>
    <programlisting role="php">
<![CDATA[
<?php
function gen_one_to_three() {
    for ($i = 1; $i <= 3; $i++) {
        // Note that $i is preserved between yields.
        yield $i;
    }
}

$generator = gen_one_to_three();
foreach ($generator as $value) {
    echo "$value\n";
}
?>
]]>
    </programlisting>
    &example.outputs;
    <screen>
<![CDATA[
1
2
3
]]>
    </screen>
   </example>

   <note>
    <para>
     Internally, sequential integer keys will be paired with the yielded
     values, just as with a non-associative array.
    </para>
   </note>

   <sect3 xml:id="control-structures.yield.associative">
    <title>Yielding values with keys</title>

    <para>
     PHP also supports associative arrays, and generators are no different. In
     addition to yielding simple values, as shown above, you can also yield a
     key at the same time.
    </para>

    <para>
     The syntax for yielding a key/value pair is very similar to that used to
     define an associative array, as shown below.
    </para>

    <example>
     <title>Yielding a key/value pair</title>
     <programlisting role="php">
<![CDATA[
<?php
/*
 * The input is semi-colon separated fields, with the first
 * field being an ID to use as a key.
 */

$input = <<<'EOF'
1;PHP;Likes dollar signs
2;Python;Likes whitespace
3;Ruby;Likes blocks
EOF;

function input_parser($input) {
    foreach (explode("\n", $input) as $line) {
        $fields = explode(';', $line);
        $id = array_shift($fields);

        yield $id => $fields;
    }
}

foreach (input_parser($input) as $id => $fields) {
    echo "$id:\n";
    echo "    $fields[0]\n";
    echo "    $fields[1]\n";
}
?>
]]>
     </programlisting>
     &example.outputs;
     <screen>
<![CDATA[
1:
    PHP
    Likes dollar signs
2:
    Python
    Likes whitespace
3:
    Ruby
    Likes blocks
]]>
     </screen>
    </example>
   </sect3>

   <sect3 xml:id="control-structures.yield.null">
    <title>Yielding null values</title>

    <para>
     Yield can be called without an argument to yield a &null; value with an
     automatic key.
    </para>

    <example>
     <title>Yielding &null;s</title>
     <programlisting role="php">
<![CDATA[
<?php
function gen_three_nulls() {
    foreach (range(1, 3) as $i) {
        yield;
    }
}

var_dump(iterator_to_array(gen_three_nulls()));
?>
]]>
     </programlisting>
     &example.outputs;
     <screen>
<![CDATA[
array(3) {
  [0]=>
  NULL
  [1]=>
  NULL
  [2]=>
  NULL
}
]]>
     </screen>
    </example>
   </sect3>

   <sect3 xml:id="control-structures.yield.references">
    <title>Yielding by reference</title>

    <para>
     Generator functions are able to yield values by reference as well as by
     value. This is done in the same way as
     <link linkend="functions.returning-values">returning references from functions</link>:
     by prepending an ampersand to the function name.
    </para>

    <example>
     <title>Yielding values by reference</title>
     <programlisting role="php">
<![CDATA[
<?php
function &gen_reference() {
    $value = 3;

    while ($value > 0) {
        yield $value;
    }
}

/*
 * Note that we can change $number within the loop, and
 * because the generator is yielding references, $value
 * within gen_reference() changes.
 */
foreach (gen_reference() as &$number) {
    echo (--$number).'... ';
}
?>
]]>
     </programlisting>
     &example.outputs;
     <screen>
<![CDATA[
2... 1... 0...
]]>
     </screen>
    </example>
   </sect3>


<sect1 xml:id="language.namespaces.importing">
  <title>Using namespaces: Aliasing/Importing</title>
  <titleabbrev>Aliasing and Importing</titleabbrev>
  <?phpdoc print-version-for="namespaces"?>
  <para>
   The ability to refer to an external fully qualified name with an alias, or importing,
   is an important feature of namespaces.  This is similar to the
   ability of unix-based filesystems to create symbolic links to a file or to a directory.
  </para>
  <para>
   PHP can alias(/import) constants, functions, classes, interfaces, traits, enums and namespaces.
  </para>
  <para>
   Aliasing is accomplished with the <literal>use</literal> operator.
   Here is an example showing all 5 kinds of importing:
   <example>
    <title>importing/aliasing with the use operator</title>
    <programlisting role="php">
     <![CDATA[
<?php
namespace foo;
use My\Full\Classname as Another;

// this is the same as use My\Full\NSname as NSname
use My\Full\NSname;

// importing a global class
use ArrayObject;

// importing a function
use function My\Full\functionName;

// aliasing a function
use function My\Full\functionName as func;

// importing a constant
use const My\Full\CONSTANT;

$obj = new namespace\Another; // instantiates object of class foo\Another
$obj = new Another; // instantiates object of class My\Full\Classname
NSname\subns\func(); // calls function My\Full\NSname\subns\func
$a = new ArrayObject(array(1)); // instantiates object of class ArrayObject
// without the "use ArrayObject" we would instantiate an object of class foo\ArrayObject
func(); // calls function My\Full\functionName
echo CONSTANT; // echoes the value of My\Full\CONSTANT
?>
]]>
    </programlisting>
   </example>
   Note that for namespaced names (fully qualified namespace names containing
   namespace separator, such as <literal>Foo\Bar</literal> as opposed to global names that
   do not, such as <literal>FooBar</literal>), the leading backslash is unnecessary and not
   recommended, as import names
   must be fully qualified, and are not processed relative to the current namespace.
  </para>
  <para>
   PHP additionally supports a convenience shortcut to place multiple use statements
   on the same line
   <example>
    <title>importing/aliasing with the use operator, multiple use statements combined</title>
    <programlisting role="php">
     <![CDATA[
<?php
use My\Full\Classname as Another, My\Full\NSname;

$obj = new Another; // instantiates object of class My\Full\Classname
NSname\subns\func(); // calls function My\Full\NSname\subns\func
?>
]]>
    </programlisting>
   </example>
  </para>
  <para>
   Importing is performed at compile-time, and so does not affect dynamic class, function
   or constant names.
   <example>
    <title>Importing and dynamic names</title>
    <programlisting role="php">
     <![CDATA[
<?php
use My\Full\Classname as Another, My\Full\NSname;

$obj = new Another; // instantiates object of class My\Full\Classname
$a = 'Another';
$obj = new $a;      // instantiates object of class Another
?>
]]>
    </programlisting>
   </example>
  </para>
  <para>
   In addition, importing only affects unqualified and qualified names.  Fully qualified
   names are absolute, and unaffected by imports.
   <example>
    <title>Importing and fully qualified names</title>
    <programlisting role="php">
     <![CDATA[
<?php
use My\Full\Classname as Another, My\Full\NSname;

$obj = new Another; // instantiates object of class My\Full\Classname
$obj = new \Another; // instantiates object of class Another
$obj = new Another\thing; // instantiates object of class My\Full\Classname\thing
$obj = new \Another\thing; // instantiates object of class Another\thing
?>
]]>
    </programlisting>
   </example>
  </para>
  <sect2 xml:id="language.namespaces.importing.scope">
   <title>Scoping rules for importing</title>
   <para>
    The <literal>use</literal> keyword must be declared in the
    outermost scope of a file (the global scope) or inside namespace
    declarations. This is because the importing is done at compile
    time and not runtime, so it cannot be block scoped. The following
    example will show an illegal use of the <literal>use</literal>
    keyword:
   </para>
   <para>
    <example>
     <title>Illegal importing rule</title>
     <programlisting role="php">
<![CDATA[
<?php
namespace Languages;

function toGreenlandic()
{
    use Languages\Danish;

    // ...
}
?>
]]>
     </programlisting>
    </example>
   </para>
   <note>
    <para>
     Importing rules are per file basis, meaning included files will
     <emphasis>NOT</emphasis> inherit the parent file's importing rules.
    </para>
   </note>
  </sect2>
  <sect2 xml:id="language.namespaces.importing.group">
   <title>Group <literal>use</literal> declarations</title>
   <para>
    Classes, functions and constants being imported from
    the same &namespace; can be grouped together in a single &use.namespace;
    statement.
   </para>
   <informalexample>
    <programlisting role="php">
<![CDATA[
<?php

use some\namespace\ClassA;
use some\namespace\ClassB;
use some\namespace\ClassC as C;

use function some\namespace\fn_a;
use function some\namespace\fn_b;
use function some\namespace\fn_c;

use const some\namespace\ConstA;
use const some\namespace\ConstB;
use const some\namespace\ConstC;

// is equivalent to the following groupped use declaration
use some\namespace\{ClassA, ClassB, ClassC as C};
use function some\namespace\{fn_a, fn_b, fn_c};
use const some\namespace\{ConstA, ConstB, ConstC};
]]>
    </programlisting>
   </informalexample>
  </sect2>
 </sect1>
 <sect1 xml:id="language.namespaces.global">
  <title>Global space</title>
  <titleabbrev>Global space</titleabbrev>
  <?phpdoc print-version-for="namespaces"?>
  <para>
   Without any namespace definition, all class and function definitions are
   placed into the global space - as it was in PHP before namespaces were
   supported. Prefixing a name with <literal>\</literal> will specify that
   the name is required from the global space even in the context of the
   namespace.
   <example>
    <title>Using global space specification</title>
    <programlisting role="php">
     <![CDATA[
<?php
namespace A\B\C;

/* This function is A\B\C\fopen */
function fopen() {
     /* ... */
     $f = \fopen(...); // call global fopen
     return $f;
}
?>
    ]]>
    </programlisting>
   </example>
  </para>
 </sect1>


<sect2 xml:id="language.types.array.syntax">
  <title>Syntax</title>

  <sect3 xml:id="language.types.array.syntax.array-func">
   <title>Specifying with <function>array</function></title>

   <para>
    An <type>array</type> can be created using the <function>array</function>
    language construct. It takes any number of comma-separated
    <literal><replaceable>key</replaceable> => <replaceable>value</replaceable></literal> pairs
    as arguments.
   </para>

   <synopsis>
array(
    <optional><replaceable>key</replaceable>  => </optional><replaceable>value</replaceable>,
    <optional><replaceable>key2</replaceable> => </optional><replaceable>value2</replaceable>,
    <optional><replaceable>key3</replaceable> => </optional><replaceable>value3</replaceable>,
    ...
)</synopsis>
   <!-- Do not fix the whitespace for the synopsis end element. A limitation of PhD prevents proper trimming -->

   <para>
    The comma after the last array element is optional and can be omitted. This is usually done
    for single-line arrays, i.e. <literal>array(1, 2)</literal> is preferred over
    <literal>array(1, 2, )</literal>. For multi-line arrays on the other hand the trailing comma
    is commonly used, as it allows easier addition of new elements at the end.
   </para>

   <note>
    <para>
     A short array syntax exists which replaces
     <literal>array()</literal> with <literal>[]</literal>.
    </para>
   </note>

   <example>
    <title>A simple array</title>
    <programlisting role="php">
<![CDATA[
<?php
$array = array(
    "foo" => "bar",
    "bar" => "foo",
);

// Using the short array syntax
$array = [
    "foo" => "bar",
    "bar" => "foo",
];
?>
]]>
    </programlisting>
   </example>

   <para>
    The <replaceable>key</replaceable> can either be an <type>int</type>
    or a <type>string</type>. The <replaceable>value</replaceable> can be
    of any type.
   </para>

   <para xml:id="language.types.array.key-casts">
    Additionally the following <replaceable>key</replaceable> casts will occur:
    <itemizedlist>
     <listitem>
      <simpara>
       <type>String</type>s containing valid decimal <type>int</type>s, unless the number is preceded by a <literal>+</literal> sign, will be cast to the
       <type>int</type> type. E.g. the key <literal>"8"</literal> will actually be
       stored under <literal>8</literal>. On the other hand <literal>"08"</literal> will
       not be cast, as it isn't a valid decimal integer.
      </simpara>
     </listitem>
     <listitem>
      <simpara>
       <type>Float</type>s are also cast to <type>int</type>s, which means that the
       fractional part will be truncated. E.g. the key <literal>8.7</literal> will actually
       be stored under <literal>8</literal>.
      </simpara>
     </listitem>
     <listitem>
      <simpara>
       <type>Bool</type>s are cast to <type>int</type>s, too, i.e. the key
       &true; will actually be stored under <literal>1</literal>
       and the key &false; under <literal>0</literal>.
      </simpara>
     </listitem>
     <listitem>
      <simpara>
       <type>Null</type> will be cast to the empty string, i.e. the key
       <literal>null</literal> will actually be stored under <literal>""</literal>.
      </simpara>
     </listitem>
     <listitem>
      <simpara>
       <type>Array</type>s and <type>object</type>s <emphasis>can not</emphasis> be used as keys.
       Doing so will result in a warning: <literal>Illegal offset type</literal>.
      </simpara>
     </listitem>
    </itemizedlist>
   </para>

   <para>
    If multiple elements in the array declaration use the same key, only the last one
    will be used as all others are overwritten.
   </para>

   <example>
    <title>Type Casting and Overwriting example</title>
    <programlisting role="php">
<![CDATA[
<?php
$array = array(
    1    => "a",
    "1"  => "b",
    1.5  => "c",
    true => "d",
);
var_dump($array);
?>
]]>
    </programlisting>
    &example.outputs;
    <screen>
<![CDATA[
array(1) {
  [1]=>
  string(1) "d"
}
]]>
    </screen>
    <para>
     As all the keys in the above example are cast to <literal>1</literal>, the value will be overwritten
     on every new element and the last assigned value <literal>"d"</literal> is the only one left over.
    </para>
   </example>

   <para>
    PHP arrays can contain <type>int</type> and <type>string</type> keys at the same time
    as PHP does not distinguish between indexed and associative arrays.
   </para>

   <example>
    <title>Mixed <type>int</type> and <type>string</type> keys</title>
    <programlisting role="php">
<![CDATA[
<?php
$array = array(
    "foo" => "bar",
    "bar" => "foo",
    100   => -100,
    -100  => 100,
);
var_dump($array);
?>
]]>
    </programlisting>
    &example.outputs;
    <screen>
<![CDATA[
array(4) {
  ["foo"]=>
  string(3) "bar"
  ["bar"]=>
  string(3) "foo"
  [100]=>
  int(-100)
  [-100]=>
  int(100)
}
]]>
    </screen>
   </example>

   <para>
    The <replaceable>key</replaceable> is optional. If it is not specified, PHP will
    use the increment of the largest previously used <type>int</type> key.
   </para>

   <example>
    <title>Indexed arrays without key</title>
    <programlisting role="php">
<![CDATA[
<?php
$array = array("foo", "bar", "hello", "world");
var_dump($array);
?>
]]>
    </programlisting>
    &example.outputs;
    <screen>
<![CDATA[
array(4) {
  [0]=>
  string(3) "foo"
  [1]=>
  string(3) "bar"
  [2]=>
  string(5) "hello"
  [3]=>
  string(5) "world"
}
]]>
    </screen>
   </example>

   <para>
    It is possible to specify the key only for some elements and leave it out for others:
   </para>

   <example>
    <title>Keys not on all elements</title>
    <programlisting role="php">
<![CDATA[
<?php
$array = array(
         "a",
         "b",
    6 => "c",
         "d",
);
var_dump($array);
?>
]]>
    </programlisting>
    &example.outputs;
    <screen>
<![CDATA[
array(4) {
  [0]=>
  string(1) "a"
  [1]=>
  string(1) "b"
  [6]=>
  string(1) "c"
  [7]=>
  string(1) "d"
}
]]>
    </screen>
    <para>
     As you can see the last value <literal>"d"</literal> was assigned the key
     <literal>7</literal>. This is because the largest integer key before that
     was <literal>6</literal>.
    </para>
   </example>


<sect3 xml:id="language.types.array.syntax.modifying">
   <title>Creating/modifying with square bracket syntax</title>

   <para>
    An existing <type>array</type> can be modified by explicitly setting values
    in it.
   </para>

   <para>
    This is done by assigning values to the <type>array</type>, specifying the
    key in brackets. The key can also be omitted, resulting in an empty pair of
    brackets (<literal>[]</literal>).
   </para>

   <synopsis>
$arr[<replaceable>key</replaceable>] = <replaceable>value</replaceable>;
$arr[] = <replaceable>value</replaceable>;
// <replaceable>key</replaceable> may be an <type>int</type> or <type>string</type>
// <replaceable>value</replaceable> may be any value of any type</synopsis>

   <para>
    If <varname>$arr</varname> doesn't exist yet or is set to &null; or &false;, it will be created, so this is
    also an alternative way to create an <type>array</type>. This practice is
    however discouraged because if <varname>$arr</varname> already contains
    some value (e.g. <type>string</type> from request variable) then this
    value will stay in the place and <literal>[]</literal> may actually stand
    for <link linkend="language.types.string.substr">string access
    operator</link>. It is always better to initialize a variable by a direct
    assignment.
   </para>
   <note>
    <simpara>
     As of PHP 7.1.0, applying the empty index operator on a string throws a fatal
     error. Formerly, the string was silently converted to an array.
    </simpara>
   </note>
   <note>
    <simpara>
     As of PHP 8.1.0, creating a new array from &false; value is deprecated.
     Creating a new array from &null; and undefined values is still allowed.
    </simpara>
   </note>

   <para>
    To change a certain
    value, assign a new value to that element using its key. To remove a
    key/value pair, call the <function>unset</function> function on it.
   </para>

   <informalexample>
    <programlisting role="php">
<![CDATA[
<?php
$arr = array(5 => 1, 12 => 2);

$arr[] = 56;    // This is the same as $arr[13] = 56;
                // at this point of the script

$arr["x"] = 42; // This adds a new element to
                // the array with key "x"

unset($arr[5]); // This removes the element from the array

unset($arr);    // This deletes the whole array
?>
]]>
    </programlisting>
   </informalexample>

   <note>
    <para>
     As mentioned above, if no key is specified, the maximum of the existing
     <type>int</type> indices is taken, and the new key will be that maximum
     value plus 1 (but at least 0). If no <type>int</type> indices exist yet, the key will
     be <literal>0</literal> (zero).
    </para>

    <para>
     Note that the maximum integer key used for this <emphasis>need not
     currently exist in the <type>array</type></emphasis>. It need only have
     existed in the <type>array</type> at some time since the last time the
     <type>array</type> was re-indexed. The following example illustrates:
    </para>

    <informalexample>
     <programlisting role="php">
<![CDATA[
<?php
// Create a simple array.
$array = array(1, 2, 3, 4, 5);
print_r($array);

// Now delete every item, but leave the array itself intact:
foreach ($array as $i => $value) {
    unset($array[$i]);
}
print_r($array);

// Append an item (note that the new key is 5, instead of 0).
$array[] = 6;
print_r($array);

// Re-index:
$array = array_values($array);
$array[] = 7;
print_r($array);
?>
]]>
     </programlisting>
     &example.outputs;
     <screen>
<![CDATA[
Array
(
    [0] => 1
    [1] => 2
    [2] => 3
    [3] => 4
    [4] => 5
)
Array
(
)
Array
(
    [5] => 6
)
Array
(
    [0] => 6
    [1] => 7
)
]]>
     </screen>
    </informalexample>

   </note>

  </sect3>

  <sect3 xml:id="language.types.array.syntax.destructuring">
   <title>Array destructuring</title>

   <para>
    Arrays can be destructured using the <literal>[]</literal> (as of PHP 7.1.0) or
    <function>list</function> language constructs. These
    constructs can be used to destructure an array into distinct variables.
   </para>

   <informalexample>
    <programlisting role="php">
<![CDATA[
<?php
$source_array = ['foo', 'bar', 'baz'];

[$foo, $bar, $baz] = $source_array;

echo $foo;    // prints "foo"
echo $bar;    // prints "bar"
echo $baz;    // prints "baz"
?>
]]>
    </programlisting>
   </informalexample>

   <para>
    Array destructuring can be used in &foreach; to destructure
    a multi-dimensional array while iterating over it.
   </para>

   <informalexample>
    <programlisting role="php">
<![CDATA[
<?php
$source_array = [
    [1, 'John'],
    [2, 'Jane'],
];

foreach ($source_array as [$id, $name]) {
    // logic here with $id and $name
}
?>
]]>
    </programlisting>
   </informalexample>

   <para>
    Array elements will be ignored if the variable is not provided. Array
    destructuring always starts at index <literal>0</literal>.
   </para>

   <informalexample>
    <programlisting role="php">
<![CDATA[
<?php
$source_array = ['foo', 'bar', 'baz'];

// Assign the element at index 2 to the variable $baz
[, , $baz] = $source_array;

echo $baz;    // prints "baz"
?>
]]>
    </programlisting>
   </informalexample>

   <para>
    As of PHP 7.1.0, associative arrays can be destructured too. This also
    allows for easier selection of the right element in numerically indexed
    arrays as the index can be explicitly specified.
   </para>

   <informalexample>
    <programlisting role="php">
<![CDATA[
<?php
$source_array = ['foo' => 1, 'bar' => 2, 'baz' => 3];

// Assign the element at index 'baz' to the variable $three
['baz' => $three] = $source_array;

echo $three;    // prints 3

$source_array = ['foo', 'bar', 'baz'];

// Assign the element at index 2 to the variable $baz
[2 => $baz] = $source_array;

echo $baz;    // prints "baz"
?>
]]>
    </programlisting>
   </informalexample>

   <para>
    Array destructuring can be used for easy swapping of two variables.
   </para>

   <informalexample>
    <programlisting role="php">
<![CDATA[
<?php
$a = 1;
$b = 2;

[$b, $a] = [$a, $b];

echo $a;    // prints 2
echo $b;    // prints 1
?>
]]>
    </programlisting>
   </informalexample>

   <note>
    <para>
      The spread operator (<literal>...</literal>) is not supported in assignments.
    </para>
   </note>

   <note>
    <para>
      Attempting to access an array key which has not been defined is
      the same as accessing any other undefined variable:
      an <constant>E_WARNING</constant>-level error message
      (<constant>E_NOTICE</constant>-level prior to PHP 8.0.0) will be
      issued, and the result will be &null;.
    </para>
   </note>
  </sect3>

 </sect2><!-- end syntax -->


<?xml version="1.0" encoding="utf-8"?>
<sect1 xml:id="language.operators.array">
 <title>Array Operators</title>
 <titleabbrev>Array</titleabbrev>
 <table>
  <title>Array Operators</title>
  <tgroup cols="3">
   <thead>
    <row>
     <entry>Example</entry>
     <entry>Name</entry>
     <entry>Result</entry>
    </row>
   </thead>
   <tbody>
    <row>
     <entry>$a + $b</entry>
     <entry>Union</entry>
     <entry>Union of <varname>$a</varname> and <varname>$b</varname>.</entry>
    </row>
    <row>
     <entry>$a == $b</entry>
     <entry>Equality</entry>
     <entry>&true; if <varname>$a</varname> and <varname>$b</varname> have the same key/value pairs.</entry>
    </row>
    <row>
     <entry>$a === $b</entry>
     <entry>Identity</entry>
     <entry>&true; if <varname>$a</varname> and <varname>$b</varname> have the same key/value pairs in the same
      order and of the same types.</entry>
    </row>
    <row>
     <entry>$a != $b</entry>
     <entry>Inequality</entry>
     <entry>&true; if <varname>$a</varname> is not equal to <varname>$b</varname>.</entry>
    </row>
    <row>
     <entry>$a <> $b</entry>
     <entry>Inequality</entry>
     <entry>&true; if <varname>$a</varname> is not equal to <varname>$b</varname>.</entry>
    </row>
    <row>
     <entry>$a !== $b</entry>
     <entry>Non-identity</entry>
     <entry>&true; if <varname>$a</varname> is not identical to <varname>$b</varname>.</entry>
    </row>
   </tbody>
  </tgroup>
 </table>
 <para>
  The <literal>+</literal> operator returns the right-hand array appended
  to the left-hand array; for keys that exist in both arrays, the elements
  from the left-hand array will be used, and the matching elements from the
  right-hand array will be ignored.
 </para>
 <para>
  <informalexample>
   <programlisting role="php">
<![CDATA[
<?php
$a = array("a" => "apple", "b" => "banana");
$b = array("a" => "pear", "b" => "strawberry", "c" => "cherry");

$c = $a + $b; // Union of $a and $b
echo "Union of \$a and \$b: \n";
var_dump($c);

$c = $b + $a; // Union of $b and $a
echo "Union of \$b and \$a: \n";
var_dump($c);

$a += $b; // Union of $a += $b is $a and $b
echo "Union of \$a += \$b: \n";
var_dump($a);
?>
]]>
   </programlisting>
  </informalexample>
  When executed, this script will print the following:
  <screen role="php">
<![CDATA[
Union of $a and $b:
array(3) {
  ["a"]=>
  string(5) "apple"
  ["b"]=>
  string(6) "banana"
  ["c"]=>
  string(6) "cherry"
}
Union of $b and $a:
array(3) {
  ["a"]=>
  string(4) "pear"
  ["b"]=>
  string(10) "strawberry"
  ["c"]=>
  string(6) "cherry"
}
Union of $a += $b:
array(3) {
  ["a"]=>
  string(5) "apple"
  ["b"]=>
  string(6) "banana"
  ["c"]=>
  string(6) "cherry"
}
]]>
  </screen>
 </para>
 <para>
  Elements of arrays are equal for the comparison if they have the
  same key and value.
 </para>
 <para>
  <example>
   <title>Comparing arrays</title>
   <programlisting role="php">
<![CDATA[
<?php
$a = array("apple", "banana");
$b = array(1 => "banana", "0" => "apple");

var_dump($a == $b); // bool(true)
var_dump($a === $b); // bool(false)
?>
]]>
   </programlisting>
  </example>
 </para>

 <sect2 role="seealso">
  &reftitle.seealso;
  <para>
   <simplelist>
    <member><link linkend="language.types.array">Array type</link></member>
    <member><link linkend="ref.array">Array functions</link></member>
   </simplelist>
  </para>
 </sect2>
</sect1>


<?xml version="1.0" encoding="utf-8"?>
<!-- $Revision$ -->
 <sect1 xml:id="language.oop5.traits" xmlns="http://docbook.org/ns/docbook">
  <title>Traits</title>
  <para>
   PHP implements a way to reuse code called Traits.
  </para>
  <para>
   Traits are a mechanism for code reuse in single inheritance languages such as
   PHP. A Trait is intended to reduce some limitations of single inheritance by
   enabling a developer to reuse sets of methods freely in several independent
   classes living in different class hierarchies. The semantics of the combination
   of Traits and classes is defined in a way which reduces complexity, and avoids
   the typical problems associated with multiple inheritance and Mixins.
  </para>
  <para>
   A Trait is similar to a class, but only intended to group functionality in a
   fine-grained and consistent way. It is not possible to instantiate a Trait on
   its own. It is an addition to traditional inheritance and enables horizontal
   composition of behavior; that is, the application of class members without
   requiring inheritance.
  </para>
  <example xml:id="language.oop5.traits.basicexample">
    <title>Trait example</title>
    <programlisting role="php">
<![CDATA[
<?php
trait ezcReflectionReturnInfo {
    function getReturnType() { /*1*/ }
    function getReturnDescription() { /*2*/ }
}

class ezcReflectionMethod extends ReflectionMethod {
    use ezcReflectionReturnInfo;
    /* ... */
}

class ezcReflectionFunction extends ReflectionFunction {
    use ezcReflectionReturnInfo;
    /* ... */
}
?>
]]>
    </programlisting>
   </example>

  <sect2 xml:id="language.oop5.traits.precedence">
   <title>Precedence</title>
   <para>
    An inherited member from a base class is overridden by a member inserted
    by a Trait. The precedence order is that members from the current class
    override Trait methods, which in turn override inherited methods.
   </para>
   <example xml:id="language.oop5.traits.precedence.examples.ex1">
    <title>Precedence Order Example</title>
    <para>
     An inherited method from a base class is overridden by the
     method inserted into MyHelloWorld from the SayWorld Trait. The behavior is
     the same for methods defined in the MyHelloWorld class. The precedence order
     is that methods from the current class override Trait methods, which in
     turn override methods from the base class.
    </para>
    <programlisting role="php">
<![CDATA[
<?php
class Base {
    public function sayHello() {
        echo 'Hello ';
    }
}

trait SayWorld {
    public function sayHello() {
        parent::sayHello();
        echo 'World!';
    }
}

class MyHelloWorld extends Base {
    use SayWorld;
}

$o = new MyHelloWorld();
$o->sayHello();
?>
]]>
    </programlisting>
    &example.outputs;
    <screen>
<![CDATA[
Hello World!
]]>
    </screen>
   </example>
   <example xml:id="language.oop5.traits.precedence.examples.ex2">
    <title>Alternate Precedence Order Example</title>
    <programlisting role="php">
<![CDATA[
<?php
trait HelloWorld {
    public function sayHello() {
        echo 'Hello World!';
    }
}

class TheWorldIsNotEnough {
    use HelloWorld;
    public function sayHello() {
        echo 'Hello Universe!';
    }
}

$o = new TheWorldIsNotEnough();
$o->sayHello();
?>
]]>
    </programlisting>
    &example.outputs;
    <screen>
<![CDATA[
Hello Universe!
]]>
    </screen>
   </example>
  </sect2>

  <sect2 xml:id="language.oop5.traits.multiple">
   <title>Multiple Traits</title>
   <para>
    Multiple Traits can be inserted into a class by listing them in the <literal>use</literal>
    statement, separated by commas.
   </para>
   <example xml:id="language.oop5.traits.multiple.ex1">
    <title>Multiple Traits Usage</title>
    <programlisting role="php">
<![CDATA[
<?php
trait Hello {
    public function sayHello() {
        echo 'Hello ';
    }
}

trait World {
    public function sayWorld() {
        echo 'World';
    }
}

class MyHelloWorld {
    use Hello, World;
    public function sayExclamationMark() {
        echo '!';
    }
}

$o = new MyHelloWorld();
$o->sayHello();
$o->sayWorld();
$o->sayExclamationMark();
?>
]]>
    </programlisting>
    &example.outputs;
    <screen>
<![CDATA[
Hello World!
]]>
    </screen>
   </example>
  </sect2>

  <sect2 xml:id="language.oop5.traits.conflict">
   <title>Conflict Resolution</title>
   <para>
    If two Traits insert a method with the same name, a fatal error is produced,
    if the conflict is not explicitly resolved.
   </para>
   <para>
    To resolve naming conflicts between Traits used in the same class,
    the <literal>insteadof</literal> operator needs to be used to choose exactly
    one of the conflicting methods.
   </para>
   <para>
    Since this only allows one to exclude methods, the <literal>as</literal>
    operator can be used to add an alias to one of the methods. Note the
    <literal>as</literal> operator does not rename the method and it does not
    affect any other method either.
   </para>
   <example xml:id="language.oop5.traits.conflict.ex1">
    <title>Conflict Resolution</title>
    <para>
      In this example, Talker uses the traits A and B.
      Since A and B have conflicting methods, it defines to use
      the variant of smallTalk from trait B, and the variant of bigTalk from
      trait A.
    </para>
    <para>
      The Aliased_Talker makes use of the <literal>as</literal> operator
      to be able to use B's bigTalk implementation under an additional alias
      <literal>talk</literal>.
    </para>
    <programlisting role="php">
<![CDATA[
<?php
trait A {
    public function smallTalk() {
        echo 'a';
    }
    public function bigTalk() {
        echo 'A';
    }
}

trait B {
    public function smallTalk() {
        echo 'b';
    }
    public function bigTalk() {
        echo 'B';
    }
}

class Talker {
    use A, B {
        B::smallTalk insteadof A;
        A::bigTalk insteadof B;
    }
}

class Aliased_Talker {
    use A, B {
        B::smallTalk insteadof A;
        A::bigTalk insteadof B;
        B::bigTalk as talk;
    }
}
?>
]]>
    </programlisting>
   </example>
  </sect2>

  <sect2 xml:id="language.oop5.traits.visibility">
   <title>Changing Method Visibility</title>
   <para>
    Using the <literal>as</literal> syntax, one can also adjust the visibility
    of the method in the exhibiting class.
   </para>
   <example xml:id="language.oop5.traits.visibility.ex1">
    <title>Changing Method Visibility</title>
    <programlisting role="php">
<![CDATA[
<?php
trait HelloWorld {
    public function sayHello() {
        echo 'Hello World!';
    }
}

// Change visibility of sayHello
class MyClass1 {
    use HelloWorld { sayHello as protected; }
}

// Alias method with changed visibility
// sayHello visibility not changed
class MyClass2 {
    use HelloWorld { sayHello as private myPrivateHello; }
}
?>
]]>
    </programlisting>
   </example>
  </sect2>

  <sect2 xml:id="language.oop5.traits.composition">
   <title>Traits Composed from Traits</title>
   <para>
    Just as classes can make use of traits, so can other traits. By using one
    or more traits in a trait definition, it can be composed partially or
    entirely of the members defined in those other traits.
   </para>
   <example xml:id="language.oop5.traits.composition.ex1">
    <title>Traits Composed from Traits</title>
    <programlisting role="php">
<![CDATA[
<?php
trait Hello {
    public function sayHello() {
        echo 'Hello ';
    }
}

trait World {
    public function sayWorld() {
        echo 'World!';
    }
}

trait HelloWorld {
    use Hello, World;
}

class MyHelloWorld {
    use HelloWorld;
}

$o = new MyHelloWorld();
$o->sayHello();
$o->sayWorld();
?>
]]>
    </programlisting>
    &example.outputs;
    <screen>
<![CDATA[
Hello World!
]]>
    </screen>
   </example>
  </sect2>


<sect2 xml:id="language.oop5.traits.abstract">
   <title>Abstract Trait Members</title>
   <para>
    Traits support the use of abstract methods in order to impose requirements
    upon the exhibiting class. Public, protected, and private methods are supported.
    Prior to PHP 8.0.0, only public and protected abstract methods were supported.
   </para>
   <caution>
    <simpara>
     As of PHP 8.0.0, the signature of a concrete method must follow the
     <link linkend="language.oop.lsp">signature compatibility rules</link>.
     Previously, its signature might be different.
    </simpara>
   </caution>
   <example xml:id="language.oop5.traits.abstract.ex1">
    <title>Express Requirements by Abstract Methods</title>
    <programlisting role="php">
<![CDATA[
<?php
trait Hello {
    public function sayHelloWorld() {
        echo 'Hello'.$this->getWorld();
    }
    abstract public function getWorld();
}

class MyHelloWorld {
    private $world;
    use Hello;
    public function getWorld() {
        return $this->world;
    }
    public function setWorld($val) {
        $this->world = $val;
    }
}
?>
]]>
    </programlisting>
   </example>
  </sect2>

  <sect2 xml:id="language.oop5.traits.static">
   <title>Static Trait Members</title>
   <para>
    Traits can define static variables, static methods and static properties.
   </para>
   <note>
    <para>
     As of PHP 8.1.0, calling a static method, or accessing a static property directly on a trait is deprecated.
     Static methods and properties should only be accessed on a class using the trait.
    </para>
   </note>
   <example xml:id="language.oop5.traits.static.ex1">
    <title>Static Variables</title>
    <programlisting role="php">
<![CDATA[
<?php
trait Counter {
    public function inc() {
        static $c = 0;
        $c = $c + 1;
        echo "$c\n";
    }
}

class C1 {
    use Counter;
}

class C2 {
    use Counter;
}

$o = new C1(); $o->inc(); // echo 1
$p = new C2(); $p->inc(); // echo 1
?>
]]>
    </programlisting>
   </example>
   <example xml:id="language.oop5.traits.static.ex2">
    <title>Static Methods</title>
    <programlisting role="php">
<![CDATA[
<?php
trait StaticExample {
    public static function doSomething() {
        return 'Doing something';
    }
}

class Example {
    use StaticExample;
}

Example::doSomething();
?>
]]>
    </programlisting>
   </example>
   <example xml:id="language.oop5.traits.static.ex3">
    <title>Static Properties</title>
    <programlisting role="php">
     <![CDATA[
<?php
trait StaticExample {
    public static $static = 'foo';
}

class Example {
    use StaticExample;
}

echo Example::$static;
?>
]]>
    </programlisting>
   </example>
  </sect2>

  <sect2 xml:id="language.oop5.traits.properties">
   <title>Properties</title>
   <para>
    Traits can also define properties.
   </para>
   <example xml:id="language.oop5.traits.properties.example">
    <title>Defining Properties</title>
    <programlisting role="php">
<![CDATA[
<?php
trait PropertiesTrait {
    public $x = 1;
}

class PropertiesExample {
    use PropertiesTrait;
}

$example = new PropertiesExample;
$example->x;
?>
]]>
    </programlisting>
   </example>
   <para>
    If a trait defines a property then a class can not define a property with
    the same name unless it is compatible (same visibility and type,
    readonly modifier, and initial value), otherwise a fatal error is issued.
   </para>
   <example xml:id="language.oop5.traits.properties.conflicts">
    <title>Conflict Resolution</title>
    <programlisting role="php">
<![CDATA[
<?php
trait PropertiesTrait {
    public $same = true;
    public $different1 = false;
    public bool $different2;
    public bool $different3;
}

class PropertiesExample {
    use PropertiesTrait;
    public $same = true;
    public $different1 = true; // Fatal error
    public string $different2; // Fatal error
    readonly protected bool $different3; // Fatal error
}
?>
]]>
    </programlisting>
   </example>
  </sect2>

 <sect2 xml:id="language.oop5.traits.constants">
  <title>&Constants;</title>
  <para>
   Traits can, as of PHP 8.2.0, also define constants.
  </para>
  <example xml:id="language.oop5.traits.constants.example">
   <title>Defining Constants</title>
   <programlisting role="php">
<![CDATA[
<?php
trait ConstantsTrait {
    public const FLAG_MUTABLE = 1;
    final public const FLAG_IMMUTABLE = 5;
}

class ConstantsExample {
    use ConstantsTrait;
}

$example = new ConstantsExample;
echo $example::FLAG_MUTABLE; // 1
?>
]]>
   </programlisting>
  </example>
  <para>
   If a trait defines a constant then a class can not define a constant with
   the same name unless it is compatible (same visibility, initial value, and
   finality), otherwise a fatal error is issued.
  </para>
  <example xml:id="language.oop5.traits.constants.conflicts">
   <title>Conflict Resolution</title>
   <programlisting role="php">
<![CDATA[
<?php
trait ConstantsTrait {
    public const FLAG_MUTABLE = 1;
    final public const FLAG_IMMUTABLE = 5;
}

class ConstantsExample {
    use ConstantsTrait;
    public const FLAG_IMMUTABLE = 5; // Fatal error
}
?>
]]>
   </programlisting>
  </example>
 </sect2>

 </sect1>
<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-omittag:t
sgml-shorttag:t
sgml-minimize-attributes:nil
sgml-always-quote-attributes:t
sgml-indent-step:1
sgml-indent-data:t
indent-tabs-mode:nil
sgml-parent-document:nil
sgml-default-dtd-file:"~/.phpdoc/manual.ced"
sgml-exposed-tags:nil
sgml-local-catalogs:nil
sgml-local-ecat-files:nil
End:
vim600: syn=xml fen fdm=syntax fdl=2 si
vim: et tw=78 syn=sgml
vi: ts=1 sw=1
-->


<?xml version="1.0" encoding="utf-8"?>
<reference xml:id="class.deprecated" role="class" xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xi="http://www.w3.org/2001/XInclude">
 <title>The Deprecated attribute</title>
 <titleabbrev>Deprecated</titleabbrev>

 <partintro>

  <section xml:id="deprecated.intro">
   &reftitle.intro;
   <simpara>
    This attribute is used to mark functionality as deprecated.
    Using deprecated functionality will cause an <constant>E_USER_DEPRECATED</constant> error to be emitted.
   </simpara>
  </section>

  <section xml:id="deprecated.synopsis">
   &reftitle.classsynopsis;

   <classsynopsis class="class">
    <ooclass>
     <modifier>final</modifier>
     <classname>Deprecated</classname>
    </ooclass>

    <classsynopsisinfo role="comment">&Properties;</classsynopsisinfo>
    <fieldsynopsis>
     <modifier>public</modifier>
     <modifier>readonly</modifier>
     <type class="union"><type>string</type><type>null</type></type>
     <varname linkend="deprecated.props.message">message</varname>
    </fieldsynopsis>
    <fieldsynopsis>
     <modifier>public</modifier>
     <modifier>readonly</modifier>
     <type class="union"><type>string</type><type>null</type></type>
     <varname linkend="deprecated.props.since">since</varname>
    </fieldsynopsis>

    <classsynopsisinfo role="comment">&Methods;</classsynopsisinfo>
    <xi:include xpointer="xmlns(db=http://docbook.org/ns/docbook) xpointer(id('class.deprecated')/db:refentry/db:refsect1[@role='description']/descendant::db:constructorsynopsis[@role='Deprecated'])">
     <xi:fallback/>
    </xi:include>
   </classsynopsis>
  </section>

  <section xml:id="deprecated.props">
   &reftitle.properties;
   <variablelist>
    <varlistentry xml:id="deprecated.props.message">
     <term><varname>message</varname></term>
     <listitem>
      <para>
       An optional message explaining the reason for the deprecation and possible replacement functionality.
       Will be included in the emitted deprecation message.
      </para>
     </listitem>
    </varlistentry>
    <varlistentry xml:id="deprecated.props.since">
     <term><varname>since</varname></term>
     <listitem>
       <para>
        An optional string indicating since when the functionality is deprecated.
        The contents are not validated by PHP and may contain a version number,
        a date or any other value that is considered appropriate.
        Will be included in the emitted deprecation message.
       </para>
       <para>
        Functionality that is part of PHP will use Major.Minor as the <varname>since</varname> value,
        for example <literal>'8.4'</literal>.
       </para>
     </listitem>
    </varlistentry>
   </variablelist>
  </section>

  <section>
   &reftitle.examples;
   <informalexample>
    <programlisting role="php">
<![CDATA[
<?php

#[\Deprecated(message: "use safe_replacement() instead", since: "1.5")]
function unsafe_function()
{
   echo "This is unsafe", PHP_EOL;
}

unsafe_function();

?>
]]>
    </programlisting>
    &example.outputs.84.similar;
    <screen>
<![CDATA[
Deprecated: Function unsafe_function() is deprecated since 1.5, use safe_replacement() instead in example.php on line 9
This is unsafe
]]>
    </screen>
   </informalexample>
  </section>

  <section xml:id="deprecated.seealso">
   &reftitle.seealso;
   <simplelist>
    <member><link linkend="language.attributes">Attributes overview</link></member>
    <member><methodname>ReflectionFunctionAbstract::isDeprecated</methodname></member>
    <member><methodname>ReflectionClassConstant::isDeprecated</methodname></member>
    <member><constant>E_USER_DEPRECATED</constant></member>
   </simplelist>
  </section>

 </partintro>

 &language.predefined.attributes.deprecated.construct;

</reference>
<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-omittag:t
sgml-shorttag:t
sgml-minimize-attributes:nil
sgml-always-quote-attributes:t
sgml-indent-step:1
sgml-indent-data:t
indent-tabs-mode:nil
sgml-parent-document:nil
sgml-default-dtd-file:"~/.phpdoc/manual.ced"
sgml-exposed-tags:nil
sgml-local-catalogs:nil
sgml-local-ecat-files:nil
End:
vim600: syn=xml fen fdm=syntax fdl=2 si
vim: et tw=78 syn=sgml
vi: ts=1 sw=1
-->


<para>
    <variablelist>
     <varlistentry xml:id="ini.short-open-tag">
      <term>
       <parameter>short_open_tag</parameter>
       <type>bool</type>
      </term>
      <listitem>
       <para>
        Tells PHP whether the short form (<userinput><? ?></userinput>)
        of PHP's open tag should be allowed.  If you want to use PHP in
        combination with XML, you can disable this option in order to
        use <userinput><?xml ?></userinput> inline.  Otherwise, you
        can print it with PHP, for example: <userinput><?php echo '<?xml
        version="1.0"?>'; ?></userinput>.  Also, if disabled, you must use the
        long form of the PHP open tag (<userinput><?php ?></userinput>).
       </para>
       <note>
        <para>
         This directive does not affect the shorthand
         <userinput><?=</userinput>, which is always available.
        </para>
       </note>
      </listitem>
     </varlistentry>

     <varlistentry xml:id="ini.precision">
      <term>
       <parameter>precision</parameter>
       <type>int</type>
      </term>
      <listitem>
       <simpara>
        The number of significant digits displayed in floating point numbers.
        <literal>-1</literal> means that an enhanced algorithm for rounding
        such numbers will be used.
       </simpara>
      </listitem>
     </varlistentry>

     <varlistentry xml:id="ini.serialize-precision">
      <term>
       <parameter>serialize_precision</parameter>
       <type>int</type>
      </term>
      <listitem>
       <simpara>
        The number of significant digits stored while serializing floating point numbers.
        <literal>-1</literal> means that an enhanced algorithm for rounding
        such numbers will be used.
      </simpara>
      </listitem>
     </varlistentry>

     <varlistentry xml:id="ini.expose-php">
      <term>
       <parameter>expose_php</parameter>
       <type>bool</type>
      </term>
      <listitem>
       <para>
        Exposes to the world that PHP is installed on the server, which includes the
        PHP version within the HTTP header (e.g., X-Powered-By: PHP/5.3.7).
       </para>
      </listitem>
     </varlistentry>

     <varlistentry xml:id="ini.disable-functions">
      <term>
       <parameter>disable_functions</parameter>
       <type>string</type>
      </term>
      <listitem>
       <simpara>
        This directive allows disables certain functions.
        It takes on a comma-delimited list of function names.
        As of PHP 8.0.0, disabling a function removes it definition
        allowing userland to redefine it.
        Prior to PHP 8.0.0, disabling a function just prevent invoking the function.
       </simpara>
       <simpara>
        Only <link linkend="functions.internal">internal functions</link> can
        be disabled using this directive.
        <link linkend="functions.user-defined">User-defined functions</link>
        are unaffected.
       </simpara>
       <simpara>
        This directive must be set in &php.ini;.
        It cannot be set in &httpd.conf;.
       </simpara>
      </listitem>
     </varlistentry>

     <varlistentry xml:id="ini.disable-classes">
      <term>
       <parameter>disable_classes</parameter>
       <type>string</type>
      </term>
      <listitem>
       <para>
        This directive allows disables certain classes.
        It takes on a comma-delimited list of class names.
        Disabling a class just prevent instantiating the class.
       </para>
       <para>
        Only internal classes can be disabled using this directive.
        User-defined classes are unaffected.
       </para>
       <simpara>
        This directive must be set in &php.ini;.
        It cannot be set in &httpd.conf;.
       </simpara>
      </listitem>
     </varlistentry>

     <varlistentry xml:id="ini.zend.assertions">
      <term>
       <parameter>zend.assertions</parameter>
       <type>int</type>
      </term>
      <listitem>
       <simpara>
        When set to <literal>1</literal>, assertion code will be generated and
        executed (development mode). When set to <literal>0</literal>,
        assertion code will be generated but it will be skipped (not executed)
        at runtime. When set to <literal>-1</literal>, assertion code will not
        be generated, making the assertions zero-cost (production mode).
       </simpara>
       <note>
        <para>
         If a process is started in production mode, <link linkend="ini.zend.assertions">zend.assertions</link>
         cannot be changed at runtime, since the code for assertions was not generated.
        </para>
        <para>
         If a process is started in development mode, <link linkend="ini.zend.assertions">zend.assertions</link>
         cannot be set to <literal>-1</literal> at runtime.
        </para>
       </note>
      </listitem>
     </varlistentry>

     <varlistentry xml:id="ini.zend.exception-string-param-max-len">
      <term>
       <parameter>zend.exception_string_param_max_len</parameter>
       <type>int</type>
      </term>
      <listitem>
       <simpara>
        The maximum length of string function arguments in stringified stack traces.
        Must range between <literal>"0"</literal> and <literal>"1000000"</literal>.
       </simpara>
      </listitem>
     </varlistentry>

     <varlistentry xml:id="ini.hard-timeout">
      <term>
       <parameter>hard_timeout</parameter>
       <type>int</type>
      </term>
      <listitem>
       <para>
        When the timeout set in <link linkend="ini.max-execution-time">max_execution_time</link>
        has been hit, the PHP runtime will tear down resources gracefully. If
        something gets stuck while this happens, the hard timeout will tick
        for the set amount of seconds. When the hard timeout is hit, PHP will
        exit ungracefully. When set to 0, the hard timeout will never activate.
       </para>
       <para>
        When PHP stops from a hard timeout, it will look something like this:
        <screen>
<![CDATA[
Fatal error: Maximum execution time of 30+2 seconds exceeded (terminated) in Unknown on line 0
]]>
        </screen>
       </para>
      </listitem>
     </varlistentry>

     <varlistentry xml:id="ini.zend.exception-ignore-args">
      <term>
       <parameter>zend.exception_ignore_args</parameter>
       <type>bool</type>
      </term>
      <listitem>
       <para>
        Excludes arguments from stack traces generated from exceptions.
       </para>
      </listitem>
     </varlistentry>

     <varlistentry xml:id="ini.zend.multibyte">
      <term>
       <parameter>zend.multibyte</parameter>
       <type>bool</type>
      </term>
      <listitem>
       <para>
        Enables parsing of source files in multibyte encodings. Enabling zend.multibyte
        is required to use character encodings like SJIS, BIG5, etc that contain special
        characters in multibyte string data. ISO-8859-1 compatible encodings like UTF-8,
        EUC, etc do not require this option.
       </para>
       <para>
        Enabling zend.multibyte requires the mbstring extension to be available.
       </para>
      </listitem>
     </varlistentry>

     <varlistentry xml:id="ini.zend.script-encoding">
      <term>
       <parameter>zend.script_encoding</parameter>
       <type>string</type>
      </term>
      <listitem>
       <para>
        This value will be used unless a
        <link linkend="control-structures.declare.encoding">declare(encoding=...)</link>
        directive appears at the top of the script. When ISO-8859-1 incompatible encoding
        is used, both zend.multibyte and zend.script_encoding must be used.
       </para>
       <para>
        Literal strings will be transliterated from zend.script_encoding to
        mbstring.internal_encoding, as if
        <function>mb_convert_encoding</function> would have been called.
       </para>
      </listitem>
     </varlistentry>


<refentry xml:id="function.simdjson-decode" xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink">
 <refnamediv>
  <refname>simdjson_decode</refname>
  <refpurpose>Decodes a JSON string</refpurpose>
 </refnamediv>

 <refsect1 role="description">
  &reftitle.description;
  <methodsynopsis>
   <type>mixed</type><methodname>simdjson_decode</methodname>
   <methodparam><type>string</type><parameter>json</parameter></methodparam>
   <methodparam choice="opt"><type>bool</type><parameter>associative</parameter><initializer>&false;</initializer></methodparam>
   <methodparam choice="opt"><type>int</type><parameter>depth</parameter><initializer>512</initializer></methodparam>
  </methodsynopsis>
  <para>
   Takes a JSON encoded string and converts it into a PHP value.
   This uses a faster Simultaneous Instruction, Multiple Data implementation
   than <function>json_decode</function> when it is supported by the computer architecture.
  </para>
 </refsect1>

 <refsect1 role="parameters">
  &reftitle.parameters;
  <variablelist>
   <varlistentry>
    <term><parameter>json</parameter></term>
    <listitem>
     <para>
      The <parameter>json</parameter> <type>string</type> being decoded.
     </para>
     <para>
      This function only works with UTF-8 encoded strings.
     </para>
     <para>
      This function parses valid inputs which
      <function>json_decode</function> can decode,
      provided that they are less than 4 GiB long.
     </para>
    </listitem>
   </varlistentry>
   <varlistentry>
    <term><parameter>associative</parameter></term>
    <listitem>
     <para>
      When &true;, JSON objects will be returned as
      associative &array;s; when &false;, JSON objects will be returned as &object;s.
     </para>
    </listitem>
   </varlistentry>
   <varlistentry>
    <term><parameter>depth</parameter></term>
    <listitem>
     <para>
      Maximum nesting depth of the structure being decoded.
      The value must be greater than <literal>0</literal>,
      and less than or equal to <literal>2147483647</literal>.

      Callers should use reasonably small values,
      because larger depths require more buffer space and will
      increase the recursion depth, unlike the current <function>json_decode</function> implementation.
     </para>
    </listitem>
   </varlistentry>
  </variablelist>
 </refsect1>

 <refsect1 role="returnvalues">
  &reftitle.returnvalues;
  <para>
   Returns the value encoded in <parameter>json</parameter> in appropriate
   PHP type. Values <literal>true</literal>, <literal>false</literal> and
   <literal>null</literal> are returned as &true;, &false; and &null;
   respectively.
  </para>
 </refsect1>

 <refsect1 role="errors">
  &reftitle.errors;
  <para>
   If <parameter>json</parameter> is invalid, a <classname>SimdJsonException</classname> is thrown as of PECL simdjson 2.1.0,
   while previously, a <classname>RuntimeException</classname> was thrown.
  </para>
  <para>
   If <parameter>depth</parameter> is outside the allowed range,
   a <classname>SimdJsonValueError</classname> is thrown as of PECL simdjson 3.0.0,
   while previously, an error of level <constant>E_WARNING</constant> was raised.
  </para>
 </refsect1>

 <refsect1 role="examples">
  &reftitle.examples;
  <para>
   <example>
    <title><function>simdjson_decode</function> examples</title>
    <programlisting role="php">
<![CDATA[
<?php
$json = '{"a":1,"b":2,"c":3}';

var_dump(simdjson_decode($json));
var_dump(simdjson_decode($json, true));

?>
]]>
    </programlisting>
    &example.outputs;
    <screen>
<![CDATA[
object(stdClass)#1 (3) {
  ["a"]=>
  int(1)
  ["b"]=>
  int(2)
  ["c"]=>
  int(3)
}
array(3) {
  ["a"]=>
  int(1)
  ["b"]=>
  int(2)
  ["c"]=>
  int(3)
}
]]>
    </screen>
   </example>
   <example>
    <title>Accessing invalid object properties</title>
    <simpara>
     Accessing elements within an object that contain characters not
     permitted under PHP's naming convention (e.g. the hyphen) can be
     accomplished by encapsulating the element name within braces and the apostrophe.
    </simpara>
    <programlisting role="php">
<![CDATA[
<?php

$json = '{"foo-bar": 12345}';

$obj = simdjson_decode($json);
print $obj->{'foo-bar'}; // 12345

?>
]]>
    </programlisting>
   </example>
   <example>
    <title>common mistakes using <function>simdjson_decode</function></title>
    <programlisting role="php">
<![CDATA[
<?php

// the following strings are valid JavaScript but not valid JSON

// the name and value must be enclosed in double quotes
// single quotes are not valid
$bad_json = "{ 'bar': 'baz' }";
simdjson_decode($bad_json); // Throws SimdJsonException

// the name must be enclosed in double quotes
$bad_json = '{ bar: "baz" }';
simdjson_decode($bad_json); // Throws SimdJsonException

// trailing commas are not allowed
$bad_json = '{ bar: "baz", }';
simdjson_decode($bad_json); // Throws SimdJsonException

?>
]]>
    </programlisting>
   </example>
   <example>
    <title><parameter>depth</parameter> errors</title>
    <programlisting role="php">
<![CDATA[
<?php
// Encode some data with a maximum depth of 4
// (array -> array -> array -> string)
$json = json_encode(
    [
        1 => [
            'English' => [
                'One',
                'January'
            ],
            'French' => [
                'Une',
                'Janvier'
            ]
        ]
    ]
);

// Show the errors for different depths.
var_dump(simdjson_decode($json, true, 4));
try {
    var_dump(simdjson_decode($json, true, 3));
} catch (SimdJsonException $e) {
     echo "Caught: ", $e->getMessage(), "\n";
}
?>
]]>
    </programlisting>
    &example.outputs;
    <screen>
<![CDATA[
array(1) {
  [1]=>
  array(2) {
    ["English"]=>
    array(2) {
      [0]=>
      string(3) "One"
      [1]=>
      string(7) "January"
    }
    ["French"]=>
    array(2) {
      [0]=>
      string(3) "Une"
      [1]=>
      string(7) "Janvier"
    }
  }
}
Caught: The JSON document was too deep (too many nested objects and arrays)
]]>
    </screen>
   </example>
   <example>
    <title><function>simdjson_decode</function> of large integers</title>
    <programlisting role="php">
<![CDATA[
<?php
$json = '{"number": 12345678901234567890}';

var_dump(simdjson_decode($json));

?>
]]>
    </programlisting>
    &example.outputs;
    <screen>
<![CDATA[
object(stdClass)#1 (1) {
  ["number"]=>
  float(1.2345678901235E+19)
}
]]>
    </screen>
   </example>
  </para>
 </refsect1>

 <refsect1 role="notes">
  &reftitle.notes;
  <note>
   <para>
    The JSON spec is not JavaScript, but a subset of JavaScript.
   </para>
  </note>
  <note>
   <para>
    In the event of a failure to decode,
    a <classname>SimdJsonException</classname> is thrown
    and <methodname>SimdJsonException::getCode</methodname> and
    <methodname>SimdJsonException::getMessage</methodname> can be used
    to determine the exact nature of the error.
   </para>
  </note>
 </refsect1>

 <refsect1 role="seealso">
  &reftitle.seealso;
  <para>
   <simplelist>
    <member><function>json_encode</function></member>
    <member><function>json_decode</function></member>
   </simplelist>
  </para>
 </refsect1>
</refentry>