<slide title="" section="php74">

<blurb fontsize="20em" align="center">PHP 7.4</blurb>

<break lines="1" section="php74_typedprop"/>
<blurb fontsize="1.1em" align="left">Typed Properties</blurb>

<example fontsize="1.1em" result='0' title="" type=""><![CDATA[<?php
class User {
    public int $id;
    public string $name;
 
    public function __construct(int $id, string $name) {
        $this->id = $id;
        $this->name = $name;
    }
}
]]></example>

<break lines="1" section="php74_arrow"/>
<blurb fontsize="1.1em" align="left">Arrow Functions</blurb>
<example fontsize="1.1em" result='0' title="" type=""><![CDATA[<?php
$cb = function ($x) use ($y) {
          return $x + $y;
      };

$cb = fn($x) => $x + $y;
]]></example>

<break lines="1" section="php74_serialize"/>
<blurb fontsize="1.1em" align="left">__serialize/__unserialize</blurb>

<example fontsize="1.1em" result='0' title="" type=""><![CDATA[<?php
class Test {
    public $prop;
    public function __serialize() {
        return ['prop' => $this->prop];
    }
    public function __unserialize(array $data) {
        $this->prop = $data['prop'];
    }
}
]]></example>

<break lines="1" section="null_coalesce_assign"/>

<blurb fontsize="1em" align="left">Null Coalescing Assignment Operator</blurb>

<example fontsize="1em" result='0' title="" type=""><![CDATA[<?php
$this->config['value']   = $this->config['value'] ?? 'default_value';
$this->config['value'] ??= 'default_value';
]]></example>

<break lines="1" section="weakref"/>

<blurb fontsize="1em" align="left">Weak References</blurb>

<example fontsize="1em" result='0' title="" type=""><![CDATA[<?php
$std = new stdClass;
$wr = WeakReference::create($std);
]]></example>

<break lines="1" section="php74_preload"/>
<blurb fontsize="1.8em" align="center">Opcache Preloading</blurb>
<list>
<item fontsize="1em">Loads userspace code at server startup as if it was part of core PHP</item>
<item fontsize="1em">Trades some flexibility for performance</item>
<item fontsize="1em">Inspired by the “Class Data Sharing” feature in Java's Hotspot VM</item>
</list>
<break lines="1" section="php74_preload1"/>
<blurb fontsize="1em" align="left">Without Opcache Preloading</blurb>

<example fontsize="1.1em" result='0' title="" type=""><![CDATA[<?php
class A {
    function __construct() {
        echo "A";
    }
}
]]></example>

<example fontsize="1em" result='0' title="" type=""><![CDATA[<?php
spl_autoload_register('__load');
function __load($c) {
    echo "Autoloader called for $c\n";
    require "/home/rasmus/".strtolower($c).".php";
}

new A;
]]></example>

<example fontsize="1.1em" result='0' title="" type="shell nohighlight"><![CDATA[
$ php script.php 
Autoloader called for A
A
]]></example>

<break lines="1" section="php74_preload2"/>

<blurb fontsize="1em" align="left">With Opcache Preloading</blurb>

<example fontsize="1em" result='0' title="" type=""><![CDATA[<?php
function preload($filename) {
    if (!opcache_compile_file($filename)) {
        trigger_error("Preloading Failed", E_USER_ERROR);
    }
}

preload("/home/rasmus/a.php");
]]></example>

<example fontsize="1.1em" result='0' title="" type="shell nohighlight"><![CDATA[
$ php -d opcache.preload=preload.php script.php 
A
]]></example>

<break lines="1" section="ffi"/>

<blurb fontsize="1em" align="left">FFI - Foreign Function Interface</blurb>

<example fontsize="1em" result='0' title="" type=""><![CDATA[<?php
// create FFI object, loading libc and exporting function printf()
$ffi = FFI::cdef(
    "int printf(const char *format, ...);",
    "libc.so.6");
// call C printf()
$ffi->printf("Hello %s!\n", "world");
]]></example>

<break lines="1" section="ffi_example"/>
<example fontsize="1em" result='0' title="" type=""><![CDATA[<?php
<?php
    $ffi = FFI::load("php_gifenc.h");

    $w = 240; $h = 180;
    $cols = $ffi->new("uint8_t[12]");
    /* 4 colours: 000000, FF0000, 00FF00, 0000FF */
    $cols[3] = 0xFF; $cols[7] = 0xFF; $cols[11] = 0xFF;

    $gif = $ffi->ge_new_gif("test.gif", $w, $h, $cols, 2, 0);

    for($i = 0; $i < 16; $i++) {
        for ($j = 0; $j < $w*$h; $j++) {
            $gif->frame[$j] = ($i*6 + $j) / 12 % 8;
        }
        echo "Add frame $i\n";
        $ffi->ge_add_frame($gif, 5);
    }
    $ffi->ge_close_gif($gif);
]]></example>
<break lines="1" section="ffi_example_header"/>
<example fontsize="1em" result='0' title="" type=""><![CDATA[<?php
#define FFI_SCOPE "gifenc"
#define FFI_LIB "libgifenc.so"

typedef struct ge_GIF {
    uint16_t w, h;
    int depth;
    int fd;
    int offset;
    int nframes;
    uint8_t *frame, *back;
    uint32_t partial;
    uint8_t buffer[0xFF];
} ge_GIF;

ge_GIF *ge_new_gif(
    const char *fname, uint16_t width, uint16_t height,
    uint8_t *palette, int depth, int loop
);
void ge_add_frame(ge_GIF *gif, uint16_t delay);
void ge_close_gif(ge_GIF* gif);
]]></example>

<break lines="1" section="ffi_example_output"/>
<image width="240" height="180" filename="test.gif" align="center"/>
</slide>
