PHP7 and Modern PHP ecosystem

Falkirk LUG Edinburgh February 2016

Old PHP logo Logo PHP 7

By Thomas Dutrion / @tdutrion - 02/02/2016

About me

  • Founder & Developer / web architect at Engineor
  • Working with PHP since 2003
  • Doing my best to work properly!
Photo Thomas Dutrion Engineor Logo

Scotland PHP

Scotland PHP logo

Aberdeen (1st Wednesday)
Edinburgh (2nd Tuesday)
Glasgow (3rd Tuesday)
Dundee (4rd Thursday)

https://www.scotlandphp.co.uk

Origins of PHP

Personal Home Page

  • 1994
  • Rasmus Lerdorf
  • Simple web pages with templating, forms and database access
  • Not a programming language

<!--include /text/header.html-->

<!--getenv HTTP_USER_AGENT-->
<!--ifsubstr $exec_result Mozilla-->
  Hey, you are using Netscape!<p>
<!--endif-->

<!--sql database select * from table where user='$username'-->
<!--ifless $numentries 1-->
  Sorry, that record does not exist<p>
<!--endif exit-->
  Welcome <!--$user-->!<p>
  You have <!--$index:0--> credits left in your account.<p>
<!--include /text/footer.html-->
						

PHP: Hypertext Preprocessor

  • 1998
  • Zend founders (Zeev Suraski and Andi Gutmans) rewrite the PHP parser
  • Gives us PHP3, change the acronym meaning
  • Transforms it into a programming language (sort of)

Unfortunately similar to what most people learn in universities and schools...

PHP 4 / 5

  • Object oriented programming
  • Keeping backward compatibility
<?php
class Car implement Vehicle
{
  private $colour;
  public function hasFourWheels()
  {
    return true;
  }
}
$car = new Car();
var_dump($car->hasFourWheels());

In a nutshell

  • Weakly typed language
  • Weird inconsistencies in function naming as a result
  • Not designed as a programming language, became one
  • Easy to learn
  • Large community, not only developers

Example (PHP 5)

<?php
function add($item1, $item2) {
  return $item1 + $item2;
}

var_dump(add(1, 1));
// int(2)

var_dump(add(1, 'test'));
// int(1)

var_dump(add(1, array('test')));
// Fatal error: Uncaught Error: Unsupported operand types

Example (PHP 5)

<?php
class Car {}
function functionUsingCar(Car $car) {}

$car1 = new Car();
functionUsingCar($car1);

$car2 = new stdClass();
functionUsingCar($car2);
// Catchable fatal error: Argument 1 passed to functionUsingCar()
// must be an instance of Car, stdClass given

Example (PHP 5)

<?php
try {
  throw new Exception('an error occurred');
} catch (Exception $e) {
  echo $e->getMessage();
  // an error occurred
}

try {
  trigger_error('an error occurred');
} catch (Exception $e) {
  echo $e->getMessage();
}
// Notice: an error occurred in /in/MoXC0 on line 10

PHP 7

  • Scalar type declarations
  • Return type declarations
  • Null coalescing operator
  • Spaceship operator
  • Constant arrays
  • Anonymous classes
  • Expectations
  • ...

http://php.net/manual/en/migration70.new-features.php

Scalar type declarations

  • coercive
  • strict

Coercive scalar type

PHP tries to convert the value to the expected type before validating the argument (default behaviour).

<?php
// Coercive mode
function sumOfInts(int ...$ints)
{
    return array_sum($ints);
}

var_dump(sumOfInts(2, '3', 4.1));
// result = 9 (2 + 3 + 4, 4.1 being converted to int)

Strict scalar type

Has to be declared in each file.

Also impacts return types, PHP build-in functions and extensions.

<?php
declare (strict_types=1)
// Strict mode
function sumOfInts(int ...$ints)
{
    return array_sum($ints);
}

var_dump(sumOfInts(2, 3, 4));
//int(9)

var_dump(sumOfInts(2, '3', 4.1));
// Fatal error: Uncaught TypeError: Argument 2 passed to sumOfInts()
// must be of the type integer, string given
// Next TypeError: Argument 3 passed to sumOfInts() must be of the
// type integer, float given

Return types (coercive)

<?php
function add($a, $b) : float {
	return $a + $b;
}
var_dump(1, 2);
// float(3)

Return types (strict)

<?php
declare (strict_types=1);
function add($a, $b) : float
{
    return $a + $b;
}

var_dump(1, 2);
// float(3)

var_dump(1.1, 2);
// Fatal error: Uncaught TypeError: Return value of add() must
// be of the type integer, float returned
  • Lots of new features, but a good language for software engineering teams
  • Flexible enough (if you do not want to specify a type, don't bother, if you want values to be casted before... that's the default behaviour)

HHVM, Facebook and so on...

HHVM is an open-source virtual machine designed for executing programs written in Hack and PHP.

Problem: how can you be sure you can run PHP programs?

Solution: Facebook and some PHP core contributors wrote a language specification based on PHP 5.6.

https://github.com/php/php-langspec

PHP FIG and PSR

Problem (?): PHP is too permissive

  • Object oriented or procedural?
  • All in one file or multiple directories?
  • Include files manually or use an autoloader?
  • ...

Problem (?): too many frameworks

  • Zend Framework
  • Symfony
  • Laravel
  • CakePHP
  • Code Igniter
  • ...

Using the community effort to write the same piece multiple times.

Solution:

a Framework Interoperability Group

Writing recommandations for interoperability.

Currently:

  • PSR0: Autoloading (deprecated)
  • PSR1: Basic coding standard
  • PSR2: Coding style guide
  • PSR3: Logging
  • PSR4: Autoloading
  • PSR6: Caching
  • PSR7: HTTP Message Interface

Example: Zend Framework 2

Zend \ Log \ LoggerInterface PSR 3
Zend \ Loader \ AutoloaderFactory PSR 4 autoloading
Zend \ Cache \ Storage \ StorageInterface PSR 6
Zend \ MVC \ Controller \ AbstractActionController PSR 7 Middleware (callable, invokable class)

Example: Zend Expressive

Routing
  • Aura.Router
  • FastRoute
  • ZF2's MVC router
DI Containers
  • Zend\ServiceManager
  • PHP-DI
  • Aura.DI
  • ...
Templating
  • Plates
  • Twig
  • ZF2's PhpRenderer

Composer

composer logo

Dependency Manager for PHP

Why composer on Twitter

How to use it

  • Requires PHP CLI
  • Parse composer.json requirements
  • Compute and retrieve packages
  • Write dependencies in composer.lock
  • Inlude vendor/autoload.php

Thanks for having me!