Posted on Friday 26 January 2007
Amfphp 1.9 beta 2 is now available for download. This is a HUGE release, making amfphp the fastest Remoting implementation ever (I kid you not).
Remoting at the speed of C
As I've mentioned earlier, there are many potential bottlenecks in a Remoting implementation which can affect speed. AMF encoding and decoding at the PHP level is not optimal, since PHP is a dynamic language, and encoding and decoding things is a repetitive, CPU and memory intensive operation. PHP, at its heart, is a thin scripting language which is powered and extended by C.
Emanuele Ruffaldi, who had previously created a Remoting implementation for C++, created a C extension for PHP which does AMF encoding and decoding. We've tested it through and through, it is very stable, and let me tell you, it is ridiculously fast. On sample data varying in size and complexity, it's 50 to 200 times faster on pure encoding and decoding than the previous PHP solution. Of course, as I've explained earlier, encoding and decoding AMF is only one of the many things that amfphp does, and the bottleneck may or may not be there depending on the size of the data. This extension will really help when sending tons of complicated data over the wire, data like large recordsets and deeply nested object trees. As users create more and more complicated apps with Flex, this will ensure that amfphp won't fall behind, and that you can continue to concentrate on your UI instead of encoding/decoding matters.
I want to stress that you don't need the extension installed to run the new version of amfphp. The extension is an add-on to PHP that the new version of amfphp will detect, load and use if it finds it, and revert to the original PHP-based encoding/decoding if it doesn't.
Here are some real world, before and after tests of amfphp's speed with this new extension:
| test | Hello world | Big RecordSet (4x1800) | Huge Recordset (20x2500) | Mike 100 | Mike 1000 | Mike 10000 | Mike 100,000 |
| total php | 28 | 140 | 1378 | 45 | 188 | 2228 | timeout |
| total native | 21 | 55 | 165 | 20 | 26 | 99 | 988 |
| diff (%) | 25% | 61% | 88% | 56% | 86% | 96% | |
| encode php | 1 | 89 | 1303 | 18 | 157 | 2164 | timeout |
| encode native | 0 | 13 | 102 | 0 | 3 | 35 | 558 |
| diff (%) | 100% | 85% | 92% | 100% | 98% | 98% | |
| size | 482 bytes | 78.4 KB | 961.5 KB | 7.2 KB | 69.6 KB | 720 KB | 7.3 MBs |
The tests are:
- A simple Hello world test
- Sending a recordset with all the cities in Quebec with their coordinates (1 integer column, 1 string column, 2 float columns)
- Sending a recordset with 2500 user profiles in a dating site (10 string columns and 10 int columns)
- Mike Potter's test, adjusted so it doesn't use AMF3 repeated strings, with 100, 1000, 10,000 and 100,000 elements.
The top half of the table shows the pingback time for every test, over localhost, with the top row showing the speed of amfphp without the extension and the bottom one with the extension. The bottom half of the table shows only the amount of time spent in the encoder.
At the extreme end of the table, you should notice that it takes amfphp with the C extension less than a second to send 7.3 MBs of data consisting of 100,000 array elements each containing an object with three fields. That is absolutely insanely fast, my friends. It's so fast in fact, that it takes Flash more time to decode the AMF data than it does for amfphp to create it, and it's such a ludicrously large amount of data that Flash 9 will time out when using ObjectUtil.toString on that dataset. Note also that the regular amfphp doesn't fare bad at all in these tests, as in the large recordset example.
I should note that the serializer times shown above include all the time spent in the serializer, not just the time calling amf_encode or writeData. Therefore in the case of the large recordset, the speed improvement is not as dramatic as in the other cases because most of the time is actually being spent in the mysql recordset adapter when using the C extension, which obscures the real speed improvement. Furthermore, these tests don't use deeply nested data, but with the limited testing I've done, I can assert that the speed improvements are even better when serializing large trees.
So here's how to enable this extension: download it from Emanuele's site. On Windows, place the dll in php's ext directory and add a php_extension=php_amf.dll line in php.ini; restart Apache. On *NIX, compile php --with-amf from the source. Once that's done, load gateway.php in a browser, and you should see "AMF C Extension is loaded and enabled" on the second line. The new extension should also appear in phpinfo(). You don't have to change a setting in amfphp to enable it, if it sees it, it'll use it, if it doesn't, it'll revert to the default PHP encoding/decoding.
Also note that on Emanuele's site there is documentation on the callbacks that the extension defines, and that Evert Pot is interested in adding support for it in SabreAMF. I've also notified Mark Piller at MidnightCoders, so they may support the extension in WebORB for php. Once the extension reaches 1.0, I would like to have a list of shared hosting services that support it on the amfphp site; if you're interested in supporting it give me a buzz.
Remoting at the speed of gzip
The second beta comes with another nice speed boost in the form of decreased transfer times over the wire, thanks to gzip encoding. Basically, if a browser sends an Accept:gzip header to the server (ie, all modern browsers since IE5), amfphp will detect it and send the content gzipped. For large amounts of data, this can result in much decreased network traffic; typical compression ratios can vary from 2:1 to 10:1, depending on data set.
The nice part is that, once again, you don't need to configure anything to get this to work; if amfphp finds the gzip extension on the server, and the browser accepts gzip encoding, it'll do it, if not, it'll revert to the default behavior. By default, only results which are more than 25KBs in length are gzipped, as below that I don't think it's worth it to compress the data; you can change this setting in gateway.php though.
Better recordset support
I've added better recordset support to amfphp, which now includes:
- MySQL
- SQLite
- PDO
- Zend::DB, including ZendDbTable_Rowset
- PHP Doctrine
- Postgres (untested)
- PEAR::DB (untested)
- ODBC (untested)
- MySQLi (untested)
- MS-SQL (untested)
- Informix (untested)
- Frontbase (untested)
- ADODB (untested)
- Oracle - oci8 (untested)
The untested adapters should work, since they used to in amfphp 1.2, but I can't install every database known to man so if you get errors, load up Charles or ServiceCapture, see the error that's being sent, and send me a buzz.
Also noteworthy is a new plain RecordSet class. Basically, sometimes you want to loop through your dataset before sending it to Flash; in this case you can use the RecordSet wrapper. For example:
for(var i = 0; i < 100; i++)
{
$rows[] = array("val" => i, "cube" => i*i*i);
}
return new RecordSet($rows);
You will receive this as a RecordSet in AMF0 and as an ArrayCollection in AMF3.
Enhanced service browser
I've tightened up the service browser interface. Most noteworthy are the enhanced info tab, which shows profiling information for every call, and the tree view tab, which allows you to browse returned object in a tree control, à la ServiceCapture and Charles.
This service browser will serve as the basis for the new Universal Remoting service browser, which is an initiative by myself, Evert Pot (SabreAMF), Aaron Smith (AMFRUBY) and Zoltan Csibi (Fluorine) to create a service browser that will work across all these Remoting implementations. That's right, all the warm fuzzy feeling of amfphp's service browser will be available in [your favorite Remoting implementation]. Fuggawesome.
ByteArray support
ByteArray support was in the last version, but I just didn't document it. Let me do that right now:
If you send a ByteArray instance from Flex to amfphp, you will receive an instance of ByteArray (a custom PHP class) in your method. The data is in $byteArray->data. To send back a ByteArray, just return an instance of ByteArray. For example, to save a bitmap through amfphp, in ActionScript:
var ba:ByteArray = bmp.getBytes();
ba.compress();
service.saveBitmap(ba);
In PHP:
function saveBitmap($ba)
{
$data = $ba->data;
$data = gzuncompress($data);
file_put_contents("rawdata.rgba", $data);
return true;
}
And to send a ByteArray to Flash:
Removed things
I've removed webservice support. If you didn't know, basically the original Remoting spec allowed you to call a SOAP-based webservice through a Remoting gateway. This was thought up in the days of Flash 6, when there wasn't an easy way to consume SOAP web services in Flash. Since Flash 7, there is a component that can connect to SOAP web services, and of course in Flex 2, it's as simple as using mx:WebService. Thus the only advantage of consuming a SOAP service through amfphp is the "free proxy", which allows you to bypass crossdomain.xml. However, it added bloat to amfphp, it was buggy, and SOAP support in PHP is pretty sucky anyway, which meant you were better off calling the webservice directly. Thus is was removed.
I've also removed a lot of settings in gateway.php which were seldom used and confused users. globals.php now contains global settings such as the service path, and this is the recommended place to add things like libraries or global includes (ie, for frameworks that expect to be included as globals, like WordPress, TextPattern, etc.).
Bug fixes
A few bugs with regards to encoding/decoding were fixed (as noticed by comparing with the C extension). A few random compatibility problems with low permissions on shared hosting were fixed. Dead code was removed. json.php can now accept an ? instead of / as the first character after it for incompatible web servers. Lots of other little things I didn't write down and can't remember right now were patched.
What's next
JSON-RPC, as opposed to straight JSON, enhanced service browser will be in the 2.0 release. I will try to find a more comprehensive solution to authentication, but I'm starting to run out of ideas. Pageable recordsets will definitely not make it back into 2.0. Zoltan figured out how to get FDS functionality working in Fluorine and we may implement a subset of that, but not until after 2.0 (and with that pageable recordsets will be back, but also lots of other nice things).
Awesome!
Nice write up, this is a nice step forward for alternative AMF projects.
Great News.
Let’s test it
[…] Leyendo el blog de Patrick Mineault. Veo el anuncio del release de la versión 1.9 Beta 2 de AMFPHP y lo mas sobresaliente de este release es que ahora la codificación/decodificación de AMF es ahora nativa de PHP. Haciendo el proceso entre 50 y 200 veces mas rápido según escribe Patrick. […]
Thank you, thank you, thank you. The php4 support is working great for me. Where’s the donate button?!
Really nice :)
The donate page is here:
http://www.amfphp.org/donate.html
Hey Patrick, any chance on talking Emanuele into posting up some pre-compiled binaries of the extension for some standard *nix platforms? If it was as easy to drop in as something like the Zend Optimizer extension I’d be all over it - I just have some limitations with some of my external hosting that makes it very cumbersome process to recompile PHP - but if I had a binary of the extension and could just edit my php.ini - that would rock. i will give this a run through on my local machine though - sounds exciting!
Rob
I’ve tried to install the extension on PHP 5.1.6 without success. On PHP 5.2.0 it’s working perfectly. Excellent work Patrick!
… and Emanuele Ruffaldi, of course :)
That’s really nice Patrick!
Thanks a lot!
Arnoud
I am improving the binary releases for Windows and Linux adding support for 5.1.6 for Windows. Check details on the project page mentioned above
hello,
Thanks for your hard work.
Amfphp is running always more and more faster.
I use amfphp with flex and flash and I have some questions.
in the previous version amfphp 1.9, everything is working perfectly at localhost but i have a problem on the distant server who send me this faultcode message :
code:
Client.Error.MessageSend
Message:
Send failed
Detail:
Channel.Connect.Failed error NetConnection.Call.Failed: HTTP: Status 500: url: ‘http://mydomain.com/flashservices/gateway.php’
what does it means ?
I test this new 1.9 version in local for the moment and the service browser send me this message in a flex fault message :
TypeError: Error #1009: Cannot access a property or method of a null object reference.
at RawAmfService/::readData()
at flash.events::EventDispatcher/flash.events:EventDispatcher::dispatchEventFunction()
at flash.events::EventDispatcher/dispatchEvent()
at flash.net::URLLoader/flash.net:URLLoader::onComplete()
the previous version of service browser works perfectly and a flex application is really a very good idea.
I hope this can help you for amfphp 2 to be perfect.
Could you load up Charles or ServiceCapture and tell me what you see in there?
Hi,
first of all thanks for your hard work on amfphp
I have tested amfphp1.9 beta 1 on my localhost (winXP, IIS , PHP52, Flex 2.1)
For do this I have made a little mxml application(app.mxml) that call a php service that return mysql query result into a datagrid.
Amfphp work for me, also serveceBrowser.swf, but if I open serviceBrowser.mxml and republish it I have many errors (may be I’m not able to configure file correctly) (I have added corelib to project)
Yesterday I have tried amfphp1.9 beta 2 with the amfphp.dll extension.
I have publish the same flex file (app.mxml) but now it not work (with or whitout amfphp.dll enabled).
When I try to call a service I have the following error:
Client.Error.DeliveryInDoubt
Client.Error.DeliveryInDoubt
Channel disconnected before an acknolwedgement was received
Any idea about it ?
I’m on localhost
amfphp is hosted on c:\inetpub\wwwroot\amfphp
Service are hosted on c:\inetpub\wwwroot\amfphp\service\
Ok .. find the solution for one problem ….
Now amfphp 1.9 beta 2 works also for me.
The problem is that I have edited services php file with an editor that set encoding file to UTF-8Y. Change this to UTF-8 or ISO correct the problem for me.
Hey there,
I get the same error as Emmanuel. ServiceCapture outputs this:
Headers:
HTTP/1.1 200 OK
Date: Mon, 29 Jan 2007 19:19:19 GMT
Server: Apache
X-Powered-By: PHP/4.4.4
Set-Cookie: PHPSESSID=f488d841a58716e829844e7ceabdabed; path=/
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Connection: close
Content-Type: application/x-amf
Fault:
description (String): Undefined index: serviceBrowser
details (String): /customers/dj-vince.nl/dj-vince.nl/httpd.www/dev/amfphp/core/shared/util/Headers.php
level (String): Notice
line (Number): 23
code (String): AMFPHPRUNTIMEERROR
I must say that AMFPHP1.2 also not runs - so I expect it to be something on the server but I absolutely have no idea what!
Thanks for the great stuff! Never had any problems with it, just on this server..
Regards,
Wesly
[…] UP at Patrick Mineaults 5etDemi here’s a very thorough explanation of the benefit of using the phpamf C extension for AMF by Emanuele Ruffaldi that they’ve gotten AMFPHP 1.9 to work with. Essentially, AMFPHP is really really fast anyways, but if you download and install this phpamf.dll At the extreme end of the table, you should notice that it takes amfphp with the C extension less than a second to send 7.3 MBs of data consisting of 100,000 array elements each containing an object with three fields. […]
If you change line 23 of said file to:
return isset($headers[$key]) ? $headers[$key] : NULL;
Does that solve the issue?
I tried to do something with this new feature in the amfphp - ByteArray class mapping, but i cant make it work. I guess, thia may be very nice and easy way to save bitmap (just like in Your example) The problem is, that I use Flash9 alpha insted of flex, and couldnt make it work. Object sended to amfphp had all needed properties like position, but data was null.
Any thoughts ? Does this feature work only with Flex ?
Thanks for this great release.
I’m trying to use the dll on my pc with Apache2 and php 4.4.4 (Appserv install) but I can’t see the extension installed on phpinfo and I don’t see “AMF C Extension is loaded and enabled” on gateway.php.. I have added extension=phpamf.dll on php.ini, placed phpamf.dll on php’s ext dir and restarted Apache.
Any idea? Thanks in advance.
Mooska,
You have to send an actual instance of flash.util.ByteArray; sending an object with the same properties won’t work. It should work in Flash 9 as well as Flex 2.
Anto,
Have you looked at the system event log and the Apache log to see if there was an error trying to load the extension?
Hey Patrick,
It works now.. But I think it had to do with Register Globals being off.. The webhost switched to PHP5 and turned Register Globals on and now it works.. Might be that or some other config thing that is on in PHP5 that wasn’t on in 4..
Great stuff!
Thanks!
Hi,
I’ve looked at the error log and I found this warning:
PHP Warning: Unknown(): Invalid library (maybe not a PHP library) ‘php_amf.dll’ in Unknown on line 0
Is this a problem with my apache/php install?
Were trying to create a global gateway that we can use Flex and other applications talk to our application using the amfphp. If you take out the SOAP then it will affect us. Were trying to convert all of our existing soap and standared php to amfphp. Can you keep the SOAP in?
Anto,
Are you sure that extension_dir is set correctly and that you placed the dll from the php4 folder in your extension dir and not the php5 one?
Jason,
I think you’re talking about something else. It’d be great to be able to talk to amfphp services using SOAP, in addition to XML-RPC and JSON-RPC and Remoting. I’m working on that. What I took out is something else, which is calling remote SOAP services by using amfphp as a proxy, which is entirely different.
Anto,
the build for PHP4 has been updated. A small bug was preventing the extension to being recognized by PHP. Please check again with the new build.
Ok! with the new build the extension is enabled.
Thanks a lot!
Outstanding stuff! Incredibly fast!
Would you mind updating browser.mxml in the package?
viewSourceURL=”index.html” is good too.
Thanks a million.
It makes a really nice sample application…
1.9 beta 2 is awesome. Locally and on my test server, its great. I’m a bit resistant right at the moment to upgrade this to my production server, mostly because of the 1.9 beta 2 tag and the relatively new release date. All this makes me speculate as to when AMFPHP 2.0 will come out! The polish of 1.9.2 into a 2.0 would be truly excellent.
Patrick,
I’m specifically interested in seeing how you’re feeding the Tree components. Most of the common Flex examples use XML as the data provider… I managed the basics, but I’m sure you’ve written something much better. If you could make it public it would really help (me).
Thanks for everything.
Nice blog. Great news!
I found that multi-bytes character was working under 1.9 beta 1 by using iconv(). But it’s not working under 1.9 beta 2. Anyone got the same problem?
For me Japanese stopped working between versions. Switching ‘iconv’ to ‘none’ fixed it.
Sorry, I got it. I change $gateway->setCharsetHandler( “iconv”, “big5″, “big5″ ); and it fix my problem.
A question: when I receive an array in Flash, is there a way to use the RecordSet method isLocal to know if it has fully downloaded? Does Flash proceed while downloading? That is: imagine i receive the result (a huge array) and then I have a trace: is it possible that flash traces something before the array is fully local? Thanks!!
>
VERY NICE
is any able to get JSON syntax working on the 1.9 beta 2 browser?
This is the correct syntax, right?
{firstname:’bill’}
You have to use {”firstname”:”bill”}. This is a limitation of Adobe’s JSON implementation.
When I load the service browser, it gets stuck: nothing shows up in the white sidebar and the clock keeps spinning endlessly…
The first time I loaded the page I was prompted to give configuration settings (and I’m still able to open that dialog using the button on the sidebar), but I can get no further than that.
Firebug tells me that a request for “history.htm” 404ed.
I’m running amfphp 1.9beta2 on WinXP sp2, php5.2, apache2.2 and using flash player 9. I get the same results in Firefox 2.0.0.1 and IE6.
Any ideas?
I have tried AMFPHP 1.9 beta2 on Turbolinux10.
It moves well without AMFEXT.
But, It doesn’t move well with AMFEXT.
String is’t converted as specified by “$gateway->setCharsetHandler” method.
I have tried AMFPHP 1.9 beta2 on Turbolinux10.
It moves well without AMFEXT.
But, It doesn’t move well with AMFEXT.
String is’t converted as specified by “$gateway->setCharsetHandler(”iconv”, “EUCJP-MS”, “CP932″)” method.
Fill a datagrid (dg) with amfphp 1.9 result mysqlquery(StringSql);
function resultHandler(evt:ResultEvent):void
{
var resAr:ArrayCollection = new ArrayCollection( ArrayUtil.toArray(evt.result));
dg.dataProvider = resAr.getItemAt(0)[’list’];
}
[…] “On sample data varying in size and complexity, it’s 50 to 200 times faster on pure encoding and decoding than the previous PHP solution.” link […]
[…] http://www.5etdemi.com/blog/archives/2007/01/amfphp-19-beta-2-ridiculously-faster/ […]
[…] After embracing Flex, Cairngorm, and AMFPHP 1.9 we have found our application development process lost for a good place to put domain logic. Please read this post from one of the T8DESIGN developers about our struggles in embracing proper MVC within our organization. Does the domain logic layer belong on the server or client? […]
With the new amfphp 1.9 when I return a recordset from php instead of an array nothing shows up in my datagrid. In the service browser this is what I see on the results tab:
(mx.collections::ArrayCollection)#0
filterFunction = (null)
length = 741
list = (mx.collections::ArrayList)#1
length = 741
source = (Array)#2
[0] (Object)#3
[1] (Object)#4
[2] (Object)#5
[3] (Object)#6
etc…
etc…
uid = “135BE76F-69C9-D97F-D152-BC434F570C89″
sort = (null)
source = (Array)#2
My flex datagrid acts like it populates because a scrollbar appears but there in nothing in the cells.
If I return an array like this:
while ($row = mssqlfetchobject($myQuery))
{
$myArray[] = $row;
}
return($myArray);
It works just fine. So can someone explain to me how I’m suppose to setup the dataprovider on the grid in flex when returning a recordset. I tried using the example above from herve, but that doesn’t work for me either. I know I’m just not doing something right.
Hi,
I’ trying amfphp 1.9 beta 2 with flash 8 but when I call a service I have the following message:
Received incompatible RecordSet version from server
I’ don’t understand ? work this only in AS3 ?
in advance thanks
[…] http://www.5etdemi.com/blog/archives/2007/01/amfphp-19-beta-2-ridiculously-faster/ […]
Hi Patrick,
I’m always experimenting this new version when i’ve time.
I made a simple test , i try to use your DiscoveryService class which is in the service folder and trace the service folder structure in a datagrid using Flex 2.
no problems, I see exactly the same results as the service browser can display.
i made a second test, i try to reproduce the helloworld example of Alessandro (Sephiroth)with this new version which is normally more simple and i’ve this message in the result text :
code:
Client.Error.DeliveryInDoubt
Message:
Channel disconnected
Detail:
Channel disconnected before an acknolwedgement was received
what does is mean ?
maybe it’s a header problem ?
Can you give a simple HelloWorld class example for this version ?
I try to use this new version with remoteObjects in Flex 2 with a mysql database but i’ve exactly the same message.
Do you have some news about amfphp 2 ?
When is the final release ?
Thanks in advance
I found that
“Channel disconnected before an acknolwedgement was received”
error happens than my php code have errors and cannot be parsed.
Fixing syntax errors in php code remove this error message.
Hi.
I’m using AMFPHP for some time. It’s great work. I’m using a CakePHP version.
Is it possible to run AMFPHP 1.9 beta 2 with cakephp? I’d like to try my cake-applications with Flex and RemoteObjects.
I was trying to run the 1.9 version on cakephp like 1.2, but it looks tricky to me. I’m not sure wich parts I can just copy, and wich are new.
Could You prepare some CakeAMFPHP 1.9 version? Or just give us some instructions.
Thanks for Your work.
Any chance of getting the Universal Service Browser into SVN. I’d still like to see the new browser source… please.
[…] Since Amfphp 1.9 beta 2, Amfphp has included an option to use gzip compression on the data sent back to the client. This new feature of Amfphp, coupled with suspicions that splitting strings in Actionscript was time consuming, made us rethink our current data exchange method between Flash, Amfphp and PHP, so we thought it was time to experiment some more with the different data types. Our goal was simple: to find which data types resulted in Actionscript having the data available and ready to process in the least amount of time (in our case, this meant having the data ready to pass to our tile generating function createTile). […]
Hi Patrick.
I’m trying to use setCredentials in Flex and beforFilter without any luck. Can you post a small example on how can we do that?
When I use setCredentials on the Flex service, Charles shows me that an error message was returned, because it enters to
if(!$handled)
{
$uriclasspath = “amfphp/Amf3Broker.php”;
$classpath = $baseClassPath . “amfphp/Amf3Broker.php”;
$classname = “Amf3Broker”;
$methodname = “handleMessage”;
}
in Actions.php and doesn’t find the amfphp/Amf3Broker.php file. The file doesn’t exist at all, but even if it would, your script searches for that file in the services/amfphp/ directory. Can you help?
And thanks for all your work :D
Just installed amf 1.9. works great locally. doesn’t work when swf is deployed on server. Better yet, it works if Service Capture is executing!!!
Can anyone help? Thanks in advance..
Hi Patrick,
I’m pretty sure I’m talking to myself here, but your service browser is the only example I know of that takes an unprepared Object and presents it properly in multiple Tree components. So here I go again. Can I please see your source?
I’ve written this method:
private function makeTreeObject(obj:Object, label:String=null):Object
{
obj[’label’] = label;
var children:Array = new Array();
}
But it’s giving me bizarre results when I use it for multiple Trees/Objects.
Patrick, anyone… comments?
How the heck are you suppose to update a database when using amfphp and flex. I can get the information to flex via amfphp and work with it in the arraycollection on the flex side, but when I’m ready to update the database with the changes this is where the explanations are lacking, no one has shown a good example of doing this! I can’t find a single real world example of someone using amfphp 1.9 and flex to update a database.
Maybe its because there isn’t a good way to do it I guess. Because in the real world you’re not working with all string types coming from the database. You are working with records that have Int’s, boolean’s, datetime, blob’s, varchars, etc.
I would LOVE to see someone write a simple example of updating a table from a database that has 5 fields (Name:varchar, age:int, sex:boolean, birth:Datetime, pic:blob). Because from my experince there is no easy way of knowing these datatypes in flex. When the arraycollection COLLECTION_CHANGE event happens the changed value is ALWAYS a string. It doesn’t seem to keep the datatype. Also, datetime types come in as strings. Please don’t say I have to convert the string back into a datatime type on the flex side. So when it comes to building the SQL statement to update the database I don’t know if the field is a string or a INT or a datatime so I don’t know how to format the SQL statement dynamically. Since you will never know which field the end user will modify at any given type in the application, it has to be something that works dynamically. Anyway, I just wish someone would write up a simple example that is a bit more real to life. The personservice example just dosen’t cut it when it comes to updating the database, and multiple datatypes.
[…] http://www.5etdemi.com/blog/archives/2007/01/amfphp-19-beta-2-ridiculously-faster/ […]
deeeg, these is amfphp…it is used to send data from flex to php and from php to flex. If you have to do updates a database you should learn mysql and php. Good luck :)
[…] 来源:http://www.5etdemi.com/blog/archives/2007/01/amfphp-19-beta-2-ridiculously-faster/ […]
Patrick
I’m having the same problem with 1.9 beta2 as Iaco, Emmanuel, and vodesign. I’m getting a “Channel disconnected before an acknolwedgement was received” error when I do the “HelloWorld” example that’s been floating around. When I run the “Service Browser” with the same setup, it works just fine. I used the “ServiceCapture” tool (a must have) to watch the packet traffic. It looks like the two services operate pretty much the same, and it looks like HelloWorld is actually returning the response in the HTTP packet (based on Content-Length), but ServiceCapture can’t decode it, and Flex times out on it.
Heres the HelloWorld PHP Service and MXML files, and the “services-config.xml”. Can you compare them to the Service Browser to see if there is any obvious difference:
(RPC code only)
Thanks
Don
The code didn’t show up here, but it’s basically the Demo at “http://www.sephiroth.it/tutorials/flashPHP/flex_remoteobject/index.php”
Don
Sorry for the ignorance. I didn’t notice that you included the all the Server Browser source. I’m stiil gonna look for the cause of the error.
Thanks
Don
Hello,
Finally succeed with amfphp 1.9 beta 2 on a distant server. (with a mysql database)
About problems related previously , if you want to succeed you must :
1) if you use sepy for coding , in the preferences : uncheck UTF BOM >> amfphp and service browser dislike this. (you’ve got header problems)
2) In the php service class, you can let the methodTable in the constructor or you can delete it but you must add : includeonce(AMFPHPBASE . “shared/util/MethodTable.php”); just after > that’s the reason for “Client.Error.DeliveryInDoubt ” message, in my case
3) the most important : you must delete or modify the .htacess file at the root of flashservices (the amfphp folder) >> I delete it and solve the problem with :
Client.Error.MessageSend
Message:
Send failed
Detail:
Channel.Connect.Failed error NetConnection.Call.Failed: HTTP: Status 500: url: ‘http://mydomain.com/flashservices/gateway.php’
I hope it can help other people with those problems to succeed too.
A comment about the new .dll files : it’s really really fast.
Thank a lot for this new version. I love it
Emmanuel
About my last comment.
A piece of text was deleted because i use the php flag.
In the second comment the text is:
2) In the php service class, you can let the methodTable in the constructor or you can delete it but you must add : includeonce(AMFPHPBASE . “shared/util/MethodTable.php”); just after the php flag.
If you use a methodTable in the constructor, be careful with your syntax. if you omit a “,” character when you add new methods > that’s the reason for “Client.Error.DeliveryInDoubt ” message, (in my case)
Hi Patrick
Have not found and problems yet with 1.9 Beta 2
I’m using the ByteArray for output from Flash, works great. Just having trouble returning a ByteArray.
Do you see any errors in the syntax?
// service
$filenameFull = PATHTOIMAGEFILES .’Users/User1.jpg’;
$fp=fopen($filenameFull, “rb”);
$buffer = fpassthru($fp);
fclose($fp);
$b = new ByteArray($buffer);
$this->_debugWrite(’UserAdmin-getUserImage’,$buffer, $b);
return $b;
// result of debugWrite
34209
bytearray Object
(
[data] => 34209
)
// service browser result
(Object)#0
message = “faultCode:INVALIDAMFMESSAGE faultString:’Invalid AMF message’ faultDetail:’ÿØÿà’”
name = “Error”
rootCause = (null)
// in application I get a fault response
Any tips would be helpfull.
Thanks
Ross MacLachlan
Ok, forget last post… ByteArray works like a charm…
my line:
$buffer = fpassthru($fp);
was my problem, addaped this from my HTML output file. Needed to buffer output to var.
$fp=fopen($filenameFull, “rb”);
while(!feof($fp)) {
$buffer .= fread($fp, 4096);
}
fclose($fp);
Great work Patrick.
I am unable to fill data into datagrid, here i am using aspx page to send the data and i am trying to access that aspx data thru http services in flex builder 2
OMFG! This is mad awesome. I plan to install C module later this month.
Whenever I call: new RecordSet($result) it will nullify any nested RecordSets inside of $result. Is there a better way to create a RecordSet with rows that also contain RecordSets?
I can’t get AMFPHP to gzip when I’m using Explorer 6, it only does it with Firefox.
Looking in ServiceCapture, it looks like Explorer doesn’t send any Accept-Encoding headers, only a Accept: /, and therefore the output from the server remains unzipped, even though Explorer supports gzip…
I’m too having Problems getting the simplest thing to run:
i have a HelloWorld.php as a service:
and
when i run the service browser i get:
(mx.rpc::Fault)#0
errorID = 0
faultCode = “Client.Error.DeliveryInDoubt”
faultDetail = “Channel disconnected before an acknolwedgement was received”
faultString = “Channel disconnected”
message = “faultCode:Client.Error.DeliveryInDoubt faultString:’Channel disconnected’ faultDetail:’Channel disconnected before an acknolwedgement was received’”
name = “Error”
rootCause = (null)
How can this be fixed ?
Amfphp 1.25 gives me the Netconnection:Badcall thingy :-(
one more thing i noticed:
while looking maybe a little too late at my php_error.log:
PHP Fatal error: Trying to clone an uncloneable object of class ReflectionMethod in D:\FlexProjects\Musikusbrauser\bin\amfphp\core\shared\app\BasicActions.php on line 101
while trying to run the serviceBrowser.
and additionally:
the DiscoveryService.php has no closing tag ?!
Hello,
Bravo to Patrick for amfphp, I am discovering it, and Flex2 at the same time, and it seems that it gonna make my life easier.
I also had the Error #1009 with amfphp 1.9 when testing a simple service (simple select from PgSQL).
It seems it was coming from a print to standard output I had in the php script. The same print was ok with amfphp 1.25 though.
Now that I have removed this useless print, everything is ok.
After some initial trial and error, I figured out the way to build the AMFEXT extension under MAC OS X. I wrote a little article explaining how I did it:
http://www.jonotaegi.com/buildingamfextphpextensionundermacos_x
I’m now successfully running AMFEXT, and my amfphp scripts accessing it work fine :)
Somehow, the url got screwed up. This is the right one:
http://www.jonotaegi.com/building-amfext-php-extension-under-mac-os-x/
I’m very interested in a version of AMFPHP as a Zend framework lib. I was wondering if this was a future plan and if not would like the ability to possibly work with you on making this happen.
One issue we’re finding with version 1.9b2 is that any data that is echoed back to the client causes Flash to “miss” the return.
This used to work in older versions of AMFPHP…
So we’re ending up reviewing all our PHP code to make sure:
1. There’s no “echo” or “print” statements anywhere in the code (that’s ok, it’s bad practise anyway)
2. Remove any trailing caracters after ?> in all PHP files, which is more of a pain.
Would be nice if this can be made retrocompatible again.
Hi, I am a little bit confused but AMFPHP 1.9 does not work on my server! Though all fine on local host .
I have PHP5 on my site. And all previous versions works fine (I use it during a couple of years.
On mysite.com when I call gateway.php with this:
http://mysite.com/amfphp2/gateway.php
I get “…all installed fine, etc.”
But when I call browser I see this message:
(mx.rpc::Fault)#0
errorID = 0
faultCode = “Client.Error.MessageSend”
faultDetail = “Channel.Connect.Failed error NetConnection.Call.BadVersion: ”
faultString = “Send failed”
message = “faultCode:Client.Error.MessageSend faultString:’Send failed’ faultDetail:’Channel.Connect.Failed error NetConnection.Call.BadVersion: ‘”
name = “Error”
rootCause = (Object)#1
code = “NetConnection.Call.BadVersion”
description = “”
details = “”
level = “error”
When I play with HelloWorld sample and service-config.xml the result is :
code:
Client.Error.MessageSend
Message:
Send failed
Detail:
Channel.Connect.Failed error NetConnection.Call.BadVersion: : url: ‘http://mysite.com/amfphp2/gateway.php’
Everywhere is UTF-8, right permissions. In PHP 5.2.1 allowurlinclude is “off”
any ideas?
Thank you for all your hard work!
I was curious if anyone tested this under PHP 4.3.2 and MySQL 3.23.58 ??
It could be some of the more advanced queries I’m making … and it could be that amfphp doesn’t FULLY work with the versions listed above. I’m unsure. My issues go away when using PHP 4.4.4 and MySQL 4 something.
Really nice stuff though! I’m a big fan of amfphp over other remoting services.
Bug:
file: core/amf/io/AMFDeserializer.php
function: readAmf3String() [Maybe other amf3 string functions too. Like readAmf3XmlString()…]
There is a little charset issue on the lates beta. I didint know where to post it so im just typing it here. The problem is amfphp not converting from utf to phpcharset using amf3. My fix for the problem is changing
Line 443: return $str;
to
return $this->charsetHandler->transliterate($str);
hope im not wrong :)
Thanks erdm!!, this work form me, now using amf3 with flex my services don’t write garbage in the database instead of special chars.
[…] ActiveRecord is a pattern and not language specific. I’ve been doing some research on a PHP ActiveRecord solution for Flash Remoting because of the speed increases that are possible with AMFPHP 2.0. PHP Doctrine was the closest PHP ActiveRecord implementation I could find to the one in Rails. However, the future of AMFPHP is now up in the air as Patrick Minnault is retiring as a programmer to become a Neuro Scientist! I always knew he was too smart to be a programmer, actually he still supports the NDP in Canada so he can’t be that bright :P […]
if you install php5 and apache2 manually.
Remember to copy the php5ts.dll to apache2/bin folder
or amfphp will not work…
It spend me one day to figure what happened
the php installation help file says
there three ways to install sapi and make php5ts.dll available to it
1.copy to apache/bin
2.copy to system32
3.set path to the folder contains php5ts.
it recommanded the third way and didn’t work….
until I installed wamp and everything worked as a charm.
I compared the config file and everything
finally I found the php5ts.dll problem….
I hope that will help to someone.
OK I make a mistake….
the whole thing is AMFPHP doesn’t work with PHP 5.2.2.2
I subtitude 5.2.22 php5ts.dll with 5.2.1.1 php5ts.dll.
in the /apache2/bin/
and one will work while the other won’t
Hi everybody,
I recently started working with Flex, and I have started using AMFPHP 1.9b2 to integrate it with my php classes. I have read all the tutorials, mailing lists, etc. yet I could find no solution for the problem below. My class has a function which should return a bit more complex array. I have set up the RemoteObject stuff, and written the AS part, but when I tested it, the ResultEvent’s result was “object”, and whatever I tried (ArrayUtils, etc.) I couldn’t do anything with it. I have added some debuging to the php script, all checked out, just before the function returns the array it is all OK. Yet when amfphp serializes the array, the result I get is just an “object”. I am using a standard php array with only integer and string values in them. Here is the array (by php’s print_r):
Array
(
[name] => Test Channel
[desc] => This channel is for testing purposes only
[enabled] => 1
[id] => 1
[news] => Array
(
[0] => Array
(
[category] => 1
[categoryName] => Tests 0
[channel] => 1
[creator] => 1
[creatorName] => Test User
[id] => 1
[link] => http://www.example.com/
[long] => Just kidding
[short] => I have been looking forward this…
[time] => 1177430203
[title] => Some guy did something last night
)
)
And this is the MXML and AS part:
internal function getchannelHandler(evt:Array):void
{
news = new ArrayCollection(ArrayUtil.toArray(evt.result));
}
Also, no fault handler is called, it just returns “object”. Flex detects no problems. Also tried RemoteObjectAMF0 and an older version of AMFPHP, nothing changed.
Any help is highly apreciated: JB
Hi, I noticed the same problem as Steven Lin. AMFPHP won’t work with PHP 5.2.2.
Is there any workaround? my webhost does not consider downgrading php as an option.. :-(
I just installed it. I wasn’t sure what options to install as. I’m on windowsXP Apache 2.2.2. PHP 5.2.2.
I have AMFPHP 1.2.5 loaded on my old machine but can’t get any of the methods to return any values for some reasonin the browser/index.html. I can’t figure out why.
So,I thought I’d try this versionI. I get an error.
(mx.rpc::Fault)#0
errorID = 0
faultCode = “Client.Error.MessageSend”
faultDetail = “Channel.Connect.Failed error NetConnection.Call.BadVersion: ”
faultString = “Send failed”
message = “faultCode:Client.Error.MessageSend faultString:’Send failed’ faultDetail:’Channel.Connect.Failed error NetConnection.Call.BadVersion: ‘”
name = “Error”
rootCause = (Object)#1
code = “NetConnection.Call.BadVersion”
description = “”
details = “”
level = “error”
Any help would be greatly appreciated!
$gateway->setCharsetHandler() isn’t implemented in C extensinon. Will be ?
maybe its keeps somebody from spending hours on debugging and error locating….
AMFPHP DOESNT WORK WITH PHP 5.2.2 !!!!!
and here´s the fix:
http://sourceforge.net/tracker/index.php?func=detail&aid=1717254&group_id=72483&atid=534662
Hello Patrick, i found something very strange while playing with the logion() and beforeFilter (here a tuto in spanish http://www.asb-labs.com/blog/) to sum up, i realize that when using php 4 i can add “description” (as shown here http://www.asb-labs.com/blog/2007/05/16/amfphp-roles-again/) by just adding a double slash forward before the function but when switching to php 5 it actually ignores those “descriptions” is it a pending task patrick? and in case it is the way it will work i was wondering how can i add the roles? according to the MethodTable.php (not sure if is being ignored in current beta 2) but there you wrote to use this way:description,args,remote,[roles]….but i cannot figure it out… any snippet?
Hi,
Is someone try to get an ByteArray from AMFPHP? I Tried but it doesn’t working!
flex code:
var ba:ByteArray = new ByteArray();
ba.writeByte(o as ByteArray);
Any idear?
I forget:
amfphp code:
return new ByteArray(filegetcontents($this->documents.”portrait/photo.jpg”));
Client side I receive an object with:
data = ÿØÿà
thanks DS, your fix works.
HI
I’m new at this and I just can’t get it to work, the gateway says everything is fine, the problem is when I open the browser, it shows up, but it never finishes loading
Please Help me
thenx
OKEY I did it!!! i got it working now on apache, NOOOOW, let’s make some flex remoting stuff
l8r
Well this package is truly one of the best amfphp-packages ever, but i have enormous problems to connect to my Oracle DB. Everytime when i invoke a method that get me data from my DB, my Flex-App returned “Channel disconnected”. But the method works and drops no error if invoked stand-alone
this f*ing line brings me up:
$result = $this->db->o_getAll( $sql , array() );
when i comment it out an say
$result = “2″;
everything works fine and no error.
Who can help