PHP 7 - how to take advantage of the new features

I have recently installed Php 7 and delighted and also amazed to say there were no problems!

I would be grateful for any recommendations, tips, tricks, tutorials on how to utilize the new features.

A feature I like and will endeavour to use as much as possible is:

<?php
// MUST(?) be declared first and is ONLY file wide(?)
declare(strict_types=1); 

I am curious to know if the declaration could be applied globally to every file (within a project) without having to hard-code the declaration?

Two other features I like:

  1. Combined Comparison Operator - the ā€œspaceshipā€ operator <=>
  2. Scalar Type Hints & Return Types - should/could be applied globally?

I have already discovered that ini_set('display_errors', 1); is not acceptable and the second parameter must be a string :frowning:

1 Like

I’ve never tried it, but I’ve seen this in the php.ini

; Automatically add files before PHP document.
; http://php.net/auto-prepend-file
auto_prepend_file =

; Automatically add files after PHP document.
; http://php.net/auto-append-file
auto_append_file =
1 Like

@Mittineague

Many thanks I was not aware of that feature.

I had a real belly laugh…

auto_prepend works and so does declare(strict_types=1); BUT it only applies to the prepended file :frowning:

That’s too bad… I guess it might come in handy for other things, Maybe a global SESSIONs?

It might be worth the time to write a recursive r+ file writing script.

Yes it is rather a neat feature and I am trying to think of the best usage. It is good that I can use it on locally and it will have no effect on files uploaded to the server.

The usage I had in mind was for a PHP Framework which uses quite a few libraries, controllers, models, views, etc. I was hoping to be able to toggle the feature and gradually eliminate the new found errors, warnings and to update the code. (I should imagine it will not be an easy task but rather an ongoing project.)

Using the ā€œ** recursive r+ file writing**ā€ would hard-code the script and I should think create problems

###Edit
I defined a boolean TOGGLE_STRICT constant in the included auto_prepend file and can now safely write a recursive r+ file.

<?php 
if ( defined( 'TOGGLE_STRICT' ) ) {
  declare(strict_types=1);
}

Above is yet to be tested.

Test Results:

Fatal error: strict_types declaration must be the very first statement
in the script in /home/john/www/a-tests/ds-rating/test-001.php on line 5

Back to the drawing board :frowning:

I’ve not plucked up the courage to upgrade yet, but I like the idea of the ?? operator - succinctly called the null coalescing operator…

intdiv() looks interesting

var_dump(intdiv(10, 3)); //  int(3)
var_dump((10/3)); //  float(3.3333333333333) 

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

and the unicode endpoint escape works

echo "\u{1F648} \u{1F649} \u{1F64A}";

Personally, I hope strict_types is used sparingly and for most cases I’m not a fan of this. Why? Because it’s against the nature of PHP, which is inherently weakly typed - all internal functions and operators operate in weak type mode and I think for consistency sake it’s a bad idea to introduce strict typing. If mixed, we will end up in two type opposing paradigms and for the developers it is not immediately obvious whether a method’s signature is weakly or strictly typed. It’s like trying to make PHP behave like a different language. I think the default scalar type hinting added in PHP 7 has been done very sensibly and is following the overall weak typing that has existed in PHP from the beginning - and I’m really fond of how it functions - checking for correct values and type casting to the desired type. If a function requires an integer I want to be able to pass it a string value of ā€œ7ā€ - just because that’s what has always worked and is consistent.

I’m aware that this may be a controversial topic and I’m not saying one typing system is better than the other. I just think that mixing the two may become messy. If strict typing is ever used by developers I hope they use it only for their internal classes - but leave weak typing for their external APIs.

Some more read on the matter: A case for weak type hints only in PHP7 — Whitewashing

You would almost certainly have to right? I mean even in C#, a strongly typed language, your API exposure is usually an XML or JSON object coming in, an XSD may validate it, but you still have to cast it down internally to the actual type you want it to be and send back an error when you get something you don’t expect.

1 Like

Well, I didn’t really mean ā€˜external’ in such an extensive sense as communicating with other systems via XML or JSON. I meant PHP libraries which expose their API to the programmers that use them in their projects - the API is usually a set of PHP classes with their public methods.

I’ve just tested declare(strict_types=1) and fortunately it cannot be used to enforce strict typing to the outside caller as I initially suspected. So a library developer cannot require its users (programmers) to use strict types when calling methods of the library - and the arguments will be type cast in a weak fashion by default. declare(strict_types=1) affects the calling code only so in this case all the power is in the hands of the library user. Whether the library developer uses strict_types or not will affect only the library classes, not the code that calls them. Seems reasonable.

1 Like

