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
Ad

More Related Content

What's hot (20)

PHP Tips for certification - OdW13
PHP Tips for certification - OdW13PHP Tips for certification - OdW13
PHP Tips for certification - OdW13
julien 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 workshop
julien pauli
 
The Php Life Cycle
The Php Life CycleThe Php Life Cycle
The Php Life Cycle
Xinchen 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
 
Spl in the wild
Spl in the wildSpl in the wild
Spl in the wild
Elizabeth Smith
 
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 memory
julien 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
 
PHP Tips for certification - OdW13
PHP Tips for certification - OdW13PHP Tips for certification - OdW13
PHP Tips for certification - OdW13
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 workshop
julien pauli
 
The Php Life Cycle
The Php Life CycleThe Php Life Cycle
The Php Life Cycle
Xinchen 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
 
Understanding PHP memory
Understanding PHP memoryUnderstanding PHP memory
Understanding PHP memory
julien 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
 

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
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
 
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
 
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
 
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
 
Ad

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.
Workhorse Computing
 
About Python
About PythonAbout Python
About Python
Shao-Chuan Wang
 
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
 
Javascript
JavascriptJavascript
Javascript
Aditya Gaur
 
Ruby Internals
Ruby InternalsRuby Internals
Ruby Internals
Burke Libbey
 
JavsScript OOP
JavsScript OOPJavsScript OOP
JavsScript OOP
LearningTech
 
Advanced php
Advanced phpAdvanced php
Advanced php
hamfu
 
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 yoolkui
Khou Suylong
 
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.com
ayandoesnotemail
 
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
tutorialsruby
 
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
tutorialsruby
 
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
 
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
 
OOP Adventures with XOOPS
OOP Adventures with XOOPSOOP Adventures with XOOPS
OOP Adventures with XOOPS
xoopsproject
 
Advanced php
Advanced phpAdvanced php
Advanced php
hamfu
 
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 yoolkui
Khou 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.com
ayandoesnotemail
 
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
tutorialsruby
 
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
tutorialsruby
 
Synapseindia object oriented programming in php
Synapseindia object oriented programming in phpSynapseindia object oriented programming in php
Synapseindia object oriented programming in php
Synapseindiappsdevelopment
 
Basic Oops concept of PHP
Basic Oops concept of PHPBasic Oops concept of PHP
Basic Oops concept of PHP
Rohan Sharma
 
Ad

More from julien pauli (12)

Doctrine with Symfony - SymfonyCon 2019
Doctrine with Symfony - SymfonyCon 2019Doctrine with Symfony - SymfonyCon 2019
Doctrine with Symfony - SymfonyCon 2019
julien pauli
 
Dns
DnsDns
Dns
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
Tcpip
julien 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 PHP
julien pauli
 
PHPTour-2011-PHP_Extensions
PHPTour-2011-PHP_ExtensionsPHPTour-2011-PHP_Extensions
PHPTour-2011-PHP_Extensions
julien pauli
 
PHPTour 2011 - PHP5.4
PHPTour 2011 - PHP5.4PHPTour 2011 - PHP5.4
PHPTour 2011 - PHP5.4
julien pauli
 
Patterns and OOP in PHP
Patterns and OOP in PHPPatterns and OOP in PHP
Patterns and OOP in PHP
julien 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
 
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
 
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
julien pauli
 
PHPTour-2011-PHP_Extensions
PHPTour-2011-PHP_ExtensionsPHPTour-2011-PHP_Extensions
PHPTour-2011-PHP_Extensions
julien pauli
 
PHPTour 2011 - PHP5.4
PHPTour 2011 - PHP5.4PHPTour 2011 - PHP5.4
PHPTour 2011 - PHP5.4
julien pauli
 
Patterns and OOP in PHP
Patterns and OOP in PHPPatterns and OOP in PHP
Patterns and OOP in PHP
julien 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
 

Recently uploaded (20)

TrustArc Webinar: Consumer Expectations vs Corporate Realities on Data Broker...
TrustArc Webinar: Consumer Expectations vs Corporate Realities on Data Broker...TrustArc Webinar: Consumer Expectations vs Corporate Realities on Data Broker...
TrustArc Webinar: Consumer Expectations vs Corporate Realities on Data Broker...
TrustArc
 
