AMF (Action Message Format) is a binary data serialization protocol. Simply put, it transforms objects in memory into a binary string, and can reverse this binary string into an object in memory. It can be used just like JSON
, and this library has been build to provide a similar API to that exposed by the JSON
functionality in PHP
.
The purpose of this library is to provide a consistent and symmetric implementation of the AMF
specification in both PHP
& JSON
.
Well, it's up to you. JSON
is perfectly suited to the web, however it does have some shortcomings which are addressed by AMF
. For starters, JSON
cannot handle complex object graphs with circular references; additionally, it cannot serialize dates & byte arrays - you would need to do some additional work to support these in JSON
(convert date to unix timestamp, byte arrays to base64).
Hells no. JSON
is great; AMF
can simply provide you with some additional funcitonality which could help you build your web app.
To begin using this library, you will need to install it via Composer:
{
"require": {
"infomaniac-amf/php": "dev-master"
}
}
Once you have run composer install
, you will be able to use the library by simply including Composer
's autoloader:
<?php
require_once 'vendor/autoload.php';
Here is a simple example of encoding an array to AMF
:
<?php
require_once 'vendor/autoload.php';
$data = array(
'any' => 'data',
'you' => 'like'
);
header('Content-Type: application/x-amf');
echo amf_encode($data);
This will produce a binary string which represents your given data.
If you were to inspect the HTTP traffic of a page that produces AMF
data, using a tool such as Charles Proxy, you would see the following output:
To decode this string, simply do the following:
$data = array(
'any' => 'data',
'you' => 'like'
);
$encodedData = amf_encode($data);
$data = amf_decode($encodedData);
If you were to var_dump
this data, it would look identical to the input data given to the amf_encode
function.
array (size=2)
'any' => string 'data' (length=4)
'you' => string 'like' (length=4)
AMF
allows you to encode an object and retain some metadata about it; for example, when serializing an instance of a class (not stdClass
) the library will retain the class' fully qualified namespace name and use it to reconstruct an object of that type upon decoding.
Consider the following class:
<?php
class Person {
public $name;
}
If we encode an instance of this object, by default its class type will be ignored and when the data is decoded, the resulting value will be a plain PHP stdClass
instance.
This is how the encoded data will look in Charles:
In order to retain the class type in AMF
, you will need to add an additional flag to the amf_encode
function call:
amf_encode($data, AMF_CLASS_MAPPING);
When the AMF_CLASS_MAPPING
flag is given, the encoded data will look like this in Charles:
Notice the additional Person
metadata in this response
Now, when this data is decoded, the library will attempt to create a new instance of the Person
class and set its public property name
to "bob"
.
object(Person)[8]
public 'name' => string 'bob' (length=3)
The AMF
spec allows for the serialization of several different data-types.
Here is a link to the latest specification: AMF3 Spec - January 2013
This library implements 10 of the 18 data-types described in the specification. The reason for the support of only a subset of these types can be seen in two lights: utility and limitation. Here is an exhaustive list of the data-types available:
Data-Type | Included | Reason for exclusion |
---|---|---|
Undefined | ✔ | - |
Null | ✔ | - |
False | ✔ | - |
True | ✔ | - |
Integer | ✔ | - |
Double | ✔ | - |
String | ✔ | - |
XML Document | ✗ | Who needs XML? |
Date | ✔ | - |
Array | ✔ | - |
Object | ✔ | - |
XML | ✗ | Who needs XML? |
ByteArray | ✔ | - |
Vector | ✗ | Not high priority - also, possible browser incompat issue with JS |
Vector | ✗ | Not high priority - also, possible browser incompat issue with JS |
Vector | ✗ | Not high priority - also, possible browser incompat issue with JS |
Vector | ✗ | Not high priority - also, possible browser incompat issue with JS |
Dictionary | ✗ | PHP cannot use objects are array keys |
This project is licensed under the MIT
license.
While writing this library, I used several libraries to validate my progress, and to help me come unstuck. I would like to extend a special thanks to the following libraries and individuals:
- SabreAMF
- AmfPhp
- Charles Proxy's wonderful AMF implementation
- Arseny Vakhrushev (neoxic) for his patience, guidance, advice and help
- Robert Cesaric, Grant McMullin and Andre Venter for their insight and advice
- My esteemed colleagues at Zando