<?xml version="1.0" encoding="utf-8"?>
<!-- $Revision$ -->
<refentry xml:id="function.substr" xmlns="http://docbook.org/ns/docbook">
 <refnamediv>
  <refname>substr</refname>
  <refpurpose>Return part of a string</refpurpose>
 </refnamediv>
 
 <refsect1 role="description">
  &reftitle.description;
  <methodsynopsis>
   <type>string</type><methodname>substr</methodname>
   <methodparam><type>string</type><parameter>string</parameter></methodparam>
   <methodparam><type>int</type><parameter>offset</parameter></methodparam>
   <methodparam choice="opt"><type class="union"><type>int</type><type>null</type></type><parameter>length</parameter><initializer>&null;</initializer></methodparam>
  </methodsynopsis>
  <para>
   Returns the portion of <parameter>string</parameter> specified by the
   <parameter>offset</parameter> and <parameter>length</parameter> parameters.
  </para>
 </refsect1>

 <refsect1 role="parameters">
  &reftitle.parameters;
  <para>
   <variablelist>
    <varlistentry>
     <term><parameter>string</parameter></term>
     <listitem>
      <para>
       The input string.
      </para>
     </listitem>
    </varlistentry>
    <varlistentry>
     <term><parameter>offset</parameter></term>
     <listitem>
      <para>
       If <parameter>offset</parameter> is non-negative, the returned string
       will start at the <parameter>offset</parameter>'th position in
       <parameter>string</parameter>, counting from zero. For instance,
       in the string '<literal>abcdef</literal>', the character at
       position <literal>0</literal> is '<literal>a</literal>', the
       character at position <literal>2</literal> is
       '<literal>c</literal>', and so forth.
      </para>
      <para>
       If <parameter>offset</parameter> is negative, the returned string
       will start at the <parameter>offset</parameter>'th character
       from the end of <parameter>string</parameter>.
      </para>
      <para>
       If <parameter>string</parameter> is less than
       <parameter>offset</parameter> characters long, an empty string will be returned.
      </para>
      <para>
       <example>
        <title>Using a negative <parameter>offset</parameter></title>
        <programlisting role="php">
<![CDATA[
<?php
$rest = substr("abcdef", -1);    // returns "f"
$rest = substr("abcdef", -2);    // returns "ef"
$rest = substr("abcdef", -3, 1); // returns "d"
?>
]]>
        </programlisting>
       </example>
      </para>
     </listitem>
    </varlistentry>
    <varlistentry>
     <term><parameter>length</parameter></term>
     <listitem>
      <para>
       If <parameter>length</parameter> is given and is positive, the string
       returned will contain at most <parameter>length</parameter> characters
       beginning from <parameter>offset</parameter> (depending on the length of
       <parameter>string</parameter>).
      </para>
      <para>
       If <parameter>length</parameter> is given and is negative, then that many
       characters will be omitted from the end of <parameter>string</parameter>
       (after the start position has been calculated when a
       <parameter>offset</parameter> is negative).  If
       <parameter>offset</parameter> denotes the position of this truncation or
       beyond, an empty string will be returned.
      </para>
      <para>
       If <parameter>length</parameter> is given and is <literal>0</literal>,
       &false; or &null;, an empty string will be returned.
      </para>
      <para>
       If <parameter>length</parameter> is omitted, the substring starting from
       <parameter>offset</parameter> until the end of the string will be
       returned.
      </para>
      <example>
       <title>Using a negative <parameter>length</parameter></title>
       <programlisting role="php">
<![CDATA[
<?php
$rest = substr("abcdef", 0, -1);  // returns "abcde"
$rest = substr("abcdef", 2, -1);  // returns "cde"
$rest = substr("abcdef", 4, -4);  // returns ""; prior to PHP 8.0.0, false was returned
$rest = substr("abcdef", -3, -1); // returns "de"
?>
]]>
       </programlisting>
      </example>
     </listitem>
    </varlistentry>
   </variablelist>
  </para>
 </refsect1>

 <refsect1 role="returnvalues">
  &reftitle.returnvalues;
  <para>
   Returns the extracted part of <parameter>string</parameter>, or
   an empty string.
  </para>
 </refsect1>

 <refsect1 role="changelog">
  &reftitle.changelog;
  <informaltable>
   <tgroup cols="2">
    <thead>
     <row>
      <entry>&Version;</entry>
      <entry>&Description;</entry>
     </row>
    </thead>
    <tbody>
     <row>
      <entry>8.0.0</entry>
      <entry>
       <parameter>length</parameter> is nullable now.
      </entry>
     </row>
     <row>
      <entry>8.0.0</entry>
      <entry>
       The function returns an empty string where it previously returned &false;.
      </entry>
     </row>
    </tbody>
   </tgroup>
  </informaltable>
 </refsect1>

 <refsect1 role="examples">
  &reftitle.examples;
  <para>
   <example>
    <title>Basic <function>substr</function> usage</title>
    <programlisting role="php">
<![CDATA[
<?php
echo substr('abcdef', 1);     // bcdef
echo substr('abcdef', 1, 3);  // bcd
echo substr('abcdef', 0, 4);  // abcd
echo substr('abcdef', 0, 8);  // abcdef
echo substr('abcdef', -1, 1); // f

// Accessing single characters in a string
// can also be achieved using "square brackets"
$string = 'abcdef';
echo $string[0];                 // a
echo $string[3];                 // d
echo $string[strlen($string)-1]; // f

?>
]]>
    </programlisting>
   </example> 
   <example>
    <title><function>substr</function> casting behaviour</title>
    <programlisting role="php">
<![CDATA[
<?php
class apple {
    public function __toString() {
        return "green";
    }
}

echo "1) ".var_export(substr("pear", 0, 2), true).PHP_EOL;
echo "2) ".var_export(substr(54321, 0, 2), true).PHP_EOL;
echo "3) ".var_export(substr(new apple(), 0, 2), true).PHP_EOL;
echo "4) ".var_export(substr(true, 0, 1), true).PHP_EOL;
echo "5) ".var_export(substr(false, 0, 1), true).PHP_EOL;
echo "6) ".var_export(substr("", 0, 1), true).PHP_EOL;
echo "7) ".var_export(substr(1.2e3, 0, 4), true).PHP_EOL;
?>
]]>
    </programlisting>
    &example.outputs;
    <screen>
<![CDATA[
1) 'pe'
2) '54'
3) 'gr'
4) '1'
5) ''
6) ''
7) '1200'
]]>
    </screen>
   </example>
  <example>
   <title>Invalid Character Range</title>
   <para>
    If an invalid character range is requested, <function>substr</function> returns
    an empty string as of PHP 8.0.0; previously, &false; was returned instead.
   </para>
   <example>
    <programlisting role="php">
<![CDATA[
<?php
var_dump(substr('a', 2));
?>
]]>
    </programlisting>
    &example.outputs.8;
    <screen>
<![CDATA[
string(0) ""
]]>]
    </screen>
    &example.outputs.7;
    <screen>
<![CDATA[
bool(false)
]]>
    </screen>
   </example>
  </example>
  </para>
 </refsect1>

 <refsect1 role="seealso">
  &reftitle.seealso;
  <para>
   <simplelist>
    <member><function>strrchr</function></member>
    <member><function>substr_replace</function></member>
    <member><function>preg_match</function></member>
    <member><function>trim</function></member>
    <member><function>mb_substr</function></member>
    <member><function>wordwrap</function></member>
    <member><link linkend="language.types.string.substr">String access and modification by character</link></member>
   </simplelist>
  </para>
 </refsect1>

</refentry>
<!-- 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
-->