CLR vs. PHP types#
This article provides information on how the runtime treats .NET types. As a result, with respect to this specification, it is possible to pass values between .NET (assuming C#
) and PHP
code implicitly, without the need of marshalling or additional conversions.
Type System#
The following table shows compatible .NET types and the corresponding PHP type:
.NET | PHP | PHP Features |
---|---|---|
PhpValue | mixed | |
bool | boolean | |
int, uint, long | integer | |
double, float | double | |
string, PhpString, byte[] | string | |
object | object | -> |
null | NULL | |
PhpResource | resource | is_resource |
PhpNumber | integer|double | |
PhpArray, ArrayAccess, IList | array, ArrayAccess | [] |
Iterator, IteratorAggregate, IEnumerable | iterable | foreach , is_iterable |
delegate, IPhpCallable, string, PhpArray(2) | callable | call_user_func , is_callable , etc. |
Nullable<T> | value|NULL | isset , unset |
System.Nullable<T>#
Values can be read from and assigned to the Nullable<T>
type. Any value of type Nullable<T>
is treated as its contained value or NULL
. An automatic conversion is performed. The operator isset
is using the Nullable.HasValue
property implicitly.
class Test {
public int? Number; // nullable field
public double? Foo() { ... }; // return nullable from method
public void Bar(bool? b) { } // gets nullable parameter
}
<?php
$t = new Test;
$t->Number = 123; // assigns `new Nullable<int>(123)`
$t->Number = null; // assigns `default(Nullable<int>)`
isset( $t->Number ); // gets Number.HasValue
print_r( $t->Foo() ); // gets NULL or double
$t->Bar( NULL ); // passes `default(Nullable<bool>)` to the method
$t->Bar( true ); // passes `new Nullable<bool>(true)` to the method
System.Delegate#
PHP's concept of callables works with string
pointing to a function name, array
of two dimensions referring to a class and its method, classes with the __invoke
method or instances of the Closure
class. Variables of these types, denoted as callable
, can be used for indirect calls as depicted in the sample below:
<?php
assert( is_callable($delegate) );
print_r( $delegate($arg1, $arg2) ); // $delegate is `callable`
PeachPie extends the set of callable
types with any CLR delegate
or objects implementing the IPhpCallable
interface (Peachpie.Runtime.dll).
Sample C# code that passes a delegate to a PHP global variable:
mycontext.Globals["delegate"] = new Func<string, bool>( str => str.IsNormalized() );
System.Collections.IEnumerable#
The sample PHP code below is able to consume a variety of CLR objects in addition to PHP's array
and Traversable
.
<?php
foreach ($enumerable as $key => $value) { }
$enumerable
may implement the following CLR interfaces:
IPhpEnumerable
(Peachpie.Runtime.dll) is the extended version ofIEnumerable
. Objects implementing this interface are capable of being enumerated in PHP'sforeach
.IDictionary
; objects implementing this interface.IEnumerable<(Key, Value)>
; objects implementingIEnumerable<>
ofValueTuple
with two items.IEnumerable<KeyValuePair<Key, Value>>
; objects implementingIEnumerable<>
ofKeyValuePair<,>
.IEnumerable
in general works withforeach
as well.$key
is auto-incremented starting with0
,$value
is the current value of the enumerator.
As a result, standard .NET classes such as .NET arrays, ArrayList
, List<>
, Dictionary<,>
or enumerators created using C# yield
are transparently supported by PHP's foreach
construct.
foreach
by reference#
<?php
foreach ($enumerable as $key => &$value) { $value = 0; }
PhpAlias
from the enumerator. Otherwise an exception of type InvalidOperationException
is thrown.
System.Collections.IList#
PHP allows the accessing of an array
and objects implementing ArrayAccess
with square brackets []
as shown in the example below:
<?php
echo $list[10];
PeachPie provides the feature for System.Collections.IList
, which allows consuming .NET arrays, List
s and other classes in PHP.
C# Event#
Implemented in
1.2.0
(#1141)
PeachPie runtime allows working with .NET/CLR event
class members in order to register and unregister callables. The following code depicts a sample C# class and a sample PHP program adding and removing an anonymous function (or any PHP callable) to it.
class SampleContainer
{
public event EventHandler MyEvent;
}
<?php
$obj = new SampleContainer;
// add callable to the event handler:
$hook = $obj->MyEvent->add(
function ($sender, $arg) {
echo "hello!";
}
);
// remove callable from the event handler
$hook->close();
In PHP, the event
class member is represented by an instance of a special class Pchp\Core\ClrEvent
with the following method:
ClrEvent::add( callable $callback ): Pchp\Core\ClrEvent\Hook
The Pchp\Core\ClrEvent\Hook
class methods:
Hook::close()
Hook::dispose() // alias to close
C# Indexers#
PHP array operator []
can be used on objects implementing C# indexers.
The following example defines a C# indexer with sample get
and set
accessors.
using System;
class SampleIndexer
{
string[] arr = new string[100];
// Define the indexer to allow to use [] operator.
public string this[int i]
{
get { return arr[i]; }
set { arr[i] = value; }
}
}
The following PHP code makes use of the C# indexer implicitly.
<?php
$sample = new \SampleIndexer;
$sample[0] = "Hello";
echo $sample[0]; // prints "Hello"
The indexer implementation
#c# this[]
is a syntactic sugar that results in compiler generated specialget_Item
andset_Item
methods. PeachPie translates the array operator into the call to the correspondingget_Item
orset_Item
method.