HCL Nomad Web – Best Practices und Verwaltung von Multiuser-Umgebungen
HCL Nomad Web – Best Practices und Verwaltung von Multiuser-UmgebungenHCL Nomad Web – Best Practices und Verwaltung von Multiuser-Umgebungen
HCL Nomad Web – Best Practices und Verwaltung von Multiuser-Umgebungen
panagenda
 
Quantum Computing Quick Research Guide by Arthur Morgan
Quantum Computing Quick Research Guide by Arthur MorganQuantum Computing Quick Research Guide by Arthur Morgan
Quantum Computing Quick Research Guide by Arthur Morgan
Arthur Morgan
 
Generative Artificial Intelligence (GenAI) in Business
Generative Artificial Intelligence (GenAI) in BusinessGenerative Artificial Intelligence (GenAI) in Business
Generative Artificial Intelligence (GenAI) in Business
Dr. Tathagat Varma
 
Into The Box Conference Keynote Day 1 (ITB2025)
Into The Box Conference Keynote Day 1 (ITB2025)Into The Box Conference Keynote Day 1 (ITB2025)
Into The Box Conference Keynote Day 1 (ITB2025)
Ortus Solutions, Corp
 
Drupalcamp Finland – Measuring Front-end Energy Consumption
Drupalcamp Finland – Measuring Front-end Energy ConsumptionDrupalcamp Finland – Measuring Front-end Energy Consumption
Drupalcamp Finland – Measuring Front-end Energy Consumption
Exove
 
Enhancing ICU Intelligence: How Our Functional Testing Enabled a Healthcare I...
Enhancing ICU Intelligence: How Our Functional Testing Enabled a Healthcare I...Enhancing ICU Intelligence: How Our Functional Testing Enabled a Healthcare I...
Enhancing ICU Intelligence: How Our Functional Testing Enabled a Healthcare I...
Impelsys Inc.
 
Increasing Retail Store Efficiency How can Planograms Save Time and Money.pptx
Increasing Retail Store Efficiency How can Planograms Save Time and Money.pptxIncreasing Retail Store Efficiency How can Planograms Save Time and Money.pptx
Increasing Retail Store Efficiency How can Planograms Save Time and Money.pptx
Anoop Ashok
 
Designing Low-Latency Systems with Rust and ScyllaDB: An Architectural Deep Dive
Designing Low-Latency Systems with Rust and ScyllaDB: An Architectural Deep DiveDesigning Low-Latency Systems with Rust and ScyllaDB: An Architectural Deep Dive
Designing Low-Latency Systems with Rust and ScyllaDB: An Architectural Deep Dive
ScyllaDB
 
Transcript: #StandardsGoals for 2025: Standards & certification roundup - Tec...
Transcript: #StandardsGoals for 2025: Standards & certification roundup - Tec...Transcript: #StandardsGoals for 2025: Standards & certification roundup - Tec...
Transcript: #StandardsGoals for 2025: Standards & certification roundup - Tec...
BookNet Canada
 
What is Model Context Protocol(MCP) - The new technology for communication bw...
What is Model Context Protocol(MCP) - The new technology for communication bw...What is Model Context Protocol(MCP) - The new technology for communication bw...
What is Model Context Protocol(MCP) - The new technology for communication bw...
Vishnu Singh Chundawat
 
HCL Nomad Web – Best Practices and Managing Multiuser Environments
HCL Nomad Web – Best Practices and Managing Multiuser EnvironmentsHCL Nomad Web – Best Practices and Managing Multiuser Environments
HCL Nomad Web – Best Practices and Managing Multiuser Environments
panagenda
 
Rusty Waters: Elevating Lakehouses Beyond Spark
Rusty Waters: Elevating Lakehouses Beyond SparkRusty Waters: Elevating Lakehouses Beyond Spark
Rusty Waters: Elevating Lakehouses Beyond Spark
carlyakerly1
 
