by Enrico Zimuel
Senior Software Engineer
Zend, a Rogue Wave Company (USA)
PHPDay 2017, Verona, 12th May
|
function hi(?string $name): ?string
{
if (null === $name) {
return null;
}
return 'Hello ' . $name;
}
echo hi(null); // returns null
echo hi('Enrico'); // returns 'Hello Enrico'
echo hi(); // Fatal error: Too few arguments to function hi(), 0 passed
interface Fooable {
function foo(): ?Fooable;
}
interface StrictFooable extends Fooable {
function foo(): Fooable; // valid
}
interface Fooable {
function foo(): Fooable;
}
interface LooseFooable extends Fooable {
function foo(): ?Fooable; // invalid
}
interface Fooable {
function foo(Fooable $f);
}
interface LooseFoo extends Fooable {
function foo(?Fooable $f); // valid
}
interface Fooable {
function foo(?Fooable $f);
}
interface StrictFoo extends Fooable {
function foo(Fooable $f); // invalid
}
function swap(&$left, &$right): void
{
if ($left === $right) {
return;
}
$tmp = $left;
$left = $right;
$right = $tmp;
}
$a = 1;
$b = 2;
var_dump(swap($a, $b), $a, $b); // null, int(2), int(1)
$data = [
['foo', 'bar', 'baz']
];
[$a, $b] = $data[0];
var_dump($a, $b); // string(3) "foo", string(3) "bar"
[$a, , $c] = $data[0];
var_dump($a, $c); // string(3) "foo", string(3) "baz"
foreach ($data as [$a, $b, $c]) {
var_dump($a, $b, $c);
// string(3) "foo"
// string(3) "bar"
// string(3) "baz"
}
Specify keys in list(), or its new shorthand [] syntax
$data = [
'a' => 'foo',
'b' => 'bar',
'c' => 'baz'
];
list('a' => $a, 'b' => $b, 'c' => $c) = $data;
var_dump($a, $b, $c);
// string(3) "foo"
// string(3) "bar"
// string(3) "baz"
['a' => $a, 'b' => $b, 'c' => $c] = $data;
var_dump($a, $b, $c);
// string(3) "foo"
// string(3) "bar"
// string(3) "baz"
// Not allowed
list([$a, $b], [$c, $d]) = [[1, 2], [3, 4]];
[list($a, $b), list($c, $d)] = [[1, 2], [3, 4]];
// Allowed
list(list($a, $b), list($c, $d)) = [[1, 2], [3, 4]];
[[$a, $b], [$c, $d]] = [[1, 2], [3, 4]];
function foo(iterable $iterable): void
{
foreach ($iterable as $value) {
var_dump($value);
}
}
foo([1,2,3]);
foo(new ArrayIterator([1,2,3]));
class ConstDemo
{
const PUBLIC_CONST_A = 1; // default to public
public const PUBLIC_CONST_B = 2;
protected const PROTECTED_CONST = 3;
private const PRIVATE_CONST = 4;
}
$obj = new ReflectionClass("ConstDemo");
foreach ($obj->getReflectionConstants() as $const) {
var_dump($const); // object(ReflectionClassConstant)
var_dump($const->getName());
var_dump($const->getValue());
var_dump($const->isPublic());
var_dump($const->isPrivate());
var_dump($const->isProtected());
}
ReflectionClassConstant is not documented (BUG #74261)
try {
// Some code...
} catch (ExceptionType1 $e) {
// Code to handle the exception
} catch (ExceptionType2 $e) {
// Same code to handle the exception
} catch (Exception $e) {
// ...
}
try {
// Some code...
} catch (ExceptionType1 | ExceptionType2 $e) {
// Code to handle the exception
} catch (\Exception $e) {
// ...
}
var_dump("abcdef"[-2]); // string(1) "e"
var_dump("abcdef"[-7]); // string(0) "", PHP Notice offset
// strpos
var_dump(strpos("aabbcc", "b", -3)); // int(3)
// get the last character of a string
$last = substr($foo, -1); // before PHP 7.1
$last = $foo[-1];
pcntl_async_signals() has been introduced to enable asynchronous signal handling without using ticks
pcntl_async_signals(true); // turn on async signals
pcntl_signal(SIGHUP, function($sig) {
echo "SIGHUP\n";
});
posix_kill(posix_getpid(), SIGHUP);
class Test
{
public function exposeFunction()
{
return Closure::fromCallable([$this, 'privateFunction']);
}
private function privateFunction($param)
{
var_dump($param);
}
}
$privFunc = (new Test)->exposeFunction();
var_dump($privFunc); // object(Closure)
$privFunc('some value'); // string(10) "some value"
Authenticated Encrypt with Associated Data (AEAD)
Support GCM and CCM encryption modes
GCM is 3x faster than CCM. See this benchmark
More info on Authenticated Encryption in PHP 7.1
string openssl_encrypt(
string $data,
string $method,
string $password,
[ int $options = 0 ],
[ string $iv = "" ],
[ string &$tag = NULL ],
[ string $aad = "" ],
[ int $tag_length = 16 ]
)
$tag contains the authentication hash
string openssl_decrypt(
string $data,
string $method,
string $password,
[ int $options = 0 ],
[ string $iv = "" ],
[ string $tag = "" ],
[ string $aad = "" ]
)
$tag is the authentication hash
$algo = 'aes-256-gcm';
$iv = random_bytes(openssl_cipher_iv_length($algo));
$key = random_bytes(32); // 256 bit
$data = random_bytes(1024); // 1 Kb of random data
$ciphertext = openssl_encrypt(
$data,
$algo,
$key,
OPENSSL_RAW_DATA,
$iv,
$tag
);
// output is $ciphertext and $tag
$tag is the authentication hash
$decrypt = openssl_decrypt(
$ciphertext,
$algo,
$key,
OPENSSL_RAW_DATA,
$iv,
$tag
);
if (false === $decrypt) {
throw new Exception(sprintf(
"OpenSSL error: %s", openssl_error_string()
));
}
printf ("Decryption %s\n", $data === $decrypt ? 'Ok' : 'Failed');
$tag is the authentication hash
$transfers = 1;
$callback = function($parent_ch, $pushed_ch, array $headers)
use (&$transfers) {
$transfers++;
return CURL_PUSH_OK;
};
$mh = curl_multi_init();
curl_multi_setopt($mh, CURLMOPT_PIPELINING, CURLPIPE_MULTIPLEX);
curl_multi_setopt($mh, CURLMOPT_PUSHFUNCTION, $callback);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://localhost:8080/index.html");
curl_setopt($ch, CURLOPT_HTTP_VERSION, 3);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0); // self-signed cert
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0); // self-signed cert
curl_multi_add_handle($mh, $ch);
$active = null;
do {
$status = curl_multi_exec($mh, $active);
do {
$info = curl_multi_info_read($mh);
if (false !== $info && $info['msg'] == CURLMSG_DONE) {
$handle = $info['handle'];
if ($handle !== null) {
$transfers--; // decrement remaining requests
$body = curl_multi_getcontent($info['handle']);
curl_multi_remove_handle($mh, $handle);
curl_close($handle);
}
}
} while ($info);
} while ($transfers);
curl_multi_close($mh);
Added hash_hkdf() function to support HKDF (RFC 5869)
$key = random_bytes(32);
$salt = random_bytes(16);
$encryptKey = hash_hkdf('sha256', $key, 32, 'encrypt', $salt);
$authKey = hash_hkdf('sha256', $key, 32, 'auth', $salt);
var_dump($encryptKey !== $authKey); // bool(true)
Added SHA3 support (224, 256, 384, and 512)
$hash = hash('sha3-224', 'This is a text');
var_dump($hash);
// string(56)"9209f5869ad03ac11549902b3c83fe8e6b7e1cd1614ab4291587db43"
Rate this talk at https://joind.in/talk/935fc
Contact me: enrico.zimuel [at] roguewave.com
Follow me: @ezimuel
This work is licensed under a
Creative Commons Attribution-ShareAlike 3.0 Unported License.
I used reveal.js to make this presentation.