The online racing simulator
PRISM & PHP 5.6.0 Examples
Implemented
  • Importing namespaced functions
    Proposes to allow importing namespaced functions through a new `use function` sequence.
    The proposal is to combine existing keywords to a new sequence that allows importing functions into a namespace. This should make namespaced functions less of a pain to use and discourage placing them in the global namespace. Since functions and classes are in separate namespaces, it is not feasible to use the use keyword for both, as it would likely result in conflicts and overhead. Instead of introducing a new keyword, it would be possible to combine use and function to a sequence. This new use function combo would work as follows:

    <?php 
    namespace foo\bar {
        function 
    baz() {
            return 
    'foo.bar.baz';
        }
        function 
    qux() {
            return 
    baz();
        }
    }

    namespace {
        use function 
    foo\bar\bazfoo\bar\qux;
        
    var_dump(baz());
        
    var_dump(qux());
    }
    ?>

    All of this applies not only to functions, but also to namespaced constants. For consistency, a use const sequence should also be introduced, that does the same thing for constants:

    <?php 
    namespace foo\bar {
        const 
    baz 42;
    }

    namespace {
        use const 
    foo\bar\baz;
        
    var_dump(baz);
    }
    ?>

    Just like classes, it should be possible to alias imported functions and constants:

    <?php 
    namespace {
        use function 
    foo\bar as foo_bar;
        use const 
    foo\BAZ as FOO_BAZ;
        
    var_dump(foo_bar());
        
    var_dump(FOO_BAZ);
    }
    ?>

    Functions can be treated as an extension of the language, or to be used to create a custom meta-language. An example of this is building a HTML tree, but this could be anything, really.
    A HTML building DSL:

    <?php 
    use function html\divhtml\phtml\em;

    $html div(p('Some'em('Text')));
    ?>

    Avoiding noise and clutter is really important to make this usable and readable.


  • Constant Scalar Expressions
    This RFC proposes adding support for Constant Scalar Expressions with support for constants being operands.
    This RFC brings static scalar expressions to the parser. This allows places that only take static values (const declarations, property declarations, function arguments, etc) to also be able to take static expressions.

    This can allow for writing far easier to understand code, by allowing for far more expressive code.

    The main difference to Anthony's RFC is (apart from a few operators more) that constants can be involved in these scalar operations:

    <?php 
    const 1;

    const 
    a?2:100// here the value of the constant "b" is dependent on the constant "a"
    ?>

    This also means that this is valid code:

    <?php 
    class Foo {
        const 
    FOO 1;
        const 
    BAR << 1;
        const 
    GREETING "HELLO";
        const 
    BAZ self::GREETING." WORLD!"
    }
    ?>

    As is this:

    <?php 
    const BAR 1;

    function 
    foo($a 1$b << 3$c BAR?10:100) {}
    ?>



  • Remove calls from incompatible context
    Calls from incompatible context deprecated in 5.6 (will be removed in next version).
  • Dedicated syntax for variadic functions
    This RFC introduces a dedicated syntax for variadic functions.
    Currently variadic functions are implemented by fetching the function arguments using func_get_args(). The following code sample shows an implementation of a variadic function used to prepare and execute a MySQL query (I'll be making use of this example throughout the RFC):

    <?php 
    class MySQL implements DB {
        protected 
    $pdo;
        public function 
    query($query) {
            
    $stmt $this->pdo->prepare($query);
            
    $stmt->execute(array_slice(func_get_args(), 1));
            return 
    $stmt;
        }
        
    // ...
    }

    $userData $db->query('SELECT * FROM users WHERE id = ?'$userID)->fetch();
    ?>

    There are two issues with the above approach:
    Firstly, by just looking at the function signature public function query($query) you cannot know that this is actually a variadic function. You'd think that the function can only run a normal query and doesn't support bound parameters.
    Secondly, because func_get_args() returns *all* arguments passed to the function you first need to remove the $query parameter using array_slice(func_get_args(), 1).

    This RFC proposed to solve these issues by adding a special syntax for variadic functions:

    <?php 
    class MySQL implements DB {
        public function 
    query($query, ...$params) {
            
    $stmt $this->pdo->prepare($query);
            
    $stmt->execute($params);
            return 
    $stmt;
        }
        
    // ...
    }

    $userData $db->query('SELECT * FROM users WHERE id = ?'$userID)->fetch();
    ?>

    The ...$params syntax indicates that this is a variadic function and that all arguments after $query should be put into the $params array. Using the new syntax both of the issues mentioned above are solved.


  • phpdbg
    Distribute phpdbg with PHP, a PHP debugger
In voting phase
  • Argument unpacking
    This RFC proposes a syntax for argument unpacking.
    This RFC complements the variadics RFC. It introduces a syntax for unpacking arrays and Traversables into argument lists (also known as “splat operator”, “scatter operator” or “spread operator”).

    As a usage example, consider a variadic method public function query($query, ...$params). You are provided a $query and an array of $params and want to call the method using these. Currently this is possible using call_user_func_array():

    <?php 
    all_user_func_array
    ([$db'query'], array_merge(array($query), $params))
    ?>

    This RFC proposes a syntax for unpacking arguments directly in the call syntax:

    <?php 
    db
    ->query($query, ...$params)
    ?>


Under Discussion
  • Expectations
    This RFC proposes adding a modern Expectation/Assertion API.
    The assertion statement has the prototype:

    <?php 
    oid assert 
    (mixed $expression [, mixed $message])
    ?>

    At execution time, expression will be evaluated, if the result is false, an AssertionException will be thrown. In some cases, expression will be an expensive evaluation that you do not wish to execute in a production environment, assertions can therefore be disabled and enabled via the PHP_INI_ALL configuration setting zend.assertions. Disabling assertions will almost entirely eliminate the performance penalty making them equivalent to an empty statement.

    In any case, assertions should never be used to perform tasks required for the code to function, nor should they change the internal state of any object except where that state is used only by other assertions, these are not rules that are enforced by Zend, but are nonetheless the best rules to follow. If an object of a class which extends AssertionException is used for message, it will be thrown if the assertion fails, any other expression will be used as the message for the AssertionException. If no message is provided, the statement will be used as the message in AssertionException. If expression is a constant string, compatibility with the old API is employed, the string is compiled and used as the expression.

    PHP programmers tend to document how their code is supposed to work in comments, this is a fine approach for generating automated documentation, but leaves us a little bewildered, and tired of digging through documentation at runtime when things go wrong:

    <?php 
    if ($i == 0) {
        
    // ...
    } else if ($i == 1) {
        
    // ...
    } else { // We know ($i % 3 == 2)
        // ...
    }
    ?>

    Becomes:

    <?php 
    if ($i == 0) {
        
    // ...
    } else if ($i == 1) {
        
    // ...
    } else {
        
    assert ($i == 2);
    }
    ?>

    In a development environment, this forces the executor to make you aware of your mistake.

    Another good example for using assertions might be a switch block with no default case:

    <?php 
    switch ($suit) {
        case 
    CLUBS:
            
    /* ... */
        
    break;

        case 
    DIAMONDS:
            
    /* ... */
        
    break;

        case 
    HEARTS:
            
    /* ... */
        
    break;

        case 
    SPADES:
            
    /* ... */
        
    break;
    }
    ?>

    The above switch assumes that suit can only be one of four values, to test this assumption add the default case:

    <?php 
    switch ($suit) {
        case 
    CLUBS:
            
    /* ... */
        
    break;

        case 
    DIAMONDS:
            
    /* ... */
        
    break;

        case 
    HEARTS:
            
    /* ... */
        
    break;

        case 
    SPADES:
            
    /* ... */
        
    break;

        default:
            
    assert (false"Unrecognized suit passed through switch: {$suit}");
    }
    ?>

    The previous example highlights another general area where you should use assertions: place an assertion at any location you assume will not be reached. The statement to use is:

    <?php 
    ssert
    (false)
    ?>

    Suppose you have a method that looks like:

    <?php 
    public function method() {
        for (
    /*...*/) {

            if (
    /* ... */)
                return 
    true;
        }

    }
    ?>

    The above code assumes that one of the iterations results in a return value being passed back to the caller of ::method(), to test this assumption:

    <?php 
    public function method() {
        for (
    /*...*/) {

            if (
    /* ... */)
                return 
    true;
        }
        
    assert(false);
    }
    ?>

    Assertions allow the possibility to perform precondition and postcondition checks:

    <?php 
    public function setResponseCode($code) {
        
    $this->code $code;
    }
    ?>

    Becomes:

    <?php 
    public function setResponseCode($code) {
        
    assert($code 550 && $code 100"Invalid response code provided: {$code}");

        
    $this->code $code;
    }
    ?>

    The example above performs a precondition check on the code parameter.


  • Automatic Property Initialization
    This RFC proposes automatic assignments of constructor arguments to properties.
    This proposal is an alternative to https://wiki.php.net/rfc/constructor-promotion. It uses a different syntactical approach to shorthand constructors borrowed from the Dart Language, in addition to suggesting variations of that approach.

    Instead of writing:

    <?php 
    class Point 
    {
        private 
    $x$y;

        public function 
    __construct($x$y)
        {
            
    $this->$x;
            
    $this->$y;
        }
    }
    ?>

    You can just write:

    <?php 
    class Point
    {
        private 
    $x$y;

        public function 
    __construct($this->x$this->y);
    }
    ?>

    The two snippets are functionally equivalent and achieve the same.
    Quoting from the Dart Manual:
    Quote :
    If an argument has this. before it in a constructor argument list, the field with that name will automatically be initialized with that argument’s value. This example shows another little feature too: if a constructor body is completely empty, you can just use a semicolon ( instead of {}.

    The proposal suggests to adopt this functionality to PHP, which is really two features:
    allow for $this→foo as constructor arguments
    allow for methodless constructors


  • Named Parameters
    This RFC proposes introducing named parameters.
    Named arguments are a way to pass arguments to a function, which makes use of the parameter names rather than the position of the parameters:

    <?php 
        
    // Using positional arguments:
        
    array_fill(010042);
        
    // Using named arguments:
        
    array_fill(start_index => 0num => 100value => 42);
    ?>

    The order in which the named arguments are passed does not matter. The above example passes them in the same order as they are declared in the function signature, but any other order is possible too:

    <?php 
    rray_fill
    (value => 42num => 100start_index => 0)
    ?>

    It is possible to combine named arguments with normal, positional arguments and it is also possible to specify only some of the optional arguments of a function, irregardless of their order:

    <?php 
        htmlspecialchars
    ($stringdouble_encode => false);
        
    // Same as
        
    htmlspecialchars($stringENT_COMPAT ENT_HTML401'UTF-8'false);
    ?>



  • Support for anonymous catches
    This RFC proposes adding catch-statements without variables, and fully anonymous catches.
    With the recent addition of the finally keyword for try-catch statements, PHP is now in line with many other languages such as C#, Python and Ruby (and probably many others). Those languages differ from PHP in that they don't require a variable to bind the exception in, and don't even require specifying a certain Exception class.
    Thus, this RFC proposes to add syntax support for:

    <?php 
    try
    {
        
    $this->connectToServer();
    }
    catch (
    ConnectionLostException)
    {
        
    $this->retry(3);
    }
    ?>

    In this case, we don't need the exception object itself as the exception type is descriptive enough of what happened, and we do not need to log anything because the operation is tried again in 3 seconds. By not specifying a variable, we avoid the impression that we do actually need it. It also helps static analysis tools (e.g. as implemented in IDEs) more accurately discover unused variables.

    We can take this one step further, to also get rid of the class:

    <?php 
    try
    {
        
    $this->connectToServer();
    }
    catch
    {
        
    $this->retry(3);
    }
    ?>



  • unset(): return bool if the variable has existed
    Add to unset a return value if the deletion was successful
    The purpose of this RFC is to make unset return something meaningful. People also shouldn't have to wonder why they can't use unset if it isn't as a standalone expression. This removes also an inconsistency: the function's return value is void, states the docs. It is until now the only function (language construct, function-like) (apart from echo, which already has an alternative: print) which has no return value.
    Change unset()'s behaviour to:
    • return true if deletion was successful
    • return false if deletion failed (e.g. there was nothing to delete or the deleting function has failed)
    The feature could be useful in if's like:

    <?php 
    public function deleteKey ($key) {
        if (unset(
    $this->array[$key])) {
            
    // do some cleanup
        
    }
    }
    ?>

    This is the way we do it today:

    <?php 
    public function deleteKey ($key) {
        if (isset(
    $this->array[$key])) {
            unset(
    $this->array[$key]);
            
    // do some cleanup
        
    }
    }
    ?>

    But even now we can't be sure if the variable was unset, because the __unset() magic method may not have deleted it. With the patch __unset() can return a value (which is internally casted to bool) and inform the caller of unset() if the deletion was successful.


  • Remove reliance of Zend API
    A proposal to remove the use of the Zend API in PHP libraries.
    Currently, PHP's interpreter, the Zend Engine, provides access to its internals via the Zend API. This RFC provides a rationale for this access, by removing the Zend API. This RFC does not describe how to remove access, and what to replace it with. That is described separately, in php_native_interface. The goals of this RFC are predicated on achieving the goals of php_native_interface.


  • PHP Native Interface
    Provide complete alternative to writing libraries interfaces using the Zend API libraries.
    This describes the design of phpni, the PHP Native Interface. This design is in early stages.
    • Remove any couping between the Zend Engine, extensions and SAPIs.
    • Support all major use cases of the Zend API
      • embedding within SAPIs
      • proving access to C libraries
      • providing the ability to rewrite performance sensitive code in C
    • Significantly simplify creation of extensions
    • Allow other PHP implementations to use the same interface.
    • This is intended to be a static process. That is, we are replacing the static compilation of extensions with another static process. We do not intend to simplify or support run-time binding, like JNI, JNA or libffi. Instead it is imagined the result will be a single libphplibs.a, which statically links into libphp5.so.
    Take the use case of wrapping a C library to expose its functionality in user space. The major idea is to “automatically” import C functions into a special namespace. The PHP library functions would then be comprised of PHP user space code which calls those C functions directly. That way it is possible to craft an API that is separate from the C implementation.

    Lets take a simple example. Assume we have a C library XXX, with 3 functions, x, y and z. We'd like to expose this in user space as a class called MyXXX, with methods a and b. We create a file with the signatures of x, y and z:

    extensions/xxx/sigs.h

    int x (int, int);
    void y (char*, int);
    void z (char*, int);

    We then write our user space code:
    extensions/xxx/MyXXX.php

    <?php 
    class MyXXX
    {
        function 
    __construct ($username)
        {
            
    $this->username $username;
        }

        function 
    ($w1$w2)
        {
            
    $foo = \internals\XXX\($w1$w2);
            \
    internals\XXX\($this->username$foo);
        }

        function 
    ($m1$m2)
        {
            
    $foo = \internals\XXX\($m1$m2);
            \
    internals\XXX\($this->username$foo);
            return 
    $foo;
        }
    }
    ?>

    In order to interface between the PHP code and the C functions, a tool will be required to generate code. This tool will obviously be implementation specific. SWIG could be used to create this. Since the libraries would no longer use the Zend API, the tight coupling would be broken. It would now be possible to change major parts of the Zend engine without affecting the operation of any other part of PHP. It would no longer be necessary to know the Zend API to write extensions. Instead, only the API of the C library is necessary, and the interface can be created in PHP user code.


  • Function call chaining
    Function call chaining implementation.

  • Enum language structure
    A proposal to add the enum language structure
    Frequently developers need to produce code like this:

    <?php 
    const    LOG_LEVEL_DEBUG 1,
            
    LOG_LEVEL_INFO 2,
            
    LOG_LEVEL_WARNING 3,
            
    LOG_LEVEL_ERROR 4;

    // Or

    class Tokens {
        const    
    T_IF 258,
                
    T_ELSE 259,
                
    T_WHILE 260,
                
    T_DO 261;
    }
    ?>

    The proposal is that this could be written in a much more concise manner:

    <?php 
    enum 
    {
        
    LOG_LEVEL_DEBUG,
        
    LOG_LEVEL_INFO,
        
    LOG_LEVEL_WARNING,
        
    LOG_LEVEL_ERROR
    };

    // Or

    class Tokens {
        
    enum {
            
    T_IF 258,
            
    T_ELSE,
            
    T_WHILE,
            
    T_DO
        
    };
    }
    ?>

    The keyword enum is reserved. An enum may be defined wherever a class or interface could be defined, and the same namespacing, naming and referencing restrictions apply.

    <?php 
    namespace Cards;

    enum Suit {
        
    SPADES => '1',
        
    HEARTS => 2,
        
    DIAMONDS// Will have value 3
        
    CLUBS,    // Will have value 4
    }

    var_dumpSuit::SPADES );         // enum(Cards\Suit)(1)
    var_dumpSuit::SPADES == );    // bool(true)
    var_dumpSuit::SPADES === );   // bool(true) - because the value is cast to an integer upon declaration
    var_dumpSuit::SPADES == '1' );  // bool(true)
    var_dumpSuit::SPADES === '1' ); // bool(false)
    ?>

    Unlike array declarations, however, a duplicate value causes a fatal error. An enum member may be referenced as EnumName::VALUE just like a class constant. A scalar may be (explicitly or implicitly) cast to an enum member:

    <?php 
    // Using declaration of Suit above
    var_dump( (Suit));       // enum(Cards\Suit)(1)
    var_dump( (Suit)true );    // enum(Cards\Suit)(1)
    var_dump( (Suit)('one') ); // null
    ?>



  • Making T_FUNCTION optional for method declarations
    A proposal for removing the requirement to use T_FUNCTION in method declarations.
    It is proposed that this is valid code:

    <?php 
    class Foo {
        const 
    42;
        private 
    $var;

        public 
    bar() {
            echo 
    "Hello World";
        }
    }

    $foo = new Foo();
    $foo->bar();
    ?>

    While technically possible this RFC suggests that the following shall NOT be valid for keeping the code readable:

    <?php 
    class Foo {
        const 
    42;
        private 
    $var;

        
    bar() {
            echo 
    "Hello World";
        }
    }

    $foo = new Foo();
    $foo->bar();
    ?>



  • CLI options for strict and quiet modes
    This RFC proposes a -W option to turn on maximum error reporting, and a -Q option for no error reporting.

  • Skipping optional parameters
    Skipping optional parameters in function calls
    As PHP does not have named parameter support, a very common for function is to have many optional arguments, like this:

    <?php 
    unction create_query
    ($where$order_by$join_type=''$execute false$report_errors true) {...
    ?>

    If we always use defaults, it's fine. But what if we need ot change $report_errors but don't care about the others? We'd have to find function definition and copy-paste all other defaults into the call, which is annoying, error-prone and may not do what you wanted if some of the defaults change.
    The proposal is to allow skipping optional arguments in a call, thus making them assume default values as they do when they are not provided, like this:

    <?php 
    reate_query
    ("deleted=0""name", default, default, /*report_errors*/ true)
    ?>

    This means that $join_type and $execute are going to use defaults. Of course, if we ever get implementation of named parameters, it may also solve this problem, but until we do, this can be a partial solution.


  • Systemd socket activation
    Systemd socket activation support for PHP-FPM

  • Add a deprecated modifier for functions
    Add a deprecated modifier for functions
    This RFC proposes the addition of a “deprecated” modifier for methods and functions giving the ZEND_ACC_DEPRECATED flag to functions, thus throwing an E_DEPRECATED error when they are called.

    <?php 
    deprecated 
    function myFunction() {
        
    // ...
    }

    myFunction();
    ?>

    Results in
    Deprecated: Function myFunction() is deprecated in ... on line 5



  • Moving to an AST-based parsing/compilation process
    Proposes to improve the current parsing/compilation process by introducing an AST as an intermediary structure
In Draft
  • Scalar Type Casting Magic Methods
    This RFC proposes a set of new scalar type casting magic methods for classes.
    This RFC and patch introduces 4 new magic methods:
    • __toInt() - Called when casting an object explicitly to an integer (or passing it to an internal function which expects an integer)
    • __toFloat() - Called when casting an object explicitly to a float (or passing it to an internal function which expects a float)
    • __toArray() - Called when casting an object explicitly to an array (or passing it to an internal function which expects an array)
    • __toScalar() - Called when using an object in an implicit scalar scope without type information (for example: $obj + 1).
    • __toBool() - Called when casting an object explicitly to a boolean (or passing it to an internal function which expects a boolean)


  • Isset/Set Operator
    This RFC proposes new operators for handling unset/falsey variables.
    ?= Will be a new operator that allows the user to set an unset or falsey variable. This handy operator will help avoid dreaded unset variable notices.

    <?php 
    $foo 
    ?= 'default';

    // which is functionally equivalent to:
    $foo = (isset($foo) && $foo) ? $foo 'default';

    // or
    if (!isset($foo) || !$foo$foo 'default';
    ?>

    ??: will be equivalent to the ternary short hand ?: except that it also checks for isset().

    <?php 
    // $bar is unset

    $foo $bar ?: 'other'// Throws undefined notice

    $foo $bar ??: 'other'// Does NOT throw undefined notice

    // ??: is functionally equivalent to:
    $foo = (isset($bar) && $foo) ? $bar $other;
    ?>

    This will be very helpful for echoing default variables in HTML like so:

    <?php 
    div 
    class="= $user ??: 'guest' "> ... </div
    ?>




  • Comparison inconsistency
    This RFC is to discuss comparison related inconsistency.

  • PDO version 1 improvements
    This RFC proposes a set of improvements to be made to PDO.

  • Tainted variables
    This RFC proposes an implementation of variable tainting in PHP.

  • Jsonable interface
    Feature request to allow support json_(encode|decode) to handle Object instance conversions.
    Consider this piece of code:

    <?php 
    class Person
    {
        public 
    $name;
        protected 
    $age;
        private 
    $salary;

        public function 
    __construct($name$age$salary)
        {
            
    $this->name $name;
            
    $this->age $age;
            
    $this->salary $salary;
        }

        
    // ...
    }

    $person = new \Person('Jesus Christ'3210000);

    echo 
    json_encode($person);
    ?>

    PHP is able to convert public variables, so the return of this script will be:

    <?php 
    "name""Jesus Christ"
    ?>

    However, we may want json_(encode|decode) to also export/import protected and private information.

    A non-intrusive solution should be smooth just like SPL Serializable interface.

    <?php 
    interface Jsonable
    {
        public function 
    __toJson();
    ?>

    It is well known that at this stage, any developer is able to write a piece of code (a method) like the following one to include a similar support:

    <?php 
    class Person implements Jsonable
    {
        public function 
    __toJson()
        {
            
    $str '{"__CLASS__": "' get_class($this) . '"';

            
    $reflClass = new \ReflectionClass($this);

            foreach (
    $reflClass->getProperties() as $reflProperty) {
                
    $reflProperty->setAccessible(true);
                
    $value $reflProperty->getValue($this);

                
    $str .= ', ' json_encode($reflProperty->getName()) . ': ';

                if (
    is_object($value) && $value instanceof Jsonable) {
                    
    $str .= $value->__toJson();
                } else if ( ! 
    is_resource($value)) {
                    
    $str .= json_encode($value);
                }
            }

            
    $str .= '}';

            return 
    $str;
        }
    }
    ?>

    By implementing natively Jsonable, it would be simply necessary to:

    <?php 
    class Person
    {
        
    // ...

        
    public function __toJson()
        {
            return array(
    'name''age''salary');
        }
    }
    ?>

    It would be even possible to add custom export support, example:

    <?php 
    class Person
    {
        
    // ...

        
    public function __toJson()
        {
            return array(
    'salary');
        }
    }
    ?>



  • Object and Array Literals
    This RFC proposes first-class, inline object and array literals similar to JSON.

    <?php 
    // new syntax for simple arrays:
    $a = [1,2,'three'];
    // equivalent to current:
    $a = array(1,2,'three');

    // associative arrays:
    // (examples are equivalent; see discussion)
    $a = ['one' => 1'two' => 2'three' => 'three'];
    $a = ['one'1'two'2'three''three'];
    // equivalent to current:
    $a = array('one' => 1'two' => 2'three' => 'three');

    // anonymous object:
    // (examples are equivalent; see discussion)
    $a = {'one'1'two'2'three'3};
    $a = {'one' => 1'two' => 2'three' => 3};
    // equivalent to:
    $a = new \StdClass;
    $a->one 1$a->two 2$a->three 'three';
    // or:
    $a = (object)array('one' => 1'two' => 2'three' => 'three');

    // PHP conventions (dynamic keys/values)
    $val 'apple';
    $record = {"favourite_fruit"$val};
    // true expression:
    $record->favourite_fruit == "apple";

    $key "colour";
    $record = {$key"red"};
    echo 
    $record->colour// outputs "red"

    $colour "green";
    $vehicle "truck";
    $record = {'notes'"Drives a {$colour} $vehicle."};
    echo 
    $record->notes// outputs "Drives a green truck."

    // inline functions:
    $creditCard '5105105105105100';
    $doc = {"credit_card_reminder"substr($creditCard, -4)};
    echo 
    $doc->credit_card_reminder// outputs "5100"

    // 'invalid' keys:
    $obj = {'key with spaces''still works'};
    echo 
    $obj->{'key with spaces'}; // outputs 'still works'
    $doc = {'$set': {"has_logged_in"'yes'}};
    echo 
    $doc->{'$set'}->has_logged_in// outputs "yes"

    ?>


  • Weak References
    This RFC proposes the introduction of Weak References in PHP via a new SPL class.

  • Line Markers in PHP
    This RFC proposes the introduction of line markers in PHP.

  • Loop+Else control structure
    This RFC proposes an optional “else” clause that can be used after while, for, and foreach loops.
    Proposed syntax will look as follows:

    <?php 
    // "foreach" example (display a list of names)
    foreach ($array as $x) {
        echo 
    "Name: {$x->name}\n";
    } else {
        echo 
    "No records found!\n";
    }

    // "for" example (unset a range of keys from array, then return it, or return null on error)
    for ($i some_very_expensive_and_ugly_looking_calculation($array); $i >= 0$i--) {
        unset(
    $array[$i]);
    } else {
        return 
    null// horrific error!
    }
    return 
    $array;

    // "while" example (return true if any $search matches have been removed from $array)
    while ($temp array_search($search$array)) {
        unset(
    $array[$temp]);
    } else {
        unset(
    $array[$search]); // just because we can
        
    return false;
    }
    return 
    true;
    ?>



FGED GREDG RDFGDR GSFDG