PHP 7.3. What's new

PHP 7.3. What's new
Mitigate the requirements for the syntax of Heredoc and Nowdoc
Support for endpoints in function and method calls
References in list ()  


Obsolete features (deprecated)

  2. Function image2wbmp () declared obsolete  
  4. Register-independent constants are declared obsolete  


New features

  2. Optional exception throw for errors in functions json_encode and json_decode  
  3. Adding the function is_countable ()  
  4. Adding the functions array_key_first () and array_key_last () Heredoc and Nowdoc required to put the closing identifier first in the new line.


        $ foo = IDENTIFIER
    the crazy dog ​​jumps over the lazy fox
    "foo" bar;


    Here the closing IDENTIFIER should be the first symbol on a new line to make it work. In addition, there should not be any other characters after the closing identifier (except
    ? , Which is optional).


    RFC for PHP 7.3 suggests removing such requirements to improve the readability of the code. First of all, to add indents when using heredoc /nowdoc identifiers.


    Full list of changes in heredoc /nowdoc Syntax:

    2. The closing identifier need not be the first character in the string.  
    3. The closing identifier has a gap with spaces or tabs.  
    4. Indentation (spaces or tabs) should not be mixed. If you do this, you will get Parse error: Invalid indentation - tabs and spaces can not be mixed in on line
    5. The exact number of spaces /tabs used before the closing identifier will be removed from each line heredoc /nowdoc expression.  
    6. If the number of backslashes used before the closing identifier is greater than in any of the expression strings, you will get Parse error: Invalid body indentation level (expecting an indentation level of at least ) in on line
    7. several expressions after the closing identifier will work without errors  


    Here is a snippet that uses new features without violating the new rules:

        $ foo =['foo', 'bar', EOT
    - hello world! --
    EOT, 'qux', 'quux'
    var_dump ($ foo);


    The output will be:

        array (5) {
    string (3) "foo"
    string (3) "bar"
    string (29) "baz
    .- hello world! -
    string (3) "qux"
    string (4) "quux"
    } `


    Note that the indents used in the declaration with heredoc do not appear in pin var_dump () , and we continued to enumerate the elements of the array after EOT identifier.


    RFC , discussion on , implementation of


    Effect on backward compatibility


    Until you use a set of identical heredox /nowdoc identifiers of characters as the beginning of the line, you are on the horse.

        $ foo = HELLO
    HELLO_WORLD <-- это не будет приниматься за окончание строкового литерала
    HELLOWORLD <-- и это не будет
    HELLO WORLD <-- а это будет


    If you have heredoc /nowdoc syntax similar to the above, I note that with PHP 7.? PHP will accept the first HELLO literal and will throw an error on the next line. In earlier versions of HELLO WORLD It was not perceived as a closing identifier for heredoc. Thanks /u /ImSuperObjective2 with reddit for the reference to this is


    Support for endpoints in function and method calls


    This is a simple change that allows the use of endpoints in calls functions and methods. This does not affect the declaration.


    For example, the following syntax is possible:

    foo ('bar', 'baz',); //Pay attention to the last comma after 'baz'


    In pre-PHP-7.3 versions, the fragment above throws an error PHP Parse error: syntax error, unexpected ')' in on line


    You can not use more than one comma at the end or use commas to skip arguments. Basically this change is for a function with variable parameters. Also, with new edits, the syntax of the array will look more consistent.


    Note that you can not use this feature in function /method declarations; this is wrong:

        function foo ($ bar, $ baz,) {//nah, you can not do this.


    RFC , discussion on , implementation of


    Effect on backward compatibility


    Nothing. The existing code will continue to work. If you have function calls accepting variable parameters, add endpoints to these locations for convenience. But to use them everywhere is clearly overkill.


    References in list ()


    Function list () It is useful for quickly assigning values ​​to the variable from the array. Prior to PHP 7.? it was not possible to specify a variable by reference. Prior to PHP 7.? the following fragment resulted in a fatal error:

        $ arr =['apple', 'orange'];
    list ($ a, & $ b) = $ arr;
    $ b = 'banana';
    echo $ arr[1];
    //Fatal error:[]and list () assignments can not be by reference in on line


    Refer to non-referencable variables can not be: list ($ a, & $ b) =[12, 14]; will issue Fatal error: Can not assign reference to non referencable value in on line


    RFC , discussion on , implementation of


    Effect on backward compatibility


    No. Instead of using list () to fill several variables, I would suggest that you use value objects to make everything simpler. They will still be passed by reference, but will make your code much cleaner.


    Function image2wbmp () declared obsolete


    image2wbmp () function from the GD extension is used to output the image in the WBMP (Wireless Bitmap) format. In PHP 7.? it is declared obsolete in favor of the function. imagewbmp () .


    If you are using image2wbmp () , then simply replace the function name with imagewbmp and all will be well! More than ?500 mentions image2wbmp () on github against more than 3?300 mentions imagewbmp () . It looks like the PHP development team is removing the rarely used functions to minimize the impact.


    RFC , discussion on , implementation of


    Effect on backward compatibility


    If you use the function image2wbmp () , replace the call with imagewbmp . Use automation, which can change it for you.




    This is moving forward. When you use filter_var ($ var, FILTER_VALIDATE_URL) , there are two additional flags that you can put to ensure strict verification of the URL: FILTER_FLAG_SCHEME_REQUIRED and FILTER_FLAG_HOST_REQUIRED .
    Starting with PHP 5.2.? both these flags are applied implicitly regardless of whether they are installed or not.


    If your code uses these flags, just delete them and it will be fine. At the moment there are more than 5000 search results on github with their use.


    RFC , discussion on , implementation of


    Effect on backward compatibility


    Since both these flags are declared obsolete, you will see a notification like:

        Deprecated: filter_var (): explicit use of FILTER_FLAG_SCHEME_REQUIRED and FILTER_FLAG_HOST_REQUIRED is deprecated in


    All you need to do is just delete the two flags, because they are already implied when using FILTER_VALIDATE_URL .


    Register-independent constants are declared obsolete


    Function define () allows you to declare a constant in register-independent mode. You must explicitly declare a constant with case sensitivity, passing the function to the third parameter. true . This is not the default behavior and certainly not consistent with the ability to declare constants through the keyword const .

        define ('Foo', 'Bar', true);    


    The above code will throw out the notification of obsolescence: Deprecated: define (): Declaration of a case-insensitive constants is deprecated in


    In addition, when you try to access constants that have been declared in case-insensitive mode ( FOO ), You will see a very useful warning: Deprecated: Case-insensitive constants are deprecated. The correct casing for this constant is "Foo"


    RFC , discussion on , implementation of


    Effect on backward compatibility


    You will have to go to the base code, where register-independent constants are declared and subsequently corrected. It is highly unlikely that there will not be any problems with this, because catching all the use cases is quite labor-intensive, but as a result, the code becomes clearer.


    I did not find examples of such use on github, but at least Drupal and WordPress (two fairly old and mature projects in PHP) have case-independent constants.


    Optional exception throw for errors in functions json_encode and json_decode


    One of my favorites. All these years json_encode () and json_decode () were silent about errors in PHP-variables or json-lines, which resulted in an accented code. This incident was even in the famous criticism PHP: The Fractal of Bad Design .

    json_decode returns null for invalid input, while null is absolutely correct for the decoded JSON. This function is completely unreliable, unless you call json_last_error every time you use it.

    It took 6 years after that blog post and we got the opportunity to get an error about the crashes with json:

        try {
    json_decode ("{", false, 51? JSON_THROW_ON_ERROR);
    catch (JsonException $ exception) {
    echo $ exception-> getMessage (); //prints "Syntax error"


    The new JsonException is the heir from Exception , and also the constant JSON_THROW_ON_ERROR and himself JsonException are in the global namespace.


    I highly recommend that you start using this feature. There are third-party libraries, such as daverandom /exceptional-json , implementing similar functionality for PHP versions 7.2 and below. With the advent of this function in the PHP kernel, you can remove this package and tons of ugly template code with a call to json_last_error () in every place where you work with json.


    RFC , discussion on , implementation of


    Effect on backward compatibility


    No, if you do not use your own exception and /or constant with the same name.


    Adding the function is_countable ()


    In PHP 7.? there are a lot of obsolete and bummed functions. If you are in PHP 7.2. call count () with the use of non- countable variable, PHP will display a warning about it. In general revisions there was a proposal to check the received one at countable before its use in count () .


    countable A variable is an array or object that implements Countable interface. Since the test will use a lot of template code, PHP 7.3 introduced a new function is_countable () , checking the variable for well the possibility of using with count () .


    I wrote polyfile for is__countable () , if you want to start using this opportunity now.


    RFC , discussion on , implementation of


    Effect on backward compatibility


    While its own function is not declared is_countable () , there will be no problems.


    Adding the functions array_key_first () and array_key_last ()


    In PHP, there are 75 different functions for working with arrays, but so far there has been no easy way to get the first and last keys of an array without changing the array pointer or enumerating all keys (through Array_keys () ) And why getting the first /last value .


    There were two new functions, array_key_first () and array_key_last () allowing it to do.


    The RFC also proposed adding array_value_first () and array_value_last () , but this part did not pass the vote.


    RFC , discussion on , implementation of


    Effect on backward compatibility


    If you did not declare your own array_key_first () and array_key_last () function, there will be no problems.


    Migration from PCRE to PCRE2


    PHP uses Perl Compatible Regular Expressions or shortly PCRE in the library for working with regular expressions. Since PHP 7.? version 8.x of legacy library PCRE is used, and in PHP 7.3 PCRE2 will already be used. Note that PCRE2 is considered a new library, although it is largely compatible with PCRE (8.x).


    The new library is more aggressive in the validation of patterns and can lead to errors in the existing code. The following snippet will be invalid with PHP 7.3:

        preg_match ('/[w-.]+ /', '');    


    PHP will throw a warning Warning: preg_match (): Compilation failed: invalid range in character class at offset 3 .
    Problem with the template: for this to work the hyphen should be moved to the end or screened.

        preg_match ('/[w-.]+ /', '');    


    The above code works fine not only with PHP 7.? but also with older versions. In the new hyphen pattern, is shielded. - in - . This is the most common problem of all that you can encounter when solving compatibility issues.


    This is a fairly minor change, but there is a chance that everything will go wrong. The error message indicates the exact position of the character in the regular expression. Be sure to carefully check your code. Check your regular expressions for compatibility with PCRE2 syntax through Regex Buddy or other similar software. For more information, see description PCRE2 syntax and the obsolete PCRE syntax .


    RFC , discussion on , implementation of


    Effect on backward compatibility


    Since PCRE2 is more picky and strict to templates, some of your preg_match () and similar calls may not work. The fix varies from a simple template update (for example, to mask hyphens) to rewriting templates. Make sure that all your tests pass.

+ 0 -

Add comment