PHP Language Trivia

PHP Language Trivia
Nikita Popov
(nikic)
Object properties
Object properties
Name mangling
class Test {
public $pub = 1;
protected $prot = 2;
private $priv = 3;
}
$obj = new Test;
$arr = (array) $obj;
var_dump($arr);
class Test {
public $pub = 1;
protected $prot = 2;
private $priv = 3;
}
$obj = new Test;
$arr = (array) $obj;
var_dump($arr);
array(3) {
["pub"]=>
int(1)
["*prot"]=>
int(2)
["Testpriv"]=>
int(3)
}
class Test {
public $pub = 1;
protected $prot = 2;
private $priv = 3;
}
$obj = new Test;
$arr = (array) $obj;
var_dump($arr);
var_dump($arr["*prot"]);
// Notice: Undefined index: *prot
array(3) {
["pub"]=>
int(1)
["*prot"]=>
int(2)
["Testpriv"]=>
int(3)
}
class Test {
public $pub = 1;
protected $prot = 2;
private $priv = 3;
}
$obj = new Test;
$arr = (array) $obj;
var_dump($arr);
var_dump($arr["0*0prot"]);
// int(2)
array(3) {
["pub"]=>
int(1)
["0*0prot"]=>
int(2)
["0Test0priv"]=>
int(3)
}
Why name mangling?
class A {
private $prop = 'A';
public function getPropA() { return $this->prop; }
}
class B extends A {
protected $prop = 'B';
public function getPropB() { return $this->prop; }
}
class C extends B {
public $prop = 'C';
public function getPropC() { return $this->prop; }
}
$obj = new C;
var_dump($obj->getPropA()); // string(1) "A"
var_dump($obj->getPropB()); // string(1) "C"
var_dump($obj->getPropC()); // string(1) "C"
class A {
private $prop = 'A';
public function getPropA() { return $this->prop; }
}
class B extends A {
protected $prop = 'B';
public function getPropB() { return $this->prop; }
}
class C extends B {
public $prop = 'C';
public function getPropC() { return $this->prop; }
}
$obj = new C;
var_dump($obj->getPropA()); // string(1) "A"
var_dump($obj->getPropB()); // string(1) "C"
var_dump($obj->getPropC()); // string(1) "C"
Refer to same property
class A {
private $prop = 'A';
public function getPropA() { return $this->prop; }
}
class B extends A {
protected $prop = 'B';
public function getPropB() { return $this->prop; }
}
class C extends B {
public $prop = 'C';
public function getPropC() { return $this->prop; }
}
$obj = new C;
var_dump($obj->getPropA()); // string(1) "A"
var_dump($obj->getPropB()); // string(1) "C"
var_dump($obj->getPropC()); // string(1) "C"
Refer to same property
Private property is independent
class A {
private $prop = 'A';
public function getPropA() { return $this->prop; }
}
class B extends A {
protected $prop = 'B';
public function getPropB() { return $this->prop; }
}
class C extends B {
public $prop = 'C';
public function getPropC() { return $this->prop; }
}
$obj = new C;
var_dump((array) $obj);
Refer to same property
Private property is independent
class A {
private $prop = 'A';
public function getPropA() { return $this->prop; }
}
class B extends A {
protected $prop = 'B';
public function getPropB() { return $this->prop; }
}
class C extends B {
public $prop = 'C';
public function getPropC() { return $this->prop; }
}
$obj = new C;
var_dump((array) $obj);
array(2) {
["0A0prop"]=> string(1) "A"
["prop"]=> string(1) "C"
}
Refer to same property
Private property is independent
Object can have multiple properties
with same name
Name mangling ensures
unique property names
No reason to expose this internal detail …
No reason to expose this internal detail …
… but libraries rely on it now
to access private properties
Object properties
Integer property names
$array = [];
$array[123] = "foo";
$array["123"] = "bar";
var_dump($array);
array(1) {
[123]=>
string(3) "bar"
}
$array = [];
$array[123] = "foo";
$array["123"] = "bar";
var_dump($array);
array(1) {
[123]=>
string(3) "bar"
}
$object = new stdClass;
$object->{123} = "foo";
$object->{"123"} = "bar";
var_dump($object);
object(stdClass)#1 (1) {
["123"]=>
string(3) "bar"
}
$array = [];
$array[123] = "foo";
$array["123"] = "bar";
var_dump($array);
array(1) {
[123]=>
string(3) "bar"
}
$object = new stdClass;
$object->{123} = "foo";
$object->{"123"} = "bar";
var_dump($object);
object(stdClass)#1 (1) {
["123"]=>
string(3) "bar"
}
Normalize to int Normalize to string
$array = [];
$array[123] = "foo";
$array["123"] = "bar";
var_dump($array);
array(1) {
[123]=>
string(3) "bar"
}
$object = new stdClass;
$object->{123} = "foo";
$object->{"123"} = "bar";
var_dump($object);
object(stdClass)#1 (1) {
["123"]=>
string(3) "bar"
}
Normalize to int Normalize to string
What happens if we mix both?
$array = [123 => "foo"];
$object = (object) $array;
var_dump($object->{123});
// Notice: Undefined property: stdClass::$123
var_dump($object->{"123"});
// Notice: Undefined property: stdClass::$123
$array = [123 => "foo"];
$object = (object) $array;
var_dump($object->{123});
// Notice: Undefined property: stdClass::$123
var_dump($object->{"123"});
// Notice: Undefined property: stdClass::$123
var_dump($object);
object(stdClass)#1 (1) {
[123]=>
string(3) "foo"
}
$array = [123 => "foo"];
$object = (object) $array;
var_dump($object->{123});
// Notice: Undefined property: stdClass::$123
var_dump($object->{"123"});
// Notice: Undefined property: stdClass::$123
var_dump($object);
object(stdClass)#1 (1) {
[123]=>
string(3) "foo"
}
Unnormalized integer property name
$object = new stdClass;
$object->{123} = "foo";
$array = (array) $object;
var_dump($array[123]);
// Notice: Undefined offset: 123
var_dump($array["123"]);
// Notice: Undefined offset: 123
$object = new stdClass;
$object->{123} = "foo";
$array = (array) $object;
var_dump($array[123]);
// Notice: Undefined offset: 123
var_dump($array["123"]);
// Notice: Undefined offset: 123
var_dump($array);
array(1) {
["123"]=>
string(3) "foo"
}
Unnormalized integral string key
Fixed in PHP 7.2!
Now integer keys are renormalized
on array->object and object->array casts
$array = [123 => "foo"];
$object = (object) $array;
var_dump($object->{123});
string(3) "foo"
$object = new stdClass;
$object->{123} = "foo";
$array = (array) $object;
var_dump($array[123]);
string(3) "foo"
Object properties
Memory usage
$array = [
"key1" => 1,
"key2" => 2,
// ...
];
class Value {
public $key1;
public $key2;
}
$object = new Value;
$object->key1 = 1;
$object->key2 = 2;
vs.
0
100
200
300
400
500
600
700
800
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
Memoryusage(bytes)
Number of properties/keys
Array Array (real) Object Object (real)
0
1
2
3
4
5
6
7
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
Arraysize/objectsize
Number of properties/keys
Ratio Ratio (real)
Optimized for different usecases
Objects: Good for fixed set of keys
Arrays: Good for dynamic set of keys
Class entry
Property 0
Property 1
…
Object
Class entry
Property 0
Property 1
…
Object
Contains [property name => property offset] map
Class entry
Properties array
Property 0
Property 1
…
Object
Contains [property name => property offset] map
[property name => property value] map,
used if there are dynamic properties
Class entry
Properties array
Property 0
Property 1
…
Object
Contains [property name => property offset] map
[property name => property value] map,
used if there are dynamic properties
Arrays:
• Store keys (and hashes) explicitly
• Always have power of two size (8, 16, …)
for faster insertions
class Value {
public $x;
}
$obj = new Value;
// $obj size: 56 bytes
foreach ($obj as $k => $v) { }
// $obj size: 432 bytes
class Value {
public $x;
}
$obj = new Value;
// $obj size: 56 bytes
foreach ($obj as $k => $v) { }
// $obj size: 432 bytes
Forces creation of properties array
class Value {
public $x;
}
$obj = new Value;
// $obj size: 56 bytes
foreach ($obj as $k => $v) { }
// $obj size: 432 bytes
Forces creation of properties array
… no way to get rid of it afterwards
// PhpParser node iteration
$names = $node->getSubNodeNames();
foreach ($names as $name) {
$value = $node->$name;
}
// PhpParser node iteration
$names = $node->getSubNodeNames();
foreach ($names as $name) {
$value = $node->$name;
}
Dynamic lookup is slow, but this
avoids large memory usage increase
Object properties
Magic get & set
Direct property access baseline
getProperty() method 2.2x slower
__get() magic 6.0x slower
Direct property access baseline
getProperty() method 2.2x slower
__get() magic 6.0x slower
Userland  internal  userland is slow
class Test {
public function __get($name) {
return $this->$name;
}
}
class Test {
public function __get($name) {
return $this->$name;
}
} Does not recurse into __get()
Will access property directly
class Test {
public function __get($name) {
return $this->$name;
}
} Does not recurse into __get()
Will access property directly
Recursion guards are property name + accessor type specific
class Test {
public function __get($name) {
return $this->$name;
}
} Does not recurse into __get()
Will access property directly
Recursion guards are property name + accessor type specific
In __get("foo"):
• $this->foo will access property
• $this->bar will call __get("bar")
• $this->foo = 42 will call __set("foo", 42)
__get("foo")
__get("bar")
__set("bar", 42)
Recursion guards:
[
"foo" => GET,
"bar" => GET|SET,
]
__get("foo")
__get("bar")
[
"foo" => GET,
"bar" => GET,
]
Recursion guards:
__get("foo")
[
"foo" => GET,
"bar" => 0,
]
Recursion guards:
[
"foo" => 0,
"bar" => 0,
]
Recursion guards:
[
"foo" => 0,
"bar" => 0,
]
Recursion guards:
Never cleaned up
[
"foo" => 0,
"bar" => 0,
]
Recursion guards:
Never cleaned up
PHP 7.1: Recursion guard array not used if
magic accessors used only for one property at a time
Object properties
Unset properties
class Test {
public $prop;
}
$obj = new Test;
unset($obj->prop);
var_dump($obj->prop);
// Notice: Undefined property: Test::$prop
class Test {
public $prop;
}
$obj = new Test;
unset($obj->prop);
var_dump($obj->prop);
// Notice: Undefined property: Test::$prop
Once unset, __get() will be called on access
-> Lazy initialization
class Test {
public $prop;
public function __construct() {
unset($this->prop);
}
public function __get($name) {
echo "__get($name)n";
$this->$name = "init";
return $this->$name;
}
}
$obj = new Test;
var_dump($obj->prop);
var_dump($obj->prop);
class Test {
public $prop;
public function __construct() {
unset($this->prop);
}
public function __get($name) {
echo "__get($name)n";
$this->$name = "init";
return $this->$name;
}
}
$obj = new Test;
var_dump($obj->prop);
var_dump($obj->prop);
Calls __get()
Does not call __get()
Scoped calls
Foo::bar()
Static method call … or is it?
class A {
public function method() {
/* ... */
}
}
class B extends A {
public function method() {
parent::method();
/* ... */
}
}
class A {
public function method() {
/* ... */
}
}
class B extends A {
public function method() {
A::method();
/* ... */
}
}
class A {
public function method() {
/* ... */
}
}
class B extends A {
public function method() {
A::method();
/* ... */
}
}
Scoped instance call:
Call A::method() with current $this
class A {
public function method() { /* ... */ }
}
class B extends A {
public function method() { /* ... */ }
}
class C extends B {
public function method() {
A::method();
/* ... */
}
}
Can also call grandparent method
class A {
public function method() {
echo 'A::method with $this=' . get_class($this) . "n";
}
}
class B /* does not extend A */ {
public function method() {
A::method();
}
}
(new B)->method();
class A {
public function method() {
echo 'A::method with $this=' . get_class($this) . "n";
}
}
class B /* does not extend A */ {
public function method() {
A::method();
}
}
(new B)->method();
// PHP 5: A::method with $this=B (+ deprecation)
class A {
public function method() {
echo 'A::method with $this=' . get_class($this) . "n";
}
}
class B /* does not extend A */ {
public function method() {
A::method();
}
}
(new B)->method();
// PHP 5: A::method with $this=B (+ deprecation)
// PHP 7.0: Undefined variable: this
// PHP 7.1: Error: Using $this when not in object context
class Test {
public function __call($name, $args) {
echo "__call($name)n";
}
public static function __callStatic($name, $args) {
echo "__callStatic($name)n";
}
public function doCall() {
Test::foobar();
}
}
Test::foobar();
(new Test)->doCall();
class Test {
public function __call($name, $args) {
echo "__call($name)n";
}
public static function __callStatic($name, $args) {
echo "__callStatic($name)n";
}
public function doCall() {
Test::foobar();
}
}
Test::foobar(); // __callStatic(foobar)
(new Test)->doCall();
class Test {
public function __call($name, $args) {
echo "__call($name)n";
}
public static function __callStatic($name, $args) {
echo "__callStatic($name)n";
}
public function doCall() {
Test::foobar(); // __call(foobar)
}
}
Test::foobar(); // __callStatic(foobar)
(new Test)->doCall();
Static Closures
class Test {
public function __construct() {
$this->fn = function() {
/* $this can be used here */
};
}
}
class Test {
public function __construct() {
$this->fn = static function() {
/* $this CANNOT be used here */
};
}
}
class Test {
public function __construct() {
$this->fn = static function() {
/* $this CANNOT be used here */
};
}
} Without static:
• Closure references $this
• $this->fn references Closure
class Test {
public function __construct() {
$this->fn = static function() {
/* $this CANNOT be used here */
};
}
} Without static:
• Closure references $this
• $this->fn references Closure
 Cycle causes delayed GC
