Magic methods

Preview:

DESCRIPTION

Originally presented at Northeast PHP 2013.

Citation preview

Magic Methods: Spilling the Secret

By Matthew Barlocker

The Barlocker

● Chief Architect at Lucid Software Inc

● Started using PHP in 2005

● Graduated with BS in CS from BYU in 2008

● Developed software for the following industries:

– Network Security

– Social Gaming

– Financial

– Productivity

Magic Methods

● All object methods beginning with '__' are reserved.

● To gain the magic functionality, define the method on the class.

<?php

class MyClass { private $var1 = 5; public function doSomething() { echo "hello!\n"; }}

<?php

class MyClass { private $var1 = 5; public function doSomething() { echo "hello!\n"; } public function __toString() { return 'This is a MyClass'; }}

Magic Methods

● Stringification

● Lifecycle

● Property Overloading

● Method Overloading

● Serialization

● Cloning

● Object Invocation

Stringification● __toString

__toString

● public string __toString()

● Called when an object is cast as a string.

● Throwing an exception inside this method will cause a fatal error.

● No default implementation.

__toString

<?php

class NoTostringExample { public $a = 1;}

$obj = new NoTostringExample();echo "Stringified " . $obj . "\n";

?>

$ php notostring.php PHP Catchable fatal error: Object of class NoTostringExample could not be converted to string in notostring.php on line 8

__toString

<?php

class TostringExample { public $a = 2; public function __toString() { return 'TostringExample(' . $this->a . ')'; }}

$obj = new TostringExample();echo "Stringified " . $obj . "\n";

?>

$ php tostring.php Stringified TostringExample(2)

__toString

<?php

class BadTostringExample {public $a = 3;public function __toString() {

echo 'TostringExample(' . $this->a . ')' . "\n";}

}

$obj = new BadTostringExample();echo "Stringified " . $obj . "\n";

?>

$ php badtostring.php TostringExample(3)PHP Catchable fatal error: Method BadTostringExample::__toString() must return a string value in badtostring.php on line 11

Lifecycle

● __construct

● __destruct

__construct

● public void __construct($params, …)

● Called when an object is first initialized.

● Must explicitly call parent::__construct() in children.

● Default implementation does nothing.

__destruct

● public void __destruct()

● Called when an object is garbage collected.

● Must explicitly call parent::__destruct() in children.

● Default implementation does nothing.

__destruct

● public void __destruct()

● Called when an object is garbage collected.

● Must explicitly call parent::__destruct() in children.

● Default implementation does nothing.

__construct / __destruct

$ php construct.php StartingConstructEndingDestruct

<?php

class Construct {public function __construct() {

echo "Construct\n";}

public function __destruct() {echo "Destruct\n";

}}

echo "Starting\n";$obj = new Construct();echo "Ending\n";

?>

__construct / __destruct

<?php

class MyDB { private $connection = null;

public function __construct($host, $user, $pass) { $this->connection = dbconnect($host, $user, $pass); }

public function __destruct() { $this->connection->close(); }}

Property Overloading

● __get

● __set

● __isset

● __unset

__get

● public mixed __get($name)

● Called when an inaccessible property is read.

● Not called in chains. ($x = $obj->noexist = 5;)

● Default implementation emits a warning and returns null or emits a fatal error.

● Does not apply to static context.

__set

● public void __set($name, $value)

● Called to write a value to an inaccessible property.

● Default implementation adds a public variable to the class.

● Does not apply to static context.

__isset

● public mixed __isset($name)

● Triggered by calling isset() or empty() on inaccessible properties

● Default implementation checks for existence of property and ignores visibility.

● Does not apply to static context.

__unset

● public mixed __unset($name)

● Triggered by calling unset() on inaccessible properties

● Default implementation removes accessible properties.

● Does not apply to static context.

Property Test

See code fromhttp://www.php.net/manual/en/language.oop5.overloading.php#object.get

Method Overloading

● __call

● __callStatic

__call

● public mixed __call($name, $params)

● Called when invoking inaccessible methods from an object context.

__callStatic

● public static mixed __callStatic($name, $params)

● Called when invoking inaccessible methods from a static context.

__call / __callStatic<?phpclass MethodTest{ public function __call($name, $arguments) { echo "Calling object method '$name' " . implode(', ', $arguments). "\n"; }

public static function __callStatic($name, $arguments) { echo "Calling static method '$name' " . implode(', ', $arguments). "\n"; }}

$obj = new MethodTest;$obj->runTest(1, 2, 3, 'in object context');MethodTest::runTest(4, 5, 6, 'in static context'); // As of PHP 5.3.0?>$ php methodtest.phpCalling object method 'runTest' 1, 2, 3, in object contextCalling static method 'runTest' 4, 5, 6, in static context

Serialization

● __sleep

● __wakeup

__sleep

● public array __sleep()

● Called when serialize() is called on the object.

● Returns an array of field names to include in the serialized version of the object.

__wakeup

● public void __wakeup()

● Called when unserialize() is called on the serialized object.

__sleep / __wakeup

See code fromhttp://www.php.net/manual/en/language.oop5.magic.php#object.sleep

Cloning

● __clone

● __set_state

__clone

● public void __clone()

● Called after the object is initialized.

● Default implementation does nothing.

__clone

See code fromhttp://www.php.net/manual/en/language.oop5.cloning.php#object.clone

__set_state

● public static void __set_state($properties)

● Called for classes exported by var_export().

__set_state

See code fromhttp://www.php.net/manual/en/language.oop5.magic.php#object.set-state

Object Invocation

● __invoke

__invoke

● public mixed __invoke($params, ...)

● Called when the object is treated like a function.

– $obj(1,2,3);

__invoke

<?phpclass CallableClass{ public function __invoke($x) { var_dump($x); }}$obj = new CallableClass;$obj(5);var_dump(is_callable($obj));?>

$ php invoke.phpint(5)bool(true)

Performance

● Each benchmark was run 10 times.

● Each run is shown as a different set of columns in the graphs.

● Each run is exactly 1 million calls to the item being tested.

Performance

Performance

Performance

Performance

Performance

Performance

Thank you for your time.Any Questions?

Lucid Software Inc● Building the next generation of collaborative web

applications

● VC funded, high growth, profitable

● Graduates from Harvard, MIT, Stanford

● Team has worked at Google, Amazon, Microsoft

https://www.lucidchart.com/jobs

Recommended