1

I'm trying to write an artisan command. I've got the basics working.

Now I'm trying to clean things up by moving some of the code to another file.

The trouble is, in that other file, commands like $this-line('hello') don't work.

Is there an easy way to make that work?

(two files below, first file is the command and it works. note in the bottom of the 'working' file, we do $tmp = new viewclass then $tmp->display()

The second file is where I want to put all the logic - how do I call inherited functions like $this->line, $this->info, $this->table, etc... from that second file?

http://laravel.com/docs/5.1/artisan#writing-output

CrudFromDb_view.php:

<?php
namespace path\laravel_crudfromdb\Commands;

use Illuminate\Console\Command;
use \path\laravel_crudfromdb\Classes\viewclass;

class CrudFromDb_Views extends Command
{
    protected $signature = 'z:viewviews';
    protected $description = 'Displays generated views on screen. Does not change or create any files';

    public function __construct()
    {
        parent::__construct();
    }

    public function handle()
    {
        $this->line(' THIS LINE WORKS');

        $tmp = new viewclass;
        $tmp->display();  // <- Fails, see 'viewclass.php' file below
    }
}

viewclass.php:

<?php
namespace path\laravel_crudfromdb\Classes;

class viewclass extends Command
{

    protected $env;
    protected $dbhost;
    protected $dbname;
    protected $dbuser;
    protected $dbpw;
    protected $connection;

    function __construct()
    {    
      //  parent::__construct();
    }

    function display()
    {
            //this fails!
            //how can I call this 'line' function?
            $this->line('This is a line');
    }
}

Note, one approach that worked, was to pass the object in.

(It feels like PHP should have a built in way to do this already?)

ie in CrudFromDb_view.php:

$tmp = new viewclass($this);
$tmp->display()

and in viewclass.php

class viewclass
{
    protected $myparent;
    function __construct($thisfromparent)
    {
        $this->myparent = $thisfromparent
    }

    function display()
    {
       $this->myparent->line('this works');
    }
}

Is there a more elegant way to do what's been done above? I've tried parent::line('text') but that doesn't work :-(

8
  • Which error you are getting? I think you should try with $tmp = new viewclass(); Commented Dec 5, 2015 at 3:15
  • Hi Ranakrunal9, thanks so much for looking at my question! The new class gets called fine - if I put an echo in the display function, that works, so i don't think its the missing () from that line (though I tried it just now and it didn't work) Commented Dec 5, 2015 at 3:18
  • The error is "PHP fatal error: Call to undefined method ....viewclass::line()" Clearly it's looking for a function in my viewclass, and not pulling the functions from the Command class. Commented Dec 5, 2015 at 3:21
  • I've tried parent::line() but line isn't in the direct parent, it's two levels up in Console - any thoughts on how to call this? Commented Dec 5, 2015 at 3:22
  • Are you not getting any errors because your viewclass doesn't have the use Illuminate\Console\Command; statement to identify the Command class it's extending? Commented Dec 5, 2015 at 3:37

2 Answers 2

2

Add below namespace in viewclass.php and allow viewclass to extend Command.

use Illuminate\Console\Command;
class viewclass extends Command
{
    protected $env;
    protected $dbhost;
    protected $dbname;
    protected $dbuser;
    protected $dbpw;
    protected $connection;

    function __construct()
    {    
        //parent::__construct();
    }

    function display()
    {
        //this fails!
        //how can I call this 'line' function?
        $this->line('This is a line');
    }
}
Sign up to request clarification or add additional context in comments.

4 Comments

I tried that, and also tried extends Command - no luck with either.
I think the issue being that the Illuminate\Console\Command has some stuff that happens in the constructor to setup the environment. I tried adding parent::__construct() in the __contstruct of my viewclass, but then it's really trying to setup a whole new laravel/artisan command, and I've already done that in the CrudFromDb_view.php file :-(
i have updated my answer , check with it may be this will solve the issue :)
Still no luck: PHP Fatal error: Call to a member function writeln() on null in /home/vagrant/Code/Laravel/vendor/laravel/framework/src/Illuminate/Console/Command.php on line 342
2

How about this?

<?php
namespace path\laravel_crudfromdb\Commands;

use Illuminate\Console\Command;
use \path\laravel_crudfromdb\Classes\viewclass;

class CrudFromDb_Views extends Command
{
    protected $signature = 'z:viewviews';
    protected $description = 'Displays generated views on screen. Does not change or create any files';

    public function handle()
    {
        $this->line('THIS LINE WORKS');

        $tmp = app()->make(viewclass::class);
        $tmp->display();  // Should work
    }
}

Using app()->make() will ensure that Laravel implements all dependency injections needed in the parent Command class. This is the core purpose of Laravel, which is at first an IoC (inversion of control) container.

To make it even more "kosher", add your viewclass class as a dependency injection itself...

<?php
namespace path\laravel_crudfromdb\Commands;

use Illuminate\Console\Command;
use \path\laravel_crudfromdb\Classes\viewclass;

class CrudFromDb_Views extends Command
{
    protected $signature = 'z:viewviews';
    protected $description = 'Displays generated views on screen. Does not change or create any files';

    protected $viewclass;

    public function __construct(viewclass $viewclass)
    {
        $this->viewclass = $viewclass;
        parent::__construct(); //put it as the last line to avoid constructor bugs.
    }
    public function handle()
    {
        $this->line('THIS LINE WORKS');
        $this->viewclass->display();  // Should still work thanks to IoC Container
    }
}

Comments

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.