<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Garbage Collector &#187; Flex 2</title>
	<atom:link href="http://garbage-collector.ru/cats/dogs/flex_2/feed" rel="self" type="application/rss+xml" />
	<link>http://garbage-collector.ru</link>
	<description>Журнал о Flash, Flex, AIR, Grails и разработке Rich Internet Applications в условиях, приближенных к реальным</description>
	<lastBuildDate>Sun, 16 May 2010 17:08:15 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Последние заплаты для Flex 2.0.1 &#8211; устраняем несовместимости с Flash CS3</title>
		<link>http://garbage-collector.ru/2007/04/flex_201_patch_final.html</link>
		<comments>http://garbage-collector.ru/2007/04/flex_201_patch_final.html#comments</comments>
		<pubDate>Tue, 17 Apr 2007 12:20:16 +0000</pubDate>
		<dc:creator>Vooparker</dc:creator>
				<category><![CDATA[Flex 2]]></category>
		<category><![CDATA[Новости]]></category>

		<guid isPermaLink="false">http://www.garbage-collector.ru/gc/2007/04/17/%d0%bf%d0%be%d1%81%d0%bb%d0%b5%d0%b4%d0%bd%d0%b8%d0%b5-%d0%b7%d0%b0%d0%bf%d0%bb%d0%b0%d1%82%d1%8b-%d0%b4%d0%bb%d1%8f-flex-201-%d1%83%d1%81%d1%82%d1%80%d0%b0%d0%bd%d1%8f%d0%b5%d0%bc-%d0%bd%d0%b5/</guid>
		<description><![CDATA[И так что же стряслось на этот раз? А стряслось вот что. После добавления SWC-библиотеки, скомпиленной во Flash CS3 Professional, к flex-проекту отлетает Design View (интересно, когда бы я это заметил? =)). Ну и плюс к этому, после установки новенького Flash Player&#8217;a версии 9.0.45.0 получаем неработающий дебаггер для браузеров семейства Mozilla. Так что вперед за [...]]]></description>
			<content:encoded><![CDATA[<p>И так что же стряслось на этот раз? А стряслось вот что. После добавления SWC-библиотеки, скомпиленной во Flash CS3 Professional, к flex-проекту отлетает Design View (интересно, когда бы я это заметил? =)). Ну и плюс к этому, после установки новенького Flash Player&#8217;a версии 9.0.45.0 получаем неработающий дебаггер для браузеров семейства Mozilla. Так что вперед за <a href="http://www.adobe.com/support/flex/ts/documents/kb401493/flex_201_patch_FINAL.zip">заплатами</a> (1.9 MB).</p>
<h3>Установка заплаток для SDK:</h3>
<ol>
<li>Откройте директорию <code>{Flex_SDK}/lib</code>.</li>
<li>Сделайте резервные копии файлов <code>swfkit.jar</code>, <code>mxmlc.jar </code>и <code>fdb.jar</code>.</li>
<li>Скачайте архив <a href="http://www.adobe.com/support/flex/ts/documents/kb401493/flex_201_patch_FINAL.zip"><code>flex_201_patch_final.zip</code></a> и распакуйте его во временную директорию.</li>
<li>Замените файлы <code>swfkit.jar</code>, <code>mxmlc.jar </code>и <code>fdb.jar</code> аналогичными из архива.</li>
</ol>
<h3>Установка заплаток для Flex Builder:</h3>
<ol>
<li>Установите заплатки для SDK (см. выше).<br />
В случае, если вы используете Standalone установку билдера, SDK должен быть здесь<br />
<code>C:\Program Files\Adobe\Flex Builder 2\Flex SDK 2\lib</code>,<br />
если билдер установлен как плагин, то здесь -<br />
<code>C:\Program Files\Adobe\Flex Builder 2 Plug-in\Flex SDK 2\lib</code>.
</li>
<li>Откройте lib директорию в папке \com.adobe.flexbuilder.flex_2.0.155577.<br />
Для Standalone установки билдера, это может быть здесь<br />
<code>C:\Program Files\Adobe\Flex Builder 2\plugins\com.adobe.flexbuilder.flex_2.0.155577\lib</code>,<br />
для плагина -<br />
<code>eclipse\plugins\com.adobe.flexbuilder.flex_2.0.155577\lib</code>.</li>
<li>Сделайте резервные копии файлов <code>swfkit.jar</code>, <code>mxmlc.jar </code>и <code>fdb.jar</code>.</li>
<li>Замените файлы <code>swfkit.jar</code>, <code>mxmlc.jar </code>и <code>fdb.jar</code> аналогичными из архива.</li>
</ol>
<p>За дополнительными сведениями <a href="http://www.adobe.com/go/kb401493">сюда</a>.</p>
<p>P.S. Обратите внимание на название архива flex_201_patch_<b>FINAL</b>.zip. Что бы это значило?..</p>
]]></content:encoded>
			<wfw:commentRss>http://garbage-collector.ru/2007/04/flex_201_patch_final.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Flex RemoteObject и AMFPHP 1.9</title>
		<link>http://garbage-collector.ru/2007/03/flex_remoteobject_n_amfphp.html</link>
		<comments>http://garbage-collector.ru/2007/03/flex_remoteobject_n_amfphp.html#comments</comments>
		<pubDate>Tue, 13 Mar 2007 11:44:13 +0000</pubDate>
		<dc:creator>Vooparker</dc:creator>
				<category><![CDATA[Client/Server]]></category>
		<category><![CDATA[Flex 2]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://www.garbage-collector.ru/gc/2007/03/13/flex_remoteobject_n_amfphp/</guid>
		<description><![CDATA[Многие люди, работающие в сфере RIA, знают, что Patrick Mineault недавно выпустил новую версию amfphp, поддерживающую Flex 2. В этой статье мы узнаем, как установить новую версию amfphp и как работать во Flex 2 с RemoteObject  в виде mxml-тэга, используя amfphp. И так, приступим.
Оригинал статьи: http://www.sephiroth.it/tutorials/flashPHP/flex_remoteobject/index.php.
Автор: Alessandro Crugnola
Перевод: Алексей «Vooparker» Аникутин.
Редактор: Юрий Яровой.
1. Загрузка [...]]]></description>
			<content:encoded><![CDATA[<p>Многие люди, работающие в сфере RIA, знают, что <a href="http://www.5etdemi.com/">Patrick Mineault</a> недавно выпустил новую версию <a href="http://www.amfphp.org/">amfphp</a>, поддерживающую Flex 2. В этой статье мы узнаем, как установить новую версию amfphp и как работать во Flex 2 с <a href="http://livedocs.macromedia.com/flex/2/langref/mx/rpc/remoting/mxml/RemoteObject.html">RemoteObject</a>  в виде mxml-тэга, используя amfphp. И так, приступим.</p>
<p>Оригинал статьи: <a href="http://www.sephiroth.it/tutorials/flashPHP/flex_remoteobject/index.php">http://www.sephiroth.it/tutorials/flashPHP/flex_remoteobject/index.php</a>.<br />
Автор: <a href="http://www.sephiroth.it/">Alessandro Crugnola</a><br />
Перевод: <a href="mailto:vooparker[at]gmail[dot]com">Алексей «Vooparker» Аникутин</a>.<br />
Редактор: <a href="http://www.garbage-collector.ru">Юрий Яровой</a>.</p>
<h3>1. Загрузка и установка amfphp 1.9</h3>
<p>Сначала скачайте архив с <a href="http://www.5etdemi.com/uploads/amfphp-1.9.beta.zip">amfphp 1.9</a> (<em>на момент перевода статьи вышла версия amfphp 1.9 beta 2 — прим. перевод.</em>) и распакуйте его в корневую директорию на вашем хосте (например, <code>http://localhost/amfphp2</code>).</p>
<h3>2. Создание первого сервиса</h3>
<p>В директории <code>amfphp2/services</code> создайте новую папку <code>tutorials</code> (в ней мы будем размещать наши php-классы). Теперь, в этой папке создайте файл <code>HelloWorld.php</code>:</p>
<div class="igBar"><span id="lphp-2"><a  href="#" onclick="javascript:showPlainTxt('php-2'); return false;"><span id='text_content'>ТЕКСТ&nbsp;С</span>&nbsp;<span id='text_p'>П</span><span id='text_o'>О</span><span id='text_d'>Д</span><span id='text_c'>С</span><span id='text_v'>В</span><span  id='text_e'>Е</span><span id='text_t'>Т</span><span id='text_k'>К</span><span  id='text_o2'>О</span><span id='text_y'>Й</span></a></span></div>
<div class="syntax_hilite"><span class="langName">PHP:</span>
<div id="php-2">
<div class="php">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#000000; font-weight:bold;">&lt;?php</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#008000;">/**</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#008000;"> * Простой учебный класс.</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#008000;"> */</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#000000; font-weight:bold;">class</span> HelloWorld <span style="color:#006600; font-weight:bold;">&#123;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color:#008000;">/**</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#008000;">&nbsp; &nbsp; &nbsp;* Простой учебный метод.</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#008000;">&nbsp; &nbsp; &nbsp;* @returns Строка 'Hello World!'</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#008000;">&nbsp; &nbsp; &nbsp;*/</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color:#000000; font-weight:bold;">function</span> sayHello<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&#123;</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#616100;">return</span> <span style="color:#FF0000;">"Hello World!"</span>;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&#125;</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#006600; font-weight:bold;">&#125;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#000000; font-weight:bold;">?&gt;</span> </div>
</li>
</ol>
</div>
</div>
</div>
<p>
Если вам уже приходилось работать с предыдущими версиями amfphp, то вы, наверное, сразу сразу заметили отсутствие <code>$this-&gt;methodTable</code> в конструкторе класса. Method <code>table</code> (список с доступными методами класса и их описанием) был упразднен в версии amfphp 1.9 и теперь попросту игнорируется.</p>
<blockquote><p>В версии amfphp 1.9 предполагается, что все методы класса могут быть вызванными удаленно до тех пор, если вы не  добавляете в начало названия метода символ подчеркивания <code>"_"</code>, или идентификатор доступа <code>private</code> (только для php5).</p></blockquote>
<p>Комментарии в стиле <code>javadoc</code>, использованные в классе как в его описании так и в описании его методов, так же будут отображены в amfphp браузере (<em>что очень удобно, особенно, когда за разработку серверной и клиентской части отвечают разные разработчики  — прим. перевод.</em>). Тех кто работал с предыдущими версиями amfphp ожидает сюрприз — новый браузер теперь сделан на Flex 2, с его помощью вы можете исследовать доступные сервисы. Сам браузер находится в директории <code>amfphp2/browser</code> (например, <code>http://localhost/amfphp2/browser</code>).</p>
<p>Браузер сервисов amfphp версии 1.9 beta2 с выбранным сервисом <code>Helloworld.php</code>:<br />
<img src="http://www.garbage-collector.ru/blog-flash-lite2/wp-content/uploads/2007/03/amfphp_browser.png" alt="Браузер сервисов AMFPHP 1.9 beta 2" /><br />
Как вы видите в браузере отображены javadoc-комментарии, описывающие как класс в целом, так и его метод. Как и в предыдущих версиях браузера вы можете протестировать методы сервиса, просто нажав кнопку <strong>Call</strong>. Если метод требует аргументов, то рядом с кнопкой <strong>Call</strong> появятся поля ввода для каждого аргумента.</p>
<h3>3. Создание Flex 2 проекта.</h3>
<p>Создайте новый проект в вашей Flex 2 IDE. Откройте его свойства (правый клик на названии проекта и выберите "Properties"). В окне диалога свойств проекта выберите раздел меню "Flex Build path", затем переключитесь на вкладку "Library Path". Убедитесь, что среди библиотек проекта находится файл "<code><strong>rpc.swc</strong></code>", как показано на рисунке:<br />
<img src="http://www.garbage-collector.ru/blog-flash-lite2/wp-content/uploads/2007/03/flex2_project_library.gif" alt="Project Library" /><br />
Теперь нам необходимо сконфигурировать удаленные сервисы для того, чтобы получить возможность вызова их методов. Поэтому создайте в корне нашего flex-проекта файл <code>services-config.xml</code> со следующим содержанием:</p>
<pre><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;services-config&gt;
	&lt;services&gt;
		&lt;service id="amfphp-flashremoting-service"
                               class="flex.messaging.services.RemotingService"
                               messageTypes="flex.messaging.messages.RemotingMessage"&gt;
			&lt;destination id="amfphp"&gt;
				&lt;channels&gt;

					&lt;channel ref="my-amfphp"/&gt;
				&lt;/channels&gt;
				&lt;properties&gt;
					&lt;source&gt;*&lt;/source&gt;
				&lt;/properties&gt;

			&lt;/destination&gt;
		&lt;/service&gt;
	&lt;/services&gt;
	&lt;channels&gt;
		&lt;channel-definition id="my-amfphp" class="mx.messaging.channels.AMFChannel"&gt;
			&lt;endpoint uri="http://localhost/amfphp2/gateway.php"
                             class="flex.messaging.endpoints.AMFEndpoint"/&gt;

		&lt;/channel-definition&gt;
	&lt;/channels&gt;
&lt;/services-config&gt;</code></pre>
<p>Теперь снова открываем свойства проекта и в разделе "Flex Compiler" добавляем следующую строку <code>-services "services-config.xml"</code> (см. картинку):<br />
<img src="http://www.garbage-collector.ru/blog-flash-lite2/wp-content/uploads/2007/03/flex2_compiler.gif" alt="Compiler settings" /><br />
И так теперь мы готовы использовать RemoteObjects.</p>
<blockquote><p>Если вы хотите узнать больше о конфигурационном файле сервисов, тогда вам <a href="http://livedocs.macromedia.com/flex/2/docs/wwhelp/wwhimpl/common/html/wwhelp.htm?context=LiveDocs_Parts&amp;file=00001099.html">сюда</a></p></blockquote>
<h4>3.1 mxml файл</h4>
<p>Создайте в проекте новый файл <code>main.mxml</code>, а в нем — очень простой лэйаут (расположение и композиция элементов):</p>
<pre><code>&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
backgroundColor="#FFFFFF" viewSourceURL="srcview/index.html"&gt;
    &lt;mx:Button x="170" y="157" label="sayHello" width="79"/&gt;
    &lt;mx:Button x="170" y="187" label="test fault"/&gt;
    &lt;mx:TextArea x="10" y="36" width="239" height="113" id="result_text"/&gt;
    &lt;mx:Label x="10" y="10" text="Result:"/&gt;
&lt;/mx:Application&gt;
</code></pre>
<p>Как вы видите, пока в нашем файле не описано никаких действий, это просто лэйаут для первого теста. У нас есть две кнопки: первая будет вызывать удаленный метод <code>sayHello</code>, вторая — метод, которого нет в вызываемом сервисе, для того, чтобы посмотреть, как осуществляется обработка ошибок. Как в случае успешного вызова, так и в случае неудачи,  результат будет отображен в текстовом поле <code>result_text</code>.</p>
<p>Теперь давайте дополним наш mxml-файл тегом <strong>RemoteObject</strong>, где опишем, какие методы мы можем вызывать из amfphp. После чего наш файл должен выглядеть так:</p>
<pre><code>&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
backgroundColor="#FFFFFF" viewSourceURL="srcview/index.html"&gt;
    &lt;mx:RemoteObject id="myservice" fault="faultHandler(event)"
              showBusyCursor="true" source="tutorials.HelloWorld" destination="amfphp"&gt;
        &lt;mx:method name="sayHello" result="resultHandler(event)" /&gt;
    &lt;/mx:RemoteObject&gt;

    &lt;mx:Script&gt;
        &lt;![CDATA[
            import mx.managers.CursorManager;
            import mx.rpc.events.ResultEvent;
            import mx.rpc.events.FaultEvent;
            private function faultHandler(fault:FaultEvent):void
            {
                CursorManager.removeBusyCursor();
                result_text.text = "code:n" + fault.fault.faultCode + "nnMessage:n" + fault.fault.faultString + "nnDetail:n" + fault.fault.faultDetail;
            }

            private function resultHandler(evt:ResultEvent):void
            {
                result_text.text = evt.message.body.toString(); // same as: evt.result.toString();
            }
        ]]&gt;
    &lt;/mx:Script&gt;

    &lt;mx:Button x="250" y="157" label="sayHello" width="79" click="myservice.getOperation('sayHello').send();"/&gt;
    &lt;mx:Button x="250" y="187" label="test fault" click="myservice.getOperation('foo').send(); "/&gt;
    &lt;mx:TextArea x="10" y="36" width="319" height="113" id="result_text"/&gt;
    &lt;mx:Label x="10" y="10" text="Result:"/&gt;
&lt;/mx:Application&gt;
</code></pre>
<blockquote><p>Два отступления перед тем как продолжить. Во первых, как вы видите я использовал код <code>myservice.getOperation('sayHello').send();</code>, чтобы вызвать метод <code>sayHello</code> удаленного сервиса. Вы можете сделать тоже самое, используя следующий код <code>myservice.sayHello.send();</code>. Во-вторых, в обработчике успешного вызова я использовал код <code>evt.message.body</code>, чтобы получить доступ к телу пришедшего сообщения. И в этом случае вы можете использовать альтернативный код <code>evt.result</code> для получения точно такого же результата.</p></blockquote>
<p>Теперь покликайте по кнопкам <strong>call</strong> и <strong>test fault</strong> и посмотрите что произойдет. Сверх того, вы можете увидеть, что происходит «за кулисами» нашего приложения, когда вы вызываете удаленные методы, в этом вам поможет <a href="http://kevinlangdon.com/serviceCapture/">Service Capture</a>.</p>
<p>Давайте посмотрим что изменилось. Мы добавили тэг <code>mx:RemoteObject</code> в начале mxml-файла и сделали это следующим образом:</p>
<ul>
<li> <code><strong>id="myservice"</strong></code> — это позволит в коде обращаться к объекту по его id</li>
<li> <code><strong>fault="faultHandler(event)"</strong></code> — назначаем метод, который по умолчанию будет обрабатывать ошибки</li>
<p></p>
<li> <code><strong>showBusyCursor="true"</strong></code> — этим мы сообщаем нашему приложению, что вовремя вызова удаленного метода, необходимо показывать busy сursor  до тех пор, пока не будет получен результат.</li>
<li> <code><strong>source="tutorials.HelloWorld"</strong></code> — это «пакетоподобный» путь к нашему php-классу, который, как вы помните, находится здесь <code>/services/tutorials/HelloWorld.php</code>.</li>
<li> <code><strong>destination="amfphp"</strong></code> — это ссылка на id тэга <code><strong>&lt;destination&gt;</strong></code> в файле <code>services-config.xml</code></li>
</ul>
<p>Теперь, когда мы описали наш remoteObject, добавляем удаленные методы, которые мы хотим вызывать. Для этого добавим тэг <code>mx:method</code> внутрь тэга <code>mx:RemoteObject</code>:<br />
<code>&lt;mx:method name="sayHello" result="resultHandler(event)" /&gt;</code></p>
<p>В этом случае, когда вернется результат вызова  метода <code>sayHello</code>, он будет обработан методом приложения <code>resultHandler</code>:</p>
<pre><code>private function resultHandler(evt:ResultEvent):void {
    result_text.text = evt.message.body.toString();
}</code></pre>
<p>Нам придется привести свойство <code>body</code> к типу String, потому как изначально оно определено как Object в интерфейсе <a href="http://livedocs.macromedia.com/flex/2/langref/mx/messaging/messages/IMessage.html">IMessage</a>.</p>
<blockquote><p> Вы так же можете использовать <code>evt.result</code> вместо <code>evt.message.body</code></p></blockquote>
<h4>3.2 Более сложный пример (RemoteAlias).</h4>
<p>Теперь давайте рассмотрим более сложный пример с возвращаемым результатом типа <a href="http://livedocs.macromedia.com/flex/2/langref/mx/collections/ArrayCollection.html">ArrayCollection</a> и использованием метатэга [<a href="http://livedocs.macromedia.com/flex/2/docs/wwhelp/wwhimpl/common/html/wwhelp.htm?context=LiveDocs_Parts&amp;file=00001187.html">RemoteClass</a>] во Flex.</p>
<p>В этом примере удаленный метод будет возвращать массив экземпляров класса <code>Person</code>, стуктура которго заранее определена (mapped classes). Это означает, что тип каждого элемента возвращаемого массива соответствует классу с идентичной структурой  в actionscript.</p>
<p>Сначала создадим новый php-класс "<code>Person.php</code>" в папке "<code>tutorials</code>":</p>
<pre><code>&lt;?php
class Person {
    var $firstName;
    var $lastName;
    var $phone;
    var $email;
    // explicit actionscript package
    var $_explicitType = "tutorials.Person";
}
?&gt;</code></pre>
<p>Свойство <code>$_explicitType</code> скажет amfphp, что этот класс имеет свой	 эквивалент "tutorials.Person" во Flex. А вот и сам аналог предыдущего класса в ActionScript (мы должны сохранять структуру пакетов, поэтому класс "<code>Person.as</code>" располагается в директории "<code>tutorials</code>" нашего Flex проекта):</p>
<pre><code>package tutorials
{
    [RemoteClass(alias="tutorials.Person")]
    [Bindable]
    public class Person
    {
        public var firstName:String;
        public var lastName:String;
        public var phone:String;
        public var email:String;
    }
}</code></pre>
<p>Метатэг RemoteClass укажет Flex'у, какой удаленный объект ассоциирован с этим классом (важно помнить, что оба класса должны иметь одинаковую структуру, иначе Flex не сможет правильно привести к нужному типу удаленный объект).</p>
<p>Теперь создадим php-класс, который будет являться нашим основным сервисом - "<code>PersonService.php</code>". В нем будет всего лишь один открытый метод "<code>getList</code>", который возвращает массив состоящий из экземпляров класса Person:</p>
<pre><code>&lt;?php

require_once "./Person.php";

class PersonService
{
    /**
     * Get a list of people
     * @returns An Array of Person
     */
    function getList()
    {
        $people = array(
            array("Alessandro", "Crugnola", "+390332730999", "alessandro@sephiroth.it"),
            array("Patrick", "Mineault", "+1234567890", "patrick@5etdemi.com"),
        );

        $p = array();

        for($a = 0; $a &lt; count($people); $a++){
            $person = new Person();
            $person-&gt;firstName = $people[$a][0];
            $person-&gt;lastName = $people[$a][1];
            $person-&gt;phone = $people[$a][2];
            $person-&gt;email = $people[$a][3];
            $p[] = $person;
        }

        return $p;
    }
}
?&gt;</code></pre>
<p>Теперь перейдем к исходному коду mxml-файла.</p>
<h4>mxml-файл</h4>
<p>Это код <code>main.mxml</code> нашего нового примера:</p>
<pre><code>&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
backgroundColor="#FFFFFF"&gt;
    &lt;mx:RemoteObject id="myservice" source="tutorials.PersonService" destination="amfphp"
fault="faultHandler(event)" showBusyCursor="true"&gt;
        &lt;mx:method name="getList" result="getListHandler(event)" fault="faultHandler(event)" /&gt;
    &lt;/mx:RemoteObject&gt;
    &lt;mx:DataGrid x="10" y="10" width="345" id="people_list" dataProvider="{dp}"
change="changeHandler(event)"&gt;
        &lt;mx:columns&gt;
            &lt;mx:DataGridColumn headerText="Last name" dataField="lastName"/&gt;
            &lt;mx:DataGridColumn headerText="First name" dataField="firstName"/&gt;
            &lt;mx:DataGridColumn headerText="Telephone" dataField="phone"/&gt;
            &lt;mx:DataGridColumn headerText="Email" dataField="email"/&gt;
        &lt;/mx:columns&gt;
    &lt;/mx:DataGrid&gt;

    &lt;mx:Script&gt;
        &lt;![CDATA[
            import mx.utils.ArrayUtil;
            import tutorials.Person;
            import mx.collections.ArrayCollection;
            import mx.rpc.events.ResultEvent;
            import mx.controls.Alert;
            import mx.rpc.events.FaultEvent;

            [Bindable]
            private var dp:ArrayCollection;

            [Bindable]
            private var selectedPerson:Person;

            private function faultHandler(fault:FaultEvent):void
            {
                Alert.show(fault.fault.faultString, fault.fault.faultCode.toString());
            }

            private function getListHandler(evt:ResultEvent):void
            {
                dp = new ArrayCollection( ArrayUtil.toArray(evt.result) );
            }

            private function changeHandler(event:Event):void
            {
                selectedPerson = Person(DataGrid(event.target).selectedItem);
            }
        ]]&gt;
    &lt;/mx:Script&gt;
    &lt;mx:Button x="290" y="357" label="get list" click="myservice.getOperation('getList').send();"/&gt;
    &lt;mx:Form x="10" y="174" width="345" height="175"&gt;
        &lt;mx:FormHeading label="Selected Person" /&gt;
        &lt;mx:FormItem label="First Name"&gt;
            &lt;mx:TextInput id="person_first_name" text="{selectedPerson.firstName}" /&gt;
        &lt;/mx:FormItem&gt;
        &lt;mx:FormItem label="Last Name"&gt;
            &lt;mx:TextInput id="person_last_name" text="{selectedPerson.lastName}" /&gt;
        &lt;/mx:FormItem&gt;
        &lt;mx:FormItem label="Telephone"&gt;
            &lt;mx:TextInput id="person_phone" text="{selectedPerson.phone}" /&gt;
        &lt;/mx:FormItem&gt;
        &lt;mx:FormItem label="Email"&gt;
            &lt;mx:TextInput id="person_email" text="{selectedPerson.email}" /&gt;
        &lt;/mx:FormItem&gt;
    &lt;/mx:Form&gt;
&lt;/mx:Application&gt;</code></pre>
<p>В тэге RemoteObject, мы указываем в качестве сервиса используется класс <code>tutorials/PersonService.php</code>, внутри тэга описываем один метод <code>getList</code>, который вызывает метод-тёску класса <code>PersonService.php</code>.</p>
<p>Обработчик удачного вызова преобразует результат, полученный от php, в ArrayCollection и записывает его в переменную "<code>dp</code>".</p>
<p>Источник данных компонента DataGrid «связан» с приватной переменной "<code>dp</code>" (ArrayCollection) (перед объявлением "<code>dp</code>" стоит метатэг [<a href="http://livedocs.macromedia.com/flex/2/docs/wwhelp/wwhimpl/common/html/wwhelp.htm?context=LiveDocs_Parts&amp;file=00001653.html">Bindable</a>], это значит, что данные в DataGrid изменяться как только они будет получены от php).</p>
<p>Другая переменная "<code>selectedPerson</code>", которая также обозначена как [Bindable], меняется как только будет выбран новый элемент в DataGrid (см. метод "<code>changeHandler</code>"). Свойства "<code>selectedPerson</code>" (firtsname, lastname и др.) отображаются  в элементах формы.</p>
<p>И наконец, кнопка, которая вызывает удаленный метод <code>getList</code>, используя для этого следующий код:</p>
<p><code>click="myservice.getOperation('getList').send();"</code></p>
<blockquote><p>AMFPHP 1.9 содержит много изменений, что позволяет корректно работать с flex2/Data services. Вы можете узнать больше о новых релизах и обо всех новых возможностях и  изменениях <a href="http://www.5etdemi.com/blog/archives/2006/12/amfphp-19-beta-get-it-now/">здесь</a>.<br />
Помните, что в статье рассмотрена только бета-версия amfphp2 и многие вещи могут измениться в будущем (надеемся, что будет реализована полная поддержка всех возможностей Flex Data Services 2).</p></blockquote>
<p>От переводчика: Спасибо автору статьи Alessandro Crugnola за разрешение на перевод и хозяину этого блога Юрию Яровому за публикацию перевода.</p>
]]></content:encoded>
			<wfw:commentRss>http://garbage-collector.ru/2007/03/flex_remoteobject_n_amfphp.html/feed</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
	</channel>
</rss>