AI EngineHost Review: Revolutionary USA Datacenter-Based Hosting with NVIDIA ...
AI EngineHost Review: Revolutionary USA Datacenter-Based Hosting with NVIDIA ...AI EngineHost Review: Revolutionary USA Datacenter-Based Hosting with NVIDIA ...
AI EngineHost Review: Revolutionary USA Datacenter-Based Hosting with NVIDIA ...
SOFTTECHHUB
 
Role of Data Annotation Services in AI-Powered Manufacturing
Role of Data Annotation Services in AI-Powered ManufacturingRole of Data Annotation Services in AI-Powered Manufacturing
Role of Data Annotation Services in AI-Powered Manufacturing
Andrew Leo
 
Mobile App Development Company in Saudi Arabia
Mobile App Development Company in Saudi ArabiaMobile App Development Company in Saudi Arabia
Mobile App Development Company in Saudi Arabia
Steve Jonas
 
Andrew Marnell: Transforming Business Strategy Through Data-Driven Insights
Andrew Marnell: Transforming Business Strategy Through Data-Driven InsightsAndrew Marnell: Transforming Business Strategy Through Data-Driven Insights
Andrew Marnell: Transforming Business Strategy Through Data-Driven Insights
Andrew Marnell
 
AI Changes Everything – Talk at Cardiff Metropolitan University, 29th April 2...
AI Changes Everything – Talk at Cardiff Metropolitan University, 29th April 2...AI Changes Everything – Talk at Cardiff Metropolitan University, 29th April 2...
AI Changes Everything – Talk at Cardiff Metropolitan University, 29th April 2...
Alan Dix
 
Heap, Types of Heap, Insertion and Deletion
Heap, Types of Heap, Insertion and DeletionHeap, Types of Heap, Insertion and Deletion
Heap, Types of Heap, Insertion and Deletion
Jaydeep Kale
 
Linux Professional Institute LPIC-1 Exam.pdf
Linux Professional Institute LPIC-1 Exam.pdfLinux Professional Institute LPIC-1 Exam.pdf
Linux Professional Institute LPIC-1 Exam.pdf
RHCSA Guru
 
TrustArc Webinar: Consumer Expectations vs Corporate Realities on Data Broker...
TrustArc Webinar: Consumer Expectations vs Corporate Realities on Data Broker...TrustArc Webinar: Consumer Expectations vs Corporate Realities on Data Broker...
TrustArc Webinar: Consumer Expectations vs Corporate Realities on Data Broker...
TrustArc
 
HCL Nomad Web – Best Practices und Verwaltung von Multiuser-Umgebungen
HCL Nomad Web – Best Practices und Verwaltung von Multiuser-UmgebungenHCL Nomad Web – Best Practices und Verwaltung von Multiuser-Umgebungen
HCL Nomad Web – Best Practices und Verwaltung von Multiuser-Umgebungen
panagenda
 
Quantum Computing Quick Research Guide by Arthur Morgan
Quantum Computing Quick Research Guide by Arthur MorganQuantum Computing Quick Research Guide by Arthur Morgan
Quantum Computing Quick Research Guide by Arthur Morgan
Arthur Morgan
 
Generative Artificial Intelligence (GenAI) in Business
Generative Artificial Intelligence (GenAI) in BusinessGenerative Artificial Intelligence (GenAI) in Business
Generative Artificial Intelligence (GenAI) in Business
Dr. Tathagat Varma
 
Into The Box Conference Keynote Day 1 (ITB2025)
Into The Box Conference Keynote Day 1 (ITB2025)Into The Box Conference Keynote Day 1 (ITB2025)
Into The Box Conference Keynote Day 1 (ITB2025)
Ortus Solutions, Corp
 
Drupalcamp Finland – Measuring Front-end Energy Consumption
Drupalcamp Finland – Measuring Front-end Energy ConsumptionDrupalcamp Finland – Measuring Front-end Energy Consumption
Drupalcamp Finland – Measuring Front-end Energy Consumption
Exove
 
Enhancing ICU Intelligence: How Our Functional Testing Enabled a Healthcare I...
Enhancing ICU Intelligence: How Our Functional Testing Enabled a Healthcare I...Enhancing ICU Intelligence: How Our Functional Testing Enabled a Healthcare I...
Enhancing ICU Intelligence: How Our Functional Testing Enabled a Healthcare I...
Impelsys Inc.
 