Ah, yes, I think I recall that from the RC when strict types were being debated. I sort of see those APIs similar to fully external APIs too though. Anytime you include an additional library, you have to assume (as the library) that any input could be invalid or in a format you didn’t expect. Handling that the best you can should always be something we devs strive to do.

I sort of agree and also think it is too late to try and introduce this feature, far better off to introduce a new PHP Mandatory Strict Typed Version possibly called PMS?

At least this introduction to using strict types is a start although I would have far preferred to have a global switch which would still allow the application to run but would be bloated because ot the generated warnings. Using strict and without any generated warning would produce a lean, mean application, performing a lot faster and use less memory (ideal for mobiles?) I think most compiled languages have this ā€œstrictā€ feature.

PHP started about 20 years ago and has cultivated a vast amount of programmers with sloppy habits. I doubt very few know of GIGO.

[Off Topic] This change reminds me when UK seat-belts were first made compulsory… how many modern drivers still do not use a seat belt? Personally I think all drivers should have a 12 inch sharp spike protruding from the steering column and not be allowed to wear safety-belts :slight_smile:

Geez! John for Prime Minister! :slight_smile:

1 Like

I mostly agree with you, however we need to remember that handling invalid formats ā€œas best as we canā€ may come at a cost of degraded performance and added complexity so the programmer has to decide how far to go in dealing with invalid inputs. Often it is not worthwhile to do elaborate input checking and the new scalar type hinting is a simple and fast way of dealing with invalid data - just type hint an argument and PHP will do the rest by throwing an exception in case of a bad value - in many cases this will be sufficient.

BTW, I have found a small new undocumented feature of PHP 7 - now it is possible to access class constants from an object instance saved in a property:

$c = $this->obj::MY_CONST;

In previous PHP versions an intermediate variable had to be used:

$obj = $this->obj;
$c = $obj::MY_CONST;

I still see that as a valid way of validating your input (as you had to tell PHP the hint). Hinting and letting the language do most of the work is definitely okay from where I stand, and then the programmer simply does the additional checks that PHP might not be able to do, is it in the format of XXX-XX-XXXX (when checking SSN), or what have you. Either way, you as a programmer took steps to validate the input by either letting the language do its part with its own type casting or adding additional logic to ensure what PHP can’t do alone is covered.

Interesting. I haven’t read the whole thread yet, but on the topic of global strict typing, I asked about it (can’t remember who), if it would be possible to make a global setting. I got the answer that it would be troublesome to do, as it might cause a lot of libraries and extension to break. I didn’t reply, as I didn’t want to push the subject, but my first thought was, ā€œMaybe that isn’t such a bad thing after all?ā€. Strict typing is needed to make JIT compilation a reality, which I would very much like to see. I’d like to see the critics be quieted, who keep saying PHP isn’t built for highly computational work.

Scott

Yes. This is one of the things I love about C#. I love that it can be compiled and it actually does have some weak typing aspects built in in a psuedo way. The var keyword for example, doesn’t tell you what must be received, but rather, that whatever value it does receive will become its type during compiling/runtime.

I actually like type hinting in PHP, I type hint just about everything now. Making it feel more strict and errors more obvious when you pass in the wrong object or what have you. I imagine a lot of other programmers will eventually move that direction, making most libraries utilizing type hinting, and thus make it easier to move to a global stict option. I believe such an option can exist, it just can’t be made default (yet and maybe never). It would then be up to each application to determine if they can enable it, if they can, great! If they can’t because of an external library, maybe push a patch to that library to make it work? (or ask them to consider making it work).

I think there are a lot of advantages to PHP supporting JIT compilation. It would drastically improve performance (even though they managed to do that with PHP 7 in other areas).

Is compilation impossible with weak typing? I understand some performance improvements can be done for compiled strict code but would weak compiled code be so much slower (if possible at all)?

No, it isn’t impossible, it just requires some dynamic compiling/interpretting at runtime. So if you do a lot of weak typing (without hints) throughout your application, your performance will likely be greatly impacted because what could be compiled, ended up being little to nothing and instead it is dynamically interpretting most of your variables on the fly.

If you use hints, the compiler can be more intuitive during compilation and optimize the output to run more efficiently.

Probably the best solution would be to have the strict mode optional in such a way that a compiler could make use of it with all optimizations - then developers could choose to use strict mode in any part of their application that they wish to compile to more efficient code. But I don’t think this will come any time soon because strict mode is not only about argument hints but also all internal and extension functions and built in operators - all that would have to be changed to operate in strict type mode, which I presume is a lot of work.

Overall, I think the only significant new features in PHP 7 that can affect in a serious way designing application structure are argument hints, return types and the error handling with exceptions. All the other features are minor convenience improvements - they are great improvements nevertheless but nothing that change the way we structure applications. Which I think is good - it’s a mixture of new features that allows for a fairly good level of backwards compatibility.