Interaction of PHP types with the Global Context.
This section details how PHP types are converted to and from Java Types when placed into and retrieved from the Global Context.
Note that much of what is here follows naturally from the general Java conversion rules which are described in the
PHP Developers guide
PHP types placed into the global context
When PHP types are placed into the Global Context using the
zput function they are converted into Java Types as described below.
String Conversion
PHP5 permits any arbitrary sequence of bytes to be stored in a PHP String. In order to be compatible with PHP5, internally the PHP runtime for Zero stores PHP strings as an array of bytes. Java Strings are not sequences of bytes, they are sequences of Java Characters which are Unicode characters. When a PHP string is converted to a Java String, the PHP string is assumed to have been encoded in the PHP
Runtime Encoding?. If the PHP string was not a valid sequence of characters in the PHP Runtime Encoding then the string will be transformed as described in the documentation for
Runtime Encoding?.
A PHP string can also be placed into Global Context as a byte array by supplying an option to the
zput function.
discuss
CJT When will a byte array need to be passed (and not converted into a string):
1) a character string in a different encoding (perhaps from an app which supports different national languages through using PHP scripts ) In this case, perhaps overriding the runtime encoding would be better, and still put it into a Java String.
2) a byte sequence which represents something other than text, such as an image or encrypted text.
Also, see Array Conversion below, the handling of strings inside arrays should be consistent with this PHP string to Java String mapping (for example, currently XAPIArrayMap has two choices: either all strings are converted or all strings are returned as byte arrays).
Array Conversion
A PHP array is placed into the Global Context as a XAPIArrayMap which extends
Map<Object, Object>. This gives a standard Java interface to the PHP array without the overhead of copying. It also means that the XAPIArrayMap can later be retrieved from the Global Context as a PHP array and the following aspects of the PHP array are preserved.
- Key->value mappings
- Integer index->value mapping
- Position of PHP array internal iterator.
- PHP references to other elements of the (multidimensional) PHP Array
- The order of elements in the PHP array
A PHP array can also be placed into Global Context as a java array of Objects (Object[]) by supplying an option to the
zput function.
discuss
CJT I think all the mappings in the array conversion should be consistent with the global context mappings. I think this is the case unless we decide to support the conversion of PHP strings as Java byte arrays.
I do not think we should support putting a PHP array as a Java array of Objects because of complexity it introduces when understanding what is added - lets have just one mapping. It will also not be symmetrical because we cannot go from Java objects to PHP array when getting from the GC.
MC Putting PHP arrays as maps in the global context breaks for some key use cases involving encoding these arrays as json, xml and atom formats. There is costly special casing done in the Zero extensions to determine if the array is indexed or not. Ideally the object that is placed in the global context should be either a Map (for associative arrays) or a List (for indexed arrays).
Object Conversion
A PHP object can be placed into the Global Context. If the PHP object is simply a
Java Bridge wrapper around a Java object then the underlying Java object is placed into the Global Context. Otherwise, if the Object is an instance of a PHP class then it is placed into the Global Conext as an com.ibm.phpj.xapi.XAPIObject. It is not intended that arbitrary Java or Groovy code should be able to interact with an XAPIObject but it can later be retrieved from the Global Context into a PHP script
CJT If the intention is to access the properties set in the PHP object (i.e. the data, not the function) then you can cast the PHP object to a PHP array first, before adding to the Global Context.
MC Does the cast apply to embedded array or object attributes of the object as well ?
Java/Groovy types retrieved from the global context
When a Java type is retrieved from the Global Context using the
zget function they are converted to PHP types as described below
| From Java Type | to resulting PHP Type | Comments |
null | null | |
Integer | int | |
Double | double | |
Boolean | bool | |
Byte | int | |
Character | int | CJT This should result in a single character PHP string (could be more than one byte), converted using the runtime encoding. |
Short | int | |
Long | int | CJT What happens with values that are too large. |
Float | double | |
byte[] | string | |
String | string | The PHP String is encoded using the runtime_encoding? |
com.ibm.phpj.xapi.XAPIArray | array | The key=>value mappings, order, internal references and internal iterator are preserved. cjt Under what circumstance would we end up with this in the GC? I think we would only get the XAPIArrayMap. |
com.ibm.phpj.xapi.XAPIArrayMap | array | The key=>value mappings, order, internal references and internal iterator are preserved. |
Map | array | (java.util.Map) the types of individual elements are converted as per this table, including nested Maps |
List | array | CJT Added this type because Groovy has native support for lists (java.util.List). Map to a PHP array with numeric keys. |
com.ibm.phpj.resources.Resource | Resource | |
com.ibm.phpj.xapi.XAPIObject | Object | |
Object[] | array | See Conversion from java Array to PHP array |
| Anything Else | object | The Java Object is wrapped as a PHP Object using the Java Bridge |
Conversion from Java Array to PHP array
- Note that arrays of primitive bytes
byte[] are converted to PHP strings. This does not apply to Byte[] which is treated like any other Object array.
- Individual elements in the Object array are converted as per these rules, including nested arrays.
- The Java array of Objects is converted into a PHP array using the index into the java object as the integer key in the PHP array.
- The "order" in the PHP array is with incrementing integer key.
- Arrays of primitive types are converted into Java arrays by boxing the types and using these conversion rules (except
byte[]).
- Multidimensional java arrays are supported and result in multidimensional PHP arrays.
- An element of a Java array can be a
Map and is converted using the rules above.
- A Java array can be primitive types (
int[], short[] etc) or boxed values (Integer[], Double[] etc)
Other global context functions and the implications
- zpost - Special handling if there is already a PHP array in the global context. Presumably this needs to be changed to look for any Map, and add to the end of it whatever the underlying implementation (a PHP array, or a Java HashMap for example)
- zlist - Lists all keys at a particular path. No change
- zcontains - True if key found. No change
- zdelete - Remove value in global context at key (optionally children too). No change. Note will remove from the global context, not destroy value if referenced from elsewhere.
- zdump - Dumps the values at specified keys. No change.
Value "pathing"
There are several ways of accessing values from inside data stored in the global context. See
Value Pathing documentation.
When a Groovy/Java object is stored in the global context, any of these ways can be used to access information, exactly as described in the Core documentation, using the type mapping described in how to get Java/Groovy types from the global context.
When adding PHP types to the global context, some of the following value pathing methods are supported:
- Maps. Will be supported for a PHP array stored in the global context.
- Lists. Will be supported for a PHP array stored in the global context.
- FirstElementList. Will be supported for a PHP array stored in the global context.
- Objects (default). Supported for all PHP types.
- Nested. Will be supported for nested PHP arrays stored in the global context.
- ValueGenerator. It is not possible to provide a PHP object which supports ValueGenerator (the getValue method). discuss
-- nicholsr - 20 Nov 2007