<?xml version="1.0" encoding="UTF-8"?>
<!-- Reviewed: no -->
<sect1 id="zend.session.basic_usage">

    <title>Basic Usage</title>

    <para>
        <classname>Zend_Session_Namespace</classname> instances provide the primary API for manipulating session data in the Zend
        Framework. Namespaces are used to segregate all session data, although a default namespace exists for those who
        only want one namespace for all their session data. <classname>Zend_Session</classname> utilizes ext/session and its
        special <varname>$_SESSION</varname> superglobal as the storage mechanism for session state data. While
        <varname>$_SESSION</varname> is still available in PHP's global namespace, developers should refrain from directly
        accessing it, so that <classname>Zend_Session</classname> and <classname>Zend_Session_Namespace</classname> can most effectively and
        securely provide its suite of session related functionality.
    </para>

    <para>
        Each instance of <classname>Zend_Session_Namespace</classname> corresponds to an entry of the <varname>$_SESSION</varname>
        superglobal array, where the namespace is used as the key.

        <programlisting language="php"><![CDATA[
$myNamespace = new Zend_Session_Namespace('myNamespace');

// $myNamespace corresponds to $_SESSION['myNamespace']
]]></programlisting>

        It is possible to use Zend_Session in conjunction with other code that uses <varname>$_SESSION</varname> directly. To
        avoid problems, however, it is highly recommended that such code only uses parts of <varname>$_SESSION</varname> that
        do not correspond to instances of <classname>Zend_Session_Namespace</classname>.
    </para>

    <sect2 id="zend.session.basic_usage.basic_examples">

        <title>Tutorial Examples</title>

        <para>
            If no namespace is specified when instantiating <classname>Zend_Session_Namespace</classname>, all data will be
            transparently stored in a namespace called "<code>Default</code>". <classname>Zend_Session</classname> is not intended
            to work directly on the contents of session namespace containers. Instead, we use
            <classname>Zend_Session_Namespace</classname>. The example below demonstrates use of this default namespace, showing
            how to count the number of client requests during a session:
        </para>

        <example id="zend.session.basic_usage.basic_examples.example.counting_page_views">

            <title>Counting Page Views</title>

            <programlisting language="php"><![CDATA[
$defaultNamespace = new Zend_Session_Namespace('Default');

if (isset($defaultNamespace->numberOfPageRequests)) {
    // this will increment for each page load.
    $defaultNamespace->numberOfPageRequests++;
} else {
    $defaultNamespace->numberOfPageRequests = 1; // first time
}

echo "Page requests this session: ",
    $defaultNamespace->numberOfPageRequests;
]]></programlisting>

        </example>

        <para>
            When multiple modules use instances of <classname>Zend_Session_Namespace</classname> having different namespaces, each
            module obtains data encapsulation for its session data. The <classname>Zend_Session_Namespace</classname> constructor
            can be passed an optional <varname>$namespace</varname> argument, which allows developers to partition session
            data into separate namespaces. Namespacing provides an effective and popular way to secure session state
            data against changes due to accidental naming collisions.
        </para>

        <para>
            Namespace names are restricted to character sequences represented as non-empty PHP strings that do not begin
            with an underscore ("<code>_</code>") character. Only core components included in Zend Framework should
            use namespace names starting with "<code>Zend</code>".
        </para>

        <example id="zend.session.basic_usage.basic_examples.example.namespaces.new">

            <title>New Way: Namespaces Avoid Collisions</title>

            <programlisting language="php"><![CDATA[
// in the Zend_Auth component
$authNamespace = new Zend_Session_Namespace('Zend_Auth');
$authNamespace->user = "myusername";

// in a web services component
$webServiceNamespace = new Zend_Session_Namespace('Some_Web_Service');
$webServiceNamespace->user = "mywebusername";
]]></programlisting>

        </example>

        <para>
            The example above achieves the same effect as the code below, except that the session objects above preserve
            encapsulation of session data within their respective namespaces.
        </para>

        <example id="zend.session.basic_usage.basic_examples.example.namespaces.old">

            <title>Old Way: PHP Session Access</title>

            <programlisting language="php"><![CDATA[
$_SESSION['Zend_Auth']['user'] = "myusername";
$_SESSION['Some_Web_Service']['user'] = "mywebusername";
]]></programlisting>

        </example>

    </sect2>

    <sect2 id="zend.session.basic_usage.iteration">

        <title>Iterating Over Session Namespaces</title>

        <para>
            <classname>Zend_Session_Namespace</classname> provides the full
            <ulink url="http://www.php.net/~helly/php/ext/spl/interfaceIteratorAggregate.html">IteratorAggregate
            interface</ulink>, including support for the <code>foreach</code> statement:
        </para>

        <example id="zend.session.basic_usage.iteration.example">

            <title>Session Iteration</title>

            <programlisting language="php"><![CDATA[
$aNamespace =
    new Zend_Session_Namespace('some_namespace_with_data_present');

foreach ($aNamespace as $index => $value) {
    echo "aNamespace->$index = '$value';\n";
}
]]></programlisting>

        </example>

    </sect2>

    <sect2 id="zend.session.basic_usage.accessors">

        <title>Accessors for Session Namespaces</title>

        <para>
            <classname>Zend_Session_Namespace</classname> implements the <methodname>__get()</methodname>, <methodname>__set()</methodname>,
            <methodname>__isset()</methodname>, and <methodname>__unset()</methodname>
            <ulink url="http://www.php.net/manual/en/language.oop5.overloading.php">magic methods</ulink>, which should
            not be invoked directly, except from within a subclass. Instead, the normal operators automatically invoke
            these methods, such as in the following example:
        </para>

        <example id="zend.session.basic_usage.accessors.example">

            <title>Accessing Session Data</title>

            <programlisting language="php"><![CDATA[
$namespace = new Zend_Session_Namespace(); // default namespace

$namespace->foo = 100;

echo "\$namespace->foo = $namespace->foo\n";

if (!isset($namespace->bar)) {
    echo "\$namespace->bar not set\n";
}

unset($namespace->foo);
]]></programlisting>

        </example>

    </sect2>

</sect1>
