PHP and immutability: objects and generalisation - part three - Simon Holywell

Европа - быстрые серверы на дисках NVMe от $5 / Русский датацентр от 199руб

Тема в разделе "PHPWorld - новости из мира PHP", создана пользователем Planet PHP, 27 апр 2017.

  1. Planet PHP

    Planet PHP Guest

    In the last article we learnt how to create modified copies of an immutable in PHP. This one is going to tackle an issue I have hitherto skirted around and avoided. Objects in immutable data structures.

    This article is part of a series I have written on the topic of immutability in PHP code:

    1. /" title="PHP and immutability: modified copies - part two">Part two - improve the process of creating modified copies of the immutable
    2. Part three - objects in immutable data structures and a generalised immutable implementation
    What’s the problem with objects?

    Objects or instances of classes are passed by reference in PHP. Any changes to the class will be reflected in all places it is passed to. This is different to scalar values like strings, that are passed by value instead.

    $class = new stdClass();
    function addItem($x, $item) {
    $x->$item = $item;
    var_dump($class); // object(stdClass)#1 (0) {}
    addItem($class, 'test');
    object(stdClass)#1 (1) {
    ["test"]=> string(4) "test"

    Here you can see a function called addItem() that adds a property to stdClass instance - this produces a side effect. The original $class is also updated as it references the same value so if we dump the variable we can see it’s value has changed.

    Now consider the same example with a simple scalar string where pass by value takes effect.

    $string = 'begin';
    function addItem($x, $item) {
    $x .= $item;
    var_dump($string); // string(5) "begin"
    addItem($string, 'end');
    var_dump($string); // string(5) "begin"

    Here the original value remains intact because, unlike an object, there is no reference to it from within the addItem() function.

    These side effects make putting an object into an immutable data structure difficult. Someone with access to the reference could simply change the object after the fact - thus breaking immutability.

    What about resources?

    Turns out the same issues plague resources as well. They are just references to a resource ID so any change to one will affect all those that also reference it. Simply moving the pointer in a file resource would break immutability.

    Truncated by Planet PHP, read more at the original (another 75431 bytes)

    Читать дальше...