Ken Guest’s online diary

August 17, 2016

Command Line Scripts in Laravel.

Filed under: laravel,php — kenguest @ 19:16

A while ago I had reason to write some command line tools using the Laravel framework. These are some notes on what I’ve learnt from the experience.

The basics.

Command line tools written for Laravel should subclass Illuminate\Console\Command.

The description and signature properties of the class are used in the artisan
listing of commands, for displaying a command specific help paragraph and
specifying what parameters the command takes.

If setting the signature in the constructor, this must be done before calling the parent’s constructor.

The main entry point is the class’s handle method.

use Illuminate\Console\Command;

class MyCommand extends Command
  protected $description = "Does this and that.";
  protected $signature = '';

  public function __construct()
    $foo = env('SOME_ENVIRONMENT_SETTING', 'myCommand');
    $this->signature = "$foo:assorted {--s|setting=$option : option's description.} {arg1 : arg1's description}";

  public function handle()
    // get arg1 as entered at the command line.
    $arg1 = $this->argument('arg1');

    // To determine if 'quiet' was set, we need all options first.
    $options = $this->option();
    $option = $options['option'];
    $this->quiet = $options['quiet'];

    // Onwards...
    if (!this->quiet) {
    try {
    } catch(\Exception $ex) {
    } finally {
    if (!this->quiet) {

Using PSR3 logging methods (such as “info”, “error” and the others), is better than just doing an echo $message as these can be presented differently depending on what style logger you might choose to use later.
As it stands, the various messages are output to the console in different colours, for example “error” lines are printed in red, “info” messages are displayed in green, and so on.
If you want to display an ordinary, non-coloured line, then use the line method:

  $this->gt;line("Plain line of text.");


A progressbar can be displayed at the command-line instead of filling up the scrollback with however many lines which might essentially indicate the same but less succinctly.

To initialise the standard progress bar:

  $this->output->progressStart($max); // $max is the total number of items being "progressed", e.g. 516 or whatever

To advance:

  while($this->completeAPortionOfWork()) {

And to finish it off at 100%:


November 6, 2015

Scan your code for old-style constructors using phpcs.

Filed under: php — kenguest @ 13:53

There are less than seven days left until PHP 7 is released, which drops support for old-style constructors – the ones where a method is a constructor if it shares the same name as the class.

You don’t want to spend too much time scrolling through codebases for that though do you? Better things to do, like watch videos of conference talks you’ve missed and such.

Well, you’re in luck. If you use php_codesniffer (and if you don’t, well shame on you), you’ll be able to get a report of old-style constructors fairly quickly.

This will run php code sniffer and identify old-style constructors.

    $ phpcs --standard=Squiz --extensions=php --sniffs=Generic.NamingConventions.ConstructorName .

It’s a bit long-winded, so wrap it up in a bash alias, say in your .bashrc:

    $ alias findoldphpconstructors='phpcs --standard=Squiz --extensions=php --sniffs=Generic.NamingConventions.ConstructorName .'

Want a CSV report of the same? Use this:

alias findoldphpconstructorsToCSV=’phpcs –standard=Squiz –report=csv  –extensions=php –sniffs=Generic.NamingConventions.ConstructorName . | cut -f1,2 -d,’

Remember your unit tests.
Naturally when you do anything at all like this you really should write and run unit tests to ensure no side-effects have been caused inadvertently.

November 5, 2015

Getting phing custom tasks up to PR standard. What I did.

Filed under: phing,php — kenguest @ 13:44
Tags: ,


Phing is a build system that I’ve written about before which is open source, and developed in PHP.

Two custom tasks that I wrote have been merged into the main phing repository on github and I thought I might write up my notes on what I did to get them up to “PR Standard”.

The first task is for creating and modifying .ini files and is now documented at

The second one is simply a ‘task-wrapper’ (trademark pending) for running notify-send so that pop-up or toaster messages (whatever you want to call them) get displayed at certain stages of a build. This is more efficient for me that alt-tabbing to the window that I’ve phing running in to see what’s going on.

I’m not going to describe how to use them here; hopefully the documentation that I wrote for them in phing is sufficient.

I’m also not going to outline how to write custom tasks – there’s already good documentation for that at

Instead I want to document what I learnt in the process of taking the earlier version of NotifySendTask ( ) and the IniFileTask, and getting them to Pull Request standard for inclusion in phing.

Who knows, this might help some of you decide to add a phing Pull Request of your own.

Documentation Driven Development.

Documentation is always a factor on how well an OSS project will be used, so this is one of the first things that I wanted to address.

The inifile task is an optional one – it is not a core phing task – so I added a new section to the optionaltasks docbook file at

Because the IniFileTask is pretty much a direct port of the ant-contrib equivalent, I took the documentation from and made just a few changes as I wanted to add support for a ‘haltonerror’
Converting it over to docbook from HTML was relatively trivial.

If I wanted, I could have used a docbook specific editor for doing this, but I was comfortable using vim, so I did.

I did something similar for the NotifySend task, except that there is an intentional non-documented attribute.


I added some examples to the documentation and only after the PR for inifiletask did I look at the PDF version of the manual.

I noticed only then that example listings look best when kept to a maximum length of 80 characters per line – after 90 characters or so the lines get truncated.

On with the code.


Obviously in a build system it is expected to see messages being logged, and possibly at differing levels of importance.

To log a message at the default level:
    $this->log("Log this message");

Or, explicitly:
    $this->log("Log this message", Project::MSG_INFO);

These are the levels/priorities that messages can be inserted into the log at:

  • Project::MSG_DEBUG
  • Project::MSG_ERR
  • Project::MSG_INFO
  • Project::MSG_VERBOSE
  • Project::MSG_WARN

You will see below that you can assert against entries being present, or not, in the log.

Knowing all this makes it easier to assert in unit tests that various edge cases are being tested properly, and without adding any visual clutter when the task is being run casually.

Enabling a new task by default.

To make the tasks visible by default, for testing and also so they can be used with the minimum of hassle, I referenced them in the file classes/phing/tasks/ by adding these lines:



The location of the unit test file for the task has to mirror the location of the actual task files; so because the ‘working’ code for the task is in phing/classes/phing/tasks/ext/inifile I put the unit tests into the test/classes/phing/tasks/ext/inifile/ directory.

The NotifySendTask that I developed is less complex in that it requires just one class rather than the four for the IniFileTask so the files for that are ini the tasks/ext directory instead of requiring a separate subdirectory for them. Though if I split out the unit tests for that into separate files then I would’ve created a subdirectory for them rather than clutter up tasks/ext.

Test specific build files for unit tests can be used, they are executed via the executeTarget and should be placed inside the etc/tasks/ext directory structure.

For example: etc/tasks/ext/NotifySendTaskTest.xml

Or a separate subdirectory structure such as ./etc/tasks/ext/inifile/inifile.xml

The unit test class should be a subclass of BuildFileTest.

BuildFileTest provides a number of helper methods, for example assertInLogsassertNotInLogs, configureProject and executeTarget, expectBuildException and others.

Use configureProject in the setUp method to initialise the project that the unit tests are for.

assertInLogs("Assert this text exists in the logs");
assertInLogs("Assert this text exists in the logs", Project::MSG_DEBUG);

 * Configure the project to point to the correct .xml file for these tests
public function setUp() {
    $this->configureProject(PHING_TEST_BASE . "/etc/tasks/ext/inifile/inifile.xml");
    $this->object = new ThisIsTheNewTask();

public function testSetterOutsideXml() {
    $this->object->setTitleProperty("test title");
    $this->assertEquals("test title", $this->object->getTitleProperty());

public function testInTarget()
    $this->assertInLogs("expected as debug log entry", Project::MSG_DEBUG);

public function testTargetUsingHelper()
    $this->expectDebuglog("targetToTest", "expected as debug log entry");

The PHING_TEST_BASE constant is used to refer to the base directory for all phing test files. As well as that, the test functions testInTarget and testTargetUsingHelper are functionally identical. There are many other useful methods in the BuildFileTest class and I looked through phing/test/classes/phing/BuildFileTest.php to get familiar with
what else it can do.
There is also a PhingTestListener class in that BuildFileTest.php file, but there currently are no tasks with unit tests which utilise it.

As mentioned earlier, build files can be used in unit tests. This is very useful so that you can test that the setters in tasks load and work properly when phing parses the XML files. Explicitly calling setters and getters for your unit tests will only go so far, while testing against actual build files will highlight whether or not setters that are expected to be called will be.
The build file to use for unit tests is specified in the configureProject call.
There are a number of helper functions that go along with the executeTarget method, such as expectPropertySet, expectLog, expectLogContaining, expectDebuglog, expectOutput, expectOutputAndError, and two more related to
catching expected exceptions.

Working on the Task code.

One of the main things that I added to the Pull-Request version of the NotifySendTask was additional logging and getters that could be utilised for unit testing.

I also added extra validation on the values being set – checking generic icon values are valid, and if a specified icon is a filename then the task logs whether the file actually exists and so on.

After considering how to handle unit tests being run on systems where notify-send itself wasn’t installed – I added a control parameter, in the vein of an Operator Presence Control, so the system can essentially fake running successfully.

This is the one attribute that I didn’t add to the documentation.

The IniFileTask code is perhaps a level of complexity above that for NotifySendTask – in that there are extra XML elements required, and so extra classes are required as well; all of which have their respective setter methods by necesitty. Also I opted to add corresponding getter methods to these to allow unit tests that don’t require specific build files for each test.

This is also why inifile got a subdirectory for itself and the simpler notifysend task did not.


That’s all folks!

If there’s anything you think I should have covered, let me know and I’ll either edit this with an update or write a follow-up, depending on how substantial it is 🙂

Blog at