| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773 |
- <?xml version="1.0" encoding="UTF-8"?>
- <!-- Reviewed: no -->
- <sect1 id="zend.amf.server">
- <title>Zend_Amf_Server</title>
- <para>
- <classname>Zend_Amf_Server</classname> provides an <acronym>RPC</acronym>-style server for
- handling requests made from the Adobe Flash Player using the <acronym>AMF</acronym>
- protocol. Like all Zend Framework server classes, it follows the SoapServer
- <acronym>API</acronym>, providing an easy to remember interface for creating servers.
- </para>
- <example id="zend.amf.server.basic">
- <title>Basic AMF Server</title>
- <para>
- Let's assume that you have created a class <classname>Foo</classname> with a
- variety of public methods. You may create an <acronym>AMF</acronym> server using the
- following code:
- </para>
- <programlisting language="php"><![CDATA[
- $server = new Zend_Amf_Server();
- $server->setClass('Foo');
- $response = $server->handle();
- echo $response;
- ]]></programlisting>
- <para>
- Alternately, you may choose to attach a simple function as a
- callback instead:
- </para>
- <programlisting language="php"><![CDATA[
- $server = new Zend_Amf_Server();
- $server->addFunction('myUberCoolFunction');
- $response = $server->handle();
- echo $response;
- ]]></programlisting>
- <para>
- You could also mix and match multiple classes and functions. When
- doing so, we suggest namespacing each to ensure that no method name
- collisions occur; this can be done by simply passing a second string
- argument to either <methodname>addFunction()</methodname> or
- <methodname>setClass()</methodname>:
- </para>
- <programlisting language="php"><![CDATA[
- $server = new Zend_Amf_Server();
- $server->addFunction('myUberCoolFunction', 'my')
- ->setClass('Foo', 'foo')
- ->setClass('Bar', 'bar');
- $response = $server->handle();
- echo $response;
- ]]></programlisting>
- <para>
- The <classname>Zend_Amf_Server</classname> also allows services to be dynamically
- loaded based on a supplied directory path. You may add as many directories as you wish
- to the server. The order that you add the directories to the server will be the
- order that the <acronym>LIFO</acronym> search will be performed on the directories to
- match the class. Adding directories is completed with the
- <methodname>addDirectory()</methodname> method.
- </para>
- <programlisting language="php"><![CDATA[
- $server->addDirectory(dirname(__FILE__) .'/../services/');
- $server->addDirectory(dirname(__FILE__) .'/../package/');
- ]]></programlisting>
- <para>
- When calling remote services your source name can have underscore ("_") and dot (".")
- directory delimiters. When an underscore is used <acronym>PEAR</acronym> and Zend
- Framework class naming conventions will be respected. This means that if you call the
- service com_Foo_Bar the server will look for the file
- <filename>Bar.php</filename> in the each of the included paths at
- <filename>com/Foo/Bar.php</filename>. If the dot notation is used for your remote
- service such as <filename>com.Foo.Bar</filename> each included path will have
- <filename>com/Foo/Bar.php</filename> append to the end to autoload
- <filename>Bar.php</filename>
- </para>
- <para>
- All <acronym>AMF</acronym> requests sent to the script will then be handled by the
- server, and an <acronym>AMF</acronym> response will be returned.
- </para>
- </example>
- <note>
- <title>All Attached Methods and Functions Need Docblocks</title>
- <para>
- Like all other server components in Zend Framework, you must document your class
- methods using <acronym>PHP</acronym> docblocks. At the minimum, you
- need to provide annotations for each required argument as well as
- the return value. As examples:
- </para>
- <programlisting language="php"><![CDATA[
- // Function to attach:
- /**
- * @param string $name
- * @param string $greeting
- * @return string
- */
- function helloWorld($name, $greeting = 'Hello')
- {
- return $greeting . ', ' . $name;
- }
- ]]></programlisting>
- <programlisting language="php"><![CDATA[
- // Attached class
- class World
- {
- /**
- * @param string $name
- * @param string $greeting
- * @return string
- */
- public function hello($name, $greeting = 'Hello')
- {
- return $greeting . ', ' . $name;
- }
- }
- ]]></programlisting>
- <para>
- Other annotations may be used, but will be ignored.
- </para>
- </note>
- <sect2 id="zend.amf.server.flex">
- <title>Connecting to the Server from Flex</title>
- <para>
- Connecting to your <classname>Zend_Amf_Server</classname> from your Flex
- project is quite simple; you simply need to point your endpoint <acronym>URI</acronym>
- to your <classname>Zend_Amf_Server</classname> script.
- </para>
- <para>
- Say, for instance, you have created your server and placed it in the
- <filename>server.php</filename> file in your application root, and thus the
- <acronym>URI</acronym> is <filename>http://example.com/server.php</filename>. In this
- case, you would modify your <filename>services-config.xml</filename> file to set the
- channel endpoint uri attribute to this value.
- </para>
- <para>
- If you have never created a <filename>service-config.xml</filename> file you can do so
- by opening your project in your Navigator window. Right click on the project name and
- select 'properties'. In the Project properties dialog go into 'Flex Build Path' menu,
- 'Library path' tab and be sure the '<filename>rpc.swc</filename>' file is added to your
- projects path and Press Ok to close the window.
- </para>
- <para>
- You will also need to tell the compiler to use the
- <filename>service-config.xml</filename> to find the RemoteObject endpoint. To do this
- open your project properties panel again by right clicking on the project folder from
- your Navigator and selecting properties. From the properties popup select 'Flex
- Compiler' and add the string: <command>-services "services-config.xml"</command>. Press
- Apply then OK to return to update the option. What you have just done is told the Flex
- compiler to look to the <filename>services-config.xml</filename> file for runtime
- variables that will be used by the RemotingObject class.
- </para>
- <para>
- We now need to tell Flex which services configuration file to use for connecting to
- our remote methods. For this reason create a new
- '<filename>services-config.xml</filename>' file into your Flex project src folder. To
- do this right click on the project folder and select 'new' 'File' which will popup a
- new window. Select the project folder and then name the file
- '<filename>services-config.xml</filename>' and press finish.
- </para>
- <para>
- Flex has created the new <filename>services-config.xml</filename> and has it open. Use
- the following example text for your <filename>services-config.xml</filename> file. Make
- sure that you update your endpoint to match that of your testing server. Make sure you
- save the file.
- </para>
- <programlisting language="xml"><![CDATA[
- <?xml version="1.0" encoding="UTF-8"?>
- <services-config>
- <services>
- <service id="zend-service"
- class="flex.messaging.services.RemotingService"
- messageTypes="flex.messaging.messages.RemotingMessage">
- <destination id="zend">
- <channels>
- <channel ref="zend-endpoint"/>
- </channels>
- <properties>
- <source>*</source>
- </properties>
- </destination>
- </service>
- </services>
- <channels>
- <channel-definition id="zend-endpoint"
- class="mx.messaging.channels.AMFChannel">
- <endpoint uri="http://example.com/server.php"
- class="flex.messaging.endpoints.AMFEndpoint"/>
- </channel-definition>
- </channels>
- </services-config>
- ]]></programlisting>
- <para>
- There are two key points in the example. First, but last in the
- listing, we create an <acronym>AMF</acronym> channel, and specify the endpoint as the
- <acronym>URL</acronym> to our <classname>Zend_Amf_Server</classname>:
- </para>
- <programlisting language="xml"><![CDATA[
- <channel-definition id="zend-endpoint"
- <endpoint uri="http://example.com/server.php"
- class="flex.messaging.endpoints.AMFEndpoint"/>
- </channel-definition>
- ]]></programlisting>
- <para>
- Notice that we've given this channel an identifier, "zend-endpoint".
- The example create a service destination that refers to this channel,
- assigning it an ID as well -- in this case "zend".
- </para>
- <para>
- Within our Flex <acronym>MXML</acronym> files, we need to bind a RemoteObject to the
- service. In <acronym>MXML</acronym>, this might be done as follows:
- </para>
- <programlisting language="xml"><![CDATA[
- <mx:RemoteObject id="myservice"
- fault="faultHandler(event)"
- showBusyCursor="true"
- destination="zend">
- ]]></programlisting>
- <para>
- Here, we've defined a new remote object identified by "myservice"
- bound to the service destination "zend" we defined in the
- <filename>services-config.xml</filename> file. We then call methods on it
- in our ActionScript by simply calling "myservice.<method>".
- As an example:
- </para>
- <programlisting language="ActionScript"><![CDATA[
- myservice.hello("Wade");
- ]]></programlisting>
- <para>
- When namespacing, you would use
- "myservice.<namespace>.<method>":
- </para>
- <programlisting language="ActionScript"><![CDATA[
- myservice.world.hello("Wade");
- ]]></programlisting>
- <para>
- For more information on Flex RemoteObject invocation, <ulink
- url="http://livedocs.adobe.com/flex/3/html/help.html?content=data_access_4.html">
- visit the Adobe Flex 3 Help site</ulink>.
- </para>
- </sect2>
- <sect2 id="zend.amf.server.errors">
- <title>Error Handling</title>
- <para>
- By default, all exceptions thrown in your attached classes or
- functions will be caught and returned as <acronym>AMF</acronym> ErrorMessages. However,
- the content of these ErrorMessage objects will vary based on whether
- or not the server is in "production" mode (the default state).
- </para>
- <para>
- When in production mode, only the exception code will be returned.
- If you disable production mode -- something that should be done for
- testing only -- most exception details will be returned: the
- exception message, line, and backtrace will all be attached.
- </para>
- <para>
- To disable production mode, do the following:
- </para>
- <programlisting language="php"><![CDATA[
- $server->setProduction(false);
- ]]></programlisting>
- <para>
- To re-enable it, pass a <constant>TRUE</constant> boolean value instead:
- </para>
- <programlisting language="php"><![CDATA[
- $server->setProduction(true);
- ]]></programlisting>
- <note>
- <title>Disable production mode sparingly!</title>
- <para>
- We recommend disabling production mode only when in development.
- Exception messages and backtraces can contain sensitive system
- information that you may not wish for outside parties to access.
- Even though <acronym>AMF</acronym> is a binary format, the specification is now
- open, meaning anybody can potentially deserialize the payload.
- </para>
- </note>
- <para>
- One area to be especially careful with is <acronym>PHP</acronym> errors themselves.
- When the <property>display_errors</property> <acronym>INI</acronym> directive is
- enabled, any <acronym>PHP</acronym> errors for the current error reporting level are
- rendered directly in the output -- potentially disrupting the <acronym>AMF</acronym>
- response payload. We suggest turning off the <property>display_errors</property>
- directive in production to prevent such problems
- </para>
- </sect2>
- <sect2 id="zend.amf.server.response">
- <title>AMF Responses</title>
- <para>
- Occasionally you may desire to manipulate the response object
- slightly, typically to return extra message headers. The
- <methodname>handle()</methodname> method of the server returns the response
- object, allowing you to do so.
- </para>
- <example id="zend.amf.server.response.messageHeaderExample">
- <title>Adding Message Headers to the AMF Response</title>
- <para>
- In this example, we add a 'foo' MessageHeader with the value
- 'bar' to the response prior to returning it.
- </para>
- <programlisting language="php"><![CDATA[
- $response = $server->handle();
- $response->addAmfHeader(new Zend_Amf_Value_MessageHeader('foo', true, 'bar'))
- echo $response;
- ]]></programlisting>
- </example>
- </sect2>
- <sect2 id="zend.amf.server.typedobjects">
- <title>Typed Objects</title>
- <para>
- Similar to <acronym>SOAP</acronym>, <acronym>AMF</acronym> allows passing objects
- between the client and server. This allows a great amount of flexibility and
- coherence between the two environments.
- </para>
- <para>
- <classname>Zend_Amf</classname> provides three methods for mapping
- ActionScript and <acronym>PHP</acronym> objects.
- </para>
- <itemizedlist>
- <listitem>
- <para>
- First, you may create explicit bindings at the server level,
- using the <methodname>setClassMap()</methodname> method. The first
- argument is the ActionScript class name, the second the <acronym>PHP</acronym>
- class name it maps to:
- </para>
- <programlisting language="php"><![CDATA[
- // Map the ActionScript class 'ContactVO' to the PHP class 'Contact':
- $server->setClassMap('ContactVO', 'Contact');
- ]]></programlisting>
- </listitem>
- <listitem>
- <para>
- Second, you can set the public property <varname>$_explicitType</varname>
- in your <acronym>PHP</acronym> class, with the
- value representing the ActionScript class to map to:
- </para>
- <programlisting language="php"><![CDATA[
- class Contact
- {
- public $_explicitType = 'ContactVO';
- }
- ]]></programlisting>
- </listitem>
- <listitem>
- <para>
- Third, in a similar vein, you may define the public method
- <methodname>getASClassName()</methodname> in your <acronym>PHP</acronym> class;
- this method should return the appropriate ActionScript class:
- </para>
- <programlisting language="php"><![CDATA[
- class Contact
- {
- public function getASClassName()
- {
- return 'ContactVO';
- }
- }
- ]]></programlisting>
- </listitem>
- </itemizedlist>
- <para>
- Although we have created the ContactVO on the server we now need to make its
- corresponding class in <acronym>AS3</acronym> for the server object to be mapped to.
- </para>
- <para>
- Right click on the src folder of the Flex project and select New -> ActionScript
- File. Name the file ContactVO and press finish to see the new file. Copy the
- following code into the file to finish creating the class.
- </para>
- <programlisting language="as"><![CDATA[
- package
- {
- [Bindable]
- [RemoteClass(alias="ContactVO")]
- public class ContactVO
- {
- public var id:int;
- public var firstname:String;
- public var lastname:String;
- public var email:String;
- public var mobile:String;
- public function ProductVO():void {
- }
- }
- }
- ]]></programlisting>
- <para>
- The class is syntactically equivalent to the <acronym>PHP</acronym> of the same name.
- The variable names are exactly the same and need to be in the same case
- to work properly. There are two unique <acronym>AS3</acronym> meta tags in this class.
- The first is bindable which makes fire a change event when it is updated.
- The second tag is the RemoteClass tag which defines that this class can
- have a remote object mapped with the alias name in this case
- <emphasis>ContactVO</emphasis>. It is mandatory that this tag the value that was set
- is the <acronym>PHP</acronym> class are strictly equivalent.
- </para>
- <programlisting language="as"><![CDATA[
- [Bindable]
- private var myContact:ContactVO;
- private function getContactHandler(event:ResultEvent):void {
- myContact = ContactVO(event.result);
- }
- ]]></programlisting>
- <para>
- The following result event from the service call is cast instantly onto the Flex
- ContactVO. Anything that is bound to myContact will be updated with the returned
- ContactVO data.
- </para>
- </sect2>
- <sect2 id="zend.amf.server.resources">
- <title>Resources</title>
- <para>
- <classname>Zend_Amf</classname> provides tools for mapping resource types
- returned by service classes into data consumable by ActionScript.
- </para>
- <para>
- In order to handle specific resource type, the user needs to create a plugin class named
- after the resource name, with words capitalized and spaces removed (so, resource
- type "mysql result" becomes MysqlResult), with some prefix, e.g.
- <classname>My_MysqlResult</classname>. This class should implement one method,
- <methodname>parse()</methodname>, receiving one argument - the resource - and returning
- the value that should be sent to ActionScript. The class should be located in the file
- named after the last component of the name, e.g. <filename>MysqlResult.php</filename>.
- </para>
- <para>
- The directory containing the resource handling plugins should be registered with
- <classname>Zend_Amf</classname> type loader:
- </para>
- <programlisting language="php"><![CDATA[
- Zend_Amf_Parse_TypeLoader::addResourceDirectory(
- "My",
- "application/library/resources/My"
- );
- ]]></programlisting>
- <para>
- For detailed discussion of loading plugins, please see
- the <link linkend="zend.loader.pluginloader">plugin loader</link> section.
- </para>
- <para>
- Default directory for <classname>Zend_Amf</classname> resources is registered
- automatically and currently contains handlers for "mysql result" and "stream"
- resources.
- </para>
- <programlisting language="php"><![CDATA[
- // Example class implementing handling resources of type mysql result
- class Zend_Amf_Parse_Resource_MysqlResult
- {
- /**
- * Parse resource into array
- *
- * @param resource $resource
- * @return array
- */
- public function parse($resource) {
- $result = array();
- while($row = mysql_fetch_assoc($resource)) {
- $result[] = $row;
- }
- return $result;
- }
- }
- ]]></programlisting>
- <para>
- Trying to return unknown resource type (i.e., one for which no handler plugin exists)
- will result in an exception.
- </para>
- </sect2>
- <sect2 id="zend.amf.server.flash">
- <title>Connecting to the Server from Flash</title>
- <para>
- Connecting to your <classname>Zend_Amf_Server</classname> from your Flash project is
- slightly different than from Flex. However once the connection Flash functions with
- <classname>Zend_Amf_Server</classname> the same way is flex. The following example can
- also be used from a Flex <acronym>AS3</acronym> file. We will reuse the same
- <classname>Zend_Amf_Server</classname> configuration along with the World class for our
- connection.
- </para>
- <para>
- Open Flash CS and create and new Flash File (ActionScript 3). Name the document
- <filename>ZendExample.fla</filename> and save the document into a folder that you will
- use for this example. Create a new <acronym>AS3</acronym> file in the same directory
- and call the file <filename>Main.as</filename>. Have both files open in your editor. We
- are now going to connect the two files via the document class. Select ZendExample and
- click on the stage. From the stage properties panel change the Document class to Main.
- This links the <filename>Main.as</filename> ActionScript file with the user interface
- in <filename>ZendExample.fla</filename>. When you run the Flash file ZendExample the
- <filename>Main.as</filename> class will now be run. Next we will add ActionScript to
- make the <acronym>AMF</acronym> call.
- </para>
- <para>
- We now are going to make a Main class so that we can send the data to the server and
- display the result. Copy the following code into your <filename>Main.as</filename> file
- and then we will walk through the code to describe what each element's role is.
- </para>
- <programlisting language="as"><![CDATA[
- package {
- import flash.display.MovieClip;
- import flash.events.*;
- import flash.net.NetConnection;
- import flash.net.Responder;
- public class Main extends MovieClip {
- private var gateway:String = "http://example.com/server.php";
- private var connection:NetConnection;
- private var responder:Responder;
- public function Main() {
- responder = new Responder(onResult, onFault);
- connection = new NetConnection;
- connection.connect(gateway);
- }
- public function onComplete( e:Event ):void{
- var params = "Sent to Server";
- connection.call("World.hello", responder, params);
- }
- private function onResult(result:Object):void {
- // Display the returned data
- trace(String(result));
- }
- private function onFault(fault:Object):void {
- trace(String(fault.description));
- }
- }
- }
- ]]></programlisting>
- <para>
- We first need to import two ActionScript libraries that perform the bulk of the work.
- The first is NetConnection which acts like a by directional pipe between the client and
- the server. The second is a Responder object which handles the return values from the
- server related to the success or failure of the call.
- </para>
- <programlisting language="as"><![CDATA[
- import flash.net.NetConnection;
- import flash.net.Responder;
- ]]></programlisting>
- <para>
- In the class we need three variables to represent the NetConnection, Responder, and
- the gateway <acronym>URL</acronym> to our <classname>Zend_Amf_Server</classname>
- installation.
- </para>
- <programlisting language="as"><![CDATA[
- private var gateway:String = "http://example.com/server.php";
- private var connection:NetConnection;
- private var responder:Responder;
- ]]></programlisting>
- <para>
- In the Main constructor we create a responder and a new connection to the
- <classname>Zend_Amf_Server</classname> endpoint. The responder defines two different
- methods for handling the response from the server. For simplicity I have called these
- onResult and onFault.
- </para>
- <programlisting language="as"><![CDATA[
- responder = new Responder(onResult, onFault);
- connection = new NetConnection;
- connection.connect(gateway);
- ]]></programlisting>
- <para>
- In the onComplete function which is run as soon as the construct has completed we send
- the data to the server. We need to add one more line that makes a call to the
- <classname>Zend_Amf_Server</classname> World->hello function.
- </para>
- <programlisting language="as"><![CDATA[
- connection.call("World.hello", responder, params);
- ]]></programlisting>
- <para>
- When we created the responder variable we defined an onResult and onFault function to
- handle the response from the server. We added this function for the successful result
- from the server. A successful event handler is run every time the connection is handled
- properly to the server.
- </para>
- <programlisting language="as"><![CDATA[
- private function onResult(result:Object):void {
- // Display the returned data
- trace(String(result));
- }
- ]]></programlisting>
- <para>
- The onFault function, is called if there was an invalid response from the server. This
- happens when there is an error on the server, the <acronym>URL</acronym> to the server
- is invalid, the remote service or method does not exist, and any other connection
- related issues.
- </para>
- <programlisting language="as"><![CDATA[
- private function onFault(fault:Object):void {
- trace(String(fault.description));
- }
- ]]></programlisting>
- <para>
- Adding in the ActionScript to make the remoting connection is now complete. Running the
- ZendExample file now makes a connection to <classname>Zend_Amf</classname>. In review
- you have added the required variables to open a connection to the remote server, defined
- what methods should be used when your application receives a response from the server,
- and finally displayed the returned data to output via <methodname>trace()</methodname>.
- </para>
- </sect2>
- <sect2 id="zend.amf.server.auth">
- <title>Authentication</title>
- <para>
- <classname>Zend_Amf_Server</classname> allows you to specify authentication and
- authorization hooks to control access to the services. It is using the infrastructure
- provided by <link linkend="zend.auth"><classname>Zend_Auth</classname></link> and
- <link linkend="zend.acl"><classname>Zend_Acl</classname></link> components.
- </para>
- <para>
- In order to define authentication, the user provides authentication adapter extening
- <classname>Zend_Amf_Auth_Abstract</classname> abstract class. The adapter should
- implement the <methodname>authenticate()</methodname> method just like regular
- <link linkend="zend.auth.introduction.adapters">authentication adapter</link>.
- </para>
- <para>
- The adapter should use properties <emphasis>_username</emphasis> and
- <emphasis>_password</emphasis> from the parent
- <classname>Zend_Amf_Auth_Abstract</classname> class in order to authenticate. These
- values are set by the server using <methodname>setCredentials()</methodname> method
- before call to <methodname>authenticate()</methodname> if the credentials are received
- in the <acronym>AMF</acronym> request headers.
- </para>
- <para>
- The identity returned by the adapter should be an object containing property
- <property>role</property> for the <acronym>ACL</acronym> access control to work.
- </para>
- <para>
- If the authentication result is not successful, the request is not proceseed further
- and failure message is returned with the reasons for failure taken from the result.
- </para>
- <para>
- The adapter is connected to the server using <methodname>setAuth()</methodname> method:
- </para>
- <programlisting language="php"><![CDATA[
- $server->setAuth(new My_Amf_Auth());
- ]]></programlisting>
- <para>
- Access control is performed by using <classname>Zend_Acl</classname> object set by
- <methodname>setAcl()</methodname> method:
- </para>
- <programlisting language="php"><![CDATA[
- $acl = new Zend_Acl();
- createPermissions($acl); // create permission structure
- $server->setAcl($acl);
- ]]></programlisting>
- <para>
- If the <acronym>ACL</acronym> object is set, and the class being called defines
- <methodname>initAcl()</methodname> method, this method will be called with the
- <acronym>ACL</acronym> object as an argument. The class then can create additional
- <acronym>ACL</acronym> rules and return <constant>TRUE</constant>, or return
- <constant>FALSE</constant> if no access control is required for this class.
- </para>
- <para>
- After <acronym>ACL</acronym> have been set up, the server will check if access is
- allowed with role set by the authentication, resource being the class name (or
- <constant>NULL</constant> for
- function calls) and privilege being the function name. If no authentication was
- provided, then if the <emphasis>anonymous</emphasis> role was defined, it will be used,
- otherwise the access will be denied.
- </para>
- <programlisting language="php"><![CDATA[
- if($this->_acl->isAllowed($role, $class, $function)) {
- return true;
- } else {
- require_once 'Zend/Amf/Server/Exception.php';
- throw new Zend_Amf_Server_Exception("Access not allowed");
- }
- ]]></programlisting>
- </sect2>
- </sect1>
- <!--
- vim:se ts=4 sw=4 et:
- -->
|