Home > Flash Platform, Zend_Amf > Lazy loading classes in Zend Amf w/ addDirectory

Lazy loading classes in Zend Amf w/ addDirectory

November 4th, 2008

lazy class loading or auto loading is a new feature that I added to Zend Amf that allows you to specify any number of paths that you would like your services to be loaded from. There are some advantages and disadvantages to this. First it really now works exactly like the the services directory did in AMFPHP with the addition of specifying as many directories as you want. The disadvantage is that I added setClass() initially so that you can make sure that the service is available on the first request rather than being searched, loaded, and then instantiated in the middle of an amf call. I recommend that you use setClass() for any of the methods that are needed instantly on the first request such as a DAO. The other hundred services can live happily out of memory until they are needed. Go update from the Zend Framework 1.7 trunk or just go get the new server file and place it in your Zend/Amf/ directory and addDirectories() away! Also thanks for all the suggestions!

documentation

The Zend Amf Server 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 LIFO search will be performed on the directories to match the class. Adding directories is completed with the addDirectory() method in your endpoint.

$server->addDirectory(dirname(__FILE__) .'/../services/');
$server->addDirectory(dirname(__FILE__) .'/../package/');

When calling remote services your source name can have underscore(_) and dot(.) directory delimiters. When an underscore is used PEAR 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 Bar.php in the each of the included paths at com/Foo/Bar.php. If the dot notation is used for your remote service such as com.Foo.Bar each included path will have com/Foo/Bar.php append to the end to auto load Bar.php