Increasing Retail Store Efficiency How can Planograms Save Time and Money.pptx
Increasing Retail Store Efficiency How can Planograms Save Time and Money.pptxIncreasing Retail Store Efficiency How can Planograms Save Time and Money.pptx
Increasing Retail Store Efficiency How can Planograms Save Time and Money.pptx
Anoop Ashok
 
Designing Low-Latency Systems with Rust and ScyllaDB: An Architectural Deep Dive
Designing Low-Latency Systems with Rust and ScyllaDB: An Architectural Deep DiveDesigning Low-Latency Systems with Rust and ScyllaDB: An Architectural Deep Dive
Designing Low-Latency Systems with Rust and ScyllaDB: An Architectural Deep Dive
ScyllaDB
 
Transcript: #StandardsGoals for 2025: Standards & certification roundup - Tec...
Transcript: #StandardsGoals for 2025: Standards & certification roundup - Tec...Transcript: #StandardsGoals for 2025: Standards & certification roundup - Tec...
Transcript: #StandardsGoals for 2025: Standards & certification roundup - Tec...
BookNet Canada
 
What is Model Context Protocol(MCP) - The new technology for communication bw...
What is Model Context Protocol(MCP) - The new technology for communication bw...What is Model Context Protocol(MCP) - The new technology for communication bw...
What is Model Context Protocol(MCP) - The new technology for communication bw...
Vishnu Singh Chundawat
 
HCL Nomad Web – Best Practices and Managing Multiuser Environments
HCL Nomad Web – Best Practices and Managing Multiuser EnvironmentsHCL Nomad Web – Best Practices and Managing Multiuser Environments
HCL Nomad Web – Best Practices and Managing Multiuser Environments
panagenda
 
Rusty Waters: Elevating Lakehouses Beyond Spark
Rusty Waters: Elevating Lakehouses Beyond SparkRusty Waters: Elevating Lakehouses Beyond Spark
Rusty Waters: Elevating Lakehouses Beyond Spark
carlyakerly1
 
AI EngineHost Review: Revolutionary USA Datacenter-Based Hosting with NVIDIA ...
AI EngineHost Review: Revolutionary USA Datacenter-Based Hosting with NVIDIA ...AI EngineHost Review: Revolutionary USA Datacenter-Based Hosting with NVIDIA ...
AI EngineHost Review: Revolutionary USA Datacenter-Based Hosting with NVIDIA ...
SOFTTECHHUB
 
Role of Data Annotation Services in AI-Powered Manufacturing
Role of Data Annotation Services in AI-Powered ManufacturingRole of Data Annotation Services in AI-Powered Manufacturing
Role of Data Annotation Services in AI-Powered Manufacturing
Andrew Leo
 
Mobile App Development Company in Saudi Arabia
Mobile App Development Company in Saudi ArabiaMobile App Development Company in Saudi Arabia
Mobile App Development Company in Saudi Arabia
Steve Jonas
 
Andrew Marnell: Transforming Business Strategy Through Data-Driven Insights
Andrew Marnell: Transforming Business Strategy Through Data-Driven InsightsAndrew Marnell: Transforming Business Strategy Through Data-Driven Insights
Andrew Marnell: Transforming Business Strategy Through Data-Driven Insights
Andrew Marnell
 
AI Changes Everything – Talk at Cardiff Metropolitan University, 29th April 2...
AI Changes Everything – Talk at Cardiff Metropolitan University, 29th April 2...AI Changes Everything – Talk at Cardiff Metropolitan University, 29th April 2...
AI Changes Everything – Talk at Cardiff Metropolitan University, 29th April 2...
Alan Dix
 
Heap, Types of Heap, Insertion and Deletion
Heap, Types of Heap, Insertion and DeletionHeap, Types of Heap, Insertion and Deletion
Heap, Types of Heap, Insertion and Deletion
Jaydeep Kale
 
Linux Professional Institute LPIC-1 Exam.pdf
Linux Professional Institute LPIC-1 Exam.pdfLinux Professional Institute LPIC-1 Exam.pdf
Linux Professional Institute LPIC-1 Exam.pdf
RHCSA Guru
 

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 - [email protected]
  • 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