php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Doc Bug #75136 readdir is returning null.
Submitted: 2017-08-30 12:51 UTC Modified: 2017-08-30 13:50 UTC
From: dmitriy dot vinograd at gmail dot com Assigned:
Status: Not a bug Package: Documentation problem
PHP Version: 7.0.22 OS: Ubuntu 16.04.3 LTS
Private report: No CVE-ID: None
 [2017-08-30 12:51 UTC] dmitriy dot vinograd at gmail dot com
Description:
------------
---
From manual page: http://www.php.net/function.readdir
---

readdir(false) is returning a null, despite the fact documentation says it must be a string or false

Which may put the example from the documentation in an infinitive loop, and in case if a server is saving warning messages into a log it will fill the server disk that in turn will put the server offline.


Test script:
---------------
var_dump(readdir(false));
//Will return
// Warning: readdir() expects parameter 1 to be resource, boolean given in /..../test.php on line 11
// /..../test.php:11:null

while (false !== ($logFile = readdir(false)))
{
    var_dump($logFile);
}
// Will put your process an infinitive loop


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2017-08-30 12:57 UTC] salathe@php.net
-Status: Open +Status: Feedback
 [2017-08-30 12:57 UTC] salathe@php.net
What makes you think false is a valid argument for the function?
 [2017-08-30 12:58 UTC] salathe@php.net
-Type: Bug +Type: Documentation Problem
 [2017-08-30 13:01 UTC] mail at pmmaga dot net
The documentation actually alerts you that this is a possible return value. Quoting:

Warning
This function may return Boolean FALSE, but may also return a non-Boolean value which evaluates to FALSE. Please read the section on Booleans for more information. Use the === operator for testing the return value of this function.
 [2017-08-30 13:08 UTC] dmitriy dot vinograd at gmail dot com
-Status: Feedback +Status: Open
 [2017-08-30 13:08 UTC] dmitriy dot vinograd at gmail dot com
//What makes you think false is a valid argument for the function?
Nothing we even have a check in our code to pretend it, but when you have a lot of processes there is still a chance that it happens in between. Which may occur with our site yesterday,

if ($dir = opendir($filePath) && is_numeric($noOfDays) > 0) 
        {
            while (false !== ($logFile = readdir($dir)))
 [2017-08-30 13:20 UTC] dmitriy dot vinograd at gmail dot com
// The documentation actually alerts you that this is a possible return value. Quoting:
Yes, you are absolutely right. Despite the fact, I still don't see any reasons why the function is returning null in this case. 

Also, I would like to add that mentioned code wasn't implemented by me and I suppose an author was encouraged by the example from the documentation.

Also, I personally believe that this is a pretty hard to predict consequences from this warning message.
 [2017-08-30 13:22 UTC] spam2 at rhsoft dot net
what makes YOU think NULL is the correct return in case of a invalid param when the doc says it returns boolean flase when not sucessful

anyways, that's why i ported a 250000 LOC codebase in the last year to declare(strict_types=1); which would lead to a exception in the case below
 [2017-08-30 13:40 UTC] salathe@php.net
-Status: Open +Status: Not a bug -Package: Directory function related +Package: Documentation problem
 [2017-08-30 13:40 UTC] salathe@php.net
Closing as not a bug for the readdir() page.  Returning NULL is a convention widely used throughout PHP and is not something we document for every individual function.

" Note: If the parameters given to a function are not what
  it expects, such as passing an array where a string is expected, 
  the return value of the function is undefined. In this case it
  will likely return NULL but this is just a convention, and
  cannot be relied upon."

  -- http://php.net/manual/en/functions.internal.php
 [2017-08-30 13:46 UTC] requinix@php.net
To add to that,

> I suppose an author was encouraged by the example from the documentation
The author apparently forgot about operator precedence. && has higher precedence than = [1] so the code is effectively
  if ($dir = (opendir($filePath) && is_numeric($noOfDays) > 0))
which means yes, the code never worked correctly to begin with. You can also quickly infer from this that readdir() is being passed true - not false.

Use "and" or parentheses. https://3v4l.org/so2bX

Perhaps the is_numeric() check was just added? Speaking of, the author of that piece apparently forgot that is_numeric returns bool, so comparing >0 is nonsensical although functional.

[1] http://php.net/manual/en/language.operators.precedence.php

Meanwhile the "which evaluates to FALSE" note is a macro which typically means the function can also return 0 or an empty string. Since readdir() does not return integers and it's not possible to have a file/directory named "" (as far as I know) the warning would be alluding to the string "0".

Side comment: opendir/readdir/closedir loops are old. scandir and glob are easier.
 [2017-08-30 13:50 UTC] dmitriy dot vinograd at gmail dot com
Thank you very much for your explanation.
 
PHP Copyright © 2001-2020 The PHP Group
All rights reserved.
Last updated: Thu Nov 26 04:01:23 2020 UTC