SlideShare a Scribd company logo
Understanding objects
PHP 5 objects internal design
Hello everybody
 Julien PAULI
 Programming in PHP since ~10y
 PHP Internals reviewer
 PHP 5.5 and 5.6 Release Manager or Co-RM
 Working at SensioLabs in Paris
 http://www.phpinternalsbook.com
 @julienpauli - github.com/jpauli - jpauli@php.net
What we'll cover together
 Covering PHP 5 only
 Quick recall on zvals
 Object structures internally
 zend_object_value
 zend_class_entry
 zend_object_handlers
 zend_object_store
 PHP objects lifecycle
 Creating and destroying an object
 Memory management & garbage collection
Zvals
Zvals
 PHP variables can carry several types
 PHP is not strongly typed
 Type juggling
 Internally, all variables are represented into a
container which can carry all supported PHP
types : "zval"
Zvals
zval management
 Classic management example :
 Reference counting management example :
zval *myval;
ALLOC_INIT_ZVAL(myval); // malloc()
ZVAL_STRINGL(myval, "foobar", sizeof("foobar")-1, 1);
/* use myval */
zval_ptr_dtor(&myval);
Z_ADDREF_P(myval);
Z_DELREF_P(myval);
Z_SET_ISREF_P(myval);
Z_UNSET_ISREF_P(myval);
zvals refcount
 Every PHP variable is a zval :
 PHP does not duplicate memory when you
duplicate variables in the same scope
 It plays with the refcount of the zval
 refcount is how many variables point to the zval
<?php
$o = new MyClass;
<?php
$o = new MyClass; // refcount = 1
$o2 = $o; // refcount = 2
zvals refcount
 The zval is automatically freed when refcount
reaches zero, and never before
 When a zval is freed, its content is freed if not
shared elsewhere
 In our case : an object
<?php
$o = new MyClass; // refcount = 1
$o2 = $o; // refcount = 2
unset($o); // refcount = 1, zval is not freed
unset($o2); // refcount = 0, zval is freed
Statement
 Objects are variables
 Variables are zvals
 Objects are not freed until their zval's refcount
reaches zero
PHP objects
PHP Objects ?
 Objects are zvals of type IS_OBJECT
 The value field used is "obj" in the zval
 zend_object_value type
PHP objects details
 An object carries :
 A handle
 Some handlers
 The handle is a unique integer designed to
fetch the "real" object from an internal store
Showing the object handle
$o = new MyClass;
$a = $o;
$b = $o;
var_dump($a, $b, $o);
object(MyClass)#1 (0) {
}
object(MyClass)#1 (0) {
}
object(MyClass)#1 (0) {
}
Objects ARE NOT references
Objects are NOT references
 Simple proof
function foo($var) {
$var = 42;
}
$o = new MyClass;
foo($o);
var_dump($o);
object(MyClass)#1 (0) {
}
Objects borrow ref. behavior
 Because each variable (zval) encapsulates the
same object handle
function foo($var) {
$var->name = 'foo';
}
$o = new MyClass;
$o->name = 'bar';
foo($o);
var_dump($o);
object(MyClass)#1 (0) {
public $name =>
string(3) "foo"
}
zvals vs object handles
 This writes to the zval container $object :
 This changes the zval value
 Before it was an object, now it's a string
 The object that was into it has never been changed here
 This fetches the object using its handle, and
writes to that object :
 All other zvals using this same object handle are
affected, whatever their scope
$object = 'overwritten';
$object->var = 'changed';
Creating a new object
 The two only ways to create a new object in the
store are :
 new keyword (unserialize() may use new as well)
 clone keyword
$o = new MyClass;
$a = $o;
$a->name = 'foo';
$b = clone $a;
$c = $b;
$b->name = 'bar';
$a = 'string';
Object#1
name => "foo"
Object#1
name => "bar"
zval1
obj_handle => #1
Object#1
name => "bar"
zval2
'string'$b
$o
object storezval storesym tables
$a
$c zval3
obj_handle => #2
Object#2
name => "bar"
zval duplication with objects
 Even when you force PHP to duplicate a zval, if it represents an
object, this latter won't be copied :
 This is PHP5 behavior
 The objects are not duplicated, weither you use PHP references or not
 Zvals may get duplicated (if you abuse PHP references usage !)
 Objects themselves also carry a refcount
$o = new MyClass;
$a = &$o; // take a reference
/* Force PHP to duplicate the zval */
$b = $a;
/* We all agree that here, modifying $a or $b or $o
will modify the *same* object */
zval duplication and objects
 Even if you force PHP to dup. a zval container,
the object stored in it won't be dup.
$o = new MyClass;
$a = &$o;
$a->name = 'foo';
$b = $a;
Object#1
name => "foo"
Object#1
name => "bar"
zval1
obj_handle => #1
$b
$o
object storezval storesym tables
$a
zval2
obj_handle => #1
First step conclusion
 Having lots of variables pointing to the same
object is not bad for memory usage
 "clone", "new" and "unserialize" are the only
ways to create an object in the store
 Thus to consume more memory
 To free (destroy) an object from memory, one
must destroy all zvals in all scopes pointing to
it
 Keeping track of this can be hard
 use xdebug, master your code, remember
Garbage collector (GC)
Circular references GC
Statements :
 PHP garbage collector is NOT object specific
 It is zval based (any PHP type so)
 PHP GC is a circular references GC
 It's only goal is to free unfetchable circular
references from userland
 PHP has always freed unused zvals of which
refcount reached zero
 GC has nothing to do with this behavior
 PHP Circular references GC appeared in 5.3
Some circular references
$a = new StdClass;
$b = new StdClass;
$a->b = $b;
$b->a = $a;
unset($a,$b);
zval1 zval2
refcount = 1
obj_handle => #2
refcount = 1
obj_handle => #1
Some circular references
$a = new StdClass;
$b = new StdClass;
$a->b = $b;
$b->a = $a;
unset($a,$b);
zval1 zval2
refcount = 1
obj_handle => #2
refcount = 1
obj_handle => #1
Some circ.ref. cleaned by GC
$a = new StdClass;
$b = new StdClass;
$a->b = $b;
$b->a = $a;
unset($a,$b);
echo gc_collect_cycles(); // 2
Objects circ.ref are common
 It is very easy to create a
circ.ref leak with objects
 This will have an impact if :
 Your objects are "heavy"
 You run long living process
 Ex are some SF2 commands
 ... with doctrine 2
class A
{
private $b;
function __construct() {
$this->b = new B($this);
}
}
class B
{
private $a;
function __construct(A $a) {
$this->a = $a;
}
}
$a = new A;
unset($a);
Diving into objects
zend_object type
 Objects in PHP are zend_object
 Objects live in a global "store"
 They are indexed using their unique handle
 As we've seen, PHP does all it can do not to
duplicate the object into the store
 Only way to duplicate : "clone"
