0

I've got a FileLocations class which stores the path's to specific files.

class FileLocations
{
    /**
     * @var array
     */
    private $files = [];

    /**
     * @param array $files
     *
     * @throws \Exception
     */
    public function __construct (array $files) {
        if (!$this->areValidFiles($files)) {
            throw new Exception;
        }
        $this->files = $files;
    }

    /**
     * @param $files
     *
     * @return bool
     */
    private function areValidFiles (array $files) {
        foreach ($files as $file) {
            return is_file($file);
        }
        return false;
    }

    /**
     * @return array
     */
    public function getFiles () {
        return $this->files;
    }
}

I've wanted to validate each file (with is_file), so i made the areValidFiles function and looped through every array index which it gets. On each array item it's doing an check.

When i run this code like this:

$fileLocations  = new FileLocations(['doesExist.js', 'doesnotExist.js']);
var_dump($fileLocations->getFiles());

It only does the validation for the first file and doesn't even reconize that there is a second file passed in the arguments.

It also doesn't throw an exception.

Questions

  • How does this come that it only reconizes one file in the validation and not throws an exception on the second file that doesn't even exist?

  • How can I make it so that i will be able to pass more parameters inside the areValidFiles function?

7
  • The return is_file() is causing the foreach to abort after the first time. Remove that is the first step to solve this. What should happen when it finds a file that does not exist? Commented Jan 4, 2015 at 13:51
  • @Bjorn It should throw an Exception in the __construct method. What do you mean with removing it? Commented Jan 4, 2015 at 13:52
  • try to return an array with booleans in areValidFiles() Commented Jan 4, 2015 at 13:52
  • No, it returns true. The return is_file() basically exits the function, stopping it from looping through the rest of the array. Commented Jan 4, 2015 at 13:53
  • Why not throw the exception directly? I.e.: foreach $files as $file: if not is_file($file): throw new Exception. Otherwise you could replace the throw new Exception with return false. Commented Jan 4, 2015 at 13:54

3 Answers 3

1

Your areValidFiles function should be rewritten:

private function areValidFiles (array $files) {
    foreach ($files as $file) {
        if (!is_file($file))
            return false;
    }
    return true;
}
Sign up to request clarification or add additional context in comments.

6 Comments

Isn't that the same as what i did? Except reversing the true with the false?
No. it's not the same.
Can i still do this then? : return !is_file($file) ?
Nope. You only want to return when it finds a file that does not exist. You do not want to return on every iteration of the loop.
Understand that when you use return your function stops working immediately.
|
1

Add a watcher to your function instead of using return after is_file

private function areValidFiles (array $files) {
    $are_all_files_valid = true;
    foreach ($files as $file) {
        if (!is_file($file)) {
            $are_all_files_valid = false;
            break;
        }
    }
    return $are_all_files_valid;
}

1 Comment

This is nice too, but i preffer @u_mulder 's answer :)
1

I`d do something like:

   /**
     * @param $files
     *
     * @return bool
     */
    private function areValidFiles (array $files) {
        $files = array();
        foreach ($files as $file) {
            $files[$file] = is_file($file);
        }
        return $files;
    }
$fileLocations  = new FileLocations(['doesExist.js', 'doesnotExist.js']);
$fileLocations['doesExist.js'] //true
$fileLocations['doesnotExist.js'] //false

OR using exceptions:

    private function areValidFiles (array $files) {
        foreach ($files as $file) {
            if(!is_file($file)){
                throw new Exception('Invalid file: '.$file);
            }
        }
    }

try{
    $fileLocations  = new FileLocations(['doesExist.js', 'doesnotExist.js']);
} catch (Exception $e)
{
    //do something
}

3 Comments

Thanks, but i dont really like the way of looping through an array of boolean's. I'd stick with u_mulder's way :)
Okay, but this way you would know which file is invalid :)
Indeed. But i dont really need that :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.