1 of 77

Recommended

PHP 7 – What changed internally? (Forum PHP 2015) by
PHP 7 – What changed internally? (Forum PHP 2015)PHP 7 – What changed internally? (Forum PHP 2015)
PHP 7 – What changed internally? (Forum PHP 2015)Nikita Popov
7.5K views83 slides
Static Optimization of PHP bytecode (PHPSC 2017) by
Static Optimization of PHP bytecode (PHPSC 2017)Static Optimization of PHP bytecode (PHPSC 2017)
Static Optimization of PHP bytecode (PHPSC 2017)Nikita Popov
7.8K views74 slides
Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016) by
Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)
Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)James Titcumb
425 views88 slides
PHP 7 – What changed internally? by
PHP 7 – What changed internally?PHP 7 – What changed internally?
PHP 7 – What changed internally?Nikita Popov
13.2K views122 slides
Electrify your code with PHP Generators by
Electrify your code with PHP GeneratorsElectrify your code with PHP Generators
Electrify your code with PHP GeneratorsMark Baker
3.7K views49 slides
Typed Properties and more: What's coming in PHP 7.4? by
Typed Properties and more: What's coming in PHP 7.4?Typed Properties and more: What's coming in PHP 7.4?
Typed Properties and more: What's coming in PHP 7.4?Nikita Popov
10.8K views63 slides

