SlideShare une entreprise Scribd logo
1  sur  58
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

Contenu connexe

Tendances

PHP Tips for certification - OdW13
PHP Tips for certification - OdW13PHP Tips for certification - OdW13
PHP Tips for certification - OdW13julien pauli
 
Php and threads ZTS
Php and threads ZTSPhp and threads ZTS
Php and threads ZTSjulien 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 performancesjulien 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 betterZendCon
 
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 PHPGuilherme Blanco
 
PHP 7 performances from PHP 5
PHP 7 performances from PHP 5PHP 7 performances from PHP 5
PHP 7 performances from PHP 5julien pauli
 
Php on the Web and Desktop
Php on the Web and DesktopPhp on the Web and Desktop
Php on the Web and DesktopElizabeth Smith
 
PHP 7 OPCache extension review
PHP 7 OPCache extension reviewPHP 7 OPCache extension review
PHP 7 OPCache extension reviewjulien pauli
 
Symfony live 2017_php7_performances
Symfony live 2017_php7_performancesSymfony live 2017_php7_performances
Symfony live 2017_php7_performancesjulien pauli
 
PHP Internals and Virtual Machine
PHP Internals and Virtual MachinePHP Internals and Virtual Machine
PHP Internals and Virtual Machinejulien 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 tek11Elizabeth 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
 

Tendances (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)
 

En vedette

10 commandments for better android development
10 commandments for better android development10 commandments for better android development
10 commandments for better android developmentTrey 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 @prezlyPrezly
 
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 meltdownRyanMichela
 
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 itRafael Dohms
 
Rethinking Best Practices
Rethinking Best PracticesRethinking Best Practices
Rethinking Best Practicesfloydophone
 
Object Calisthenics Applied to PHP
Object Calisthenics Applied to PHPObject Calisthenics Applied to PHP
Object Calisthenics Applied to PHPGuilherme Blanco
 
Programming objects with android
Programming objects with androidProgramming objects with android
Programming objects with androidfirenze-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 - 010PHPRafael Dohms
 
Integrating React.js with PHP projects
Integrating React.js with PHP projectsIntegrating React.js with PHP projects
Integrating React.js with PHP projectsIgnacio Martín
 
Enterprise PHP: mappers, models and services
Enterprise PHP: mappers, models and servicesEnterprise PHP: mappers, models and services
Enterprise PHP: mappers, models and servicesAaron 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 WeeklyChris Johnson
 
Linux Profiling at Netflix
Linux Profiling at NetflixLinux Profiling at Netflix
Linux Profiling at NetflixBrendan Gregg
 

En vedette (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
 

Similaire à 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-2Jalpesh Vasa
 
OOP Adventures with XOOPS
OOP Adventures with XOOPSOOP Adventures with XOOPS
OOP Adventures with XOOPSxoopsproject
 
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.pptAntoJoseph36
 
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_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_for_killerphp.com
Oop in php_tutorial_for_killerphp.comOop in php_tutorial_for_killerphp.com
Oop in php_tutorial_for_killerphp.comayandoesnotemail
 
Synapseindia object oriented programming in php
Synapseindia object oriented programming in phpSynapseindia object oriented programming in php
Synapseindia object oriented programming in phpSynapseindiappsdevelopment
 
Basic Oops concept of PHP
Basic Oops concept of PHPBasic Oops concept of PHP
Basic Oops concept of PHPRohan Sharma
 

Similaire à 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_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 in php tutorial
Oop in php tutorialOop in php tutorial
Oop in php tutorial
 
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
 

Plus de julien pauli

Doctrine with Symfony - SymfonyCon 2019
Doctrine with Symfony - SymfonyCon 2019Doctrine with Symfony - SymfonyCon 2019
Doctrine with Symfony - SymfonyCon 2019julien 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 PRNGjulien 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 Yourselfjulien pauli
 
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ésentationjulien pauli
 
AlterWay SolutionsLinux Outils Industrialisation PHP
AlterWay SolutionsLinux Outils Industrialisation PHPAlterWay SolutionsLinux Outils Industrialisation PHP
AlterWay SolutionsLinux Outils Industrialisation PHPjulien pauli
 
Apache for développeurs PHP
Apache for développeurs PHPApache for développeurs PHP
Apache for développeurs PHPjulien pauli
 

Plus de 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
 

Dernier

Sample pptx for embedding into website for demo
Sample pptx for embedding into website for demoSample pptx for embedding into website for demo
Sample pptx for embedding into website for demoHarshalMandlekar2
 
Artificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxArtificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxhariprasad279825
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxLoriGlavin3
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity PlanDatabarracks
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024Lonnie McRorey
 
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024BookNet Canada
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebUiPathCommunity
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenHervé Boutemy
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc
 
Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...Rick Flair
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsSergiu Bodiu
 
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxLoriGlavin3
 
Advanced Computer Architecture – An Introduction
Advanced Computer Architecture – An IntroductionAdvanced Computer Architecture – An Introduction
Advanced Computer Architecture – An IntroductionDilum Bandara
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii SoldatenkoFwdays
 
Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Manik S Magar
 
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxLoriGlavin3
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxLoriGlavin3
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfAddepto
 
A Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersA Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersNicole Novielli
 

Dernier (20)

Sample pptx for embedding into website for demo
Sample pptx for embedding into website for demoSample pptx for embedding into website for demo
Sample pptx for embedding into website for demo
 
Artificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxArtificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptx
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity Plan
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024
 
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio Web
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache Maven
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
 
Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platforms
 
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
 
Advanced Computer Architecture – An Introduction
Advanced Computer Architecture – An IntroductionAdvanced Computer Architecture – An Introduction
Advanced Computer Architecture – An Introduction
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko
 
Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!
 
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptx
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdf
 
A Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersA Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software Developers
 

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