<?php
include_once $_SERVER['DOCUMENT_ROOT'] . '/include/shared-manual.inc';
$TOC = array();
$TOC_DEPRECATED = array();
$PARENTS = array();
include_once dirname(__FILE__) ."/toc/book.yar.inc";
$setup = array (
  'home' => 
  array (
    0 => 'index.php',
    1 => 'PHP Manual',
  ),
  'head' => 
  array (
    0 => 'UTF-8',
    1 => 'en',
  ),
  'this' => 
  array (
    0 => 'yar.examples.php',
    1 => 'Examples',
    2 => 'Examples',
  ),
  'up' => 
  array (
    0 => 'book.yar.php',
    1 => 'Yar',
  ),
  'prev' => 
  array (
    0 => 'yar.constants.php',
    1 => 'Predefined Constants',
  ),
  'next' => 
  array (
    0 => 'class.yar-server.php',
    1 => 'Yar_Server',
  ),
  'alternatives' => 
  array (
  ),
  'source' => 
  array (
    'lang' => 'en',
    'path' => 'reference/yar/examples.xml',
  ),
  'history' => 
  array (
  ),
);
$setup["toc"] = $TOC;
$setup["toc_deprecated"] = $TOC_DEPRECATED;
$setup["parents"] = $PARENTS;
manual_setup($setup);

contributors($setup);

?>
<div id="yar.examples" class="chapter">
 <h1 class="title">Examples</h1>

 <p class="simpara">
  The examples below walk through a complete service: a server that
  exposes a few arithmetic methods, a synchronous client that calls
  them, a client that fans several calls out concurrently, and a
  client that talks to a server over TCP.
 </p>

 <div class="example" id="example-1">
  <p><strong>Example #1 Yar Server Example</strong></p>
  <div class="example-contents"><p>
   A Yar service is just a regular PHP class wrapped by
   <span class="classname"><a href="class.yar-server.php" class="classname">Yar_Server</a></span>. Every public method of the
   object becomes an RPC endpoint; protected and private methods, as
   well as methods whose names start with an underscore, stay hidden
   from clients. The doc comments of the public methods are collected
   and shown on the service information page.
  </p></div>
  <div class="example-contents"><p>
   RPC requests arrive as HTTP POST requests carrying a binary Yar
   protocol payload, so the script is usually mapped to a URI on a
   regular web server.
  </p></div>
  <div class="example-contents">
<div class="phpcode"><pre><code style="color: #000000"><span style="color: #0000BB">&lt;?php

</span><span style="color: #FF8000">/* assume this page can be accessed by http://api.example.com/operator.php */

</span><span style="color: #007700">class </span><span style="color: #0000BB">Operator </span><span style="color: #007700">{

    </span><span style="color: #FF8000">/**
     * Add two operands
     * @param integer
     * @return integer
     */
    </span><span style="color: #007700">public function </span><span style="color: #0000BB">add</span><span style="color: #007700">(</span><span style="color: #0000BB">$a</span><span style="color: #007700">, </span><span style="color: #0000BB">$b</span><span style="color: #007700">) {
        return </span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">_add</span><span style="color: #007700">(</span><span style="color: #0000BB">$a</span><span style="color: #007700">, </span><span style="color: #0000BB">$b</span><span style="color: #007700">);
    }

    </span><span style="color: #FF8000">/**
     * Sub
     */
    </span><span style="color: #007700">public function </span><span style="color: #0000BB">sub</span><span style="color: #007700">(</span><span style="color: #0000BB">$a</span><span style="color: #007700">, </span><span style="color: #0000BB">$b</span><span style="color: #007700">) {
        return </span><span style="color: #0000BB">$a </span><span style="color: #007700">- </span><span style="color: #0000BB">$b</span><span style="color: #007700">;
    }

    </span><span style="color: #FF8000">/**
     * Mul
     */
    </span><span style="color: #007700">public function </span><span style="color: #0000BB">mul</span><span style="color: #007700">(</span><span style="color: #0000BB">$a</span><span style="color: #007700">, </span><span style="color: #0000BB">$b</span><span style="color: #007700">) {
        return </span><span style="color: #0000BB">$a </span><span style="color: #007700">* </span><span style="color: #0000BB">$b</span><span style="color: #007700">;
    }

    </span><span style="color: #FF8000">/**
     * Protected methods will not be exposed
     * @param integer
     * @return integer
     */
    </span><span style="color: #007700">protected function </span><span style="color: #0000BB">_add</span><span style="color: #007700">(</span><span style="color: #0000BB">$a</span><span style="color: #007700">, </span><span style="color: #0000BB">$b</span><span style="color: #007700">) {
        return </span><span style="color: #0000BB">$a </span><span style="color: #007700">+ </span><span style="color: #0000BB">$b</span><span style="color: #007700">;
    }
}

