<?xml version="1.0" encoding="UTF-8"?>
<!-- Reviewed: no -->
<sect1 id="zend.uri.chapter">
    <title>Zend_Uri</title>

    <sect2 id="zend.uri.overview">
        <title>Overview</title>

        <para>
            <classname>Zend_Uri</classname> is a component that aids in manipulating and validating
            <ulink url="http://www.w3.org/Addressing/">Uniform Resource Identifiers</ulink> (URIs).
            <classname>Zend_Uri</classname> exists primarily to service other components, such as
            <classname>Zend_Http_Client</classname>, but is also useful as a standalone utility.
        </para>

        <para>
            <acronym>URI</acronym>s always begin with a scheme, followed by a colon. The
            construction of the many different schemes varies significantly. The
            <classname>Zend_Uri</classname> class provides a factory that returns a subclass
            of itself which specializes in each scheme. The subclass will be named
            <classname>Zend_Uri_&lt;scheme&gt;</classname>, where
            <emphasis>&lt;scheme&gt;</emphasis> is the scheme, lowercased with the first letter
            capitalized. An exception to this rule is <acronym>HTTPS</acronym>, which is also
            handled by <classname>Zend_Uri_Http</classname>.
        </para>
    </sect2>

    <sect2 id="zend.uri.creation">
        <title>Creating a New URI</title>

        <para>
            <classname>Zend_Uri</classname> will build a new <acronym>URI</acronym> from scratch
            if only a scheme is passed to <methodname>Zend_Uri::factory()</methodname>.
        </para>

        <example id="zend.uri.creation.example-1">
            <title>Creating a New URI with Zend_Uri::factory()</title>

            <programlisting language="php"><![CDATA[
// To create a new URI from scratch, pass only the scheme.
$uri = Zend_Uri::factory('http');

// $uri instanceof Zend_Uri_Http
]]></programlisting>
        </example>

        <para>
            To create a new <acronym>URI</acronym> from scratch, pass only the scheme to
            <methodname>Zend_Uri::factory()</methodname><footnote><para>At the time of writing,
            <classname>Zend_Uri</classname> only provides built-in support for the <acronym>HTTP</acronym>
            and <acronym>HTTPS</acronym> schemes.</para></footnote>. If an unsupported scheme is
            passed and no scheme-specific class is specified, a <classname>Zend_Uri_Exception</classname>
            will be thrown.
        </para>

        <para>
            If the scheme or <acronym>URI</acronym> passed is supported,
            <methodname>Zend_Uri::factory()</methodname> will return a subclass of itself that
            specializes in the scheme to be created.
        </para>

        <sect3>
            <title>Creating a New Custom-Class URI</title>

            <para>
                Starting from Zend Framework 1.10.5, you can specify a custom class to be
                used when creating the Zend_Uri instance, as a second parameter to the
                <methodname>Zend_Uri::factory()</methodname> method.
                This enables you to subclass Zend_Uri and create your own custom URI classes,
                and instantiate new URI objects based on your own custom classes.
            </para>

            <para>
                The 2nd parameter passed to <methodname>Zend_Uri::factory()</methodname> must
                be a string with the name of a class extending <classname>Zend_Uri</classname>.
                The class must either be alredy-loaded, or loadable using <methodname>Zend_Loader::loadClass()</methodname> -
                that is, it must follow the Zend Framework class and file naming conventions, and
                must be in your include_path.
            </para>

            <example id="zend.uri.creation.custom.example-1">
                <title>Creating a URI using a custom class</title>

                <programlisting language="php"><![CDATA[
// Create a new 'ftp' URI based on a custom class
$ftpUri = Zend_Uri::factory(
    'ftp://user@ftp.example.com/path/file',
    'MyLibrary_Uri_Ftp'
);

// $ftpUri is an instance of MyLibrary_Uri_Ftp, which is a subclass of Zend_Uri
]]></programlisting>
            </example>
        </sect3>

    </sect2>

    <sect2 id="zend.uri.manipulation">
        <title>Manipulating an Existing URI</title>

        <para>
            To manipulate an existing <acronym>URI</acronym>, pass the entire <acronym>URI</acronym>
            to <methodname>Zend_Uri::factory()</methodname>.
        </para>

        <example id="zend.uri.manipulation.example-1">
            <title>Manipulating an Existing URI with Zend_Uri::factory()</title>

            <programlisting language="php"><![CDATA[
// To manipulate an existing URI, pass it in.
$uri = Zend_Uri::factory('http://www.zend.com');

// $uri instanceof Zend_Uri_Http
]]></programlisting>
        </example>

        <para>
            The <acronym>URI</acronym> will be parsed and validated. If it is found to be invalid,
            a <classname>Zend_Uri_Exception</classname> will be thrown immediately. Otherwise,
            <methodname>Zend_Uri::factory()</methodname> will return a subclass of itself that
            specializes in the scheme to be manipulated.
        </para>
    </sect2>

    <sect2 id="zend.uri.validation">
        <title>URI Validation</title>

        <para>
            The <methodname>Zend_Uri::check()</methodname> method can only be used if validation
            of an existing <acronym>URI</acronym> is needed.
        </para>

        <example id="zend.uri.validation.example-1">
            <title>URI Validation with Zend_Uri::check()</title>

            <programlisting language="php"><![CDATA[
// Validate whether a given URI is well formed
$valid = Zend_Uri::check('http://uri.in.question');

// $valid is TRUE for a valid URI, or FALSE otherwise.
]]></programlisting>
        </example>

        <para>
            <methodname>Zend_Uri::check()</methodname> returns a boolean, which is more convenient
            than using <methodname>Zend_Uri::factory()</methodname> and catching the exception.
        </para>

        <sect3 id="zend.uri.validation.allowunwise">
            <title>Allowing "Unwise" characters in URIs</title>

            <para>
                By default, <classname>Zend_Uri</classname> will not accept the following
                characters: <emphasis>"{", "}", "|", "\", "^", "`"</emphasis>. These characters are
                defined by the <acronym>RFC</acronym> as "unwise" and invalid; however, many
                implementations do accept these characters as valid.
            </para>

            <para>
                <classname>Zend_Uri</classname> can be set to accept these "unwise" characters by
                setting the 'allow_unwise' option to boolean <constant>TRUE</constant> using
                <methodname>Zend_Uri::setConfig()</methodname>:
            </para>

            <example id="zend.uri.validation.allowunwise.example-1">
                <title>Allowing special characters in URIs</title>

                <programlisting language="php"><![CDATA[
// Contains '|' symbol
// Normally, this would return false:
$valid = Zend_Uri::check('http://example.com/?q=this|that');

// However, you can allow "unwise" characters
Zend_Uri::setConfig(array('allow_unwise' => true));

// will return 'true'
$valid = Zend_Uri::check('http://example.com/?q=this|that');

// Reset the 'allow_unwise' value to the default FALSE
Zend_Uri::setConfig(array('allow_unwise' => false));
]]></programlisting>
            </example>

            <note>
                <para>
                    <methodname>Zend_Uri::setConfig()</methodname> sets configuration options
                    globally. It is recommended to reset the 'allow_unwise' option to
                    '<constant>FALSE</constant>', like in the example above, unless you are certain
                    you want to always allow unwise characters globally.
                </para>
            </note>
        </sect3>
    </sect2>

    <sect2 id="zend.uri.instance-methods">
        <title>Common Instance Methods</title>

        <para>
            Every instance of a <classname>Zend_Uri</classname> subclass (e.g.
            <classname>Zend_Uri_Http</classname>) has several instance methods that are useful for
            working with any kind of <acronym>URI</acronym>.
        </para>

        <sect3 id="zend.uri.instance-methods.getscheme">
            <title>Getting the Scheme of the URI</title>

            <para>
                The scheme of the <acronym>URI</acronym> is the part of the <acronym>URI</acronym>
                that precedes the colon. For example, the scheme of
                <filename>http://www.zend.com</filename> is 'http'.
            </para>

            <example id="zend.uri.instance-methods.getscheme.example-1">
                <title>Getting the Scheme from a Zend_Uri_* Object</title>

                <programlisting language="php"><![CDATA[
$uri = Zend_Uri::factory('http://www.zend.com');

$scheme = $uri->getScheme();  // "http"
]]></programlisting>
            </example>

            <para>
                The <methodname>getScheme()</methodname> instance method returns only the scheme
                part of the <acronym>URI</acronym> object.
            </para>
        </sect3>

        <sect3 id="zend.uri.instance-methods.geturi">
            <title>Getting the Entire URI</title>

            <example id="zend.uri.instance-methods.geturi.example-1">
                <title>Getting the Entire URI from a Zend_Uri_* Object</title>

                <programlisting language="php"><![CDATA[
$uri = Zend_Uri::factory('http://www.zend.com');

echo $uri->getUri();  // "http://www.zend.com"
]]></programlisting>
            </example>

            <para>
                The <methodname>getUri()</methodname> method returns the string representation
                of the entire <acronym>URI</acronym>.
            </para>
        </sect3>

        <sect3 id="zend.uri.instance-methods.valid">
            <title>Validating the URI</title>

            <para>
                <methodname>Zend_Uri::factory()</methodname> will always validate any
                <acronym>URI</acronym> passed to it and will not instantiate a new
                <classname>Zend_Uri</classname> subclass if the given <acronym>URI</acronym> is
                found to be invalid. However, after the <classname>Zend_Uri</classname> subclass is
                instantiated for a new <acronym>URI</acronym> or an existing valid one, it is
                possible that the <acronym>URI</acronym> can later become invalid after it
                is manipulated.
            </para>

            <example id="zend.uri.instance-methods.valid.example-1">
                <title>Validating a Zend_Uri_* Object</title>

                <programlisting language="php"><![CDATA[
$uri = Zend_Uri::factory('http://www.zend.com');

$isValid = $uri->valid();  // TRUE
]]></programlisting>
            </example>

            <para>
                The <methodname>valid()</methodname> instance method provides a means to check that
                the <acronym>URI</acronym> object is still valid.
            </para>
        </sect3>
    </sect2>
</sect1>
<!--
vim:se ts=4 sw=4 et:
-->
