Skip to content

SplFileObject::__toString() reads next line #9883

Closed

Description

@cmb69

Description

The following code:

<?php
$file_stream = new SplFileObject(__FILE__, 'rb');

echo $file_stream; // line 4
echo $file_stream; // line 5
echo $file_stream; // line 6
echo $file_stream; // line 7
echo $file_stream; // line 8
echo $file_stream; // line 9

Resulted in this output:

<?php

$file_stream = new SplFileObject(__FILE__, 'rb');

echo $file_stream; // line 4
echo $file_stream; // line 5

But I expected this output instead:

<?php
<?php
<?php
<?php
<?php
<?php

See https://3v4l.org/gF4tm.

The issue is due to the erroneous fix of bug 77024, where ::__toString() is now an alias of ::fgets() what appears to be strange.

This issue has been discovered by @derickr.

PHP Version

PHP 8.0

Operating System

any

Activity

  1. hormus commented on Nov 12, 2022

    @hormus

    hi @cmb69 nice bug, I prefer unexpected terminology. Since the READ_CSV flag exists, the SplFileObject::current() method returns array or string or otherwise false. The SplFileObject class uses the alias __tostring (). Magic method __tostring() It is worth noting that prior to PHP 5.2.0 the __toString method was only called when combined directly with echo() or print(). As of PHP 5.2.0, it is called in any string context (e.g. in printf() with the% s modifier) ​​but not in other context types (e.g. with the% d modifier). Starting with PHP 5.2.0, converting objects without the __toString method to string would cause E_RECOVERABLE_ERROR. The first unexpected action is the magic method tostring() instead uses alias SplFileObject:: tostring(), the second unexpected action is SplFileObject::current() which does not return array although the bitmask for example 10 (e.g. READ_AHEAD | READ_CSV) uses READ_CSV. The third expected action is the modification of (alias of magic method __tostring()) SplFileObject::__tostring() if the bitmask uses READ_CSV accepts the input array and converts it to string

    Pseudo code check:

    <?php
    $file = new SplFileObject(__FILE__, "rb");
    echo 'string with key ' . $file->key();
    echo $file->current(); // Bug, if SplFileObject::__tostring() alias of SplFileObject::fgets() next key
    //$file->rewind(); // if SplFileObject::__tostring() alias of SplFileObject::fgets() or if SplFileObject::__tostring() alias of SplFileObject::current() for magic method __tostring() e.g. echo $file; now is array
    $file->setFlags(SplFileObject::READ_CSV);
    if(!is_array($file->current())) {
    echo 'Not array' . "\r\n";
    }
    $flag_read_csv = 8 & $file->getFlags();
    echo $file; // bug Magic method __tostring() and current(), is string
    $file->setFlags(SplFileObject::READ_AHEAD | SplFileObject::READ_CSV);
    $flag_read_csv2 = 8 & $file->getFlags();
    $file->setFlags(0);
    //$file->rewind(); // If SplFileObject::__current() don't update SplFileObject::__current()
    if(is_array($file->current())) {
    echo 'bug' . "\r\n";
    }
    var_dump('use flag READ_CSV:', $flag_read_csv, $flag_read_csv2);
    ?>

    Output for 5.2.0 - 5.2.17, 5.3.0 - 5.3.29, 5.4.0 - 5.4.45, 5.5.0 - 5.5.38, 5.6.0 - 5.6.40, 7.0.0 - 7.0.33, 7.1.0 - 7.1.33, 7.2.0 - 7.2.18, 7.3.0 - 7.3.5 (if SplFileObject::__tostring() alias of SplFileObject::current():

    string with key 0<?php
    Not array
    <?php
    string(18) "use flag READ_CSV:"
    int(8)
    int(8)
    

    Expected result:

    string with key 0<?php
    <?php
    string(18) "use flag READ_CSV:"
    int(8)
    int(8)
    
  2. added a commit that references this issue on Nov 21, 2022
    3ee0a59
  3. added 2 commits that reference this issue on Nov 22, 2022
    6e87485
    b97d2b6
  4. added a commit that references this issue on Mar 29, 2024
    6fbf81c
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions