New things in php

58
"NEW" THINGS IN PHP CHECKING THE MOST RECENT AND USEFUL RESOURCES FROM PHP Juan Basso ( ) from Zumba Fitness ® @jrbasso

description

Presentation from Juan Basso, Technical Architect, about few PHP features to all developers in Technology department. The goal is to keep all developers in synch with all features used by Zumba applications.

Transcript of New things in php

Page 1: New things in php

"NEW" THINGS IN PHPCHECKING THE MOST RECENT AND USEFUL RESOURCES FROM PHP

Juan Basso ( ) from Zumba Fitness ®@jrbasso

Page 2: New things in php

AUTOLOADPros:

Don't worry about require/includeLazy load files

Cons:

Slower than requireRequire some standard in file names

Page 3: New things in php

AUTOLOADExample of file organization

lib / PHPUnit / Framework / TestCase.phplib / PHPUnit / Framework / TestSuite.phpautoloader.php

Page 4: New things in php

AUTOLOAD - HOW TO NOT LOAD

Used in PHP 4Limited to one per requestDO NOT USE IT!!!

function __autoload($class) { $filename = str_replace('_', DIRECTORY_SEPARATOR, $class); if (file_exists($filename)) { require $filename; }}

Page 5: New things in php

AUTOLOAD - HOW TO LOAD

Available since PHP 5.1.2Allow multiple registrations per requestCan be any callable

function phpunit_loader($class) { if (strpos($class, 0, 8) !== 'PHPUnit_') { return; }

$filename = str_replace('_', DIRECTORY_SEPARATOR, $class); if (file_exists($filename)) { require $filename; }}spl_autoload_register('phpunit_loader');

Page 6: New things in php

AUTOLOAD - COMMON PATTERNPEAR - UNDERSCORED CLASSES

Every underscore in the class means the directory separator.

Compatible with PHP 4.

Ie, PHPUnit_Framework_TestCase refers toPHPUnit/Framework/TestCase.php.

Page 7: New things in php

AUTOLOAD - COMMON PATTERNPHP STANDARD RECOMMENDATION (PSR-0)

Same as PEAR, but also cover namespaced classes.

In namespaces, the namespace separator is replaced by directoryseparator.

Ie, Cake\Controller\Component\AuthComponent referens toCake/Controller/Component/AuthComponent.php.

Page 8: New things in php

STANDARD PHP LIBRARY (SPL)Classes, interfaces and functions built for standard problems.

Most used: exceptions, iterators, file manipulation, autoload

Page 9: New things in php

SPL - COUNTABLECan use count function in objects.

class Foo implements Countable { protected $items = array();

public function add($item) { $this->items[] = $item; }

public function count() { return count($this->items); }}$obj = new Foo();$obj->add('bar');$obj->add('foobar');$size = count($obj); // Results 2

Page 10: New things in php

SPL - TRAVERSABLEAllow foreach in objects.

class Foo implements Traversable, IteratorAggregate { protected $a = 'foo'; protected $b = 'bar';

public function getIterator() { return new ArrayIterator($this); }}$obj = new Foo();foreach ($obj as $key => $value) {}/* Same as: array( 'a' => 'foo', 'b' => 'bar )*/

Page 11: New things in php

SPL - FILE INFOSplFileInfo give information about specific file. Can be used with

folders and symbolic links too.try { $file = new SplFileInfo('/path/to/file'); $file->isFile(); // boolean if it is a file $file->isWritable(); // Can write in the file $file->getBasename(); // Filename, without folder $file->getLinkTarget(); // Where the link goes $file->getSize(); // File size $file->getRealPath(); // Real path of file} catch (Exception $e) { echo $e->getMessage(); // Probably a file not found}

Page 12: New things in php

SPL - DIRECTORY ITERATORLook for files, folders and symbolic links in specific folder.

$dir = new DirectoryIterator(__DIR__);

foreach ($dir as $fileinfo) { if (!$fileinfo->isDot()) { continue; } echo $fileinfo->getFilename(), "\n";}

Page 13: New things in php

SPL - EXCEPTIONSThere are couple build in exceptions.

if ($value > $max || $value < $min) { throw new OutOfBoundsException();}

switch ($value) { case 'foo': return 'bar'; default: throw new UnexpectedValueException();}

Page 14: New things in php

SPLCheck more in http://php.net/spl

Page 15: New things in php

EXCEPTIONSStop the code at that point and just stop in a catch block.

Help to revert changes in case of problems.

Page 16: New things in php

EXCEPTIONSExample:

try { $db->beginTransaction(); $db->query('UPDATE ...'); $db->query('INSERT ...'); $db->query('UPDATE ...'); // this throws an exception $db->commit();} catch (Exception $e) { $db->rollback(); echo $e->getMessage();}

Page 17: New things in php

EXCEPTIONSDoesn't matter the number of levels, it will stop until the catch.

function a() { throw new Exception('Oops'); }function b() { echo 'This works'; a(); echo 'This is not called';}function c() { echo 'This works'; b(); echo 'This is not called';}

try { c();} catch (Exception $e) { echo 'I got a() exception!'; }

Page 18: New things in php

EXCEPTIONSWhat happen if you not catch the exception?

Remember it could happen in the middle of a money transaction!

PHP Fatal error: Uncaught exception 'Exception' in ...

Stack trace:#0 {main} ...

Page 19: New things in php

EXCEPTIONSExceptions are classes. You can extend and take different actions for

each case.

Catch is tested in order using instanceof.

try { method1(); method2(); method3();} catch (InvalidArgumentException $e1) { echo 'Some method received an invalid argument';} catch (RangeException $e2) { echo 'Oops, some range problem';} catch (Exception $e) { echo 'Any generic exception';}

Page 20: New things in php

EXCEPTIONSSoapClient throws exception!!!

Always, I mean always, use try/catch when you do SOAP requests.

try { $cybersource = new SoapClient(...); $cybersource->chargeCard('4111111111111111', ...);} catch (SoapException $e) { // Transaction failed. Do not place the order}

Page 21: New things in php

EXCEPTIONS

Page 22: New things in php

ABSTRACTA class that can't be instanciated directly.

Used as base of other classes to have a standard.abstract class Foo {}

class Bar extends Foo {}

$bar = new Bar();// OK

$foo = new Foo();// PHP Fatal error: Cannot instantiate abstract class Foo ...

Page 23: New things in php

ABSTRACTabstract class User { protected $name;

public function name() { return $this->name; }

abstract public function isAbleToBuy();}

class Consumer extends User { public function isAbleToBuy() { return true; }}

class Admin extends User { public function isAbleToBuy() { return false; }}

class Distributor extends User {}// It will cause fatal error because do not// implement isAbleToBuy function

Page 24: New things in php

ABSTRACTYou can make your method expect an abstract class because you

know there is a method.class Shop { public function init(User $user) { if (!$user->isAbleToBuy()) { return false; } // ... }}

$user = new Consumer();$shop = new Shop();$shop->init($user);

var_dump($user instanceof Consumer); // Return truevar_dump($user instanceof User); // Return true

Page 25: New things in php

INTERFACECan't be instanciated or extended.Can use multiple in one class.Can provide abstract methods.Can provide attributes.Can't provide implemented methods.Can check if a class implements using instanceof.

Page 26: New things in php

INTERFACEinterface Foo { public function bar();}

class Blah implements Foo, Countable { public function bar() { return 'foobar'; }

public function count() { return 0; }}

var_dump(new Blah() implements Foo); // Return true

Page 27: New things in php

FINALDo not allow override by child classes.

Final can be used with classes and methods.final class Foo {

final public function bar() { }

}

Page 28: New things in php

FINALWhat is the different of final and private?

class Foo {

final public function init() {}

private function drop() {}

}

class Bar { public function __construct() { $this->init(); // It is OK $this->drop(); // It is not OK }}

Page 29: New things in php

TRAITSLazy Copy and Paste!

PHP 5.4+

Page 30: New things in php

TRAITStrait Foo { public function log($message) { Log::write($message); } public function sum($a, $b) { return $a + $b; } public function here() { return $this->here; }}

class Bar { use Foo;

protected $here;}

$obj = new Bar();$obj->foo('Lala');

Page 31: New things in php

TRAITSCan use multiple traits in the same class.Can change method visibility from the traits.Traits can use traits.Traits can contain abstract methods, attributes.

Page 32: New things in php

NAMESPACESThe partner library has a class called Address. The application also

has Address class.

How do you integrate???

Page 33: New things in php

NAMESPACESCan you have the same filename in the same directory? No. It happen

with PHP classes too.

Solution: namespaces!

Namespaces separate classes in groups and allow to re-use the sameclass name in different scope.

Page 34: New things in php

NAMESPACESnamespace Partner { class Foo { }}

namespace MyApp { class Foo { }}

$partner = new \Partner\Foo();$myapp = new \MyApp\Foo();

Page 35: New things in php

NAMESPACESClasses in the same namespace do not require the prefix.

namespace Foo;

class Bar { // Remember the class is \Foo\Bar}

class Foobar { public function __construct() { $this->bar = new Bar(); // Do not require the \Foo prefix }}

Page 36: New things in php

NAMESPACESClass in different namespace require prefix or use.

namespace Foo;

class Bar { public function __construct() { $this->foobar = new \Partner\Address(); }}

namespace Foo;use \Partner\Address;

class Bar { public function __construct() { $this->foobar = new Address(); }}

Page 37: New things in php

NAMESPACESBe careful to not conflict class from the same namespace with aliases.

namespace Foo;

use \Bar\Foobar, \Bar\DateTime as BarDateTime, \DateTime as GlobalDateTime;

$foobar = new Foobar(); // Instantiate \Bar\Foobar

$datetime = new BarDateTime(); // Instantiate \Bar\DateTime$datetime = new GlobalDateTime(); // Instantiate \DataTime$datetime = new DateTime(); // Instantiate \Foo\DateTime

class_alias('Bar\Foobar', 'Foo\FakeFoobar');$foobar = new FakeFoobar(); // Try to instantiate \Foo\Fakebar, // that is an alias for \Bar\Foobar

Page 38: New things in php

NAMESPACESRemember that PHP classes don't define a specific namespace. So

they are part of the global namespace.namespace Foo;

class Bar { public function __construct() { // Wrong - It will look for the class \Foo\DateTime $this->now = new DateTime();

// Correct $this->now = new \DateTime(); }}

Page 39: New things in php

NAMESPACESBe very careful with exceptions too!

namespace Foo;

try { func1(); // This method return a global Exception} catch (Exception $e) { // This code is not called} catch (\Exception $e) { // This code is called}

Page 40: New things in php

NAMESPACESNamespaces are not only for classes. You can do for functions too!namespace Foo;

function substr($string, $start, $end = null) { return 'something special';}

// It will use the function above$var = substr($var, 0, 10);

// It will use the PHP function$var = \substr($var, 0, 10);

// If not in the namespace, PHP will use global$pos = strpos($var, 'bar');

Page 41: New things in php

SESSION OR CACHE?User informations? SessionProduct information? CacheProducts bought by User? CacheCredit card? None!User addresses? Do you really need to store it?

Page 42: New things in php

SESSION OR CACHEHow to decide?

When the information...

Is strict for the user and can be reused in couple pages: store insession.Is shared between multiple users: store in cache.Is sensitive: do not store.Is big: consider to store.

Page 43: New things in php

SESSION OR CACHEWhy not store big data? It save queries!

Yes, it saves database, but remember that session is saved andrestored every request. If you have big data in the session, it will be

very slow to get the session in all pages.

Page 44: New things in php

SESSION - HOW IT WORKSClient side:

Client (browser) just store one IDClient (browser) send the ID in all requestsUsually the ID is a cookie, but could be a query/post parameterThe content of the session is not accessible by the browser

Page 45: New things in php

SESSION - HOW IT WORKSServer side:

Server receive the ID from the browser or generate a new IDServer load the session from the storage (database, file, memcache,...)Code read/write the values in the sessionWhen request finish, PHP put the session content on the storageagainWith the content, the expiration date/time is also savedEven if the session is not changed, it must be saved to update theexpiration time

Page 46: New things in php

CONSOLECan run console applications using PHP similar from web.

Provide $argc and $argv global variables.

Don't have few attributes from $_SERVER.

Finish with codes for the OS.

Can create threads/forks.

Can catch system events (ie, ctrl+c).

Can run for long time.

Can receive parameters from the terminal.

Can give you headaches.

Page 47: New things in php

PHPUNITclass Math {

public function sum($a, $b) { return $a + $b; }

}

class MathTest extends PHPUnit_Framework_TestCase {

public function testSum() { $math = new Math(); $this->assertSame(2, $math->sum(1, 1)); $this->assertSame(0, $math->sum(1, -1)); }

}

Page 48: New things in php

PHPUNIT - RESULTSjrbasso@zumba:/tmp$ phpunit MathTest.phpPHPUnit 3.7.0RC2 by Sebastian Bergmann.

.

Time: 0 seconds, Memory: 2.75Mb

OK (1 test, 2 assertions)

Page 49: New things in php

PHPUNIT - USUAL ASSERTSassertSame - Type and value identicals, same of ===assertEquals - Same value, same of ==assertTrue and assertFalse - Check boolean valuesassertNull - Check null valuesassertEmpty - Check empty variables, same of empty()assertInstanceOf - Check if the class (or parent class) matches.Same of instanceofAll assert above has the not version, ie assertNotSame

Page 50: New things in php

PHPUNIT - PARAMS AND MESSAGESParam order matter! Expected values first.

You could put error messages to enhance.

$this->assertSame($result, 5); // Wrong$this->assertSame(5, $result); // Correct

$this->assertSame(2, $result, 'I was expecting more from you');

1) MathTest::testSumI was expecting more from youFailed asserting that 23 is identical to 2.

Page 51: New things in php

PHPUNIT - ANNOTATION/EXCEPTIONS

REMEMBER: PHPUnit is PHP! Anything after the exception is NOTcalled! Don't put 2 tests in the same test method.

public function woops() { throw UnexpectedValueException('Not a good idea');}

public function testWoopsAlternative() { $this->setExpectedException('UnexpectedValueException'); $this->woops();}

/** * @expectedException UnexpectedValueException */public function testWoops() { $this->woops();}

Page 52: New things in php

PHPUNIT - DATA PROVIDERSDRY!

/** * @dataProvider sumData */public function testSum($a, $b, $expected) { $this->assertTrue($expected, $this->math->sum($a, $b));}

public function sumData() { return array( array(1, 1, 2), array(1, -1, 0), array(10000, 13, 10013), );}

Page 53: New things in php

PHPUNIT - MOCKCheck values or ignore behavior or both

class A {

public funciton run($ok) { if ($ok) { $this->email('[email protected]'); return true; } return false; }

protected function email($to) { return mail($to, 'It is ok', 'OK'); }

}

Page 54: New things in php

PHPUNIT - MOCKclass ATest extends PHPUnit_Framework_TestCase {

public function testRun() { $mock = $this->getMock('A', array('email'));

$mock->expects($this->at(0)) ->method('email') ->with($this->equals('[email protected]')) ->will($this->returnValue(true)); $this->assertTrue($mock->run(true));

$mock->expects($this->never()) ->method('email'); $this->assertFalse($mock->run(false)); }

}

Page 55: New things in php

PHPUNIT

Page 56: New things in php

PERFORMANCENetwork is your enemy!Cache can be fast, but involves networkRetrieve big content from cache/database is better than multiplesmallDo the table(s) the indexes necessary for your query?Big session, big delay, big headachesWeb servers are scalable, use it!Use more CPU and memory instead heavy requests to database

Page 57: New things in php

FASTCGI PROCESS MANAGER (FPM)Run PHP as daemon. Generic for any web server (apache, nginx, ...).

One web server can use multiple FPM servers (remotely).

Faster and safer than regular CGI.

Best option for non-apache solutions.

Page 58: New things in php

QUESTIONS?