Procházet zdrojové kódy

[DOCUMENTATION] Russian:
- Sync with r22743
- added EN-Revision tag

git-svn-id: http://framework.zend.com/svn/framework/standard/trunk@23640 44c647ce-9c0f-0410-b52a-842ac1e357ba

xerkus před 15 roky
rodič
revize
0ba7242a24

+ 1 - 0
documentation/manual/ru/module_specs/Zend_Application-Introduction.xml

@@ -1,4 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
+<!-- EN-Revision: 15814 -->
 <!-- Reviewed: no -->
 <sect1 id="zend.application.introduction">
     <title>Введение</title>

+ 382 - 697
documentation/manual/ru/module_specs/Zend_Session-AdvancedUsage.xml

@@ -1,847 +1,532 @@
-<sect1 id="zend.session.advancedusage">
-
-    <title>Расширенное использование<!--Advanced Usage--></title>
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- EN-Revision: 22743 -->
+<!-- Reviewed: no -->
+<sect1 id="zend.session.advanced_usage">
+    <title>Расширенное использование</title>
 
     <para>
-        Хотя базовое использование является совершенно допустимым вариантом
-        использования сессий Zend Framework, стоит рассмотреть другие
-        возможности их использования. См.
-        <link linkend="zend.auth.introduction.using"> пример на
-        <code>Zend_Auth</code></link>, который по умолчанию неявно
-        использует Zend_Session_Namespace для сохранения меток аутентификации.
-        Этот пример показывает один из способов быстрой и легкой интеграции
-        Zend_Session_Namespace и Zend_Auth.
-<!--
-        While the basic usage examples are a perfectly acceptable way to utilize Zend Framework sessions, there are some
-        best practices to consider. Consider the
-        <link linkend="zend.auth.introduction.using"><code>Zend_Auth</code> example</link>
-        that transparently uses Zend_Session_Namespace by default to persist authentication tokens. This example shows
-        one approach to quickly and easily integrate Zend_Session_Namespace and Zend_Auth.
--->
+        Хотя базовое использование является совершенно допустимым вариантом использования
+        сессий Zend Framework, стоит рассмотреть другие возможности их использования.
+        В этой секции обсуждаются тонкости работы с сессиями и показывается более продвинутое
+        использование компонента <classname>Zend_Session</classname>.
     </para>
 
-    <sect2 id="zend.session.startingasession">
-
-        <title>Старт сессии<!--Starting a Session--></title>
+    <sect2 id="zend.session.advanced_usage.starting_a_session">
+        <title>Запуск сессии</title>
 
         <para>
-            Если вы хотите, чтобы все запросы имели сессии и использовали
-            сессии Zend Framework, то стартуйте сессию в файле загрузки:
-<!--
-            If you want all requests to have a session and use Zend Framework sessions, then start the session in the
-            bootstrap file:
--->
+            Если вы хотите, чтобы все запросы использовали сессии через
+            <classname>Zend_Session</classname>, тогда запускайте сессию в файле инициализации 
+            (bootstrap):
         </para>
 
-        <example>
-            <title>Старт общей сессии<!--Starting the Global Session--></title>
-<programlisting language="php">
-<![CDATA[<?php
-...
-require_once 'Zend/Session.php';
+        <example id="zend.session.advanced_usage.starting_a_session.example">
+            <title>Запуск глобальной сессии</title>
+
+            <programlisting language="php"><![CDATA[
 Zend_Session::start();
-...
-?>]]></programlisting>
+]]></programlisting>
         </example>
 
         <para>
-            Стартуя сессию в файле загрузки, вы исключаете вероятность того, что
-            старт сессии произойдет после того, как заголовки будут
-            отправлены броузеру, что вызвовет исключение и, возможно,
-            отображение испорченной страницы посетителю сайта. Некоторые
-            расширенные возможности Zend_Session требуют вызова
-            <code>Zend_Session_Core::start()</code> в начале (больше о
-            расширенных возможностях будет написано позднее).
-<!--
-            By starting the session in the bootstrap file, you avoid the possibility that your session might be started
-            after headers have been sent to the browser, which results in an exception, and possibly a broken page for
-            website viewers. Various advanced features require <code>Zend_Session_Core::start()</code> first. (More on
-            advanced features later).
--->
+            Запуская сессию в файле инициализации, вы исключаете вероятность её запуска после
+            отправки заголовков браузеру, генерации исключения и возможного
+            отображения испорченой страницы посетителю сайта. Некоторые расширенные возможности
+            так же требуют вызова <methodname>Zend_Session::start()</methodname> до начала их
+            использования (Подробнее о расширенных возможностях будет написано позднее.)
         </para>
 
         <para>
-            Есть четыре способа стартовать сессию, используя Zend_Session. Два
-            из них - неправильные.
-<!--            There are four ways to start a session, when using Zend_Session. Two are wrong.
--->
+            Существует четыре способа запустить сессию, используя 
+            <classname>Zend_Session</classname>. Два из них - неправильные.
         </para>
 
-        <itemizedlist mark='opencircle'>
+        <orderedlist>
             <listitem>
                 <para>