zend_class_entry
 Represents a PHP class
or an interface
 By far the biggest
structure !
 This structure's been
shrinked to fit the slide
 The structure size is
~500 bytes
Object memory consumption
 Object declared attributes are stored once in the class
structure at compile time
 When you create an object (new), PHP will duplicate
the zval attributes from the class to the object
 The object now effectively owns its own copy of attributes
 zvals pointers are copied, not zval values. COW still effective
 Conclusion : An object weight is directly bound to its
attributes weight
 As class informations are shared between objects
Object memory consumption
 Every declared property is stored in the class structure
 They are stored with info structures
 Those also consume memory
 The class also embeds
 Its own static properties
 its own constants
 an array of interfaces it implements
 an array of traits it uses
 more info
 class consumes much more memory than an object
 But the same class is shared between all its children objects
Lifetimes
 Objects start living when you create them and
stop living when they are destroyed
 when the last zval pointing to the object is destroyed
 Classes start living when PHP starts parsing a
T_CLASS (class {) token
 Classes stop living when PHP shuts down (end
of request)
 Every class info, e.g its static members, have a
lifetime of the class itself
unset(MyClass::$variable);
Fatal error: Attempt to unset static property
Object handlers
Object handlers
 Every operation on objects is done by handlers
Object handlers
 Every single tiny operation on objects is done
using a handler (a redefinable function)
 For example
 calling a method on an object
 Fetching an object property
 But also :
 Casting an object (zend_object_cast_t)
 Comparing an object with something (zend_object_compare_t)
 ...
Object default handlers
 PHP uses default handlers
Object default handler example
 Default handlers implement default behavior
we all are used to :
static union _zend_function *zend_std_get_method(zval **object_ptr,
char *method_name, int method_len, const zend_literal *key TSRMLS_DC) {
// ...
if (UNEXPECTED(zend_hash_quick_find(&zobj->ce->function_table,
lc_method_name, method_len+1, hash_value, (void **)&fbc) == FAILURE)) {
if (zobj->ce->__call) {
return zend_get_user_call_function(zobj->ce, method_name, method_len);
} else {
return NULL;
}
}
Overriding object handlers
 You should know about "special behaving PHP
objects" don't you ?
Overriding object handlers
 You should know about "special behaving PHP
objects" don't you ?
 SimpleXmlElement
 PDOStatement
 DateTime
 ...
 They all redefine default handlers
And from PHP land ?
 You may overwrite some handlers from PHP
Land
 ArrayAccess
 Serializable
 Countable
 Designing a PHP extension, you may overwrite
any handler you want
 That's great
 Customize PHP object behavior
PHP OOP gotchas
construct. params strangeness
 Please, explain that behavior :
new StdClass($a=5);
var_dump($a);
PHP Notice : undefined variable $a
new DateTime($a='now');
var_dump($a);
string(3) "now"
Destructor secrets
 __destruct() is called when an object is
destroyed
 Destroyed == freeed (often)
 Reminder : An object is destroyed when no
more zvals point to it
$a = new SomeClass; // refcount = 1
/* calls __destruct() */
unset($a); // refcount reaches 0
Destructor secrets
 Let's now see what happens at shutdown
 When you don't destruct your objects yourself
 That's bad, you'll see
 When you leave PHP's shutdown clean your objects
 Yes, that's bad
$a = new SomeClass; // refcount = 1
/* Shutdown sequence */
Destructors at shutdown
 3-step shutdown
1
2
3
Shutdown and destructors #1
 PHP will loop backward the global symbol table
and destroy objects which zval's refcount = 1
 Last object created = first cleared
1 2 3
class Foo { public function __destruct() { var_dump("Destroyed Foo"); } }
class Bar { public function __destruct() { var_dump("Destroyed Bar"); } }
$a = new Foo,
$b = new Bar;
$a = new Bar,
$b = new Foo;
"Destroyed Bar"
"Destroyed Foo"
"Destroyed Foo"
"Destroyed Bar"
$a = new Bar,
$b = new Foo;
$c = $b;
"Destroyed Bar"
"Destroyed Foo"
Shutdown and destructors #2
 Then (for objects where refcount > 1) PHP will
loop forward the object store and destroy all
objects
 In order of their creation so (forward)
$a = new Foo;
$a2 = $a;
$b = new Bar;
$b2 = $b;
"Destroyed Foo"
"Destroyed Bar"
Shutdown and destructors #3
 If a destructor exit()s or die()s, the other
destructors are not executed
 But the objects are "marked as destructed"
$a = new Foo;
$a2 = $a;
$b = new Bar;
$b2 = $b;
"Destroyed Foo"
class Foo { public function __destruct() { var_dump("Destroyed Foo"); die(); } }
class Bar { public function __destruct() { var_dump("Destroyed Bar"); } }
__destruct() weirdness
 So, knowing that, we can meet weird behaviors
class Foo
{
public $state = 'alive';
function __destruct() {
$this->state = 'destructed';
}
}
class Bar
{
public $foo;
function __destruct() {
var_dump($this->foo->state);
}
}
$foo = new Foo;
$bar = new Bar;
$bar->foo = $foo;
$foo = new Foo;
$bar = new Bar;
$bar->foo = $foo;
$a = $bar;
"alive"
"destructed"
"Destroying" an object
 When you destroy an object, PHP will
immediatly free it
 When PHP destroys an object during shutdown
sequence, it will only call __destruct() and will
not free the object immediately
 That's why you can reuse "destroyed" objects
 See preceding slide
 The objects will be freed when the engine will
shutdown
$a = new SomeClass;
unset($a);
__destruct() in shutdown
 PHP's shutdown sequence is clear
 http://lxr.php.net/xref/PHP_5_4/main/main.c#1728
 1. call shutdown functions
 2. call object destructors
 3. end output buffering
 4. shutdown all extensions
 5. destroy superglobals
 6. shutdown scanner/executor/compiler
 Frees object storage
 Every object handling done after phase #2 can
lead to weird behavior and/or crash PHP
A great conclusion of this
 Don't rely on PHP's shutdown behavior
 It has changed throughout PHP versions
 It will change in the future
 It can make PHP hang or crash in worst cases
 Just destroy and free the resources yourself !
function stack serialized
 serializing an Exception serializes its stack trace
 Which itself could be not serializable ...
function foo(SimpleXMlElement $x, $a)
{
echo serialize(new Exception());
}
foo(new SimpleXmlElement('<a />'), 'a');
Fatal error: Uncaught exception 'Exception' with message
'Serialization of 'SimpleXMLElement' is not allowed'
Class Early Binding
 Early binding = compiler declares solo classes
 Inheritence is honnored at runtime
 Conditionnal declarations are honnored at runtime
 Declare your classes in the "right" order
 Use runtime autoloader
class C extends B {}
class B extends A {}
class A {}
Fatal error: Class 'B' not found
class C extends A {}
class A {}
/* all right */
Thank you for listening

More Related Content

What's hot

PHP Tips for certification - OdW13
PHP Tips for certification - OdW13PHP Tips for certification - OdW13
PHP Tips for certification - OdW13julien pauli
 
PHP5.5 is Here
PHP5.5 is HerePHP5.5 is Here
PHP5.5 is Here
julien pauli
 
Php and threads ZTS
Php and threads ZTSPhp and threads ZTS
Php and threads ZTS
julien pauli
 
Php extensions workshop
Php extensions workshopPhp extensions workshop
Php extensions workshopjulien pauli
 
The Php Life Cycle
The Php Life CycleThe Php Life Cycle
The Php Life CycleXinchen Hui
 
SymfonyCon 2017 php7 performances
SymfonyCon 2017 php7 performancesSymfonyCon 2017 php7 performances
SymfonyCon 2017 php7 performances
julien pauli
 
PECL Picks - Extensions to make your life better
PECL Picks - Extensions to make your life betterPECL Picks - Extensions to make your life better
PECL Picks - Extensions to make your life better
ZendCon
 
Streams, sockets and filters oh my!
Streams, sockets and filters oh my!Streams, sockets and filters oh my!
Streams, sockets and filters oh my!
Elizabeth Smith
 
Doctrine 2.0 Enterprise Persistence Layer for PHP
Doctrine 2.0 Enterprise Persistence Layer for PHPDoctrine 2.0 Enterprise Persistence Layer for PHP
Doctrine 2.0 Enterprise Persistence Layer for PHP
Guilherme Blanco
 
PHP 7 performances from PHP 5
PHP 7 performances from PHP 5PHP 7 performances from PHP 5
PHP 7 performances from PHP 5
julien pauli
 
Php on the Web and Desktop
Php on the Web and DesktopPhp on the Web and Desktop
Php on the Web and Desktop
Elizabeth Smith
 
PHP 7 OPCache extension review
PHP 7 OPCache extension reviewPHP 7 OPCache extension review
PHP 7 OPCache extension review
julien pauli
 
Symfony live 2017_php7_performances
Symfony live 2017_php7_performancesSymfony live 2017_php7_performances
Symfony live 2017_php7_performances
julien pauli
 
PHP Internals and Virtual Machine
PHP Internals and Virtual MachinePHP Internals and Virtual Machine
PHP Internals and Virtual Machine
julien pauli
 
PHP 7 new engine
PHP 7 new enginePHP 7 new engine
PHP 7 new engine
julien pauli
 
Php engine
Php enginePhp engine
Php engine
julien pauli
 
Understanding PHP memory
Understanding PHP memoryUnderstanding PHP memory
Understanding PHP memoryjulien pauli
 
Writing and using php streams and sockets tek11
Writing and using php streams and sockets   tek11Writing and using php streams and sockets   tek11
Writing and using php streams and sockets tek11
Elizabeth Smith
 
Diving into HHVM Extensions (PHPNW Conference 2015)
Diving into HHVM Extensions (PHPNW Conference 2015)Diving into HHVM Extensions (PHPNW Conference 2015)
Diving into HHVM Extensions (PHPNW Conference 2015)
James Titcumb
 

What's hot (20)

PHP Tips for certification - OdW13
PHP Tips for certification - OdW13PHP Tips for certification - OdW13
PHP Tips for certification - OdW13
 
PHP5.5 is Here
PHP5.5 is HerePHP5.5 is Here
PHP5.5 is Here
 
Php and threads ZTS
Php and threads ZTSPhp and threads ZTS
Php and threads ZTS
 
Php extensions workshop
Php extensions workshopPhp extensions workshop
Php extensions workshop
 
The Php Life Cycle
The Php Life CycleThe Php Life Cycle
The Php Life Cycle
 
SymfonyCon 2017 php7 performances
SymfonyCon 2017 php7 performancesSymfonyCon 2017 php7 performances
SymfonyCon 2017 php7 performances
 
PECL Picks - Extensions to make your life better
PECL Picks - Extensions to make your life betterPECL Picks - Extensions to make your life better
PECL Picks - Extensions to make your life better
 
Streams, sockets and filters oh my!
Streams, sockets and filters oh my!Streams, sockets and filters oh my!
Streams, sockets and filters oh my!
 
Doctrine 2.0 Enterprise Persistence Layer for PHP
Doctrine 2.0 Enterprise Persistence Layer for PHPDoctrine 2.0 Enterprise Persistence Layer for PHP
Doctrine 2.0 Enterprise Persistence Layer for PHP
 
PHP 7 performances from PHP 5
PHP 7 performances from PHP 5PHP 7 performances from PHP 5
PHP 7 performances from PHP 5
 
Php on the Web and Desktop
Php on the Web and DesktopPhp on the Web and Desktop
Php on the Web and Desktop
 
PHP 7 OPCache extension review
PHP 7 OPCache extension reviewPHP 7 OPCache extension review
PHP 7 OPCache extension review
 
Symfony live 2017_php7_performances
Symfony live 2017_php7_performancesSymfony live 2017_php7_performances
Symfony live 2017_php7_performances
 
PHP Internals and Virtual Machine
PHP Internals and Virtual MachinePHP Internals and Virtual Machine
PHP Internals and Virtual Machine
 
Spl in the wild
Spl in the wildSpl in the wild
Spl in the wild
 
PHP 7 new engine
PHP 7 new enginePHP 7 new engine
PHP 7 new engine
 
Php engine
Php enginePhp engine
Php engine
 
Understanding PHP memory
Understanding PHP memoryUnderstanding PHP memory
Understanding PHP memory
 
Writing and using php streams and sockets tek11
Writing and using php streams and sockets   tek11Writing and using php streams and sockets   tek11
Writing and using php streams and sockets tek11
 
Diving into HHVM Extensions (PHPNW Conference 2015)
Diving into HHVM Extensions (PHPNW Conference 2015)Diving into HHVM Extensions (PHPNW Conference 2015)
Diving into HHVM Extensions (PHPNW Conference 2015)
 

Viewers also liked

10 commandments for better android development
10 commandments for better android development10 commandments for better android development
10 commandments for better android development
Trey Robinson
 
Visual guide to selling software as a service by @prezly
Visual guide to selling software as a service by @prezlyVisual guide to selling software as a service by @prezly
Visual guide to selling software as a service by @prezly
Prezly
 
Kicking the Bukkit: Anatomy of an open source meltdown
Kicking the Bukkit: Anatomy of an open source meltdownKicking the Bukkit: Anatomy of an open source meltdown
Kicking the Bukkit: Anatomy of an open source meltdown
RyanMichela
 
Your code sucks, let's fix it
Your code sucks, let's fix itYour code sucks, let's fix it
Your code sucks, let's fix it
Rafael Dohms
 
Rethinking Best Practices
Rethinking Best PracticesRethinking Best Practices
Rethinking Best Practices
floydophone
 
Object Calisthenics Applied to PHP
Object Calisthenics Applied to PHPObject Calisthenics Applied to PHP
Object Calisthenics Applied to PHP
Guilherme Blanco
 
Programming objects with android
Programming objects with androidProgramming objects with android
Programming objects with android
firenze-gtug
 
We Built It, And They Didn't Come!
We Built It, And They Didn't Come!We Built It, And They Didn't Come!
We Built It, And They Didn't Come!
Lukas Fittl
 
Composer The Right Way - 010PHP
Composer The Right Way - 010PHPComposer The Right Way - 010PHP
Composer The Right Way - 010PHP
Rafael Dohms
 
Clean code
Clean codeClean code
Clean code
Bulat Shakirzyanov
 
Integrating React.js with PHP projects
Integrating React.js with PHP projectsIntegrating React.js with PHP projects
Integrating React.js with PHP projects
Ignacio Martín
 
How to Design Indexes, Really
How to Design Indexes, ReallyHow to Design Indexes, Really
How to Design Indexes, Really
Karwin Software Solutions LLC
 
Enterprise PHP: mappers, models and services
Enterprise PHP: mappers, models and servicesEnterprise PHP: mappers, models and services
Enterprise PHP: mappers, models and services
Aaron Saray
 
From development environments to production deployments with Docker, Compose,...
From development environments to production deployments with Docker, Compose,...From development environments to production deployments with Docker, Compose,...
From development environments to production deployments with Docker, Compose,...
Jérôme Petazzoni
 
Enterprise PHP Architecture through Design Patterns and Modularization (Midwe...
Enterprise PHP Architecture through Design Patterns and Modularization (Midwe...Enterprise PHP Architecture through Design Patterns and Modularization (Midwe...
Enterprise PHP Architecture through Design Patterns and Modularization (Midwe...
Aaron Saray
 
Functional Programming Patterns (BuildStuff '14)
Functional Programming Patterns (BuildStuff '14)Functional Programming Patterns (BuildStuff '14)
Functional Programming Patterns (BuildStuff '14)
Scott Wlaschin
 
From Idea to Execution: Spotify's Discover Weekly
From Idea to Execution: Spotify's Discover WeeklyFrom Idea to Execution: Spotify's Discover Weekly
From Idea to Execution: Spotify's Discover Weekly
Chris Johnson
 
Linux Profiling at Netflix
Linux Profiling at NetflixLinux Profiling at Netflix
Linux Profiling at Netflix
Brendan Gregg
 

Viewers also liked (18)

10 commandments for better android development
10 commandments for better android development10 commandments for better android development
10 commandments for better android development
 
Visual guide to selling software as a service by @prezly
Visual guide to selling software as a service by @prezlyVisual guide to selling software as a service by @prezly
Visual guide to selling software as a service by @prezly
 
Kicking the Bukkit: Anatomy of an open source meltdown
Kicking the Bukkit: Anatomy of an open source meltdownKicking the Bukkit: Anatomy of an open source meltdown
Kicking the Bukkit: Anatomy of an open source meltdown
 
Your code sucks, let's fix it
Your code sucks, let's fix itYour code sucks, let's fix it
Your code sucks, let's fix it
 
Rethinking Best Practices
Rethinking Best PracticesRethinking Best Practices
Rethinking Best Practices
 
Object Calisthenics Applied to PHP
Object Calisthenics Applied to PHPObject Calisthenics Applied to PHP
Object Calisthenics Applied to PHP
 
Programming objects with android
Programming objects with androidProgramming objects with android
Programming objects with android
 
We Built It, And They Didn't Come!
We Built It, And They Didn't Come!We Built It, And They Didn't Come!
We Built It, And They Didn't Come!
 
Composer The Right Way - 010PHP
Composer The Right Way - 010PHPComposer The Right Way - 010PHP
Composer The Right Way - 010PHP
 
Clean code
Clean codeClean code
Clean code
 
Integrating React.js with PHP projects
Integrating React.js with PHP projectsIntegrating React.js with PHP projects
Integrating React.js with PHP projects
 
How to Design Indexes, Really
How to Design Indexes, ReallyHow to Design Indexes, Really
How to Design Indexes, Really
 
Enterprise PHP: mappers, models and services
Enterprise PHP: mappers, models and servicesEnterprise PHP: mappers, models and services
Enterprise PHP: mappers, models and services
 
From development environments to production deployments with Docker, Compose,...
From development environments to production deployments with Docker, Compose,...From development environments to production deployments with Docker, Compose,...
From development environments to production deployments with Docker, Compose,...
 
Enterprise PHP Architecture through Design Patterns and Modularization (Midwe...
Enterprise PHP Architecture through Design Patterns and Modularization (Midwe...Enterprise PHP Architecture through Design Patterns and Modularization (Midwe...
Enterprise PHP Architecture through Design Patterns and Modularization (Midwe...
 
Functional Programming Patterns (BuildStuff '14)
Functional Programming Patterns (BuildStuff '14)Functional Programming Patterns (BuildStuff '14)
Functional Programming Patterns (BuildStuff '14)
 
From Idea to Execution: Spotify's Discover Weekly
From Idea to Execution: Spotify's Discover WeeklyFrom Idea to Execution: Spotify's Discover Weekly
From Idea to Execution: Spotify's Discover Weekly
 
Linux Profiling at Netflix
Linux Profiling at NetflixLinux Profiling at Netflix
Linux Profiling at Netflix
 

Similar to Understanding PHP objects

Object Trampoline: Why having not the object you want is what you need.
Object Trampoline: Why having not the object you want is what you need.Object Trampoline: Why having not the object you want is what you need.
Object Trampoline: Why having not the object you want is what you need.
Workhorse Computing
 
Object Oriented PHP - PART-2
Object Oriented PHP - PART-2Object Oriented PHP - PART-2
Object Oriented PHP - PART-2
Jalpesh Vasa
 
Let's JavaScript
Let's JavaScriptLet's JavaScript
Let's JavaScript
Paweł Dorofiejczyk
 
OOP Adventures with XOOPS
OOP Adventures with XOOPSOOP Adventures with XOOPS
OOP Adventures with XOOPS
xoopsproject
 
Ruby Internals
Ruby InternalsRuby Internals
Ruby Internals
Burke Libbey
 
JavsScript OOP
JavsScript OOPJavsScript OOP
JavsScript OOP
LearningTech
 
Advanced php
Advanced phpAdvanced php
Advanced phphamfu
 
DESIGNING A PERSISTENCE FRAMEWORK WITH PATTERNS.ppt
DESIGNING A PERSISTENCE FRAMEWORK WITH PATTERNS.pptDESIGNING A PERSISTENCE FRAMEWORK WITH PATTERNS.ppt
DESIGNING A PERSISTENCE FRAMEWORK WITH PATTERNS.ppt
AntoJoseph36
 
Introduction to javascript and yoolkui
Introduction to javascript and yoolkuiIntroduction to javascript and yoolkui
Introduction to javascript and yoolkuiKhou Suylong
 
oop_in_php_tutorial_for_killerphp.com
oop_in_php_tutorial_for_killerphp.comoop_in_php_tutorial_for_killerphp.com
oop_in_php_tutorial_for_killerphp.comtutorialsruby
 
Oop in php tutorial
Oop in php tutorialOop in php tutorial
Oop in php tutorial
Gua Syed Al Yahya
 
Oop in php_tutorial_for_killerphp.com
Oop in php_tutorial_for_killerphp.comOop in php_tutorial_for_killerphp.com
Oop in php_tutorial_for_killerphp.comayandoesnotemail
 
oop_in_php_tutorial_for_killerphp.com
oop_in_php_tutorial_for_killerphp.comoop_in_php_tutorial_for_killerphp.com
oop_in_php_tutorial_for_killerphp.comtutorialsruby
 
Oop's in php
Oop's in php Oop's in php
Oop's in php
umesh patil
 
Synapseindia object oriented programming in php
Synapseindia object oriented programming in phpSynapseindia object oriented programming in php
Synapseindia object oriented programming in php
Synapseindiappsdevelopment
 
Dci in PHP
Dci in PHPDci in PHP
Dci in PHP
Herman Peeren
 
Basic Oops concept of PHP
Basic Oops concept of PHPBasic Oops concept of PHP
Basic Oops concept of PHP
Rohan Sharma
 
Introduction Php
Introduction PhpIntroduction Php
Introduction Php
sanjay joshi
 

Similar to Understanding PHP objects (20)

Object Trampoline: Why having not the object you want is what you need.
Object Trampoline: Why having not the object you want is what you need.Object Trampoline: Why having not the object you want is what you need.
Object Trampoline: Why having not the object you want is what you need.
 
About Python
About PythonAbout Python
About Python
 
Object Oriented PHP - PART-2
Object Oriented PHP - PART-2Object Oriented PHP - PART-2
Object Oriented PHP - PART-2
 
Let's JavaScript
Let's JavaScriptLet's JavaScript
Let's JavaScript
 
OOP Adventures with XOOPS
OOP Adventures with XOOPSOOP Adventures with XOOPS
OOP Adventures with XOOPS
 
Javascript
JavascriptJavascript
Javascript
 
Ruby Internals
Ruby InternalsRuby Internals
Ruby Internals
 
JavsScript OOP
JavsScript OOPJavsScript OOP
JavsScript OOP
 
Advanced php
Advanced phpAdvanced php
Advanced php
 
DESIGNING A PERSISTENCE FRAMEWORK WITH PATTERNS.ppt
DESIGNING A PERSISTENCE FRAMEWORK WITH PATTERNS.pptDESIGNING A PERSISTENCE FRAMEWORK WITH PATTERNS.ppt
DESIGNING A PERSISTENCE FRAMEWORK WITH PATTERNS.ppt
 
Introduction to javascript and yoolkui
Introduction to javascript and yoolkuiIntroduction to javascript and yoolkui
Introduction to javascript and yoolkui
 
oop_in_php_tutorial_for_killerphp.com
oop_in_php_tutorial_for_killerphp.comoop_in_php_tutorial_for_killerphp.com
oop_in_php_tutorial_for_killerphp.com
 
Oop in php tutorial
Oop in php tutorialOop in php tutorial
Oop in php tutorial
 
Oop in php_tutorial_for_killerphp.com
Oop in php_tutorial_for_killerphp.comOop in php_tutorial_for_killerphp.com
Oop in php_tutorial_for_killerphp.com
 
oop_in_php_tutorial_for_killerphp.com
oop_in_php_tutorial_for_killerphp.comoop_in_php_tutorial_for_killerphp.com
oop_in_php_tutorial_for_killerphp.com
 
Oop's in php
Oop's in php Oop's in php
Oop's in php
 
Synapseindia object oriented programming in php
Synapseindia object oriented programming in phpSynapseindia object oriented programming in php
Synapseindia object oriented programming in php
 
Dci in PHP
Dci in PHPDci in PHP
Dci in PHP
 
Basic Oops concept of PHP
Basic Oops concept of PHPBasic Oops concept of PHP
Basic Oops concept of PHP
 
Introduction Php
Introduction PhpIntroduction Php
Introduction Php
 

More from julien pauli

Doctrine with Symfony - SymfonyCon 2019
Doctrine with Symfony - SymfonyCon 2019Doctrine with Symfony - SymfonyCon 2019
Doctrine with Symfony - SymfonyCon 2019
julien pauli
 
Basics of Cryptography - Stream ciphers and PRNG
Basics of Cryptography - Stream ciphers and PRNGBasics of Cryptography - Stream ciphers and PRNG
Basics of Cryptography - Stream ciphers and PRNG
julien pauli
 
Mastering your home network - Do It Yourself
Mastering your home network - Do It YourselfMastering your home network - Do It Yourself
Mastering your home network - Do It Yourself
julien pauli
 
Tcpip
TcpipTcpip
Communications Réseaux et HTTP avec PHP
Communications Réseaux et HTTP avec PHPCommunications Réseaux et HTTP avec PHP
Communications Réseaux et HTTP avec PHPjulien pauli
 
PHPTour-2011-PHP_Extensions
PHPTour-2011-PHP_ExtensionsPHPTour-2011-PHP_Extensions
PHPTour-2011-PHP_Extensionsjulien pauli
 
PHPTour 2011 - PHP5.4
PHPTour 2011 - PHP5.4PHPTour 2011 - PHP5.4
PHPTour 2011 - PHP5.4julien pauli
 
Patterns and OOP in PHP
Patterns and OOP in PHPPatterns and OOP in PHP
Patterns and OOP in PHPjulien pauli
 
ZendFramework2 - Présentation
ZendFramework2 - PrésentationZendFramework2 - Présentation
ZendFramework2 - Présentation
julien pauli
 
AlterWay SolutionsLinux Outils Industrialisation PHP
AlterWay SolutionsLinux Outils Industrialisation PHPAlterWay SolutionsLinux Outils Industrialisation PHP
AlterWay SolutionsLinux Outils Industrialisation PHP
julien pauli
 
Apache for développeurs PHP
Apache for développeurs PHPApache for développeurs PHP
Apache for développeurs PHP
julien pauli
 

More from julien pauli (12)

Doctrine with Symfony - SymfonyCon 2019
Doctrine with Symfony - SymfonyCon 2019Doctrine with Symfony - SymfonyCon 2019
Doctrine with Symfony - SymfonyCon 2019
 
Dns
DnsDns
Dns
 
Basics of Cryptography - Stream ciphers and PRNG
Basics of Cryptography - Stream ciphers and PRNGBasics of Cryptography - Stream ciphers and PRNG
Basics of Cryptography - Stream ciphers and PRNG
 
Mastering your home network - Do It Yourself
Mastering your home network - Do It YourselfMastering your home network - Do It Yourself
Mastering your home network - Do It Yourself
 
Tcpip
TcpipTcpip
Tcpip
 
Communications Réseaux et HTTP avec PHP
Communications Réseaux et HTTP avec PHPCommunications Réseaux et HTTP avec PHP
Communications Réseaux et HTTP avec PHP
 
PHPTour-2011-PHP_Extensions
PHPTour-2011-PHP_ExtensionsPHPTour-2011-PHP_Extensions
PHPTour-2011-PHP_Extensions
 
PHPTour 2011 - PHP5.4
PHPTour 2011 - PHP5.4PHPTour 2011 - PHP5.4
PHPTour 2011 - PHP5.4
 
Patterns and OOP in PHP
Patterns and OOP in PHPPatterns and OOP in PHP
Patterns and OOP in PHP
 
ZendFramework2 - Présentation
ZendFramework2 - PrésentationZendFramework2 - Présentation
ZendFramework2 - Présentation
 
AlterWay SolutionsLinux Outils Industrialisation PHP
AlterWay SolutionsLinux Outils Industrialisation PHPAlterWay SolutionsLinux Outils Industrialisation PHP
AlterWay SolutionsLinux Outils Industrialisation PHP
 
Apache for développeurs PHP
Apache for développeurs PHPApache for développeurs PHP
Apache for développeurs PHP
 

Recently uploaded

LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
DanBrown980551
 
The Future of Platform Engineering
The Future of Platform EngineeringThe Future of Platform Engineering
The Future of Platform Engineering
Jemma Hussein Allen
 
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdfSmart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
91mobiles
 
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdfFIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance
 
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
Product School
 
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
Product School
 
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdfFIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance
 
GraphRAG is All You need? LLM & Knowledge Graph
GraphRAG is All You need? LLM & Knowledge GraphGraphRAG is All You need? LLM & Knowledge Graph
GraphRAG is All You need? LLM & Knowledge Graph
Guy Korland
 
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdfFIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
FIDO Alliance
 
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Thierry Lestable
 
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
UiPathCommunity
 
Transcript: Selling digital books in 2024: Insights from industry leaders - T...
Transcript: Selling digital books in 2024: Insights from industry leaders - T...Transcript: Selling digital books in 2024: Insights from industry leaders - T...
Transcript: Selling digital books in 2024: Insights from industry leaders - T...
BookNet Canada
 
How world-class product teams are winning in the AI era by CEO and Founder, P...
How world-class product teams are winning in the AI era by CEO and Founder, P...How world-class product teams are winning in the AI era by CEO and Founder, P...
How world-class product teams are winning in the AI era by CEO and Founder, P...
Product School
 
JMeter webinar - integration with InfluxDB and Grafana
JMeter webinar - integration with InfluxDB and GrafanaJMeter webinar - integration with InfluxDB and Grafana
JMeter webinar - integration with InfluxDB and Grafana
RTTS
 
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
James Anderson
 
UiPath Test Automation using UiPath Test Suite series, part 4
UiPath Test Automation using UiPath Test Suite series, part 4UiPath Test Automation using UiPath Test Suite series, part 4
UiPath Test Automation using UiPath Test Suite series, part 4
DianaGray10
 
Generating a custom Ruby SDK for your web service or Rails API using Smithy
Generating a custom Ruby SDK for your web service or Rails API using SmithyGenerating a custom Ruby SDK for your web service or Rails API using Smithy
Generating a custom Ruby SDK for your web service or Rails API using Smithy
g2nightmarescribd
 
Connector Corner: Automate dynamic content and events by pushing a button
Connector Corner: Automate dynamic content and events by pushing a buttonConnector Corner: Automate dynamic content and events by pushing a button
Connector Corner: Automate dynamic content and events by pushing a button
DianaGray10
 
Securing your Kubernetes cluster_ a step-by-step guide to success !
Securing your Kubernetes cluster_ a step-by-step guide to success !Securing your Kubernetes cluster_ a step-by-step guide to success !
Securing your Kubernetes cluster_ a step-by-step guide to success !
KatiaHIMEUR1
 
Mission to Decommission: Importance of Decommissioning Products to Increase E...
Mission to Decommission: Importance of Decommissioning Products to Increase E...Mission to Decommission: Importance of Decommissioning Products to Increase E...
Mission to Decommission: Importance of Decommissioning Products to Increase E...
Product School
 

Recently uploaded (20)

LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
 
The Future of Platform Engineering
The Future of Platform EngineeringThe Future of Platform Engineering
The Future of Platform Engineering
 
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdfSmart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
 
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdfFIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
 
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
 
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
 
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdfFIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
 
GraphRAG is All You need? LLM & Knowledge Graph
GraphRAG is All You need? LLM & Knowledge GraphGraphRAG is All You need? LLM & Knowledge Graph
GraphRAG is All You need? LLM & Knowledge Graph
 
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdfFIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
 
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
 
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
 
Transcript: Selling digital books in 2024: Insights from industry leaders - T...
Transcript: Selling digital books in 2024: Insights from industry leaders - T...Transcript: Selling digital books in 2024: Insights from industry leaders - T...
Transcript: Selling digital books in 2024: Insights from industry leaders - T...
 
How world-class product teams are winning in the AI era by CEO and Founder, P...
How world-class product teams are winning in the AI era by CEO and Founder, P...How world-class product teams are winning in the AI era by CEO and Founder, P...
How world-class product teams are winning in the AI era by CEO and Founder, P...
 
JMeter webinar - integration with InfluxDB and Grafana
JMeter webinar - integration with InfluxDB and GrafanaJMeter webinar - integration with InfluxDB and Grafana
JMeter webinar - integration with InfluxDB and Grafana
 
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
 
UiPath Test Automation using UiPath Test Suite series, part 4
UiPath Test Automation using UiPath Test Suite series, part 4UiPath Test Automation using UiPath Test Suite series, part 4
UiPath Test Automation using UiPath Test Suite series, part 4
 
Generating a custom Ruby SDK for your web service or Rails API using Smithy
Generating a custom Ruby SDK for your web service or Rails API using SmithyGenerating a custom Ruby SDK for your web service or Rails API using Smithy
Generating a custom Ruby SDK for your web service or Rails API using Smithy
 
Connector Corner: Automate dynamic content and events by pushing a button
Connector Corner: Automate dynamic content and events by pushing a buttonConnector Corner: Automate dynamic content and events by pushing a button
Connector Corner: Automate dynamic content and events by pushing a button
 
Securing your Kubernetes cluster_ a step-by-step guide to success !
Securing your Kubernetes cluster_ a step-by-step guide to success !Securing your Kubernetes cluster_ a step-by-step guide to success !
Securing your Kubernetes cluster_ a step-by-step guide to success !
 
Mission to Decommission: Importance of Decommissioning Products to Increase E...
Mission to Decommission: Importance of Decommissioning Products to Increase E...Mission to Decommission: Importance of Decommissioning Products to Increase E...
Mission to Decommission: Importance of Decommissioning Products to Increase E...
 

Understanding PHP objects

  • 1. Understanding objects PHP 5 objects internal design
  • 2. Hello everybody  Julien PAULI  Programming in PHP since ~10y  PHP Internals reviewer  PHP 5.5 and 5.6 Release Manager or Co-RM  Working at SensioLabs in Paris  http://www.phpinternalsbook.com  @julienpauli - github.com/jpauli - jpauli@php.net
  • 3. What we'll cover together  Covering PHP 5 only  Quick recall on zvals  Object structures internally  zend_object_value  zend_class_entry  zend_object_handlers  zend_object_store  PHP objects lifecycle  Creating and destroying an object  Memory management & garbage collection
  • 5. Zvals  PHP variables can carry several types  PHP is not strongly typed  Type juggling  Internally, all variables are represented into a container which can carry all supported PHP types : "zval"
  • 7. zval management  Classic management example :  Reference counting management example : zval *myval; ALLOC_INIT_ZVAL(myval); // malloc() ZVAL_STRINGL(myval, "foobar", sizeof("foobar")-1, 1); /* use myval */ zval_ptr_dtor(&myval); Z_ADDREF_P(myval); Z_DELREF_P(myval); Z_SET_ISREF_P(myval); Z_UNSET_ISREF_P(myval);
  • 8. zvals refcount  Every PHP variable is a zval :  PHP does not duplicate memory when you duplicate variables in the same scope  It plays with the refcount of the zval  refcount is how many variables point to the zval <?php $o = new MyClass; <?php $o = new MyClass; // refcount = 1 $o2 = $o; // refcount = 2
  • 9. zvals refcount  The zval is automatically freed when refcount reaches zero, and never before  When a zval is freed, its content is freed if not shared elsewhere  In our case : an object <?php $o = new MyClass; // refcount = 1 $o2 = $o; // refcount = 2 unset($o); // refcount = 1, zval is not freed unset($o2); // refcount = 0, zval is freed
  • 10. Statement  Objects are variables  Variables are zvals  Objects are not freed until their zval's refcount reaches zero
  • 12. PHP Objects ?  Objects are zvals of type IS_OBJECT  The value field used is "obj" in the zval  zend_object_value type
  • 13. PHP objects details  An object carries :  A handle  Some handlers  The handle is a unique integer designed to fetch the "real" object from an internal store
  • 14. Showing the object handle $o = new MyClass; $a = $o; $b = $o; var_dump($a, $b, $o); object(MyClass)#1 (0) { } object(MyClass)#1 (0) { } object(MyClass)#1 (0) { }
  • 15. Objects ARE NOT references
  • 16. Objects are NOT references  Simple proof function foo($var) { $var = 42; } $o = new MyClass; foo($o); var_dump($o); object(MyClass)#1 (0) { }
  • 17. Objects borrow ref. behavior  Because each variable (zval) encapsulates the same object handle function foo($var) { $var->name = 'foo'; } $o = new MyClass; $o->name = 'bar'; foo($o); var_dump($o); object(MyClass)#1 (0) { public $name => string(3) "foo" }
  • 18. zvals vs object handles  This writes to the zval container $object :  This changes the zval value  Before it was an object, now it's a string  The object that was into it has never been changed here  This fetches the object using its handle, and writes to that object :  All other zvals using this same object handle are affected, whatever their scope $object = 'overwritten'; $object->var = 'changed';
  • 19. Creating a new object  The two only ways to create a new object in the store are :  new keyword (unserialize() may use new as well)  clone keyword $o = new MyClass; $a = $o; $a->name = 'foo'; $b = clone $a; $c = $b; $b->name = 'bar'; $a = 'string'; Object#1 name => "foo" Object#1 name => "bar" zval1 obj_handle => #1 Object#1 name => "bar" zval2 'string'$b $o object storezval storesym tables $a $c zval3 obj_handle => #2 Object#2 name => "bar"
  • 20. zval duplication with objects  Even when you force PHP to duplicate a zval, if it represents an object, this latter won't be copied :  This is PHP5 behavior  The objects are not duplicated, weither you use PHP references or not  Zvals may get duplicated (if you abuse PHP references usage !)  Objects themselves also carry a refcount $o = new MyClass; $a = &$o; // take a reference /* Force PHP to duplicate the zval */ $b = $a; /* We all agree that here, modifying $a or $b or $o will modify the *same* object */
  • 21. zval duplication and objects  Even if you force PHP to dup. a zval container, the object stored in it won't be dup. $o = new MyClass; $a = &$o; $a->name = 'foo'; $b = $a; Object#1 name => "foo" Object#1 name => "bar" zval1 obj_handle => #1 $b $o object storezval storesym tables $a zval2 obj_handle => #1
  • 22. First step conclusion  Having lots of variables pointing to the same object is not bad for memory usage  "clone", "new" and "unserialize" are the only ways to create an object in the store  Thus to consume more memory  To free (destroy) an object from memory, one must destroy all zvals in all scopes pointing to it  Keeping track of this can be hard  use xdebug, master your code, remember
  • 25. Statements :  PHP garbage collector is NOT object specific  It is zval based (any PHP type so)  PHP GC is a circular references GC  It's only goal is to free unfetchable circular references from userland  PHP has always freed unused zvals of which refcount reached zero  GC has nothing to do with this behavior  PHP Circular references GC appeared in 5.3
  • 26. Some circular references $a = new StdClass; $b = new StdClass; $a->b = $b; $b->a = $a; unset($a,$b); zval1 zval2 refcount = 1 obj_handle => #2 refcount = 1 obj_handle => #1
  • 27. Some circular references $a = new StdClass; $b = new StdClass; $a->b = $b; $b->a = $a; unset($a,$b); zval1 zval2 refcount = 1 obj_handle => #2 refcount = 1 obj_handle => #1
  • 28. Some circ.ref. cleaned by GC $a = new StdClass; $b = new StdClass; $a->b = $b; $b->a = $a; unset($a,$b); echo gc_collect_cycles(); // 2
  • 29. Objects circ.ref are common  It is very easy to create a circ.ref leak with objects  This will have an impact if :  Your objects are "heavy"  You run long living process  Ex are some SF2 commands  ... with doctrine 2 class A { private $b; function __construct() { $this->b = new B($this); } } class B { private $a; function __construct(A $a) { $this->a = $a; } } $a = new A; unset($a);
  • 31. zend_object type  Objects in PHP are zend_object  Objects live in a global "store"  They are indexed using their unique handle  As we've seen, PHP does all it can do not to duplicate the object into the store  Only way to duplicate : "clone"
  • 32. zend_class_entry  Represents a PHP class or an interface  By far the biggest structure !  This structure's been shrinked to fit the slide  The structure size is ~500 bytes
  • 33. Object memory consumption  Object declared attributes are stored once in the class structure at compile time  When you create an object (new), PHP will duplicate the zval attributes from the class to the object  The object now effectively owns its own copy of attributes  zvals pointers are copied, not zval values. COW still effective  Conclusion : An object weight is directly bound to its attributes weight  As class informations are shared between objects
  • 34. Object memory consumption  Every declared property is stored in the class structure  They are stored with info structures  Those also consume memory  The class also embeds  Its own static properties  its own constants  an array of interfaces it implements  an array of traits it uses  more info  class consumes much more memory than an object  But the same class is shared between all its children objects
  • 35. Lifetimes  Objects start living when you create them and stop living when they are destroyed  when the last zval pointing to the object is destroyed  Classes start living when PHP starts parsing a T_CLASS (class {) token  Classes stop living when PHP shuts down (end of request)  Every class info, e.g its static members, have a lifetime of the class itself unset(MyClass::$variable); Fatal error: Attempt to unset static property
  • 37. Object handlers  Every operation on objects is done by handlers
  • 38. Object handlers  Every single tiny operation on objects is done using a handler (a redefinable function)  For example  calling a method on an object  Fetching an object property  But also :  Casting an object (zend_object_cast_t)  Comparing an object with something (zend_object_compare_t)  ...
  • 39. Object default handlers  PHP uses default handlers
  • 40. Object default handler example  Default handlers implement default behavior we all are used to : static union _zend_function *zend_std_get_method(zval **object_ptr, char *method_name, int method_len, const zend_literal *key TSRMLS_DC) { // ... if (UNEXPECTED(zend_hash_quick_find(&zobj->ce->function_table, lc_method_name, method_len+1, hash_value, (void **)&fbc) == FAILURE)) { if (zobj->ce->__call) { return zend_get_user_call_function(zobj->ce, method_name, method_len); } else { return NULL; } }
  • 41. Overriding object handlers  You should know about "special behaving PHP objects" don't you ?
  • 42. Overriding object handlers  You should know about "special behaving PHP objects" don't you ?  SimpleXmlElement  PDOStatement  DateTime  ...  They all redefine default handlers
  • 43. And from PHP land ?  You may overwrite some handlers from PHP Land  ArrayAccess  Serializable  Countable  Designing a PHP extension, you may overwrite any handler you want  That's great  Customize PHP object behavior
  • 45. construct. params strangeness  Please, explain that behavior : new StdClass($a=5); var_dump($a); PHP Notice : undefined variable $a new DateTime($a='now'); var_dump($a); string(3) "now"
  • 46. Destructor secrets  __destruct() is called when an object is destroyed  Destroyed == freeed (often)  Reminder : An object is destroyed when no more zvals point to it $a = new SomeClass; // refcount = 1 /* calls __destruct() */ unset($a); // refcount reaches 0
  • 47. Destructor secrets  Let's now see what happens at shutdown  When you don't destruct your objects yourself  That's bad, you'll see  When you leave PHP's shutdown clean your objects  Yes, that's bad $a = new SomeClass; // refcount = 1 /* Shutdown sequence */
  • 48. Destructors at shutdown  3-step shutdown 1 2 3
  • 49. Shutdown and destructors #1  PHP will loop backward the global symbol table and destroy objects which zval's refcount = 1  Last object created = first cleared 1 2 3 class Foo { public function __destruct() { var_dump("Destroyed Foo"); } } class Bar { public function __destruct() { var_dump("Destroyed Bar"); } } $a = new Foo, $b = new Bar; $a = new Bar, $b = new Foo; "Destroyed Bar" "Destroyed Foo" "Destroyed Foo" "Destroyed Bar" $a = new Bar, $b = new Foo; $c = $b; "Destroyed Bar" "Destroyed Foo"
  • 50. Shutdown and destructors #2  Then (for objects where refcount > 1) PHP will loop forward the object store and destroy all objects  In order of their creation so (forward) $a = new Foo; $a2 = $a; $b = new Bar; $b2 = $b; "Destroyed Foo" "Destroyed Bar"
  • 51. Shutdown and destructors #3  If a destructor exit()s or die()s, the other destructors are not executed  But the objects are "marked as destructed" $a = new Foo; $a2 = $a; $b = new Bar; $b2 = $b; "Destroyed Foo" class Foo { public function __destruct() { var_dump("Destroyed Foo"); die(); } } class Bar { public function __destruct() { var_dump("Destroyed Bar"); } }
  • 52. __destruct() weirdness  So, knowing that, we can meet weird behaviors class Foo { public $state = 'alive'; function __destruct() { $this->state = 'destructed'; } } class Bar { public $foo; function __destruct() { var_dump($this->foo->state); } } $foo = new Foo; $bar = new Bar; $bar->foo = $foo; $foo = new Foo; $bar = new Bar; $bar->foo = $foo; $a = $bar; "alive" "destructed"
  • 53. "Destroying" an object  When you destroy an object, PHP will immediatly free it  When PHP destroys an object during shutdown sequence, it will only call __destruct() and will not free the object immediately  That's why you can reuse "destroyed" objects  See preceding slide  The objects will be freed when the engine will shutdown $a = new SomeClass; unset($a);
  • 54. __destruct() in shutdown  PHP's shutdown sequence is clear  http://lxr.php.net/xref/PHP_5_4/main/main.c#1728  1. call shutdown functions  2. call object destructors  3. end output buffering  4. shutdown all extensions  5. destroy superglobals  6. shutdown scanner/executor/compiler  Frees object storage  Every object handling done after phase #2 can lead to weird behavior and/or crash PHP
  • 55. A great conclusion of this  Don't rely on PHP's shutdown behavior  It has changed throughout PHP versions  It will change in the future  It can make PHP hang or crash in worst cases  Just destroy and free the resources yourself !
  • 56. function stack serialized  serializing an Exception serializes its stack trace  Which itself could be not serializable ... function foo(SimpleXMlElement $x, $a) { echo serialize(new Exception()); } foo(new SimpleXmlElement('<a />'), 'a'); Fatal error: Uncaught exception 'Exception' with message 'Serialization of 'SimpleXMLElement' is not allowed'
  • 57. Class Early Binding  Early binding = compiler declares solo classes  Inheritence is honnored at runtime  Conditionnal declarations are honnored at runtime  Declare your classes in the "right" order  Use runtime autoloader class C extends B {} class B extends A {} class A {} Fatal error: Class 'B' not found class C extends A {} class A {} /* all right */
  • 58. Thank you for listening