Rasmus Lerdorf
@rasmus
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#define ishex(x) (((x) >= '0' && (x) <= '9') || ((x) >= 'a' && \
(x) <= 'f') || ((x) >= 'A' && (x) <= 'F'))
int htoi(char *s) {
int value;
char c;
c = s[0];
if(isupper(c)) c = tolower(c);
value=(c >= '0' && c <= '9' ? c - '0' : c - 'a' + 10) * 16;
c = s[1];
if(isupper(c)) c = tolower(c);
value += c >= '0' && c <= '9' ? c - '0' : c - 'a' + 10;
return(value);
}
void main(int argc, char *argv[]) {
char *params, *data, *dest, *s, *tmp;
char *name, *age;
puts("Content-type: text/html\r\n");
puts("<HTML><HEAD><TITLE>Form Example</TITLE></HEAD>");
puts("<BODY><H1>My Example Form</H1>");
puts("<FORM action=\"form.cgi\" method=\"GET\">");
puts("Name: <INPUT type=\"text\" name=\"name\">");
puts("Age: <INPUT type=\"text\" name=\"age\">");
puts("<BR><INPUT type=\"submit\">");
puts("</FORM>");
data = getenv("QUERY_STRING");
if(data && *data) {
params = data; dest = data;
while(*data) {
if(*data=='+') *dest=' ';
else if(*data == '%' && ishex(*(data+1))&&ishex(*(data+2))) {
*dest = (char) htoi(data + 1);
data+=2;
} else *dest = *data;
data++;
dest++;
}
*dest = '\0';
s = strtok(params,"&");
do {
tmp = strchr(s,'=');
if(tmp) {
*tmp = '\0';
if(!strcmp(s,"name")) name = tmp+1;
else if(!strcmp(s,"age")) age = tmp+1;
}
} while(s=strtok(NULL,"&"));
printf("Hi %s, you are %s years old\n",name,age);
}
puts("</BODY></HTML>");
}
use CGI qw(:standard);
print header;
print start_html('Form Example'),
h1('My Example Form'),
start_form,
"Name: ", textfield('name'),
p,
"Age: ", textfield('age'),
p,
submit,
end_form;
if(param()) {
print "Hi ",em(param('name')),
"You are ",em(param('age')),
" years old";
}
print end_html;
<html><head><title>Form Example</title></head>
<body><h1>My Example Form</h1>
<form action="form.phtml" method="POST">
Name: <input type="text" name="name">
Age: <input type="text" name="age">
<br><input type="submit">
</form>
<?if($name):?>
Hi <?echo $name?>, you are <?echo $age?> years old
<?endif?>
</body></html>
void Cos(void) {
Stack *s;
char temp[64];
s = Pop();
if(!s) {
Error("Stack error in cos");
return;
}
sprintf(temp,"%f",cos(s->douval));
Push(temp,DNUMBER);
}
<html><head><title>Cos Example</title></head>
<body><h1>Cos Example</h1>
<?echo Cos($input)>
</body></html>
array_search($needle, $haystack);
strstr($haystack, $needle);
in_array($needle, $haystack);
substr_count($haystack, $needle);
array_key_exists($needle, $haystack);
strchr($haystack, $needle);
Typed Properties
class User {
public int $id;
public string $name;
public function __construct(int $id, string $name) {
$this->id = $id;
$this->name = $name;
}
}
Arrow Functions
$cb = function ($x) use ($y) {
return $x + $y;
};
$cb = fn($x) => $x + $y;
__serialize/__unserialize
class Test {
public $prop;
public function __serialize() {
return ['prop' => $this->prop];
}
public function __unserialize(array $data) {
$this->prop = $data['prop'];
}
}
Null Coalescing Assignment Operator
$this->config['value'] = $this->config['value'] ?? 'default_value';
$this->config['value'] ??= 'default_value';
Weak References
$std = new stdClass;
$wr = WeakReference::create($std);
Opcache Preloading
Without Opcache Preloading
class A {
function __construct() {
echo "A";
}
}
spl_autoload_register('__load');
function __load($c) {
echo "Autoloader called for $c\n";
require "/home/rasmus/".strtolower($c).".php";
}
new A;
$ php script.php
Autoloader called for A
A
With Opcache Preloading
function preload($filename) {
if (!opcache_compile_file($filename)) {
trigger_error("Preloading Failed", E_USER_ERROR);
}
}
preload("/home/rasmus/a.php");
$ php -d opcache.preload=preload.php script.php
A
FFI - Foreign Function Interface
// 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");
<?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);
#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);