-                    1. Неправильно: Устанавливать опцию session.auto_start в
-                    php.ini или .htaccess (http://www.php.net/manual/en/ref.session.php#ini.session.auto-start).
-                    Если вы не имеете возможность отключить эту опцию в php.ini,
-                    то, если используется mod_php (или его эквивалент) и в
-                    php.ini уже установлена эта опция, добавьте строку
-                    <code>php_value session.auto_start 0</code> в ваш файл
-                    .htaccess (обычно находится в корневой директории для
-                    HTML-документов).
-<!--
-                    1. Wrong: Do not set PHP's session.auto_start ini setting in either php.ini or .htaccess
-                    (http://www.php.net/manual/en/ref.session.php#ini.session.auto-start). If you do not have the
-                    ability to disable this setting in php.ini, you are using mod_php (or equivalent), and the setting
-                    is already enabled in php.ini, then add <code>php_value session.auto_start 0</code> to your
-                    .htaccess file (usually in your HTML document root directory).
--->
+                    Неправильно: Не устанавливайте параметр <acronym>PHP</acronym> конфигурации
+                    <ulink
+                        url="http://www.php.net/manual/en/ref.session.php#ini.session.auto-start">
+                        <code>session.auto_start</code></ulink>. Если у вас нет возможности
+                    отключить этот параметр в <code>php.ini</code>, вы используете mod_php(или
+                    аналог), тогда добавьте следующие строки в ваш <code>.htaccess</code> файл
+                    (Обычно находится в корневой директории для <acronym>HTML</acronym>-документов):
                 </para>
+
+                <programlisting language="httpd.conf"><![CDATA[
+php_value session.auto_start 0
+]]></programlisting>
             </listitem>
+
             <listitem>
                 <para>
-                    2. Неправильно: Непосредственно использовать функцию
-                    <ulink url="http://www.php.net/session_start"><code>session_start()</code></ulink>.
-                    Если вы вызываете <code>session_start()</code> напрямую и
-                    начинаете использование Zend_Session_Namespace, то при
-                    вызове метода <code>Zend_Session::start()</code> будет
-                    сгенерировано исключение ("session has already been
-                    started"). Если вы вызываете <code>session_start()</code>
-                    после использования Zend_Session_Namespace или явного вызова
-                    <code>Zend_Session::start()</code>, то будет сгенерирована
-                    ошибка уровня E_NOTICE и проигнорирован вызов функции.
-<!--
-                    2. Wrong: Do not use PHP's <code>
-                    <ulink url="http://www.php.net/session_start">session_start()</ulink>
-                    </code> function directly. If you use <code>session_start()</code> directly, and then start using
-                    Zend_Session_Namespace, an exception will be thrown by <code>Zend_Session::start()</code> ("session
-                    has already been started"). If you call <code>session_start()</code>, after using
-                    Zend_Session_Namespace or starting <code>Zend_Session::start()</code> explicitly, an error of level
-                    E_NOTICE will be generated, and the call will be ignored.
--->
+                    Неправильно: Не используйте вызов <acronym>PHP</acronym> функции <ulink
+                        url="http://www.php.net/session_start">
+                        <methodname>session_start()</methodname></ulink> напрямую.
+                    Если вы вызываете <methodname>session_start()</methodname> напрямую и потом
+                    начинаете использовать <classname>Zend_Session_Namespace</classname>, 
+                    <methodname>Zend_Session::start()</methodname> сгенерирует исключение
+                    ("session has already been started"). Если вы вызовете 
+                    <methodname>session_start()</methodname>после использования
+                    <classname>Zend_Session_Namespace</classname> или вызова
+                    <methodname>Zend_Session::start()</methodname>, то будет сгенерирована ошибка
+                    уровня <constant>E_NOTICE</constant> и вызов будет проигнорирован.
                 </para>
             </listitem>
+
             <listitem>
                 <para>
-                    3. Правильно:
-                    Используйте <code>Zend_Session::start()</code>. Если
-                    необходимо, чтобы все запросы имели и использовали сессии,
-                    то поместите вызов этой функции в коде загрузки близко к
-                    точке входа и без условной логики. При этом присутствуют
-                    некоторые издержки за счет сессий. Если для одних запросов
-                    нужны сессии, а для других - нет, то:
-<!--
-                    3. Correct: Use <code>Zend_Session::start()</code>. If you want all requests to have and use
-                    sessions, then place this function call early and unconditionally in your ZF bootstrap code.
-                    Sessions have some overhead. If some requests need sessions, but other requests will not need to use
-                    sessions, then:
--->
+                    Правильно: Используйте <methodname>Zend_Session::start()</methodname>. Если
+                    необходимо, чтобы все запросы имели и использовали сессии, то поместите вызов
+                    этой функции в коде инициализации близко к точке входа и без условной логики.
+                    При этом присутствуют издержки за счет сессий. Если сессии нужны только
+                    некоторым запросам, а остальным - нет, то:
                 </para>
-                <itemizedlist mark='opencircle'>
+
+                <itemizedlist mark="opencircle">
                     <listitem>
                         <para>
-                            Установите опцию <code>strict</code> в true (см.
-                            <link linkend="zend.session.startingasession"><code>Zend_Session::setOptions()</code></link>) в коде загрузки.
-<!--
-                            Unconditionally, set the <code>strict</code> option to true (see
-                            <link
-                        linkend="zend.session.startingasession"><code>Zend_Session::setOptions()</code>
-                            </link>
-                            ) in your userland bootstrap.
--->
+                            Установите опцию <code>strict</code> в значение
+                            <constant>TRUE</constant> используя
+                            <methodname>Zend_Session::setOptions()</methodname> в файле
+                            инициализации.
                         </para>
                     </listitem>
+
                     <listitem>
                         <para>
-                            Вызывайте <code>Zend_Session::start()</code>
-                            только при тех запросах, для которых нужны сессии,
-                            и до того, как будет произведен первый вызов
-                            <code>new Zend_Session_Namespace()</code>.
-<!--
-                            Call <code>Zend_Session::start()</code>, only for requests that need to use sessions, before
-                            the first call to <code>new Zend_Session_Namespace()</code>.
--->
+                            Вызывайте <methodname>Zend_Session::start()</methodname> только для
+                            запросов, которым нужно использовать сессии, до создания любого 
+                            объекта <classname>Zend_Session_Namespace</classname>.
                         </para>
                     </listitem>
+
                     <listitem>
                         <para>
-                            Используйте
-                            <code>new Zend_Session_Namespace()</code> как
-                            обычно и там, где это нужно, но при этом необходимо
-                            убедиться, что
-                            <code>Zend_Session::start()</code> был вызван ранее.
-<!--
-                            Use <code>new Zend_Session_Namespace()</code> normally, where needed, but make sure
-                            <code>Zend_Session::start()</code> has been called previously.
--->
+                            Используйте "<code>new Zend_Session_Namespace()</code>" как обычно, там
+                            где требуется, но убедитесь, что
+                            <methodname>Zend_Session::start()</methodname> был вызван ранее.
                         </para>
                     </listitem>
                 </itemizedlist>
+
                 <para>
-                    Опция <code>strict</code> предотвращает автоматический
-                    старт сессии с использованием
-                    <code>Zend_Session::start()</code> при вызове
-                    <code>new Zend_Session_Namespace()</code>. Эта опция
-                    помогает разработчикам пользовательских областей приложений
-                    ZF следовать принятому при проектировании решению не
-                    использовать сессии для определенных запросов, т.к. при
-                    установке этой опции и последующем инстанцировании
-                    Zend_Session_Namespace до явного вызова
-                    <code>Zend_Session::start()</code> будет сгенерировано
-                    исключение. Не используйте эту опцию в коде библиотек ZF,
-                    поскольку проектные решения должны принимать только
-                    разработчики пользовательской области. Аналогичным образом,
-                    все разработчики "библиотек" должны осторожно подходить
-                    к использованию <code>Zend_Session::setOptions()</code>
-                    в коде их библиотек, поскольку эти опции имеют глобальную
-                    область действия (как и лежащие в основе опции расширения
-                    ext/session).
-<!--
-                    The <code>strict</code> option prevents <code>new Zend_Session_Namespace()</code> from automatically
-                    starting the session using <code>Zend_Session::start()</code>. Thus, this option helps developers of
-                    userland ZF applications enforce a design decision to avoid using sessions for certain requests,
-                    since an error will be thrown when using this option and instantiating Zend_Session_Namespace,
-                    before an explicit call to <code>Zend_Session::start()</code>. Do not use this option in ZF core
-                    library code, because only userland developers should make this design choice. Similarly, all
-                    "library" developers should carefully consider the impact of using
-                    <code>Zend_Session::setOptions()</code> on users of their library code, since these options have
-                    global side-effects (as do the underlying options for ext/session).
--->
+                    Опция <code>strict</code> предотвращает автоматический старт сессии с
+                    использованием <methodname>Zend_Session::start()</methodname> при вызове
+                    <code>new Zend_Session_Namespace()</code> Эта опция помогает разработчикам
+                    пользовательских приложений следовать принятому при проектировании решению не
+                    использовать сессии для определенных запросов, т.к. при установке этой опции и
+                    последующем инстанциировании <classname>Zend_Session_Namespace</classname> до
+                    явного вызова <methodname>Zend_Session::start()</methodname> будет сгенерировано
+                    исключение. Разработчики должны осторожно подходить к использованию
+                    <methodname>Zend_Session::setOptions()</methodname>, поскольку эти опции имеют
+                    глобальную область действия, вследствие их связи с лежащими в основе опциями
+                    расширения ext/session.
                 </para>
             </listitem>
+
             <listitem>
                 <para>
-                    4. Правильно: Просто используйте
-                    <code>new Zend_Session_Namespace()</code> где необходимо, и
-                    сессия будет автоматически запущена в Zend_Session. Это
-                    наиболее простой вариант использования, подходящий для
-                    большинства случаев. Но необходимо будет следить за тем,
-                    чтобы первый вызов
-                    <code>new Zend_Session_Namespace()()</code> всегда
-                    происходил <emphasis>до того</emphasis>, как
-                    выходные данные будут отправлены клиенту (т.е. до того, как
-                    агенту пользователя будут отправлены HTTP-заголовки),
-                    если используются основанные на куках сессии
-                    (очень рекомендуется). Использование
-                    <ulink url="http://php.net/outcontrol">буферизации
-                    вывода</ulink> может быть удачным решением, при этом может
-                    быть улучшена производительность. Например, в
-                    <code>php.ini</code>
-                    "<code>output_buffering = 65535</code>" включает буферизацию
-                    вывода с размером буфера 64K.
-<!--
-                    4. Correct: Just use <code>new Zend_Session_Namespace()</code> whenever needed, and the session will
-                    be automatically started within Zend_Session. This offers extremely simple usage that works well in
-                    most situations. However, you then become responsible for ensuring that the first <code>new
-                    Zend_Session_Namespace()</code> happens <emphasis>before</emphasis> any output (i.e.
-                    <ulink url="http://www.php.net/headers_sent">HTTP headers</ulink>
-                    ) has been sent by PHP to the client, if you are using the default, cookie-based sessions (strongly
-                    recommended). Using
-                    <ulink url="http://php.net/outcontrol">output buffering</ulink>
-                    often is sufficient to prevent this issue and may help improve performance. For example, in
-                    <code>php.ini</code>, "<code>output_buffering = 65535</code>" enables output buffering with a 64K
-                    buffer.
--->
+                    Правильно: Просто используйте <classname>Zend_Session_Namespace</classname> где
+                    необходимо, и <acronym>PHP</acronym> сессия будет запущена автоматически.
+                    Это наиболее простой вариант использования, подходящий для большинства случаев.
+                    Но необходимо следить зе тем, чтобы первый вызов
+                    <code>new Zend_Session_Namespace()</code> происходил
+                    <emphasis>до того</emphasis>, как <acronym>PHP</acronym> отправит клиенту любые
+                    данные(т.е. до того, как агенту пользователя отправлены 
+                    <ulink url="http://www.php.net/headers_sent">HTTP-заголовки</ulink>), если
+                    используется основанные на куки сессии (рекомендуемый вариант). Больше
+                    информации можно найти в 
+                    <link linkend="zend.session.global_session_management.headers_sent">этой
+                        секции</link>.
                 </para>
             </listitem>
-        </itemizedlist>
-
+        </orderedlist>
     </sect2>
 
-    <sect2 id="zend.session.locking">
-
-        <title>Блокировка пространств имен<!--Locking Session Namespaces--></title>
+    <sect2 id="zend.session.advanced_usage.locking">
+        <title>Блокировка пространств имен сессии</title>
 
         <para>
-            Можно применять блокировку к пространствам имен для предотвращения
-            изменения данных в этом пространстве имен. Используйте
-            метод <code>Zend_Session_Namespace::lock()</code> для того, чтобы
-            сделать определенное пространство имен доступным только для чтения,
-            <code>unLock()</code> - чтобы сделать пространство имен доступным
-            для чтения и изменений, а <code>isLocked()</code> для проверки того,
-            не было ли пространство имен заблокировано ранее. Блокировка не
-            сохраняется от одного запроса к другому. Блокировка пространства
-            имен не действует на методы установки (setter methods) в объектах,
-            сохраненных в пространстве имен, но предотвращает использование
-            методов установки пространства имен сессии для удаления или замены
-            объектов, сохраненных непосредственно в пространстве имен.
-            Также блокирование пространств имен Zend_Session_Namespace не
-            препятствует использованию ссылок на те же данные
-            (см. <ulink url="http://www.php.net/references">PHP references</ulink>).
-<!--
-            Session namespaces can be locked, to prevent further alterations to the data in that namespace. Use
-            <code>Zend_Session_Namespace's lock()</code> to make a specific namespace read-only, <code>unLock()</code>
-            to make a read-only namespace read-write, and <code>isLocked()</code> to test if a namespace has been
-            previously locked. Locks are transient and do not persist from one request to the next. Locking the
-            namespace has no effect on setter methods of objects stored in the namespace, but does prevent the use of
-            the namespace's setter method to remove or replace objects stored directly in the namespace. Similarly,
-            locking Zend_Session_Namespace namespaces does not prevent the use of symbol table aliases to the same data
-            (see
-            <ulink url="http://www.php.net/references">PHP references</ulink>
-            ).
--->
+            Можно применять блокировку к пространству имен для предотвращения изменения данных в
+            нем. Используйте метод <methodname>lock()</methodname> для того,
+            чтобы сделать определенное пространство имен доступным только для чтения,
+            <methodname>unLock()</methodname> - чтобы сделать пространство имен доступным для
+            чтения и изменений, а <methodname>isLocked()</methodname> - для проверки, не было ли
+            пространство имен заблокировано ранее. Блокировка не сохраняется от запроса к запросу,
+            не действует на методы установки(setter methods) в объектах, сохраненных в этом
+            пространстве имен, но предотвращает использование методов
+            установки для замены или удаления объектов, сохраненных непосредственно в пространстве
+            имен. Аналогично, блокировка экземпляра
+            <classname>Zend_Session_Namespace</classname> не препятствует использованию ссылок на
+            те же данные (смотри <ulink url="http://www.php.net/references">PHP references</ulink>).
         </para>
 
-        <example>
-            <title>Блокировка пространств имен<!--Locking Session Namespaces--></title>
-<programlisting language="php">
-<![CDATA[<?php
-    // assuming:
-    $userProfileNamespace = new Zend_Session_Namespace('userProfileNamespace');
-
-    // marking session as read only locked
-    $userProfileNamespace->lock();
-
-    // unlocking read-only lock
-    if ($userProfileNamespace->isLocked()) {
-        $userProfileNamespace->unLock();
-    }
-?>]]></programlisting>
-        </example>
+        <example id="zend.session.advanced_usage.locking.example.basic">
+            <title>Блокировка пространства имен сессии</title>
 
-        <para>
-            Есть некоторые идеи по поводу того, как организовывать модели в
-            парадигме MVC для Веб, включая создание моделей представления для
-            использования видами (views). Иногда имеющиеся данные, являются ли
-            они частью вашей доменной модели или нет, являются подходящими для
-            этой задачи. Для того, чтобы предотвратить изменение таких данных,
-            используйте блокировку пространств имен сессий до того, как
-            предоставить видам доступ к этим подмножествам вашей модели
-            представления.
-<!--
-            There are numerous ideas for how to manage models in MVC paradigms for the Web, including creating
-            presentation models for use by views. Sometimes existing data, whether part of your domain model or not, is
-            adequate for the task. To discourage views from applying any processing logic to alter such data, consider
-            locking session namespaces before permitting views to access this subset of your "presentation" model.
--->
-        </para>
+            <programlisting language="php"><![CDATA[
+$userProfileNamespace = new Zend_Session_Namespace('userProfileNamespace');
 
-        <example>
-            <title>Блокировка сессий в видах<!--Locking Sessions in Views--></title>
-<programlisting language="php">
-<![CDATA[<?php
-class FooModule_View extends Zend_View
-{
-    public function show($name)
-    {
-        if (!isset($this->mySessionNamespace)) {
-            $this->mySessionNamespace = Zend::registry('FooModule');
-        }
-
-        if ($this->mySessionNamespace->isLocked()) {
-            return parent::render($name);
-        }
-
-        $this->mySessionNamespace->lock();
-        $return = parent::render($name);
-        $this->mySessionNamespace->unLock();
-
-        return $return;
-    }
+// помечаем сессию как заблокированную только для чтения
+$userProfileNamespace->lock();
+
+// снимаем блокировку
+if ($userProfileNamespace->isLocked()) {
+    $userProfileNamespace->unLock();
 }
-?>]]></programlisting>
+]]></programlisting>
         </example>
-
     </sect2>
 
-    <sect2 id="zend.session.expiration">
-
-        <title>Время жизни пространства имен<!--Namespace Expiration--></title>
+    <sect2 id="zend.session.advanced_usage.expiration">
+        <title>Время жизни пространства имен</title>
 
         <para>
-            Время жизни может быть ограничено как у пространства имен в целом,
-            так и у отдельных ключей. Общие случаи использования
-            включают в себя передачу временной информации между запросами
-            и повышение защищенности от определенных угроз безопасности
-            посредством устранения доступа к потенциально чувствительной
-            информации по прошествии некоторого времени после
-            аутентификации. Истечение времени жизни может быть основано на
-            количестве секунд или на концепции "прыжков" (hops), в которой
-            "прыжком" считается каждый успешный запрос, в котором активируется
-            пространство имен через, как минимум, один
-            <varname>$space = new Zend_Session_Namespace('myspace');</varname>.
-<!--
-            Limits can be placed on the longevity of both namespaces and
-            individual keys in namespaces. Common use cases
-            include passing temporary information between requests, and
-            reducing exposure to certain security risks by
-            removing access to potentially sensitive information some time
-            after authentication occurred. Expiration can
-            be based on elapsed seconds, or based on the concept of "hops",
-            where a hop occurs for each successive
-            request that activates the namespace via at least one
-            <varname>$space = new Zend_Session_Namespace('myspace');</varname>.
--->
+            Время жизни может быть ограничено как у пространства имен в целом, так и у отдельных
+            ключей. Общие случаи использованию включают в себя передачу временной информации между
+            запросами и повышение защищенности от определенных угроз безопасности посредством
+            удаления доступа к потенциально чувствительной информации по прошествии некоторого
+            времени после аутентификации. Устаревание может быть основано на количестве секунд или
+            на концепции "прыжков" (hops), в которой "прыжок" происходит при каждом успешном
+            запросе.
         </para>
 
-        <example>
-            <title>Примеры установки времени жизни<!--Expiration Examples--></title>
-<programlisting language="php">
-<![CDATA[<?php
+        <example id="zend.session.advanced_usage.expiration.example">
+            <title>Примеры установки времени жизни</title>
+
+            <programlisting language="php"><![CDATA[
 $s = new Zend_Session_Namespace('expireAll');
 $s->a = 'apple';
 $s->p = 'pear';
 $s->o = 'orange';
 
-// Время жизни установлено только для ключа "a" (5 секунд)
+// время жизни установлено в 5 секунд только для ключа "a"
 $s->setExpirationSeconds(5, 'a');
 
-// Время жизни всего пространства имен - 5 "прыжков"
+// установить время жизни всему пространству имен в 5 "прыжков"
 $s->setExpirationHops(5);
 
 $s->setExpirationSeconds(60);
-// Пространство имен "expireAll" будет помечено как с истекшим временем жизни
-// при первом запросе, произведенном после того, как прошло 60 секунд,
-// или после 5 "прыжков" - в зависимости от того, что произошло раньше
-?>]]></programlisting>
+// пространство имен "expireAll" будет помечено как истекшее по
+// прошествии 60 секунд при ближайшем запросе
+// или через 5 "прыжков", в зависимости от того, что произойдет раньше.
+]]></programlisting>
         </example>
 
         <para>
             При работе с данными, время жизни которых истекает в текущем запросе,
             будьте внимательны при их извлечении. Несмотря на то, что данные
             возвращаются по ссылке, изменение этих данных не приведет к их
-            сохранению после текущего запроса. Для "сброса" времени истечения
+            сохранению после текущего запроса. Для сброса истечения времени жизни,
             извлеките данные во временные переменные, уничтожьте эти данные в
             пространстве имен и затем установите соответствующий ключ снова.
-<!--
-            When working with data expiring from the session in the current
-            request, care should be used when retrieving
-            it. Although the data is returned by reference, modifying the data
-            will not make expiring data persist past
-            the current request. In order to "reset" the expiration time, fetch
-            the data into temporary variables, use
-            the namespace to unset it, and then set the appropriate keys again.
--->
         </para>
-
     </sect2>
 
-    <sect2 id="zend.session.controllers">
-
-        <title>Инкапсуляция сессий и контроллеры<!--Session Encapsulation and Controllers--></title>
+    <sect2 id="zend.session.advanced_usage.controllers">
+        <title>Инкапсуляция сессий и контроллеры</title>
 
         <para>
-            Пространства имен могут также использоваться для разделения доступа
-            контроллеров к сессиям, чтобы защитить переменные от повреждения.
-            Например, контроллер 'Zend_Auth' может хранить свои постоянные
-            данные сессии отдельно от всех остальных контроллеров.
-<!--
-            Namespaces can also be used to separate session access by controllers to protect variables from
-            contamination. For example, the 'Zend_Auth' controller might keep its session state data separate from all
-            other controllers.
--->
+            Пространство имен может быть использовано для разделения доступа контроллеров к сессии,
+            для защиты переменных от повреждения. К примеру, контроллер аутентификации может хранить
+            свои данные в сессии отдельно от всех остальных контроллеров для достижения требований
+            безопасности.
         </para>
 
-        <example>
-            <title>Сессии с пространствами имен для контроллеров с автоматическим истечением времени<!--Namespaced Sessions for Controllers with Automatic Expiration--></title>
-<programlisting language="php">
-<![CDATA[<?php
-require_once 'Zend/Session.php';
+        <example id="zend.session.advanced_usage.controllers.example">
+            <title>Пространства имен сессий с автоматическим устареванием для контроллеров</title>
+
+            <para>
+                Следующий код, как часть контроллера, отображающего вопрос в тесте, создает
+                переменную с булевым значением для обозначения, должен ли быть принят ответ
+                на вопрос теста. В данном случае пользователю приложения дается 300 секунд на ответ
+                для отображаемого вопроса.
+            </para>
+
+            <programlisting language="php"><![CDATA[
+// ...
 // контроллер для вывода вопроса
 $testSpace = new Zend_Session_Namespace('testSpace');
 // установка времени жизни только для этой переменной
-$testSpace->setExpirationSeconds(300, "accept_answer");
+$testSpace->setExpirationSeconds(300, 'accept_answer');
 $testSpace->accept_answer = true;
-
---
-
-// контроллер для обработки ответа на вопрос
+//...
+]]></programlisting>
+
+            <para>
+                Ниже показан контроллер, обрабатывающий ответы на вопросы теста. Он
+                определяет, принимать ли ответ, на основе того, был ли он отправлен в отведенное
+                время:
+            </para>
+
+            <programlisting language="php"><![CDATA[
+// ...
+// контроллер обработки ответа
 $testSpace = new Zend_Session_Namespace('testSpace');
-
 if ($testSpace->accept_answer === true) {
-    // время не истекло
+    // в отведенное время
 }
 else {
-    // время истекло
+    // больше отведенного времени
 }
-?>]]></programlisting>
+// ...
+]]></programlisting>
         </example>
-
     </sect2>
 
-    <sect2 id="zend.session.limitinginstances">
-
-        <title>Ограничение количества экземпляров Zend_Session_Namespace до одного на каждое пространство имен<!--Limiting Instances of Zend_Session to One Per Namespace--></title>
+    <sect2 id="zend.session.advanced_usage.single_instance">
+        <title>Ограничение количества экземпляров на каждое пространство имен</title>
 
         <para>
-            Мы рекомендуем использовать блокировку сессии (см. выше) вместо этой
-            функциональной возможности, которая накладывает дополнительное бремя
-            на разработчика, состоящее в передаче экземпляров
-            Zend_Session_Namespace во все функции и объекты, нуждающихся в
-            использовании этих пространств имен.
-<!--
-            We recommend using session locking (see above) instead of the feature below, which places extra management
-            burden on the developer to pass any Zend_Session_Namespace instances into whatever functions and objects
-            need access to each namespace.
--->
+            Хотя <link linkend="zend.session.advanced_usage.locking">блокировка сессии</link>
+            предоставляет неплохой уровень защиты против непреднамеренного использования данных
+            сессии в кокретном пространстве имен, <classname>Zend_Session_Namespace</classname>
+            так же предоставляет
+            возможность предотвратить создание множества экземпляров для одного пространства имен.
         </para>
 
         <para>
-            Когда создается первый экземпляр Zend_Session_Namespace, связанный с
-            определенным пространством имен, вы можете дать команду
-            Zend_Session_Namespace больше не создавать объекты для этого
-            пространства имен. Таким образом, в дальнейшем попытка создать
-            экземпляр Zend_Session_Namespace для
-            того же пространства имен вызовет генерацию исключения. Это
-            поведение является опциональным и не принято по умолчанию, но
-            остается доступным для тех, кто предпочитает передавать по коду
-            единственный объект для каждого пространства имен. Это повышает
-            защиту пространства имен от изменений компонентами, которые не
-            должны делать этого, поскольку тогда они не будут иметь свободного
-            доступа к пространствам имен. Тем не менее, ограничение пространства
-            имен до одного экземпляра модет привести к большему объему кода или
-            к его усложнению, поскольку он отменяет возможность использования
-            директив вида
-            <varname>$aNamespace = new Zend_Session_Namespace('aNamespace');</varname>
-            после того, как был создан первый экземпляр. Это продемонстрировано
-            в примере ниже:
-<!--
-            When constructing the first instance of Zend_Session_Namespace attached to a specific namespace, you can
-            also instruct Zend_Session_Namespace to not make any more instances for that namespace. Thus, any future
-            attempts to construct a Zend_Session_Namespace instance having the same namespace will throw an error. Such
-            behavior is optional, and not the default behavior, but remains available to those who prefer to pass around
-            a single instance object for each namespace. This increases protection from changes by components that
-            should not modify a particular session namespace, because they won't have easy access. However, limiting a
-            namespace to a single instance may lead to more code or more complex code, as it removes access to the
-            convient <varname>$aNamespace = new Zend_Session_Namespace('aNamespace');</varname>, after the first intance has
-            been created, as follows in the example below:
--->
+            Для включения этой возможности, передайте <constant>TRUE</constant> вторым аргументом 
+            конструктора при создании последнего разрешенного экземпляра
+            <classname>Zend_Session_Namespace</classname>. Любая последующая попытка инстанциации
+            этого пространства имен сгенерирует исключение.
         </para>
 
-        <example>
-            <title>Ограничение до единичных экземпляров<!--Limiting to Single Instances--></title>
-<programlisting language="php">
-<![CDATA[<?php
-    require_once 'Zend/Session.php';
-    $authSpaceAccessor1 = new Zend_Session_Namespace('Zend_Auth');
-    $authSpaceAccessor2 = new Zend_Session_Namespace('Zend_Auth', Zend_Session_Namespace::SINGLE_INSTANCE);
-    $authSpaceAccessor1->foo = 'bar';
-    assert($authSpaceAccessor2->foo, 'bar');
-    doSomething($options, $authSpaceAccessor2);
-    .
-    .
-    .
-    $aNamespaceObject = new Zend_Session_Namespace('Zend_Auth'); // это вызовет ошибку
-?>]]></programlisting>
+        <example id="zend.session.advanced_usage.single_instance.example">
+            <title>Ограничение доступа к пространству имен сессии одним экземпляром</title>
+
+            <programlisting language="php"><![CDATA[
+// создаем экземпляр для пространства имен
+$authSpaceAccessor1 = new Zend_Session_Namespace('Zend_Auth');
+
+// Создание второго экземпляра для пространства имен,
+// и запрет на создание новых
+$authSpaceAccessor2 = new Zend_Session_Namespace('Zend_Auth', true);
+
+// Создание ссылок на существующие возможно
+$authSpaceAccessor3 = $authSpaceAccessor2;
+
+$authSpaceAccessor1->foo = 'bar';
+
+assert($authSpaceAccessor2->foo, 'bar');
+
+try {
+    $aNamespaceObject = new Zend_Session_Namespace('Zend_Auth');
+} catch (Zend_Session_Exception $e) {
+    echo 'Cannot instantiate this namespace since ' .
+         '$authSpaceAccessor2 was created\n';
+}
+]]></programlisting>
         </example>
 
         <para>
-            Второй параметр в конструкторе выше говорит Zend_Session, что
-            в будущем создание любых других экземпляров Zend_Session_Namespace с
-            пространством имен 'Zend_Auth' не допустимо. Поскольку
-            директиву <code>new Zend_Session_Namespace('Zend_Auth')</code>
-            нельзя использовать после того, как будет выполнен приведенный выше
-            код, то разработчику нужно будет где-либо сохранять объект
-            (<varname>$authSpaceAccessor2</varname> в
-            примере выше), если в дальнейшем при обработке того же запроса
-            необходим доступ к этому пространству имен сессии.
+            Второй параметр в конструкторе выше говорит
+            <classname>Zend_Session_Namespace</classname>, что любые новые экземпляры с
+            пространством имен "<classname>Zend_Auth</classname>" не разрешены. Попытка создания
+            такого экземпляра вызовет генерацию исключения конструктором. Разработчик сам отвечает
+            за хранение ссылки на экземпляры объектов(<varname>$authSpaceAccessor1</varname>,
+            <varname>$authSpaceAccessor2</varname>, или
+            <varname>$authSpaceAccessor3</varname> в примере выше), если в дальнейшем при обработке
+            того же запроса необходим доступ к этому пространству имен сессии.
             Например, вы можете сохранять экземпляр в статической переменной или
-            передавать его другим методам, которым нужен доступ к данному
-            пространству имен.
-<!--
-            The second parameter in the constructor above will tell Zend_Session_Namespace that any future
-            Zend_Session's that are instantiated with the 'Zend_Auth' namespace are not allowed, and will thus cause an
-            exception. Since <code>new Zend_Session_Namespace('Zend_Auth')</code> will not be allowed after the code
-            above has been executed, the developer becomes responsible for storing the instance object
-            (<varname>$authSpaceAccessor2</varname> in the example above) somewhere, if access to this session namespace is
-            needed at a later time during the same request. For example, a developer may store the instance in a static
-            variable, or pass it to other methods that might need access to this session namespace. Session locking (see
-            above) provides a more convenient, and less burdensome approach to limiting access to namespaces.
--->
+            передавать его <ulink
+                url="http://www.martinfowler.com/eaaCatalog/registry.html">реестру</ulink> (смотри
+            <link linkend="zend.registry">Zend_Registry</link>), или передавать его другим методам,
+            которым нужен доступ к данному пространству имен.
         </para>
-
     </sect2>
 
-    <sect2 id="zend.session.modifyingarray">
-
-        <title>Работа с массивами в пространствах имен<!--Working with Arrays in Namespaces--></title>
+    <sect2 id="zend.session.advanced_usage.arrays">
+        <title>Работа с массивами</title>
 
         <para>
-            Изменение массива внутри пространства имен невозможно. Простейшим
-            решением является сохранение массивов после того, как все желаемые
-            значения были установлены. <ulink url="http://framework.zend.com/issues/browse/ZF-800">ZF-800</ulink>
-            подтверждает известный баг, затрагивающий многие PHP-приложения,
-            использующие "магические" методы и массивы.
-
-<!--
-            Modifying an array inside a namespace does not work. The simplest solution is to store arrays after all
-            desired values have been set.
-            <ulink url="http://framework.zend.com/issues/browse/ZF-800">ZF-800</ulink>
-            documents a known issue affecting many PHP applications using magic methods and arrays.
--->
+            Всвязи с историей реализаций магических методов в <acronym>PHP</acronym>, изменение
+            массивов внутри пространства имен может не работать при версиях <acronym>PHP</acronym>
+            меньше 5.2.1. Если вы будете работать только с версиями <acronym>PHP</acronym> 5.2.1 или
+            более поздними, тогда вы можете
+            <link linkend="zend.session.advanced_usage.objects">перейти к следующей секции</link>.
         </para>
 
-        <example>
-            <title>Известные проблемы с массивами<!--Known problem with arrays--></title>
-<programlisting language="php">
-<![CDATA[<?php
-    $sessionNamespace = new Zend_Session_Namespace('Foo');
-    $sessionNamespace->array = array();
-    $sessionNamespace->array['testKey'] = 1; // Не работает в версиях ниже PHP 5.2.1
-?>]]></programlisting>
+        <example id="zend.session.advanced_usage.arrays.example.modifying">
+            <title>Изменение данных массивов с помощью Zend_Session_Namespace</title>
+
+            <para>
+                Далее показано, как эта проблема может быть воспроизведена:
+            </para>
+
+            <programlisting language="php"><![CDATA[
+$sessionNamespace = new Zend_Session_Namespace();
+$sessionNamespace->array = array();
+
+// может не работать, как ожидается, в версиях PHP до 5.2.1
+$sessionNamespace->array['testKey'] = 1;
+echo $sessionNamespace->array['testKey'];
+]]></programlisting>
         </example>
 
-        <para>
-            Если вам нужно изменить массив после того, как добавили его в
-            пространство имен, извлеките массив, произведите необходимые
-            изменения и сохраните его под тем же ключом в пространстве имен.
-<!--
-            If you need to modify the array after assigning it to a session namespace key, fetch the array, then
-            modify it and save the array back to the session namespace.
--->
-        </para>
+        <example id="zend.session.advanced_usage.arrays.example.building_prior">
+            <title>Формирование массива до сохранения в сессию</title>
+
+            <para>
+                Если возможно, всецело избегайте данной проблемы, сохраняя массивы в пространство
+                имен сессии только после того, как все необходимые значения были установлены.
+            </para>
 
-        <example>
-            <title>Обходной путь: извлечение, изменение и сохранение<!--Workaround: fetch, modify, save--></title>
-<programlisting language="php">
-<![CDATA[<?php
-    $sessionNamespace = new Zend_Session_Namespace('Foo');
-    $sessionNamespace->array = array('tree' => 'apple');
-    $tmp = $sessionNamespace->array;
-    $tmp['fruit'] = 'peach';
-    $sessionNamespace->array = $tmp;
-?>]]></programlisting>
+            <programlisting language="php"><![CDATA[
+$sessionNamespace = new Zend_Session_Namespace('Foo');
+$sessionNamespace->array = array('a', 'b', 'c');
+]]></programlisting>
         </example>
 
         <para>
-            Можно также сохранить массив, содержащий ссылку на желаемый массив
-            и косвенно работать с ним.
-<!--
-            Alternatively, store an array containing a reference to the desired array, and then access it indirectly.
--->
+            Если вы используете подверженную проблеме версию <acronym>PHP</acronym> и необходимо
+            изменить массив после его сохранения в пространстве имен сессии, вы можете использовать
+            оба или один из следующих обходных путей:
         </para>
 
-        <example>
-            <title>Обходной путь: сохранение массива, содержащего ссылку<!--Workaround: store array containing reference--></title>
-<programlisting language="php">
-<![CDATA[<?php
-    $myNamespace = new Zend_Session_Namespace('mySpace');
-
-    // работает даже с версиями PHP, содержащими баг
-    $a = array(1,2,3);
-    $myNamespace->someArray = array( & $a ) ;
-    $a['foo'] = 'bar';
-?>]]></programlisting>
-        </example>
+        <example id="zend.session.advanced_usage.arrays.example.workaround.reassign">
+            <title>Обходной путь: Пересохранение измененного массива</title>
 
-    </sect2>
+            <para>
+                В последующем коде создается копия сохраненного массива, изменяется и сохраняется
+                обратно, перезаписывая оригинал.
+            </para>
 
-    <sect2 id="zend.session.auth">
+            <programlisting language="php"><![CDATA[
+$sessionNamespace = new Zend_Session_Namespace();
 
-        <title>Использование сессий вместе с аутентификацией<!--Using Sessions with Authentication--></title>
+// устанавливаем исходный массив
+$sessionNamespace->array = array('tree' => 'apple');
 
-        <para>
-            Если ваш адаптер аутентификации для <code>Zend_Auth</code>
-            возвращает результат, в котором идетификатором авторизации является
-            объект (не рекомендуется) вместо массива, то выполняйте проверку
-            класса идентификатора авторизации до того, как стартовать сессию.
-            Вместо этого мы рекомендуем хранить идентификаторы авторизации,
-            вычисленные в адаптере авторизации, под хорошо известным ключом в
-            пространстве имен сессии. Например, по умолчанию
-            <code>Zend_Auth</code> размещает идентификаторы под ключом 'storage'
-            пространства имен 'Zend_Auth'.
-<!--
-            If your authentication adapter for <code>Zend_Auth</code> returns a result where the authorization identity
-            is an object (not recommended), instead of an array, then make sure to require your authorization identity
-            class definition before starting the session. Instead, we recommend storing the authorization ids computed
-            within an authentication adapter inside a well-known key in a session namespace. For example, the default
-            behavior of <code>Zend_Auth</code> places this in the 'storage' key of the 'Zend_Auth' namespace.
--->
-        </para>
+// делаем копию массива
+$tmp = $sessionNamespace->array;
 
-        <para>
-            Если вы приказали <code>Zend_Auth</code> не сохранять метку сессии в
-            сессиях, то можете вручную сохранять ID авторизации под хорошо
-            известным ключом в любом пространстве имен сессии.
-            Часто приложения имеют свои
-            требования к тому, где хранить "мандат" (учетная запись с
-            праметрами доступа пользователя) и идентификатор авторизации.
-            Приложения часто устанавливают соответствие идентификаторов
-            аутентификации (например, имена пользователей) и идентификаторов
-            авторизации (например, присвоенное уникальное целое число) во время
-            аутентификации, которая должна производится внутри метода
-            <code>authenticate()</code> адаптера аутентификации Zend_Auth.
-<!--
-            If you tell <code>Zend_Auth</code> to not persist authentication tokens in sessions, then you can manually
-            store the authorization id in the session namespace, in a well-known location in a session namespace of your
-            choice. Often, applications have specific needs about where to store credentials used (if any) and
-            "authorization" identity. Applications often map authentication identities (e.g. usernames) to authorization
-            identities (e.g. a uniquely assigned integer) during authentication, which would occur in the Zend_Auth
-            authentication adapter's <code>authenticate()</code> method.
--->
-        </para>
+// изменяем копию массива
+$tmp['fruit'] = 'peach';
 
-        <example>
-            <title>Пример: Простой доступ к ID авторизации<!--Example: Simplified access of authorization ids--></title>
-<programlisting language="php">
-<![CDATA[<?php
-    // pre-authentication request
-    require_once 'Zend/Auth/Adapter/Digest.php';
-    $adapter = new Zend_Auth_Adapter_Digest($filename, $realm, $username, $password);
-    $result = $adapter->authenticate();
-    require_once 'Zend/Session/Namespace.php';
-    $namespace = new Zend_Session_Namespace('Zend_Auth');
-    if ($result->isValid()) {
-        $namespace->authorizationId = $result->getIdentity();
-        $namespace->date = time();
-    } else {
-        $namespace->attempts++;
-    }
-
-    // subsequent requests
-    require_once 'Zend/Session.php';
-    Zend_Session::start();
-    $namespace = new Zend_Session_Namespace('Zend_Auth');
-
-    echo "Valid: ", (empty($namespace->authorizationId) ? 'No' : 'Yes'), "\n"';
-    echo "Authorization / user Id: ", (empty($namespace->authorizationId)
-        ? 'none' : print_r($namespace->authorizationId, true)), "\n"';
-    echo "Authentication attempts: ", (empty($namespace->attempts)
-        ? '0' : $namespace->attempts), "\n"';
-    echo "Authenticated on: ",
-        (empty($namespace->date) ? 'No' : date(DATE_ATOM, $namespace->date), "\n"';
-?>]]></programlisting>
+// устанавливаем копию массива обратно в пространство имен сессии
+$sessionNamespace->array = $tmp;
+
+echo $sessionNamespace->array['fruit']; // выводит "peach"
+]]></programlisting>
         </example>
 
-        <para>
-            Идентификаторы авторизации, хранящиеся на клиентской стороне, могут
-            использоваться в атаках на поднятие привилегий, если им доверяет
-            серверная сторона и если они, например, не дублируются на серверной
-            стороне (например, в данных сессии) и затем сверяются с
-            идентификатором авторизации, предоставленным клентом для
-            действующией сессии. Мы различаем понятия "идентификаторов
-            аутентификации" (например, имена пользователей) и "идентификаторов
-            авторизации" (например, ID пользователя #101 в таблице БД для
-            пользователей).
-<!--
-            Authorization ids stored client-side are subject to privilege escalation vulnerabilities, if these ids are
-            used and trusted by the server, unless, for example, the id is duplicated on the server-side (e.g. in the
-            session) and then cross-checked with the authorization id claimed by the client for the in-effect session.
-            We are differentiating between "authentication ids" (e.g. usernames) and "authorization ids" (e.g. user id
-            #101 in the users DB table).
--->
-        </para>
+        <example id="zend.session.advanced_usage.arrays.example.workaround.reference">
+            <title>Обходной путь: Сохранение массива, содержащего ссылку</title>
+
+            <para>
+                В качестве альтернативы, сохраниение массива, содержащего ссылку на интересующий
+                массив, с его последующим непрямым изменением:
+            </para>
+
+            <programlisting language="php"><![CDATA[
+$myNamespace = new Zend_Session_Namespace('myNamespace');
+$a = array(1, 2, 3);
+$myNamespace->someArray = array( &$a );
+$a['foo'] = 'bar';
+echo $myNamespace->someArray['foo']; // выводит "bar"
+]]></programlisting>
+        </example>
+    </sect2>
+
+    <sect2 id="zend.session.advanced_usage.objects">
+        <title>Использование сессии с объектами</title>
 
         <para>
-            Последнее часто используется для повышения производительности -
-            например, для выборки из пула серверов, кеширующих данные сессии,
-            чтобы решить проблему "курицы и яйца". Часто
-            возникают дебаты о том, использовать ли настоящий ID авторизации в
-            куках или некую замену, которая помогает установить соответствие
-            с настоящим ID авторизации (или сессии сервера(ов), хранящего
-            сессию/профиль пользователя и т.д.), в то время как некоторые
-            архитекторы системной безопасности предпочитают избегать
-            публикования истинных значений первичных ключей, пытаясь достичь
-            некоторого дополнительного уровня защиты в случае наличия
-            уязвимостей к SQL-инъекциям.
-<!--
-            The latter is not uncommon for performance reasons, such as helping select from a pool of servers caching
-            session information to help solve chicken-and-egg problems. Often debates ensue about whether to use the
-            real authorization id in the cookie, or some substitute that aids in mapping to the real authorization id
-            (or session or server(s) holding the user's session/profile, etc.), as some system security architects wish
-            to prevent true "DB primary keys" from escaping into the wild. These architects try and obtain some level of
-            protection by obfuscation in the event of a SQL injection vulnerability in their system. Not everyone uses
-            auto-increment strategies for authorization ids.
--->
+            Если вы планируете хранить объекты в <acronym>PHP</acronym> сессии, имейте в виду, что
+            они будут <ulink
+            url="http://www.php.net/manual/en/language.oop.serialization.php">сериализованы</ulink>
+            для сохранения. Таким образом, любые объекты, сохраненные в <acronym>PHP</acronym>
+            сессии, должны быть десериализованы при извлечении из хранилища. Подразумевается что
+            разработчик должен обеспечить определение классов для сохраненных объектов до
+            десериализации объекта из сессионного хранилища. Если класс десериализуемого объекта
+            не определен, он становится экземпляром <code>stdClass</code>.
         </para>
-
     </sect2>
 
-    <sect2 id="zend.session.testing">
-
-        <title>Использование сессий с юнит-тестами<!--Using Sessions with Unit Tests--></title>
+    <sect2 id="zend.session.advanced_usage.testing">
+        <title>Использование сессии с юнит тестами</title>
 
         <para>
-            Zend Framework использует PHPUnit для своего тестирования. Многие
-            разработчики расширяют существующие наборы
-            юнит-тестов для покрытия кода в своих приложениях.
-            Если при выполнении юнит-тестирований после завершения сессии были
-            использованы любые связанные с записью методы, то генерируется
-            исключение "<emphasis>Zend_Session is currently marked
-            as read-only</emphasis>" ("Zend_Session помечен как доступный только
-            для чтения"). Тем не менее, юнит-тесты, использующие Zend_Session,
-            требуют особого внимания в разработке, поскольку закрытие
-            (<code>Zend_Session::writeClose()</code>) или уничтожение сессии
-            (<code>Zend_Session::destroy()</code>) не дает впоследствии
-            устанавливать или сбрасывать ключи в любом объекте
-            Zend_Session_Namespace. Это поведение является прямым следствием
-            использования лежащего в основе расширения ext/session,
-            функций <code>session_destroy()</code> и
-            <code>session_write_close()</code>, которые не имеют механизма
-            "отмены" для облегчения установки/демонтажа в юнит-тестировании.
-<!--
-            Zend Framework relies on PHPUnit to facilitate testing of itself. Many developers extend the existing
-            suite of unit tests to cover the code in their applications. The exception
-            "<emphasis>Zend_Session is currently marked as read-only</emphasis>" is thrown while
-            performing unit tests, if any write-related methods are used after ending the session. However, unit tests
-            using Zend_Session require extra attention, because closing (<code>Zend_Session::writeClose()</code>), or
-            destroying a session (<code>Zend_Session::destroy()</code>) prevents any further setting or unsetting of
-            keys in any Zend_Session_Namespace. This behavior is a direct result of the underlying ext/session mechanism
-            and PHP's <code>session_destroy()</code> and <code>session_write_close()</code>, which has no "undo"
-            mechanism to facilitate setup/teardown with unit tests.
--->
+            Zend Framework опирается на PHPUnit для облегчения своего тестирования. Многие
+            разработчики расширяют существующий набор юнит тестов для покрытия кода в их приложении.
+            Если во время выполнения юнит тестирования после закрытия сессии происходит попытка
+            использования пишущих в сессию методов, генерируется исключение "<emphasis>Zend_Session
+            is currently marked as read-only</emphasis> (Zend_Session в данный момент помечен как
+            только для чтения)". Однако <classname>Zend_Session</classname> требует особое внимание,
+            так как закрытие (<methodname>Zend_Session::writeClose()</methodname>), или уничтожение
+            (<methodname>Zend_Session::destroy()</methodname>) сессии предотвращает дальнейшую
+            установку или удаление ключей в любом экземпляре 
+            <classname>Zend_Session_Namespace</classname>.
+            Это поведение - прямой результат используемого механизма ext/session, методов
+            <methodname>session_destroy()</methodname> и
+            <methodname>session_write_close()</methodname> в <acronym>PHP</acronym>, которые не
+            имеют механизма "отменить" для выполнения настройки/сброса юнит теста.
         </para>
 
         <para>
-            Чтобы обойти это, см. юнит-тест
-            <code>testSetExpirationSeconds()</code> в
-            <code>tests/Zend/Session/SessionTest.php</code> и
-            <code>SessionTestHelper.php</code>, которые используют
-            <code>exec()</code> для запуска отдельного процесса. Новый процесс
-            более точно имитирует второй, последующий, запрос из броузера.
-            Отдельный процесс начинается с "чистой" сессии, так же, как при
-            выполнении любого PHP-скрипта для веб-запроса. Кроме этого,
-            любые изменения в <varname>$_SESSION[]</varname>, произведенные при вызове
-            процесса, становятся доступными и в дочернем процессе, что дает
-            родительскому процессу возможность закрыть сессию до использования
-            <code>exec()</code>.
-<!--
-            To work around this, see the unit test <code>testSetExpirationSeconds()</code> in
-            <code>tests/Zend/Session/SessionTest.php and SessionTestHelper.php</code>, which make use of PHP's
-            <code>exec()</code> to launch a separate process. The new process more accurately simulates a second,
-            successive request from a browser. The separate process begins with a "clean" session, just like any PHP
-            script execution for a web request. Also, any changes to <varname>$_SESSION[]</varname> made in the calling
-            process become available to the child process, provided the parent closed the session before using
-            <code>exec()</code>
--->
+            Для обхода этой проблемы, смотри метод
+            <methodname>testSetExpirationSeconds()</methodname> юнит тестов в
+            <code>SessionTest.php</code> и <code>SessionTestHelper.php</code>. Оба находятся в
+            <code>tests/Zend/Session</code>. Они используют функцию <acronym>PHP</acronym> -
+            <methodname>exec()</methodname> для запуска отдельного процесса. Новый процесс более
+            точно симулирует второй, последующий, запрос от браузера. Отдельный процесс стартует с
+            "чистой" сессией, как любое другое выполнение <acronym>PHP</acronym> скрипта по web
+            запросу. Также, любые изменения в <varname>$_SESSION</varname> сделанные в вызывающем
+            процессе становятся доступны дочернему процессу, при условии что родитель закрыл сессию
+            до вызова <methodname>exec()</methodname>.
         </para>
 
-        <example>
-            <title>Использование PHPUnit для тестирования кода, написанного с использованием Zend_Session*<!--Using PHPUnit to test code written using Zend_Session*--></title>
-<programlisting language="php">
-<![CDATA[<?php
-        // testing setExpirationSeconds()
-        require 'tests/Zend/Session/SessionTestHelper.php'; // also see SessionTest.php in trunk/
-        $script = 'SessionTestHelper.php';
-        $s = new Zend_Session_Namespace('space');
-        $s->a = 'apple';
-        $s->o = 'orange';
-        $s->setExpirationSeconds(5);
-
-        Zend_Session::regenerateId();
-        $id = Zend_Session::getId();
-        session_write_close(); // release session so process below can use it
-        sleep(4); // not long enough for things to expire
-        exec($script . "expireAll $id expireAll", $result);
-        $result = $this->sortResult($result);
-        $expect = ';a === apple;o === orange;p === pear';
-        $this->assertTrue($result === $expect,
-            "iteration over default Zend_Session namespace failed; expecting result === '$expect', but got '$result'");
-
-        sleep(2); // long enough for things to expire (total of 6 seconds waiting, but expires in 5)
-        exec($script . "expireAll $id expireAll", $result);
-        $result = array_pop($result);
-        $this->assertTrue($result === '',
-            "iteration over default Zend_Session namespace failed; expecting result === '', but got '$result')");
-        session_start(); // resume artificially suspended session
-
-        // We could split this into a separate test, but actually, if anything leftover from above
-        // contaminates the tests below, that is also a bug that we want to know about.
-        $s = new Zend_Session_Namespace('expireGuava');
-        $s->setExpirationSeconds(5, 'g'); // now try to expire only 1 of the keys in the namespace
-        $s->g = 'guava';
-        $s->p = 'peach';
-        $s->p = 'plum';
-
-        session_write_close(); // release session so process below can use it
-        sleep(6); // not long enough for things to expire
-        exec($script . "expireAll $id expireGuava", $result);
-        $result = $this->sortResult($result);
-        session_start(); // resume artificially suspended session
-        $this->assertTrue($result === ';p === plum',
-            "iteration over named Zend_Session namespace failed (result=$result)");
-?>]]></programlisting>
-        </example>
+        <example id="zend.session.advanced_usage.testing.example">
+            <title>PHPUnit тестирование кода, зависимого от Zend_Session</title>
 
+            <programlisting language="php"><![CDATA[
+// тестирование setExpirationSeconds()
+$script = 'SessionTestHelper.php';
+$s = new Zend_Session_Namespace('space');
+$s->a = 'apple';
+$s->o = 'orange';
+$s->setExpirationSeconds(5);
+
+Zend_Session::regenerateId();
+$id = Zend_Session::getId();
+session_write_close(); // освобождаем сессию для процесса ниже
+sleep(4); // недостаточно долго для истекания сессии
+exec($script . "expireAll $id expireAll", $result);
+$result = $this->sortResult($result);
+$expect = ';a === apple;o === orange;p === pear';
+$this->assertTrue($result === $expect,
+    "iteration over default Zend_Session namespace failed; " .
+    "expecting result === '$expect', but got '$result'");
+
+sleep(2); // достаточно для истекания сессии(всего 6 секунд
+          // ожидания, но истекла за 5)
+exec($script . "expireAll $id expireAll", $result);
+$result = array_pop($result);
+$this->assertTrue($result === '',
+    "iteration over default Zend_Session namespace failed; " .
+    "expecting result === '', but got '$result')");
+session_start(); // Восстанавливаем искусственно остановленную сессию
+
+// Мы можем выделить это в отдельный тест, но на самом деле, если
+// какие-либо остатки от теста выше загрязняют тест ниже, это тоже баг,
+// о котором мы хотели бы знать.
+$s = new Zend_Session_Namespace('expireGuava');
+$s->setExpirationSeconds(5, 'g'); // теперь устанавливаем время жизни только
+                                  // одному ключу в пространстве имен сессии
+$s->g = 'guava';
+$s->p = 'peach';
+$s->p = 'plum';
+
+session_write_close(); // освобождаем сессию для процесса ниже
+sleep(6); // недостаточно долго для истекания сессии
+exec($script . "expireAll $id expireGuava", $result);
+$result = $this->sortResult($result);
+session_start(); // Восстанавливаем искусственно остановленную сессию
+$this->assertTrue($result === ';p === plum',
+    "iteration over named Zend_Session namespace failed (result=$result)");
+]]></programlisting>
+        </example>
     </sect2>
-
 </sect1>