Archive for April 2015

Trying out Visual Studio Code

Yesterday Microsoft held Build 2015 and presented lots of nice things to the developer community. I have always loved Microsoft's developer tools, and started using Visual Studio back in 1997, hacking away with Visual Basic and Visual C++.

Now I still use Visual Studio at work, but for my personal projects, I mostly do web development in PHP and sometimes ASP.NET MVC. For the PHP projects, I have been using Komodo Edit for a while now, and am happy with it.

Visual Studio Code

Installing VS Code

After a quick download and a smooth installation, Visual Studio Code booted. I opened a folder full of PHP and JavaScript files. Syntax highlighting, bracket matching, syntax errors and warnings work really well for PHP, JavaScript, HTML and CSS, but PHP IntelliSense isn't included in this preview version, which unfortunately means I won't be switching. Yet. However, JavaScript IntelliSense is amazing! It found a rookie mistake for me...

Don't do bitwise operations on bool

IntelliSense in Visual Studio Code is really good in every language it supports. Code completion and suggestions for JavaScript, HTML, CSS, SASS and C# are instant, but some features are missing from HTML IntelliSense.

A couple of HTML IntelliSense suggestions

  • Allowed attribute values should be suggested, like when typing <link rel=", I would like a popdown list to suggest things like stylesheet and so on.
  • Element suggestion should only include elements that make sense in the context. Directly inside an <ul> element, there is no point in suggesting a <blockquote>. Only <li>, <script> and <template> elements make any sense.

Bad elements in UL

What will make me switch

The editor is really nice to work with, it feels snappy and does things well. Changing personal settings is done in JSON, which is cool, because JSON... Until PHP IntelliSense is added, and some improvements are made in HTML editing, I will stick to Komodo Edit, but I will probably switch to Visual Studio Code eventually.

Posted by Anders Tornblad on Category Tools Labels
Tweet this

Reinventing a PHP MVC framework, part 1

Let's reinvent the wheel

This is the first part of a series of articles about the mt-mvc PHP MVC framework.

I wanted to know how ASP.NET MVC does what it does, so I decided to find out... by trying to reinvent it... in PHP. My line of thought was this:

  • I know how to USE the ASP.NET MVC framework
  • I know the effects of using the various features of the ASP.NET MVC framework
  • I know the principles of TDD
  • I should be able to reinvent (or reverse-engineer) a working MVC framework by adding unit tests for increasingly complex use of MVC, and making one or a few tests pass at a time
  • I also want to become a better PHP developer

I am perfectly aware of the fact that there are lots of MVC frameworks for PHP that are really capable of taking care of business, but this is not a website development effort. This is a learning effort. Reinventing the wheel works fine for learning - not for production code.

MVC the ASP.NET way

Let's start with something simple. The most basic use of ASP.NET MVC, in the default setting, appears to work by separating the request path of an incoming request into a Controller class name, a View method name, and an optional parameter value that gets passed into the method. Also, there are default values for all parts of the path.

First set of tests

I imagine a class that's solely responsible for parsing a path, and suggesting the name of a controller class, and a method to call, so I write some tests for that class first. Hooking things up to the PHP HTTP infrastructure gets added later.

// First batch of tests

class RoutingTests {
    public function CheckAllDefaults() {
        $routing = new Routing();
        $route = $routing->handle('');
        The($route->controllerClassName)->shouldEqual('HomeController');
        The($route->methodName)->shouldEqual('Index');
        The($route->parameter)->shouldNotBeSet();
    }

    public function CheckDefaultMethodNameAndParameter() {
        $routing = new Routing();
        $route = $routing->handle('Articles');
        The($route->controllerClassName)->shouldEqual('ArticlesController');
        The($route->methodName)->shouldEqual('Index');
        The($route->parameter)->shouldNotBeSet();
    }

    public function CheckDefaultParameter() {
        $routing = new Routing();
        $route = $routing->handle('Categories/List');
        The($route->controllerClassName)->shouldEqual('CategoriesController');
        The($route->methodName)->shouldEqual('List');
        The($route->parameter)->shouldNotBeSet();
    }

    public function CheckNoDefaults() {
        $routing = new Routing();
        $route = $routing->handle('Products/Item/123x');
        The($route->controllerClassName)->shouldEqual('ProductsController');
        The($route->methodName)->shouldEqual('Item');
        The($route->parameter)->shouldEqual('123x');
    }
}

These tests are about the default out-of-the-box behavior of the routing subsystem. More advanced features, like registering custom url patterns, get added later.

// First chunk of code

class Routing {
    public function handle($url) {
        $parts = explode('/', $url);
        $controllerName = @$parts[0];
        $methodName = @$parts[1];
        $parameter = @$parts[2];

        if (!$controllerName) $controllerName = 'Home';
        if (!$methodName) $methodName = 'Index';

        return (object) [
            'controllerClassName' => $controllerName . 'Controller',
            'methodName' => $methodName,
            'parameter' => $parameter
        ];
    }
}

Usefulness right now This class does the bare minimum, and making some real use of it requires a lot of nuts and bolts in place – some URL redirection, a request/response pipeline system, some use of reflection to dynamically create controller instances and calling methods, a lot of thought about how to connecting views to the controller methods, and so on. Don't worry; all of that will be covered in the following posts.

You'll find the code from this article in the related release on GitHub. The latest version is always available in the GitHub repository.

Posted by Anders Tornblad on Category PHP Labels
Tweet this