gstreamer0.10-ffmpeg
gstreamer0.10-plugins-good
packages.
Of course the big big features of PHP 7 are scalar type-hinting and return types. Let's play with scalar type-hinting first.
Open up src/AppBundle/Controller/GenusController.php
. Let's create a new page to play with: public function typesExampleAction()
. Above that, I'll use @Route("/types")
to map a URL to this.
I already have a normal PHP class called Genus
... which is a type of animal classification. It has an id
, name
, speciesCount
, funFact
and a few other things.
Back in the controller, let's create a new genus: $genus = new Genus()
. The genus's name should obviously be a string. But, let's be difficult and set it to an integer: $genus->setName(4)
. Below, var_dump($genus);
and then die;
.
... line 2 | |
namespace AppBundle\Controller; | |
... lines 4 - 14 | |
class GenusController extends Controller | |
{ | |
/** | |
* @Route("/types") | |
*/ | |
public function typesExampleAction() | |
{ | |
$genus = new Genus(); | |
$genus->setName(4); | |
var_dump($genus);die; | |
} | |
... lines 27 - 152 | |
} |
Cool! In the browser, head to /types
to check it out. It works! Even though we think name
should be a string, PHP lets us pass whatever we want. Right now, name
is actually an int.
In PHP 5, we could type-hint arguments... but only with either array
, callable
or a class name. Well, no more! In PHP 7, we can type-hint with string
... or int
, float
, bool
or pizza
. Wait, not pizza
.
... lines 2 - 3 | |
namespace AppBundle\Entity; | |
... lines 5 - 17 | |
class Genus | |
{ | |
... lines 20 - 102 | |
public function setName(string $name) | |
{ | |
$this->name = $name; | |
} | |
... lines 107 - 222 | |
} |
But, woh! PhpStorm is super mad about this. That's because my PHPStorm is living in the past! It's still configured to parse things as PHP 5. Open the PHP Storm settings and search for PHP. Under "Languages and Frameworks", set the version to 7.1 We'll also be showing off some 7.1 features.
So much happier! With just this one small change, go back, refresh and watch closely. Specifically, watch the "name integer 4" part. Woh! Now it's a string 4.
You see, PHP 7 types now have two modes: weak mode and strict mode. When you use weak mode - which is the default - PHP will try to "coerce" the argument into whatever the type-hint is. In this case, it turns the integer 4 into a string 4. And we're totally accustomed to this in PHP: if you try to echo an integer or treat it like a string in any way, PHP automatically makes it a string.
But if you use strict mode, things are much different. Instead of changing the value from an integer to a string, it will throw an error: a TypeError
. How do we activate strict mode?
At the top of Genus
, make the very first thing in the file say declare(strict_types=1);
. This must be the first line in the file.
declare(strict_types = 1); | |
... line 3 | |
namespace AppBundle\Entity; | |
... lines 5 - 17 | |
class Genus | |
{ | |
... lines 20 - 222 | |
} |
But check this out: when we refresh... still no error! What's the deal? Copy that line, open GenusController
and paste it here.
declare(strict_types = 1); | |
... line 3 | |
namespace AppBundle\Controller; | |
... lines 5 - 15 | |
class GenusController extends Controller | |
{ | |
... lines 18 - 153 | |
} |
Now refresh again.
Boom!
This is the error we expected:
TypeError
Argument 1 passed tosetName()
must be type string, integer given.
This... is a bit confusing. The important thing is that strict_types
is added to the file where we pass the value... not actually the file where we add the type-hint. When you add strict_types=1
, you're saying:
I want "strict" type-checking to be applied to all function calls I make from this file.
It's done this way on purpose: if you download an external library that uses scalar type-hints, you get to decide whether or not you want arguments you pass to its functions to be strictly type-checked. You, the developer, get to opt into strict mode.
So... which should you use? It's up to you... just remember that you've been using PHP for years in "weak mode". If it's never bothered you that PHP automatically changes integers to strings instead of throwing an error, you might choose to keep using weak mode. When you enable strict mode, your code will be more predictable... but you'll also see - and need to correct - a lot more errors.
And remember! You can use scalar type-hints in either mode. There's also one more thing to consider when choosing between weak or strict mode: return types.
Hey Emin,
We require PHP ">=5.5.9" that means it'll work on PHP 7 as well, so you don't need to change this to allow PHP 7 in your project.
Cheers!
Hi @vvictor,
First Thank you for the fast reply
When i revert it back to the old state it seems it locks on to version 5.5 and i cant seem to unlock it to set it to 7.1
Kind regards,
Emin
Hey Emin,
Hm, probably I do not completely understand what exactly is locked? Are you talking about some dependencies that are locked to PHP 5.5? Do you mean Composer dependencies are locked for PHP 5.5? I bet you can just run "composer update" without changing that "php": ">=5.5.9" line and composer will update your dependencies according to PHP 7.
Cheers!
// composer.json
{
"require": {
"php": ">=5.5.9",
"symfony/symfony": "3.3.*", // v3.3.18
"doctrine/orm": "^2.5", // v2.7.2
"doctrine/doctrine-bundle": "^1.6", // 1.10.3
"doctrine/doctrine-cache-bundle": "^1.2", // 1.3.2
"symfony/swiftmailer-bundle": "^2.3", // v2.5.4
"symfony/monolog-bundle": "^2.8", // v2.12.1
"symfony/polyfill-apcu": "^1.0", // v1.3.0
"sensio/distribution-bundle": "^5.0", // v5.0.19
"sensio/framework-extra-bundle": "^3.0.2", // v3.0.25
"incenteev/composer-parameter-handler": "^2.0", // v2.1.2
"knplabs/knp-markdown-bundle": "^1.4", // 1.5.1
"doctrine/doctrine-migrations-bundle": "^1.1", // v1.2.1
"stof/doctrine-extensions-bundle": "^1.2", // v1.2.2
"composer/package-versions-deprecated": "^1.11" // 1.11.99
},
"require-dev": {
"sensio/generator-bundle": "^3.0", // v3.1.4
"symfony/phpunit-bridge": "^3.0", // v3.2.8
"nelmio/alice": "^2.1", // v2.3.1
"doctrine/doctrine-fixtures-bundle": "^2.3", // v2.4.1
"symfony/web-server-bundle": "3.3.*"
}
}
Hey,
Thanks for these video's i really enjoy them watching. Maybe an idea.
When i try to change php 5 to php 7 i realised that in the composer.json its locked to version 5 maybe make a composer.json that its on 5 first then you get the list like in the video.
Kind regards,
Emin