1

I'm using the Symfonys Console component and I'm creating a command that displays what files in a directory have been executed. To do this I want to display the data in a Table using their Table helper.

In their documentation it only uses examples with hard coded output, is it possible to have this data added dynamically. Here is my code:

    // Create a new Table object
        $table = new Table($output);


    // Set the table headers
        $table->setHeaders(['Executed', 'File', 'Processed']);


    // Create a new Iterator object
        $iterator = new FilesystemIterator(dirname(__DIR__) . Config::SCRIPT_PATH);


    // Cycle through iterated files
        foreach ($iterator as $item) {

            // Set the file
                $file = (object) [
                    'executed' => 'No',
                    'name' => $item->getFilename(),
                    'processed' => ''
                ];


            // Find the script in the database
                $script = Script::where('file', $file->name)->first();


            // Check Script exists
                if ($script) {

                    // Update the file properties
                        $file->executed = 'Yes';
                        $file->processed = $script->created_at

                }


            // Set the table rows
                $table->setRows([
                    [$file->executed, $file->name, $file->processed]
                ]);

        }


    // Render the table to the console
        $table->render();

To me, every file it should find (currently 3) should be displayed in the table with it's correct data, but it only shows the last one, so each time setRows() is obviously being overwritten by the last cycle of the $iterator loop.

I tried creating a $files array and pushing each $file into it at the end of the $iterator loop, then moving $table->setRows() outside of the $iterator loop but of course doing a foreach ($files as $file) with setRows() inside it brings you back to the same situation of the last loop overriding the previous one.

As far as I can see from their documentation there isn't a setRow() method to set an individual row that I could use for each $iterator loop and you can't put a foreach loop within the setRows method either.

There must be a way to set the rows dynamically but I'm failing to see it, hopefully someone can help me out.

0

1 Answer 1

1

Build the array then pass it to setRows, don't use setRows inside the loop.

Try the following code:

<?php
// Create a new Table object
$table = new Table($output);

// Set the table headers
$table->setHeaders(['Executed', 'File', 'Processed']);

// Create a new Iterator object
$iterator = new FilesystemIterator(dirname(__DIR__) . Config::SCRIPT_PATH);

// Cycle through iterated files
$rows = [];
foreach ($iterator as $item) {

    // Set the file
    $file = (object) [
        'executed' => 'No',
        'name' => $item->getFilename(),
        'processed' => ''
    ];

    // Find the script in the database
    $script = Script::where('file', $file->name)->first();

    // Check Script exists
    if ($script) {
        // Update the file properties
        $file->executed = 'Yes';
        $file->processed = $script->created_at;
    }

    $rows[] = [$file->executed, $file->name, $file->processed];
}

// Set the table rows
$table->setRows($rows);

// Render the table to the console
$table->render();
Sign up to request clarification or add additional context in comments.

6 Comments

I had also tried that, I created a $files array and pushed each $file to it and tried $table->setRows($files) but it doesn't work. Although, thinking about it, I'm making $file an object and not an array, so I'll try changing that. Thank you
The important line is: $rows[] = [$file->executed, $file->name, $file->processed]; its an array not an object. I cant see how the above does not work from looking at the docs. Whats it not doing?
I get ya, you pushed the as-is $file object to the array so it was an array of objects. I think it needs to be an array of arrays.
Yeah sorry, that's what I meant, your way works by putting the objects properties into an array first and passing the array through to setRows, works perfectly, appreciate it!
np, glad to help.. If you like that functionality, check out climate.thephpleague.com it has some great features.
|

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.