More Related Content

What's hot

Jsphp 110312161301-phpapp02 by
Jsphp 110312161301-phpapp02Jsphp 110312161301-phpapp02
Jsphp 110312161301-phpapp02Seri Moth
514 views87 slides
PHP Performance Trivia by
PHP Performance TriviaPHP Performance Trivia
PHP Performance TriviaNikita Popov
6.7K views66 slides
A Functional Guide to Cat Herding with PHP Generators by
A Functional Guide to Cat Herding with PHP GeneratorsA Functional Guide to Cat Herding with PHP Generators
A Functional Guide to Cat Herding with PHP GeneratorsMark Baker
993 views49 slides
Looping the Loop with SPL Iterators by
Looping the Loop with SPL IteratorsLooping the Loop with SPL Iterators
Looping the Loop with SPL IteratorsMark Baker
240 views142 slides
PHPCon 2016: PHP7 by Witek Adamus / XSolve by
PHPCon 2016: PHP7 by Witek Adamus / XSolvePHPCon 2016: PHP7 by Witek Adamus / XSolve
PHPCon 2016: PHP7 by Witek Adamus / XSolveXSolve
1K views141 slides
Being functional in PHP (DPC 2016) by
Being functional in PHP (DPC 2016)Being functional in PHP (DPC 2016)
Being functional in PHP (DPC 2016)David de Boer
528 views71 slides

What's hot(20)

