by Enrico Zimuel
Senior Software Engineer
Rogue Wave Software, Inc.
ZendCon 2017, Las Vegas (NV), Oct. 26
|
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
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, 2, 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); // foo, bar, baz
['a' => $a, 'b' => $b, 'c' => $c] = $data;
var_dump($a, $b, $c); // foo, bar, 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 CONST_A = 1; // public
public const CONST_B = 2;
protected const CONST_C = 3;
private const CONST_D = 4;
}
$obj = new ReflectionClass("ConstDemo");
foreach ($obj->getReflectionConstants() as $const) {
var_dump($const); // ReflectionClassConstant
var_dump($const->getName());
var_dump($const->getValue());
var_dump($const->isPublic());
var_dump($const->isPrivate());
var_dump($const->isProtected());
}
More info: ReflectionClassConstant
try {
// Some code...
} catch (ExceptionA | ExceptionB $e) {
// Handle exceptions A or B
} catch (\Exception $e) {
// ...
}
var_dump("abcdef"[-2]); // string(1) "e"
var_dump("abcdef"[-7]); // string(0) "", PHP Notice
// 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, 'privF']);
}
private function privF($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 . $tag
$decrypt = openssl_decrypt(
$ciphertext,
$algo,
$key,
OPENSSL_RAW_DATA,
$iv,
$tag
);
if (false === $decrypt) {
throw new Exception(openssl_error_string());
}
echo $data === $decrypt ? 'Ok' : 'Failure';
$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"
GA: Nov 30 2017
Rate this talk at https://joind.in/talk/f8f7e
Contact me: enrico [at] zend.com
Follow me: @ezimuel