</span><span style="color: #0000BB">$server </span><span style="color: #007700">= new </span><span style="color: #0000BB">Yar_Server</span><span style="color: #007700">(new </span><span style="color: #0000BB">Operator</span><span style="color: #007700">());
</span><span style="color: #0000BB">$server</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">handle</span><span style="color: #007700">();
</span><span style="color: #0000BB">?&gt;</span></code></pre></div>
  </div>

 </div>

 <div class="example" id="example-2">
  <p><strong>Example #2 Access the server in browser (GET request)</strong></p>
  <div class="example-contents"><p>
   When a GET request is issued to the service URI — for instance by
   opening it in a browser — Yar does not perform an RPC call but
   renders an information page listing every public method of the
   executor object together with its doc comment. This is controlled
   by the <a href="yar.configuration.php#ini.yar.expose-info" class="link">yar.expose_info</a>
   directive; when it is off, a GET request fails instead.
  </p></div>
  <div class="example-contents"><p>The above example will output
something similar to:</p></div>
  <div class="mediaobject">
   
   <div class="imageobject">
    <img src="images/4fd86c7f1b197d1d954ad0f4b033dc93-yar.png" alt="Yar Server Info" width="700px"  />
   </div>
  </div>
 </div>

 <div class="example" id="example-3">
  <p><strong>Example #3 Yar Client Example</strong></p>
  <div class="example-contents"><p>
   A <span class="classname"><a href="class.yar-client.php" class="classname">Yar_Client</a></span> is bound to a single service
   address. Calling any undefined method on it is transparently turned
   into a synchronous RPC call, so remote methods look and feel like
   local ones; <span class="methodname"><a href="yar-client.call.php" class="methodname">Yar_Client::call()</a></span> does the same
   thing explicitly by name.
  </p></div>
  <div class="example-contents"><p>
   Protected methods are not exposed: calling one fails with a
   <span class="exceptionname"><a href="class.yar-client-exception.php" class="exceptionname">Yar_Client_Exception</a></span> whose code is
   <strong><code><a href="yar.constants.php#constant.yar-err-request">YAR_ERR_REQUEST</a></code></strong>.
  </p></div>
  <div class="example-contents">
<div class="phpcode"><pre><code style="color: #000000"><span style="color: #0000BB">&lt;?php
$client </span><span style="color: #007700">= new </span><span style="color: #0000BB">Yar_Client</span><span style="color: #007700">(</span><span style="color: #DD0000">"http://api.example.com/operator.php"</span><span style="color: #007700">);