Jsphp 110312161301-phpapp02 by Seri Moth
Jsphp 110312161301-phpapp02Jsphp 110312161301-phpapp02
Jsphp 110312161301-phpapp02
Seri Moth514 views
PHP Performance Trivia by Nikita Popov
PHP Performance TriviaPHP Performance Trivia
PHP Performance Trivia
Nikita Popov6.7K views
A Functional Guide to Cat Herding with PHP Generators by Mark Baker
A Functional Guide to Cat Herding with PHP GeneratorsA Functional Guide to Cat Herding with PHP Generators
A Functional Guide to Cat Herding with PHP Generators
Mark Baker993 views
Looping the Loop with SPL Iterators by Mark Baker
Looping the Loop with SPL IteratorsLooping the Loop with SPL Iterators
Looping the Loop with SPL Iterators
Mark Baker240 views
PHPCon 2016: PHP7 by Witek Adamus / XSolve by XSolve
PHPCon 2016: PHP7 by Witek Adamus / XSolvePHPCon 2016: PHP7 by Witek Adamus / XSolve
PHPCon 2016: PHP7 by Witek Adamus / XSolve
XSolve1K views
Being functional in PHP (DPC 2016) by David de Boer
Being functional in PHP (DPC 2016)Being functional in PHP (DPC 2016)
Being functional in PHP (DPC 2016)
David de Boer528 views
You code sucks, let's fix it by Rafael Dohms
You code sucks, let's fix itYou code sucks, let's fix it
You code sucks, let's fix it
Rafael Dohms56.4K views
Doctrine MongoDB ODM (PDXPHP) by Kris Wallsmith
Doctrine MongoDB ODM (PDXPHP)Doctrine MongoDB ODM (PDXPHP)
Doctrine MongoDB ODM (PDXPHP)
Kris Wallsmith2.1K views
PHP data structures (and the impact of php 7 on them), phpDay Verona 2015, Italy by Patrick Allaert
PHP data structures (and the impact of php 7 on them), phpDay Verona 2015, ItalyPHP data structures (and the impact of php 7 on them), phpDay Verona 2015, Italy
PHP data structures (and the impact of php 7 on them), phpDay Verona 2015, Italy
Patrick Allaert20.8K views
PHP for Adults: Clean Code and Object Calisthenics by Guilherme Blanco
PHP for Adults: Clean Code and Object CalisthenicsPHP for Adults: Clean Code and Object Calisthenics
PHP for Adults: Clean Code and Object Calisthenics
Guilherme Blanco2.8K views
Object Calisthenics Applied to PHP by Guilherme Blanco
Object Calisthenics Applied to PHPObject Calisthenics Applied to PHP
Object Calisthenics Applied to PHP
Guilherme Blanco22.5K views
Your code sucks, let's fix it by Rafael Dohms
Your code sucks, let's fix itYour code sucks, let's fix it
Your code sucks, let's fix it
Rafael Dohms36.3K views
Introdução ao Perl 6 by garux
Introdução ao Perl 6Introdução ao Perl 6
Introdução ao Perl 6
garux1.8K views
"How was it to switch from beautiful Perl to horrible JavaScript", Viktor Tur... by Fwdays
"How was it to switch from beautiful Perl to horrible JavaScript", Viktor Tur..."How was it to switch from beautiful Perl to horrible JavaScript", Viktor Tur...
"How was it to switch from beautiful Perl to horrible JavaScript", Viktor Tur...
Fwdays234 views
Corephpcomponentpresentation 1211425966721657-8 by PrinceGuru MS
Corephpcomponentpresentation 1211425966721657-8Corephpcomponentpresentation 1211425966721657-8
Corephpcomponentpresentation 1211425966721657-8
PrinceGuru MS491 views
Functional Pe(a)rls version 2 by osfameron
Functional Pe(a)rls version 2Functional Pe(a)rls version 2
Functional Pe(a)rls version 2
osfameron799 views
(Parameterized) Roles by sartak
(Parameterized) Roles(Parameterized) Roles
(Parameterized) Roles
sartak1.2K views
The Origin of Lithium by Nate Abele
The Origin of LithiumThe Origin of Lithium
The Origin of Lithium
Nate Abele8.4K views

Similar to PHP Language Trivia