Flash Platform, Zend_Amf

  1. John
    November 5th, 2008 at 00:20 | #1

    Sweet! Thanks for the update.

    …now just need that service browser. :)

  2. November 5th, 2008 at 00:44 | #2

    Just can’t make everyone happy ;-)

  3. John
    November 5th, 2008 at 01:14 | #3

    I’m happy.. but never satisfied. ;)

    Thank again for all your AMFPHP work and ZendAMF.

  4. November 5th, 2008 at 07:07 | #4

    Slick! Nice addition, Wade!

  5. Joshua McDonald
    November 5th, 2008 at 16:42 | #5

    Looks good, looks like it should potentially overcome one issue I’ve seen.

    Previously I could add multiple classes with setClass multiple times… I actually still prefer that to just making a directory full of them.

    The problem with setClass is that if different classes have conflicting function names (ie Foo::Bar() and Jaz::Bar() ) it would throw an error because the two Bar() functions conflict. I don’t have time to test the addDirectory yet, but does it overcome this some how? It looks like it won’t since the table is written with the function name as the first index.

  6. November 26th, 2008 at 21:58 | #6

    hi.. Zend_Amf is great.. and its really help me a lot.. thanks for that.. i just have a question.. how can i log the error or fault error.. and im excited for the service browser.. thanks men…

  7. December 16th, 2008 at 22:13 | #7

    @Joshua McDonald
    Download the latest build as that issue is now resolved with setClass(). Thanks for the feedback!

  8. Allen Scheinhaus
    December 22nd, 2008 at 09:07 | #8

    Hi Wade,

    I noticed that even on the latest release, on the Server class method getDirectory() on line 505 is returning a $_directory variable that doesnt exist. Instead it should return $_directories. Just wanted to point that out.

    I am having some serious problem getting the addDirectory() method to work.
    Im even thinking about going back to AmfPhp. I am 100% sure my paths are correct. My Classes have their methods commented. Im simply trying to replicate the same services folder functionality that AmfPhp had.

    I can get it working fine if I manually include a class in the bootstrap and then use the setClass() method. That works great.

    In my case, other than the a Login class method for logging in to my app, the other remote methods called will be determined by the user interaction with the app.

    And yes, like I mentioned I downloaded the latest build yesterday and replace on my Amf folder with the new one. I was eager about switching to ZendAmf but its been a pain in the arse so far.

    This is actually my first time commenting here in your blog. I’ve being using AmfPhp for a while now, and I absolutely could not work without it. Thanks for all your work on that. I have zero complaints on that.

    Thanks,

    Allen

  9. Leo
    December 31st, 2008 at 07:41 | #9

    Hi Wade and Allen
    @Allen Scheinhaus
    Try this: addDirectory(realpath(dirname(__FILE__) . ‘/../../services/what/ever/’));
    Regarding the addDirectory-method I’ve experienced the following strange thing. To demonstrate I take the polular example of Mihai Corlan (http://corlan.org/2008/11/13/flex-and-php-remoting-with-zend-amf/). Using
    $server->setClass(“MyService”);
    $server->setClassMap(“VOAuthor”, “VOAuthor”);
    everything works out well. If I use
    $server->addDirectory(..)
    I can read information, I can write a simple string, but I can’t write a (complex Value) Object. Any idea is appreciated.

    Leo

  10. January 1st, 2009 at 21:47 | #10

    @allen and @leo can you please submit a bug with the minimal amount of AS and PHP code to the zend framework. Like the examples shows you need to be submitting the entire file path to the server (./services/) should not work. If it does I have no idea how…
    $server->addDirectory(dirname(__FILE__) .’/services/’);
    will do the trick.

  11. yemi
    January 30th, 2009 at 14:23 | #11

    Hi Wade, I noticed something strange. I setup a test application using the $_explicitType class mapping method for Zend_AMF. When I send an object [like addUser(user)] from flex to PHP i get the disconnected error but when I do a get [like getUser();] on the same object it works fine. I have been on it all week. So I decided to tweak the sample provided by Mihai at: http://corlan.org/2008/11/13/flex-and-php-remoting-with-zend-amf/comment-page-2/#comment-1741 and this is what i figured out.

    I commented out:
    //$server->setClassMap(”VOAuthor”, “VOAuthor”);
    and added:
    public $_explicitType =’VOAuthor’;
    to the class VOAuthor in PHP.

    … and then the datagrid in the sample throws thesame error when updating (i’e sending an object like addUser(user) to the server won’t work). So I added the $server->setClassMap to my test application and it worked fine. Am I doing something wrong or missing out something in using the $_explicitType method. I downloaded the latest release of Zend_AMF yesterday but thesame problem. I think my mapping is okay because I can get/receive but not send. Please advise. Thanks.

  12. oscaroxy
    February 9th, 2009 at 11:30 | #12

    I’ve a problem similar to “yemi”:
    I’ve put VOAuthor class into a package “business” (either AS3 and PHP) and if I use “$server->setClassMap(”VOAuthor”, “VOAuthor”);” (without specify package) then Zend work fine, while if I use “var $_explicitType =’VOAuthor’;” (into class) then Zend don’t work fine.

    I receive from PHP (php_error.log):

    PHP Fatal error: Uncaught exception ‘Zend_Amf_Exception’ with message ‘Unable to parse null body data VOAuthor mapped class is not defined’ in C:\wamp\www\provaZendAMF2\Zend\Amf\Request.php:174
    Stack trace:
    #0 C:\wamp\www\provaZendAMF2\Zend\Amf\Request.php(125): Zend_Amf_Request->readBody()
    #1 C:\wamp\www\provaZendAMF2\Zend\Amf\Request.php(93): Zend_Amf_Request->readMessage(Object(Zend_Amf_Parse_InputStream))
    #2 C:\wamp\www\provaZendAMF2\Zend\Amf\Request\Http.php(64): Zend_Amf_Request->initialize(’????????null??/…’)
    #3 C:\wamp\www\provaZendAMF2\Zend\Amf\Server.php(365): Zend_Amf_Request_Http->__construct()
    #4 C:\wamp\www\provaZendAMF2\Zend\Amf\Server.php(313): Zend_Amf_Server->getRequest()
    #5 C:\wamp\www\provaZendAMF2\ZendAMF\gateway.php(18): Zend_Amf_Server->handle()
    #6 {main}
    thrown in C:\wamp\www\provaZendAMF2\Zend\Amf\Request.php on line 174

    I prefer to write $_explicitType =’VOAuthor’; into every business class! Maybe Do it need the package?

    In add … why I can’t specify a package? So I can’t write 2 class with self name!

    for example I would write business.Utente and transition.Utente in PHP so in RemoteObject into Flex I can write source=”transition.Utente”

    Thanks

  13. February 9th, 2009 at 15:51 | #13

    @oscaroxy This was a bug that is checked in and closed but you will either need to wait until the 1.7.4 release or get Zend_Amf from the svn repository.
    http://framework.zend.com/svn/framework/standard/trunk/library/Zend/Amf/

  14. oscaroxy
    February 10th, 2009 at 04:35 | #14

    Thanks for your reply … how I can download Zend_Amf from the svn repository???? I read only page html and it don’t give me a download button.

  15. oscaroxy
    February 10th, 2009 at 05:00 | #15

    I tired to replace every file AMF from svc to my project, but the problem continue…….

  16. oscaroxy
    April 16th, 2009 at 09:21 | #16

    I found another big problem with zend_amf… it is very slow into server of production, while into my machine (local) it work fine and fast.
    Why? Exist a mode for quickly zend? I found many require_once into Zend’s page that delay the entire process ….

  17. April 16th, 2009 at 10:22 | #17

    @oscaroxy 1.7.8 build is the most up to date source code. Zend_Amf is open source so if there are optimizations you find just file an improvement patch into the Zend Framework jira issue tracker.

  18. jazman
    May 13th, 2009 at 09:09 | #18

    Hi Wade,
    i have a problem with zendamf-flashcs3 on production server
    on local server with wamp every think work fine
    but on production server i received this error from flash :Error #2044: Unhandled NetStatusEvent:. level=error, code=NetConnection.Call.Failed

    I have allready :Zend Amf Endpoint (on production server)
    these are some PhpInfo :
    PHP Version 5.2.5
    Apache Version Apache/2.2.0
    This server is protected with the Suhosin Patch 0.9.6.2
    This program makes use of the Zend Scripting Language Engine: v2.2.0

    Any Help will be apreciated
    thanks

  19. Vikram Malhotra
    December 14th, 2009 at 04:39 | #19

    Hello Wade

    i have been using this addDirectory method for quite time and it has worked quite well. But I have run into a roadblock with this. Consider this snippet:

    $server = new Zend_Amf_Server();
    $server->addDirectory( APPLICATION_PATH . “/services/” ); // Adding the services here
    $server->addDirectory( APPLICATION_PATH . “/vo/” ); // Adding the value objects here
    echo $server->handle();

    Now the services are mapped like a dream. The problem is in VOs, where I am not able to map the VOs from php to Flex. The reverse works. I followed <a href="http://www.wadearnold.com/tutorials/zend/classmap/"?this tutorial of yours and just replaced the classMap with addDirectory. I used the $_explicitType construct in my php VO.

    Is there a problem in my code or is there something that needs to be added some somewhere?

    Thanks and Regards
    Vikram

  1. December 14th, 2008 at 09:25 | #1