</span><span style="color: #FF8000">/* call directly */
</span><span style="color: #0000BB">var_dump</span><span style="color: #007700">(</span><span style="color: #0000BB">$client</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">add</span><span style="color: #007700">(</span><span style="color: #0000BB">1</span><span style="color: #007700">, </span><span style="color: #0000BB">2</span><span style="color: #007700">));

</span><span style="color: #FF8000">/* call via call() */
</span><span style="color: #0000BB">var_dump</span><span style="color: #007700">(</span><span style="color: #0000BB">$client</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">call</span><span style="color: #007700">(</span><span style="color: #DD0000">"add"</span><span style="color: #007700">, array(</span><span style="color: #0000BB">3</span><span style="color: #007700">, </span><span style="color: #0000BB">2</span><span style="color: #007700">)));

</span><span style="color: #FF8000">/* _add cannot be called: it is not public */
</span><span style="color: #0000BB">var_dump</span><span style="color: #007700">(</span><span style="color: #0000BB">$client</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">_add</span><span style="color: #007700">(</span><span style="color: #0000BB">1</span><span style="color: #007700">, </span><span style="color: #0000BB">2</span><span style="color: #007700">));
</span><span style="color: #0000BB">?&gt;</span></code></pre></div>
  </div>

  <div class="example-contents"><p>The above example will output
something similar to:</p></div>
  <div class="example-contents screen">
<div class="cdata"><pre>
int(3)
int(5)
PHP Fatal error:  Uncaught Yar_Client_Exception: call to undefined api Operator::_add() in *
</pre></div>
  </div>
 </div>

 <div class="example" id="example-4">
  <p><strong>Example #4 Yar Concurrent Client Example</strong></p>
  <div class="example-contents"><p>
   Instead of calling services one after another,
   <span class="classname"><a href="class.yar-concurrent-client.php" class="classname">Yar_Concurrent_Client</a></span> registers several calls
   first and then dispatches them all at once with
   <span class="methodname"><a href="yar-concurrent-client.loop.php" class="methodname">Yar_Concurrent_Client::loop()</a></span>. The responses
   are passed to the callback in the order they arrive, not in the
   order the calls were registered.
  </p></div>
  <div class="example-contents"><p>
   Right after all requests have been sent, the callback is invoked
   once with <strong><code><a href="reserved.constants.php#constant.null">null</a></code></strong> arguments so that the caller knows no further
   request is pending; the example below checks for this notification.
  </p></div>
  <div class="example-contents">
<div class="phpcode"><pre><code style="color: #000000"><span style="color: #0000BB">&lt;?php
</span><span style="color: #007700">function </span><span style="color: #0000BB">callback</span><span style="color: #007700">(</span><span style="color: #0000BB">$ret</span><span style="color: #007700">, </span><span style="color: #0000BB">$callinfo</span><span style="color: #007700">) {
    if (</span><span style="color: #0000BB">$callinfo </span><span style="color: #007700">== </span><span style="color: #0000BB">NULL</span><span style="color: #007700">) {
        </span><span style="color: #FF8000">/* all requests are sent, waiting for the responses */
        </span><span style="color: #007700">return;
    }
    echo </span><span style="color: #0000BB">$callinfo</span><span style="color: #007700">[</span><span style="color: #DD0000">'method'</span><span style="color: #007700">], </span><span style="color: #DD0000">" result: "</span><span style="color: #007700">, </span><span style="color: #0000BB">$ret</span><span style="color: #007700">, </span><span style="color: #DD0000">"\n"</span><span style="color: #007700">;
}

function </span><span style="color: #0000BB">error_callback</span><span style="color: #007700">(</span><span style="color: #0000BB">$type</span><span style="color: #007700">, </span><span style="color: #0000BB">$error</span><span style="color: #007700">, </span><span style="color: #0000BB">$callinfo</span><span style="color: #007700">) {
    </span><span style="color: #0000BB">error_log</span><span style="color: #007700">(</span><span style="color: #DD0000">"[</span><span style="color: #0000BB">$type</span><span style="color: #DD0000">] </span><span style="color: #0000BB">$error</span><span style="color: #DD0000">"</span><span style="color: #007700">);
}

</span><span style="color: #FF8000">/* register async calls to remote services */
</span><span style="color: #0000BB">Yar_Concurrent_Client</span><span style="color: #007700">::</span><span style="color: #0000BB">call</span><span style="color: #007700">(</span><span style="color: #DD0000">"http://api.example.com/operator.php"</span><span style="color: #007700">, </span><span style="color: #DD0000">"add"</span><span style="color: #007700">, array(</span><span style="color: #0000BB">1</span><span style="color: #007700">, </span><span style="color: #0000BB">2</span><span style="color: #007700">), </span><span style="color: #DD0000">"callback"</span><span style="color: #007700">);
</span><span style="color: #0000BB">Yar_Concurrent_Client</span><span style="color: #007700">::</span><span style="color: #0000BB">call</span><span style="color: #007700">(</span><span style="color: #DD0000">"http://api.example.com/operator.php"</span><span style="color: #007700">, </span><span style="color: #DD0000">"sub"</span><span style="color: #007700">, array(</span><span style="color: #0000BB">2</span><span style="color: #007700">, </span><span style="color: #0000BB">1</span><span style="color: #007700">), </span><span style="color: #DD0000">"callback"</span><span style="color: #007700">);
</span><span style="color: #0000BB">Yar_Concurrent_Client</span><span style="color: #007700">::</span><span style="color: #0000BB">call</span><span style="color: #007700">(</span><span style="color: #DD0000">"http://api.example.com/operator.php"</span><span style="color: #007700">, </span><span style="color: #DD0000">"mul"</span><span style="color: #007700">, array(</span><span style="color: #0000BB">2</span><span style="color: #007700">, </span><span style="color: #0000BB">2</span><span style="color: #007700">), </span><span style="color: #DD0000">"callback"</span><span style="color: #007700">);

</span><span style="color: #FF8000">/* send all requests and wait for the responses */
</span><span style="color: #0000BB">Yar_Concurrent_Client</span><span style="color: #007700">::</span><span style="color: #0000BB">loop</span><span style="color: #007700">(</span><span style="color: #DD0000">"callback"</span><span style="color: #007700">, </span><span style="color: #DD0000">"error_callback"</span><span style="color: #007700">);
</span><span style="color: #0000BB">?&gt;</span></code></pre></div>
  </div>

  <div class="example-contents"><p>The above example will output
something similar to:</p></div>
  <div class="example-contents screen">
<div class="cdata"><pre>
mul result: 4
sub result: 1
add result: 3
</pre></div>
  </div>
 </div>

 <div class="example" id="example-5">
  <p><strong>Example #5 Yar TCP Client Example</strong></p>
  <div class="example-contents"><p>
   Besides HTTP, <span class="classname"><a href="class.yar-client.php" class="classname">Yar_Client</a></span> can talk to Yar
   compatible servers over TCP or Unix sockets, for example a service
   implemented with the
   <a href="https://github.com/laruence/yar-c" class="link external">&raquo;&nbsp;Yar C framework</a>,
   which serves the same binary Yar protocol that the PHP server uses.
  </p></div>
  <div class="example-contents">
<div class="phpcode"><pre><code style="color: #000000"><span style="color: #0000BB">&lt;?php
$client </span><span style="color: #007700">= new </span><span style="color: #0000BB">Yar_Client</span><span style="color: #007700">(</span><span style="color: #DD0000">"tcp://127.0.0.1:8600"</span><span style="color: #007700">);

</span><span style="color: #0000BB">var_dump</span><span style="color: #007700">(</span><span style="color: #0000BB">$client</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">add</span><span style="color: #007700">(</span><span style="color: #0000BB">1</span><span style="color: #007700">, </span><span style="color: #0000BB">2</span><span style="color: #007700">));
</span><span style="color: #0000BB">?&gt;</span></code></pre></div>
  </div>

 </div>

</div>
<?php manual_footer($setup); ?>