Crazy things done on PHP by
Crazy things done on PHPCrazy things done on PHP
Crazy things done on PHPTaras Kalapun
14K views33 slides
JavaScript for PHP developers by
JavaScript for PHP developersJavaScript for PHP developers
JavaScript for PHP developersStoyan Stefanov
15.6K views84 slides
Intermediate PHP by
Intermediate PHPIntermediate PHP
Intermediate PHPBradley Holt
2.5K views78 slides
Oops in php by
Oops in phpOops in php
Oops in phpGourishankar R Pujar
789 views52 slides
Mirror, mirror on the wall - Building a new PHP reflection library (Nomad PHP... by
Mirror, mirror on the wall - Building a new PHP reflection library (Nomad PHP...Mirror, mirror on the wall - Building a new PHP reflection library (Nomad PHP...
Mirror, mirror on the wall - Building a new PHP reflection library (Nomad PHP...James Titcumb
265 views89 slides

Similar to PHP Language Trivia(20)

Crazy things done on PHP by Taras Kalapun
Crazy things done on PHPCrazy things done on PHP
Crazy things done on PHP
Taras Kalapun14K views
JavaScript for PHP developers by Stoyan Stefanov
JavaScript for PHP developersJavaScript for PHP developers
JavaScript for PHP developers
Stoyan Stefanov15.6K views
Mirror, mirror on the wall - Building a new PHP reflection library (Nomad PHP... by James Titcumb
Mirror, mirror on the wall - Building a new PHP reflection library (Nomad PHP...Mirror, mirror on the wall - Building a new PHP reflection library (Nomad PHP...
Mirror, mirror on the wall - Building a new PHP reflection library (Nomad PHP...
James Titcumb265 views
Revisiting SOLID Principles by Anis Ahmad
Revisiting  SOLID Principles Revisiting  SOLID Principles
Revisiting SOLID Principles
Anis Ahmad72 views
Introducing CakeEntity by Basuke Suzuki
Introducing CakeEntityIntroducing CakeEntity
Introducing CakeEntity
Basuke Suzuki1.9K views
The History of PHPersistence by Hugo Hamon
The History of PHPersistenceThe History of PHPersistence
The History of PHPersistence
Hugo Hamon2.3K views
Adding Dependency Injection to Legacy Applications by Sam Hennessy
Adding Dependency Injection to Legacy ApplicationsAdding Dependency Injection to Legacy Applications
Adding Dependency Injection to Legacy Applications
Sam Hennessy1.8K views
Switching from java to groovy by Paul Woods
Switching from java to groovySwitching from java to groovy
Switching from java to groovy
Paul Woods895 views
SPL: The Missing Link in Development by jsmith92
SPL: The Missing Link in DevelopmentSPL: The Missing Link in Development
SPL: The Missing Link in Development
jsmith92733 views
Groovy grails types, operators, objects by Husain Dalal
Groovy grails types, operators, objectsGroovy grails types, operators, objects
Groovy grails types, operators, objects
Husain Dalal458 views
Kotlin Advanced - Apalon Kotlin Sprint Part 3 by Kirill Rozov
Kotlin Advanced - Apalon Kotlin Sprint Part 3Kotlin Advanced - Apalon Kotlin Sprint Part 3
Kotlin Advanced - Apalon Kotlin Sprint Part 3
Kirill Rozov328 views
Document Classification In PHP by Ian Barber
Document Classification In PHPDocument Classification In PHP
Document Classification In PHP
Ian Barber10.2K views
Google Guava - Core libraries for Java & Android by Jordi Gerona
Google Guava - Core libraries for Java & AndroidGoogle Guava - Core libraries for Java & Android
Google Guava - Core libraries for Java & Android
Jordi Gerona11.5K views
PhpUnit - The most unknown Parts by Bastian Feder
PhpUnit - The most unknown PartsPhpUnit - The most unknown Parts
PhpUnit - The most unknown Parts
Bastian Feder4.3K views

More from Nikita Popov

A whirlwind tour of the LLVM optimizer by
A whirlwind tour of the LLVM optimizerA whirlwind tour of the LLVM optimizer
A whirlwind tour of the LLVM optimizerNikita Popov
7.4K views109 slides
Opaque Pointers Are Coming by
Opaque Pointers Are ComingOpaque Pointers Are Coming
Opaque Pointers Are ComingNikita Popov
962 views69 slides
What's new in PHP 8.0? by
What's new in PHP 8.0?What's new in PHP 8.0?
What's new in PHP 8.0?Nikita Popov
3.2K views79 slides
Just-In-Time Compiler in PHP 8 by
Just-In-Time Compiler in PHP 8Just-In-Time Compiler in PHP 8
Just-In-Time Compiler in PHP 8Nikita Popov
1.6K views80 slides
What's new in PHP 8.0? by
What's new in PHP 8.0?What's new in PHP 8.0?
What's new in PHP 8.0?Nikita Popov
10K views73 slides
PHP 7 – What changed internally? (PHP Barcelona 2015) by
PHP 7 – What changed internally? (PHP Barcelona 2015)PHP 7 – What changed internally? (PHP Barcelona 2015)
PHP 7 – What changed internally? (PHP Barcelona 2015)Nikita Popov
12.2K views88 slides

More from Nikita Popov(6)

A whirlwind tour of the LLVM optimizer by Nikita Popov
A whirlwind tour of the LLVM optimizerA whirlwind tour of the LLVM optimizer
A whirlwind tour of the LLVM optimizer
Nikita Popov7.4K views
Opaque Pointers Are Coming by Nikita Popov
Opaque Pointers Are ComingOpaque Pointers Are Coming
Opaque Pointers Are Coming
Nikita Popov962 views
What's new in PHP 8.0? by Nikita Popov
What's new in PHP 8.0?What's new in PHP 8.0?
What's new in PHP 8.0?
Nikita Popov3.2K views
Just-In-Time Compiler in PHP 8 by Nikita Popov
Just-In-Time Compiler in PHP 8Just-In-Time Compiler in PHP 8
Just-In-Time Compiler in PHP 8
Nikita Popov1.6K views
What's new in PHP 8.0? by Nikita Popov
What's new in PHP 8.0?What's new in PHP 8.0?
What's new in PHP 8.0?
Nikita Popov10K views
PHP 7 – What changed internally? (PHP Barcelona 2015) by Nikita Popov
PHP 7 – What changed internally? (PHP Barcelona 2015)PHP 7 – What changed internally? (PHP Barcelona 2015)
PHP 7 – What changed internally? (PHP Barcelona 2015)
Nikita Popov12.2K views

Recently uploaded

2FA and OAuth2 in CloudStack - Andrija Panić - ShapeBlue by
2FA and OAuth2 in CloudStack - Andrija Panić - ShapeBlue2FA and OAuth2 in CloudStack - Andrija Panić - ShapeBlue
2FA and OAuth2 in CloudStack - Andrija Panić - ShapeBlueShapeBlue
103 views23 slides
GDG Cloud Southlake 28 Brad Taylor and Shawn Augenstein Old Problems in the N... by
GDG Cloud Southlake 28 Brad Taylor and Shawn Augenstein Old Problems in the N...GDG Cloud Southlake 28 Brad Taylor and Shawn Augenstein Old Problems in the N...
GDG Cloud Southlake 28 Brad Taylor and Shawn Augenstein Old Problems in the N...James Anderson
156 views32 slides
Business Analyst Series 2023 - Week 4 Session 7 by
Business Analyst Series 2023 -  Week 4 Session 7Business Analyst Series 2023 -  Week 4 Session 7
Business Analyst Series 2023 - Week 4 Session 7DianaGray10
126 views31 slides
CloudStack Object Storage - An Introduction - Vladimir Petrov - ShapeBlue by
CloudStack Object Storage - An Introduction - Vladimir Petrov - ShapeBlueCloudStack Object Storage - An Introduction - Vladimir Petrov - ShapeBlue
CloudStack Object Storage - An Introduction - Vladimir Petrov - ShapeBlueShapeBlue
93 views15 slides
Microsoft Power Platform.pptx by
Microsoft Power Platform.pptxMicrosoft Power Platform.pptx
Microsoft Power Platform.pptxUni Systems S.M.S.A.
80 views38 slides
State of the Union - Rohit Yadav - Apache CloudStack by
State of the Union - Rohit Yadav - Apache CloudStackState of the Union - Rohit Yadav - Apache CloudStack
State of the Union - Rohit Yadav - Apache CloudStackShapeBlue
253 views53 slides

Recently uploaded(20)

2FA and OAuth2 in CloudStack - Andrija Panić - ShapeBlue by ShapeBlue
2FA and OAuth2 in CloudStack - Andrija Panić - ShapeBlue2FA and OAuth2 in CloudStack - Andrija Panić - ShapeBlue
2FA and OAuth2 in CloudStack - Andrija Panić - ShapeBlue
ShapeBlue103 views
GDG Cloud Southlake 28 Brad Taylor and Shawn Augenstein Old Problems in the N... by James Anderson
GDG Cloud Southlake 28 Brad Taylor and Shawn Augenstein Old Problems in the N...GDG Cloud Southlake 28 Brad Taylor and Shawn Augenstein Old Problems in the N...
GDG Cloud Southlake 28 Brad Taylor and Shawn Augenstein Old Problems in the N...
James Anderson156 views
Business Analyst Series 2023 - Week 4 Session 7 by DianaGray10
Business Analyst Series 2023 -  Week 4 Session 7Business Analyst Series 2023 -  Week 4 Session 7
Business Analyst Series 2023 - Week 4 Session 7
DianaGray10126 views
CloudStack Object Storage - An Introduction - Vladimir Petrov - ShapeBlue by ShapeBlue
CloudStack Object Storage - An Introduction - Vladimir Petrov - ShapeBlueCloudStack Object Storage - An Introduction - Vladimir Petrov - ShapeBlue
CloudStack Object Storage - An Introduction - Vladimir Petrov - ShapeBlue
ShapeBlue93 views
State of the Union - Rohit Yadav - Apache CloudStack by ShapeBlue
State of the Union - Rohit Yadav - Apache CloudStackState of the Union - Rohit Yadav - Apache CloudStack
State of the Union - Rohit Yadav - Apache CloudStack
ShapeBlue253 views
DRBD Deep Dive - Philipp Reisner - LINBIT by ShapeBlue
DRBD Deep Dive - Philipp Reisner - LINBITDRBD Deep Dive - Philipp Reisner - LINBIT
DRBD Deep Dive - Philipp Reisner - LINBIT
ShapeBlue140 views
Centralized Logging Feature in CloudStack using ELK and Grafana - Kiran Chava... by ShapeBlue
Centralized Logging Feature in CloudStack using ELK and Grafana - Kiran Chava...Centralized Logging Feature in CloudStack using ELK and Grafana - Kiran Chava...
Centralized Logging Feature in CloudStack using ELK and Grafana - Kiran Chava...
ShapeBlue101 views
The Power of Heat Decarbonisation Plans in the Built Environment by IES VE
The Power of Heat Decarbonisation Plans in the Built EnvironmentThe Power of Heat Decarbonisation Plans in the Built Environment
The Power of Heat Decarbonisation Plans in the Built Environment
IES VE69 views
VNF Integration and Support in CloudStack - Wei Zhou - ShapeBlue by ShapeBlue
VNF Integration and Support in CloudStack - Wei Zhou - ShapeBlueVNF Integration and Support in CloudStack - Wei Zhou - ShapeBlue
VNF Integration and Support in CloudStack - Wei Zhou - ShapeBlue
ShapeBlue163 views
Confidence in CloudStack - Aron Wagner, Nathan Gleason - Americ by ShapeBlue
Confidence in CloudStack - Aron Wagner, Nathan Gleason - AmericConfidence in CloudStack - Aron Wagner, Nathan Gleason - Americ
Confidence in CloudStack - Aron Wagner, Nathan Gleason - Americ
ShapeBlue88 views
Updates on the LINSTOR Driver for CloudStack - Rene Peinthor - LINBIT by ShapeBlue
Updates on the LINSTOR Driver for CloudStack - Rene Peinthor - LINBITUpdates on the LINSTOR Driver for CloudStack - Rene Peinthor - LINBIT
Updates on the LINSTOR Driver for CloudStack - Rene Peinthor - LINBIT
ShapeBlue166 views
KVM Security Groups Under the Hood - Wido den Hollander - Your.Online by ShapeBlue
KVM Security Groups Under the Hood - Wido den Hollander - Your.OnlineKVM Security Groups Under the Hood - Wido den Hollander - Your.Online
KVM Security Groups Under the Hood - Wido den Hollander - Your.Online
ShapeBlue181 views
Keynote Talk: Open Source is Not Dead - Charles Schulz - Vates by ShapeBlue
Keynote Talk: Open Source is Not Dead - Charles Schulz - VatesKeynote Talk: Open Source is Not Dead - Charles Schulz - Vates
Keynote Talk: Open Source is Not Dead - Charles Schulz - Vates
ShapeBlue210 views
Extending KVM Host HA for Non-NFS Storage - Alex Ivanov - StorPool by ShapeBlue
Extending KVM Host HA for Non-NFS Storage -  Alex Ivanov - StorPoolExtending KVM Host HA for Non-NFS Storage -  Alex Ivanov - StorPool
Extending KVM Host HA for Non-NFS Storage - Alex Ivanov - StorPool
ShapeBlue84 views
Automating a World-Class Technology Conference; Behind the Scenes of CiscoLive by Network Automation Forum
Automating a World-Class Technology Conference; Behind the Scenes of CiscoLiveAutomating a World-Class Technology Conference; Behind the Scenes of CiscoLive
Automating a World-Class Technology Conference; Behind the Scenes of CiscoLive
Digital Personal Data Protection (DPDP) Practical Approach For CISOs by Priyanka Aash
Digital Personal Data Protection (DPDP) Practical Approach For CISOsDigital Personal Data Protection (DPDP) Practical Approach For CISOs
Digital Personal Data Protection (DPDP) Practical Approach For CISOs
Priyanka Aash153 views
Live Demo Showcase: Unveiling Dell PowerFlex’s IaaS Capabilities with Apache ... by ShapeBlue
Live Demo Showcase: Unveiling Dell PowerFlex’s IaaS Capabilities with Apache ...Live Demo Showcase: Unveiling Dell PowerFlex’s IaaS Capabilities with Apache ...
Live Demo Showcase: Unveiling Dell PowerFlex’s IaaS Capabilities with Apache ...
ShapeBlue85 views
Mitigating Common CloudStack Instance Deployment Failures - Jithin Raju - Sha... by ShapeBlue
Mitigating Common CloudStack Instance Deployment Failures - Jithin Raju - Sha...Mitigating Common CloudStack Instance Deployment Failures - Jithin Raju - Sha...
Mitigating Common CloudStack Instance Deployment Failures - Jithin Raju - Sha...
ShapeBlue138 views

PHP Language Trivia

  • 4. class Test { public $pub = 1; protected $prot = 2; private $priv = 3; } $obj = new Test; $arr = (array) $obj; var_dump($arr);
  • 5. class Test { public $pub = 1; protected $prot = 2; private $priv = 3; } $obj = new Test; $arr = (array) $obj; var_dump($arr); array(3) { ["pub"]=> int(1) ["*prot"]=> int(2) ["Testpriv"]=> int(3) }
  • 6. class Test { public $pub = 1; protected $prot = 2; private $priv = 3; } $obj = new Test; $arr = (array) $obj; var_dump($arr); var_dump($arr["*prot"]); // Notice: Undefined index: *prot array(3) { ["pub"]=> int(1) ["*prot"]=> int(2) ["Testpriv"]=> int(3) }
  • 7. class Test { public $pub = 1; protected $prot = 2; private $priv = 3; } $obj = new Test; $arr = (array) $obj; var_dump($arr); var_dump($arr["0*0prot"]); // int(2) array(3) { ["pub"]=> int(1) ["0*0prot"]=> int(2) ["0Test0priv"]=> int(3) }
  • 9. class A { private $prop = 'A'; public function getPropA() { return $this->prop; } } class B extends A { protected $prop = 'B'; public function getPropB() { return $this->prop; } } class C extends B { public $prop = 'C'; public function getPropC() { return $this->prop; } } $obj = new C; var_dump($obj->getPropA()); // string(1) "A" var_dump($obj->getPropB()); // string(1) "C" var_dump($obj->getPropC()); // string(1) "C"
  • 10. class A { private $prop = 'A'; public function getPropA() { return $this->prop; } } class B extends A { protected $prop = 'B'; public function getPropB() { return $this->prop; } } class C extends B { public $prop = 'C'; public function getPropC() { return $this->prop; } } $obj = new C; var_dump($obj->getPropA()); // string(1) "A" var_dump($obj->getPropB()); // string(1) "C" var_dump($obj->getPropC()); // string(1) "C" Refer to same property
  • 11. class A { private $prop = 'A'; public function getPropA() { return $this->prop; } } class B extends A { protected $prop = 'B'; public function getPropB() { return $this->prop; } } class C extends B { public $prop = 'C'; public function getPropC() { return $this->prop; } } $obj = new C; var_dump($obj->getPropA()); // string(1) "A" var_dump($obj->getPropB()); // string(1) "C" var_dump($obj->getPropC()); // string(1) "C" Refer to same property Private property is independent
  • 12. class A { private $prop = 'A'; public function getPropA() { return $this->prop; } } class B extends A { protected $prop = 'B'; public function getPropB() { return $this->prop; } } class C extends B { public $prop = 'C'; public function getPropC() { return $this->prop; } } $obj = new C; var_dump((array) $obj); Refer to same property Private property is independent
  • 13. class A { private $prop = 'A'; public function getPropA() { return $this->prop; } } class B extends A { protected $prop = 'B'; public function getPropB() { return $this->prop; } } class C extends B { public $prop = 'C'; public function getPropC() { return $this->prop; } } $obj = new C; var_dump((array) $obj); array(2) { ["0A0prop"]=> string(1) "A" ["prop"]=> string(1) "C" } Refer to same property Private property is independent
  • 14. Object can have multiple properties with same name Name mangling ensures unique property names
  • 15. No reason to expose this internal detail …
  • 16. No reason to expose this internal detail … … but libraries rely on it now to access private properties
  • 18. $array = []; $array[123] = "foo"; $array["123"] = "bar"; var_dump($array); array(1) { [123]=> string(3) "bar" }
  • 19. $array = []; $array[123] = "foo"; $array["123"] = "bar"; var_dump($array); array(1) { [123]=> string(3) "bar" } $object = new stdClass; $object->{123} = "foo"; $object->{"123"} = "bar"; var_dump($object); object(stdClass)#1 (1) { ["123"]=> string(3) "bar" }
  • 20. $array = []; $array[123] = "foo"; $array["123"] = "bar"; var_dump($array); array(1) { [123]=> string(3) "bar" } $object = new stdClass; $object->{123} = "foo"; $object->{"123"} = "bar"; var_dump($object); object(stdClass)#1 (1) { ["123"]=> string(3) "bar" } Normalize to int Normalize to string
  • 21. $array = []; $array[123] = "foo"; $array["123"] = "bar"; var_dump($array); array(1) { [123]=> string(3) "bar" } $object = new stdClass; $object->{123} = "foo"; $object->{"123"} = "bar"; var_dump($object); object(stdClass)#1 (1) { ["123"]=> string(3) "bar" } Normalize to int Normalize to string What happens if we mix both?
  • 22. $array = [123 => "foo"]; $object = (object) $array; var_dump($object->{123}); // Notice: Undefined property: stdClass::$123 var_dump($object->{"123"}); // Notice: Undefined property: stdClass::$123
  • 23. $array = [123 => "foo"]; $object = (object) $array; var_dump($object->{123}); // Notice: Undefined property: stdClass::$123 var_dump($object->{"123"}); // Notice: Undefined property: stdClass::$123 var_dump($object); object(stdClass)#1 (1) { [123]=> string(3) "foo" }
  • 24. $array = [123 => "foo"]; $object = (object) $array; var_dump($object->{123}); // Notice: Undefined property: stdClass::$123 var_dump($object->{"123"}); // Notice: Undefined property: stdClass::$123 var_dump($object); object(stdClass)#1 (1) { [123]=> string(3) "foo" } Unnormalized integer property name
  • 25. $object = new stdClass; $object->{123} = "foo"; $array = (array) $object; var_dump($array[123]); // Notice: Undefined offset: 123 var_dump($array["123"]); // Notice: Undefined offset: 123
  • 26. $object = new stdClass; $object->{123} = "foo"; $array = (array) $object; var_dump($array[123]); // Notice: Undefined offset: 123 var_dump($array["123"]); // Notice: Undefined offset: 123 var_dump($array); array(1) { ["123"]=> string(3) "foo" } Unnormalized integral string key
  • 27. Fixed in PHP 7.2! Now integer keys are renormalized on array->object and object->array casts
  • 28. $array = [123 => "foo"]; $object = (object) $array; var_dump($object->{123}); string(3) "foo" $object = new stdClass; $object->{123} = "foo"; $array = (array) $object; var_dump($array[123]); string(3) "foo"
  • 30. $array = [ "key1" => 1, "key2" => 2, // ... ]; class Value { public $key1; public $key2; } $object = new Value; $object->key1 = 1; $object->key2 = 2; vs.
  • 31. 0 100 200 300 400 500 600 700 800 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 Memoryusage(bytes) Number of properties/keys Array Array (real) Object Object (real)
  • 32. 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 Arraysize/objectsize Number of properties/keys Ratio Ratio (real)
  • 33. Optimized for different usecases Objects: Good for fixed set of keys Arrays: Good for dynamic set of keys
  • 35. Class entry Property 0 Property 1 … Object Contains [property name => property offset] map
  • 36. Class entry Properties array Property 0 Property 1 … Object Contains [property name => property offset] map [property name => property value] map, used if there are dynamic properties
  • 37. Class entry Properties array Property 0 Property 1 … Object Contains [property name => property offset] map [property name => property value] map, used if there are dynamic properties Arrays: • Store keys (and hashes) explicitly • Always have power of two size (8, 16, …) for faster insertions
  • 38. class Value { public $x; } $obj = new Value; // $obj size: 56 bytes foreach ($obj as $k => $v) { } // $obj size: 432 bytes
  • 39. class Value { public $x; } $obj = new Value; // $obj size: 56 bytes foreach ($obj as $k => $v) { } // $obj size: 432 bytes Forces creation of properties array
  • 40. class Value { public $x; } $obj = new Value; // $obj size: 56 bytes foreach ($obj as $k => $v) { } // $obj size: 432 bytes Forces creation of properties array … no way to get rid of it afterwards
  • 41. // PhpParser node iteration $names = $node->getSubNodeNames(); foreach ($names as $name) { $value = $node->$name; }
  • 42. // PhpParser node iteration $names = $node->getSubNodeNames(); foreach ($names as $name) { $value = $node->$name; } Dynamic lookup is slow, but this avoids large memory usage increase
  • 44. Direct property access baseline getProperty() method 2.2x slower __get() magic 6.0x slower
  • 45. Direct property access baseline getProperty() method 2.2x slower __get() magic 6.0x slower Userland  internal  userland is slow
  • 46. class Test { public function __get($name) { return $this->$name; } }
  • 47. class Test { public function __get($name) { return $this->$name; } } Does not recurse into __get() Will access property directly
  • 48. class Test { public function __get($name) { return $this->$name; } } Does not recurse into __get() Will access property directly Recursion guards are property name + accessor type specific
  • 49. class Test { public function __get($name) { return $this->$name; } } Does not recurse into __get() Will access property directly Recursion guards are property name + accessor type specific In __get("foo"): • $this->foo will access property • $this->bar will call __get("bar") • $this->foo = 42 will call __set("foo", 42)
  • 51. __get("foo") __get("bar") [ "foo" => GET, "bar" => GET, ] Recursion guards:
  • 52. __get("foo") [ "foo" => GET, "bar" => 0, ] Recursion guards:
  • 53. [ "foo" => 0, "bar" => 0, ] Recursion guards:
  • 54. [ "foo" => 0, "bar" => 0, ] Recursion guards: Never cleaned up
  • 55. [ "foo" => 0, "bar" => 0, ] Recursion guards: Never cleaned up PHP 7.1: Recursion guard array not used if magic accessors used only for one property at a time
  • 57. class Test { public $prop; } $obj = new Test; unset($obj->prop); var_dump($obj->prop); // Notice: Undefined property: Test::$prop
  • 58. class Test { public $prop; } $obj = new Test; unset($obj->prop); var_dump($obj->prop); // Notice: Undefined property: Test::$prop Once unset, __get() will be called on access -> Lazy initialization
  • 59. class Test { public $prop; public function __construct() { unset($this->prop); } public function __get($name) { echo "__get($name)n"; $this->$name = "init"; return $this->$name; } } $obj = new Test; var_dump($obj->prop); var_dump($obj->prop);
  • 60. class Test { public $prop; public function __construct() { unset($this->prop); } public function __get($name) { echo "__get($name)n"; $this->$name = "init"; return $this->$name; } } $obj = new Test; var_dump($obj->prop); var_dump($obj->prop); Calls __get() Does not call __get()
  • 63. class A { public function method() { /* ... */ } } class B extends A { public function method() { parent::method(); /* ... */ } }
  • 64. class A { public function method() { /* ... */ } } class B extends A { public function method() { A::method(); /* ... */ } }
  • 65. class A { public function method() { /* ... */ } } class B extends A { public function method() { A::method(); /* ... */ } } Scoped instance call: Call A::method() with current $this
  • 66. class A { public function method() { /* ... */ } } class B extends A { public function method() { /* ... */ } } class C extends B { public function method() { A::method(); /* ... */ } } Can also call grandparent method
  • 67. class A { public function method() { echo 'A::method with $this=' . get_class($this) . "n"; } } class B /* does not extend A */ { public function method() { A::method(); } } (new B)->method();
  • 68. class A { public function method() { echo 'A::method with $this=' . get_class($this) . "n"; } } class B /* does not extend A */ { public function method() { A::method(); } } (new B)->method(); // PHP 5: A::method with $this=B (+ deprecation)
  • 69. class A { public function method() { echo 'A::method with $this=' . get_class($this) . "n"; } } class B /* does not extend A */ { public function method() { A::method(); } } (new B)->method(); // PHP 5: A::method with $this=B (+ deprecation) // PHP 7.0: Undefined variable: this // PHP 7.1: Error: Using $this when not in object context
  • 70. class Test { public function __call($name, $args) { echo "__call($name)n"; } public static function __callStatic($name, $args) { echo "__callStatic($name)n"; } public function doCall() { Test::foobar(); } } Test::foobar(); (new Test)->doCall();
  • 71. class Test { public function __call($name, $args) { echo "__call($name)n"; } public static function __callStatic($name, $args) { echo "__callStatic($name)n"; } public function doCall() { Test::foobar(); } } Test::foobar(); // __callStatic(foobar) (new Test)->doCall();
  • 72. class Test { public function __call($name, $args) { echo "__call($name)n"; } public static function __callStatic($name, $args) { echo "__callStatic($name)n"; } public function doCall() { Test::foobar(); // __call(foobar) } } Test::foobar(); // __callStatic(foobar) (new Test)->doCall();
  • 74. class Test { public function __construct() { $this->fn = function() { /* $this can be used here */ }; } }
  • 75. class Test { public function __construct() { $this->fn = static function() { /* $this CANNOT be used here */ }; } }
  • 76. class Test { public function __construct() { $this->fn = static function() { /* $this CANNOT be used here */ }; } } Without static: • Closure references $this • $this->fn references Closure
  • 77. class Test { public function __construct() { $this->fn = static function() { /* $this CANNOT be used here */ }; } } Without static: • Closure references $this • $this->fn references Closure  Cycle causes delayed GC