<?xml version="1.0" encoding="UTF-8"?>
<!-- Reviewed: no -->
<!-- EN-Revision: 24249 -->
<sect1 id="zend.memory.memory-objects">

    <title>メモリオブジェクト</title>

    <sect2 id="zend.memory.memory-objects.movable">

        <title>移動可能なオブジェクト</title>

        <para>
            移動可能なメモリオブジェクトを作成するには、メモリマネージャの
            <methodname>create([$data])</methodname> メソッドを使用します。
        </para>

        <programlisting language="php"><![CDATA[
$memObject = $memoryManager->create($data);
]]></programlisting>

        <para>
            "移動可能" とは、このオブジェクトがスワップされ、
            メモリから削除される可能性があるということです。
            アプリケーションがこのオブジェクトにアクセスする際に、
            再度メモリに読み込まれます。
        </para>

    </sect2>

    <sect2 id="zend.memory.memory-objects.locked">

        <title>ロックされたオブジェクト</title>

        <para>
            ロックされたメモリオブジェクトを作成するには、メモリマネージャの
            <methodname>createLocked([$data])</methodname> メソッドを使用します。
        </para>

        <programlisting language="php"><![CDATA[
$memObject = $memoryManager->createLocked($data);
]]></programlisting>

        <para>
            "ロックされた" とは、このオブジェクトは決してスワップされず、
            メモリから削除されないということです。
        </para>

        <para>
            ロックされたオブジェクトは、移動可能なオブジェクトと同じインターフェイス
            (<classname>Zend_Memory_Container_Interface</classname>) を提供します。
            したがって、ロックされたオブジェクトは
            どんな場面でも、移動可能なオブジェクトのかわりに使用できます。
        </para>

        <para>
            パフォーマンスを考慮し、一部のオブジェクトは
            スワップさせないようにしたいなどといった場合に、これは有用です。
        </para>

        <para>
            ロックされたオブジェクトへのアクセスはより高速になります。
            というのも、メモリマネージャがそのオブジェクトの変更内容を追いかける必要がないからです。
        </para>

        <para>
            ロックされたオブジェクトのクラス (<classname>Zend_Memory_Container_Locked</classname>)
            は、通常の文字列変数と事実上同程度のパフォーマンスを保証します。
            オーバーヘッドとなるのは、クラスのプロパティを取得する際の参照の解決のみです。
        </para>

    </sect2>

    <sect2 id="zend.memory.memory-objects.value">
        <title>メモリコンテナの 'value' プロパティ</title>

        <para>
            (移動可能な、あるいはロックされた) メモリコンテナの '<property>value</property>'
            プロパティを使用して、メモリオブジェクトのデータを扱います。
        </para>

        <programlisting language="php"><![CDATA[
$memObject = $memoryManager->create($data);

echo $memObject->value;

$memObject->value = $newValue;

$memObject->value[$index] = '_';

echo ord($memObject->value[$index1]);

$memObject->value = substr($memObject->value, $start, $length);
]]></programlisting>

        <para>
            メモリオブジェクトのデータにアクセスするもうひとつの方法として、
            <link linkend="zend.memory.memory-objects.api.getRef"><methodname>getRef()</methodname></link>
            メソッドを使うものがあります。<acronym>PHP</acronym> のバージョンが 5.2 より古い場合は、
            <emphasis>必ず</emphasis> このメソッドを使用しなければなりません。
            パフォーマンスの問題から、その他の場合にもこれを使わなければならないことがあるかもしれません。
        </para>
    </sect2>

    <sect2 id="zend.memory.memory-objects.api">
        <title>メモリコンテナのインターフェイス</title>

        <para>
            メモリコンテナは、以下のメソッドを提供します。
        </para>

        <sect3 id="zend.memory.memory-objects.api.getRef">
            <title>getRef() メソッド</title>

            <programlisting language="php"><![CDATA[
public function &getRef();
]]></programlisting>

            <para>
                <methodname>getRef()</methodname> メソッドは、オブジェクトの値への参照を返します。
            </para>

            <para>
                移動可能なオブジェクトは、もしメモリ内になければ
                この時点でキャッシュから読み込まれます。
                オブジェクトをキャッシュから読み込んだ場合に、
                メモリ内で管理しているオブジェクトのサイズが制限に達すると、
                他のオブジェクトのスワップが発生します。
            </para>

            <para>
                <acronym>PHP</acronym> のバージョンが 5.2 より古い場合、メモリオブジェクトのデータにアクセスするには
                <emphasis>必ず</emphasis> <methodname>getRef()</methodname>
                メソッドを使用する必要があります。
            </para>

            <para>
                データの変更内容を追いかけるには、余分なリソースが必要となります。
                <methodname>getRef()</methodname> メソッドは文字列への参照を返し、
                これはアプリケーションから直接変更することになります。
                つまり、データの内容を処理する際には <methodname>getRef()</methodname>
                メソッドを使用するのがうまいやり方となります。
            </para>

            <programlisting language="php"><![CDATA[
$memObject = $memoryManager->create($data);

$value = &$memObject->getRef();

for ($count = 0; $count < strlen($value); $count++) {
    $char = $value[$count];
    ...
}
]]></programlisting>
        </sect3>

        <sect3 id="zend.memory.memory-objects.api.touch">
            <title>touch() メソッド</title>

            <programlisting language="php"><![CDATA[
public function touch();
]]></programlisting>

            <para>
                <methodname>touch()</methodname> メソッドは
                <methodname>getRef()</methodname> と同じように使用しなければなりません。
                これは、オブジェクトの値が変更されたことを通知します。
            </para>

            <programlisting language="php"><![CDATA[
$memObject = $memoryManager->create($data);
...

$value = &$memObject->getRef();

for ($count = 0; $count < strlen($value); $count++) {
    ...
    if ($condition) {
        $value[$count] = $char;
    }
    ...
}

$memObject->touch();
]]></programlisting>
        </sect3>

        <sect3 id="zend.memory.memory-objects.api.lock">
            <title>lock() メソッド</title>

            <programlisting language="php"><![CDATA[
public function lock();
]]></programlisting>

            <para>
                <methodname>lock()</methodname> メソッドは、オブジェクトをメモリ内にロックします。
                これを使用して、スワップしたくないオブジェクトを選択します。
                通常はこれは不要です。なぜなら、メモリマネージャが
                うまい具合にスワップする候補を選ぶようにできているからです。
                しかし、どうしてもスワップしてはならないオブジェクトがあることがわかっている場合は、
                それをロックするとよいでしょう。
            </para>

            <para>
                オブジェクトをメモリ内にロックすることで、ロックを解除するまでは
                <methodname>getRef()</methodname> メソッドの返す参照が有効であることが保証されます。
            </para>

            <programlisting language="php"><![CDATA[
$memObject1 = $memoryManager->create($data1);
$memObject2 = $memoryManager->create($data2);
...

$memObject1->lock();
$memObject2->lock();

$value1 = &$memObject1->getRef();
$value2 = &$memObject2->getRef();

for ($count = 0; $count < strlen($value2); $count++) {
    $value1 .= $value2[$count];
}

$memObject1->touch();
$memObject1->unlock();
$memObject2->unlock();
]]></programlisting>
        </sect3>

        <sect3 id="zend.memory.memory-objects.api.unlock">
            <title>unlock() メソッド</title>

            <programlisting language="php"><![CDATA[
public function unlock();
]]></programlisting>

            <para>
                <methodname>unlock()</methodname> メソッドは、
                ロックが不要となったオブジェクトのロックを解除します。
                上の例を参照ください。
            </para>

        </sect3>

        <sect3 id="zend.memory.memory-objects.api.isLocked">
            <title>isLocked() メソッド</title>

            <programlisting language="php"><![CDATA[
public function isLocked();
]]></programlisting>

            <para>
                <methodname>isLocked()</methodname> メソッドを使用して、
                オブジェクトがロックされているかどうかを調べます。
                オブジェクトがロックされている場合は <constant>TRUE</constant>、
                ロックされていない場合は <constant>FALSE</constant> を返します。
                "ロックされている" オブジェクトについては、これは常に
                <constant>TRUE</constant> を返します。また "移動可能な" オブジェクトの場合は
                <constant>TRUE</constant> あるいは <constant>FALSE</constant> のいずれかを返します。
            </para>

        </sect3>
    </sect2>
</sect1>
