Table of contents:
- What's new
- Installing Remoting components
- Installing AMFPHP
- Testing AMFPHP
- 10,000 foot view of Remoting
- Creating Remoting methods
- Method table reference
- Helper classes
- NetDebug
- Authenticate
- DateWrapper
- Datatypes
- Class mapping
- Security
- Authentication
- Sending recordsets
- Manual recordsets
- Pageable recordsets
- Consuming web services (SOAP)
- Other platforms
- FAME
- Flex
- FlashCom
- The service browser
- Debugging
- Debugging primer
- NetConnection debugger
- Debugging proxies
- NetDebug::trace and exceptions
- Common confusing errors
- Deploying
- Credits
Common confusing, intractable errors
Some AMFPHP errors can be hard to track down if you don't have a low level knowledge of Remoting. In particular these features are often a source of confusion:
- BOM headers in Unicode files cause corrupt output
- Remoting batches calls
- Remoting objects are not persistent
- Remoting is binary data and is therefore not affected by magic quotes
- amfphp classes are run in a sandbox making globals act unexpectedly
BOM headers in Unicode files cause corrupt output
BOM headers in your service files may cause the output stream to become corrupt. That is because the output stream will contain the BOM header which is not valid AMF. Although in 99% of cases the BOM headers will not cause issues, some combinations of PHP version and server version and possibly the alignment of Jupiter may cause this rather nasty problem to show up. The solution is either to save as ASCII or to save as Unicode in an editor that doesn't add a BOM header, and deleting the old BOM header with an hex editor. UltraEdit in particular will do the job. To verify if this is indeed happening, load up Charles or Service Capture. If you see an error like 'cannot modify header information, output started at (guilty file):line number', then you've found the source of the error. Resave as DOS or Unix ASCII and it should work fine.
Problems related to batched calls
If you call several remote methods within the same frame, Remoting can and will batch calls. That means that a single AMF message to the server can contain several sub messages. This is a very useful feature that has caused a lot of confusion.
Results won't come back until all calls have finished
If you call several methods within the same frame, such as:
var pc1 = service.myFirstMethod(); var pc2 = service.mySecondMethod();
Expect the results of both method calls to come back at the same time when both are finished. That means that if in the myFirstMethod you call sleep(10) you can expect the results of the second method to take a full 10 seconds to come back. This is because they are sent at the same time using the same AMF packet. Thus AMFPHP processes one call after the other and sends it back when each and every one is finished.
include and require will cause failure on second call
If you include a file within one of your methods, it may fail on the second call within the same batch. This is because in reality this code is called twice and the include will be called twice. Thus if you define a function in the included file, this function will be redefined on the second call, which will make PHP choke. Also if you call different services that include the same file (for example if several services use PEAR::DB), this will cause problems. Thus, always use require_once and include_once with AMFPHP.
There is an exception to this rule, and that is when including the methodTable in the constructor of your class. In that case, ALWAYS use include and require and not include_once and require_once. Otherwise the second call will fail, telling you there is no methodTable defined.
Problems related to non persistent objects
It’s tempting to think that variables will be available across remoting calls in your functions by magic. That’s not the way AMFPHP works. One batch of methods is called, then the variables are scrapped. Remoting is an RPC implementation, not a way to create SharedObjects. Therefore if you need persistence, store the data in a session. You don’t need to call session_start() as it’s already done for you.
Problems related to magic quotes
AMFPHP uses $HTTP_RAW_POST_DATA as its input. This variable is not affected by magic quotes. Thus all your service arguments will act as though magic quotes was set to off. If you try to insert something with a quote in it without escaping it you will receive an error back from your sql driver. Use the database specific escaping function on your strings before running SQL, for example mysql_real_escape_string for MySQL.
Issues with globals
amfphp runs classes inside of asandbox, meaning globals and $_GLOBALS probably won't work as expected. For example, consider:
<?php
$myVar = "stuff";
class myClass
{
/** [MethodTable and constructor, etc. would go here] **
function returnStuff()
{
global $myVar;
return $myVar; //returns NULL
}
}
?>
Here $myVar is NOT a global. That means it won't be accessible inside the class. The workaround is:
<?php
global $myVar;
$myVar = "stuff";
class myClass
{
/** [MethodTable and constructor, etc. would go here] **
function returnStuff()
{
global $myVar;
return $myVar; //returns "stuff"
}
}
?>
Note that this also applies to variables defined in included or required files. When in doubt about using globals, declare variables as globals before working with them, and write a global declaration at the top of every method.
