<sect1 id="zend.session.basic_usage">

    <title>基本用法</title>

    <para>
        在Zend Framework中，<code>Zend_Session_Namespace</code>实例提供了操作会话数据主要的API。命名空间常用于隔离所有的会话数据，尽管也为所有会话数据只需要一个命名空间的情况提供了一个默认的命名空间。Zend_Session利用了PHP内置的会话模块（ext/session），以及它特有的<code>$_SESSION</code>全局数组做为会话状态数据的存储机制。虽然<code>$_SESSION</code>在PHP的全局命名空间内仍然可以访问，但是开发者不应该直接访问它，这样<code>Zend_Session</code> 和 <code>Zend_Session_Namespace</code>可以提供一组最可靠、安全的处理会话相关的功能。
    </para>

    <para>
        每个<code>Zend_Session_Namespace</code>的实例对应于<code>$_SESSION</code>全局数组的一个条目，在那里命名空间被用作键。

        <programlisting role="php"><![CDATA[<?php
require_once 'Zend/Session/Namespace.php';

$myNamespace = new Zend_Session_Namespace('myNamespace');

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

         用Zend_Session直接和其它使用 <code>$_SESSION</code>的代码协同工作是可能的。然而，为避免问题，强烈建议这样的代码只使用<code>$_SESSION</code>中不和<code>Zend_Session_Namespace</code>的实例想对应的部分。
    </para>

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

        <title>实例教程</title>

        <para>
            在初始化Zend_Session时，如果没有指定命名空间，所有的数据将被透明地储存在<code>'Default'</code>命名空间下。<code>Zend_Session</code>不打算直接处理会话命名空间容器的内容，取而代之，我们可以使用<code>Zend_Session_Namespace</code>。下面的例子演示了缺省命名空间的使用，和怎样计算用户访问页面的次数：
        </para>

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

            <title>页面浏览计数</title>

            <programlisting role="php"><![CDATA[<?php
require_once 'Zend/Session/Namespace.php';

$defaultNamespace = new Zend_Session_Namespace('Default');

if (isset($defaultNamespace->numberOfPageRequests)) {
    $defaultNamespace->numberOfPageRequests++; // 每次页面加载，这个将递增
} else {
    $defaultNamespace->numberOfPageRequests = 1; // 第一次
}

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

        </example>

        <para>
            当多个模块使用<code>Zend_Session_Namespace</code>的实例拥有不同的命名空间，每个模块为它自己的会话数据获得数据封装。可以传递给<code>Zend_Session_Namespace</code>构造函数一个可选的<code>$namespace</code>参数，它允许开发者分割会话数据到分离的命名空间。命名空间机制提供了一个有效的、流行的方法来确保处于命名空间之下的会话数据不遭到意外地改变。
        </para>

        <para>
            命名空间的名称被限定为字符序列，它表示为不以下划线("<code>_</code>")开头的非空PHP字符串。只有Zend Framework的核心模块可使用以"<code>Zend</code>"开头的命名空间的名称。
        </para>

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

            <title>新方法： 使用命名空间避免冲突</title>

            <programlisting role="php"><![CDATA[<?php
require_once 'Zend/Session/Namespace.php';

// 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>
            上述例子中的代码与下面的代码有相同的效果，不过，上述例子中的会话对象把会话数据封装进了各自的命名空间。
        </para>

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

            <title>老方法: PHP会话访问</title>

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

        </example>

    </sect2>

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

        <title>迭代会话命名空间</title>

        <para>
            <code>Zend_Session_Namespace</code>提供了<ulink url="http://www.php.net/~helly/php/ext/spl/interfaceIteratorAggregate.html">IteratorAggregate接口</ulink>所有的能力，包括对<code>foreach</code>语句的支持：
        </para>

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

            <title>会话迭代</title>

            <programlisting role="php"><![CDATA[<?php
require_once 'Zend/Session/Namespace.php';

$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>会话命名空间的访问器</title>

        <para>
            <code>Zend_Session_Namespace</code>实现<code>__get()</code>, <code>__set()</code>, <code>__isset()</code>, and <code>__unset()</code>这些 <ulink url="http://www.php.net/manual/en/language.oop5.overloading.php">魔术方法</ulink>，除了在一个子类里，这些魔术方法不能被直接调用。相反，正常的操作符自动调用这些方法，如下例所示：
        </para>

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

            <title>访问会话数据</title>

            <programlisting role="php"><![CDATA[<?php
require_once 'Zend/Session/Namespace.php';

$namespace = new Zend_Session_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>
