Lucid MVC – Development Update 1

Development Update 1 For Lucid MVC

This is a small update on Lucid MVC. Although I haven’t started work on the FormHelper or Database classes yet, I have made several improvements, and fleshed out the demo site (which will be included with the release).

A contact form page

A contact form page

Most of the work has been on improving form validation, which has been further simplified and made more flexible;

It didn’t really make sense to have the validators created from within the controller, and due to the way validation worked previously, it had to be done after a call to Model::load();. Validators can now be added anywhere within the Model and at any time, which also allows for ad-hoc validation if you want to add/remove validation at any time during the Model’s life-cycle.

With that in mind, validators can be removed simply by passing in the same parameters that match the validator that was added via Model::addvalidator();.

So, if we wanted to remove email validation, we could, for example, remove it before validating our form within the controller;

This is just a simple example. You might wish to remove validation based on user-submitted data. For example, if the user wanted to skip a part of the form, or if the user only had to fill in at least one of two form inputs, you could check if one input was filled in, then remove the “required” validator from the other.

Helpers

Another area I’ve been working on are the Helper classes, so far we have;

  • AlertsHelper – for rendering Bootstrap alert messages
  • SessionHelper – various methods for handling sessions
  • UrlHelper – various methods for generating links (absolute, relative, etc..)

As well as the FormHelper class, I’ll also be creating a DebugHelper for logging output to file/screen.

Configurations

The final area I’ve been working on has been the configuration settings within the project, and how best to represent them. Two of the more common approaches are arrays and .ini files, however both would require additional coding to require them automatically where needed, or additional code to call them.

In the end I decided to use a static class representation;

This made the most sense, given that Lucid MVC requires in classes automatically. Configuration settings can be included anywhere within your project, just by accessing the static class property. For example;

You can of course create your own configuration classes if you wish. The private class constructor is just there to prevent the class from being instantiated.

Other ideas

I’m also considering adding in some of the following;

  • Events/Listeners – Add events to Models/Views/Controllers at certain execution points
  • Dynamic Models – the ability to create new model attributes dynamically outside of the class
  • Modifiers that can change/convert data before/after it’s loaded into the model using callables.

Lucid MVC – A light PHP framework for small online projects

Building an MVC framework from the ground-up

Having worked with several PHP MVC frameworks now (Laraval, Nova Framework, Yii2, Joomla), I thought it would be a rewarding challenge to develop my own framework, based on what I liked about these frameworks, and what benefits me as someone who works with PHP frameworks.

The main goals of this project are;

  • Light MVC framework that’s fast to learn
  • Easy to work with, with minimal boiler-plate code
  • Fast form-building
  • Easy form validation
  • Automated URL routing
An early screenshot of the Lucid MVC Framework

An early screenshot of the Lucid MVC Framework

With that in mind, I’ve been working on Lucid MVC; a light PHP Model-View-Controller framework designed for small projects, but with enough features and functionality to avoid repetition and too much boiler-plate code. For example, there is no manual URL routing to speak of, so URLs are automatically translated to direct to the correct controller, passing any additional parameters to the controller if the controller method accepts them.

For example, the URL:

library/books/author/richard-dawkins

Would instantiate the libraryController, run the books method, and pass in the parameters “author” and “richard-dawkins”. The route will only be successful if the controller method can be called successfully, otherwise, the user will be redirected to the ErrorController, telling them the URL they have reached is invalid (our standard 404 “page not found” page). If the controller allows for optional parameters, then they can be omitted from the URL, and the default parameters will be used. This allows for flexible controller paths, leaving it up to the developer to handle any further validation if they require it.

Like Yii2, a layout template can be applied to the entire view, rendering the view content inside it. Different layouts can be applied in the controller before a view is rendered, or the default layout can be used.

Views themselves are fairly straight-forward. Model attributes, variables or other values are passed to the view via the controller, and can be accessed like normal variables.

Contact Form Controller

This is the controller for the contact form page at the beginning of this post. So far, models can load POST data (assigning it to the model attributes), store data, and perform data validation through a growing-list of validation filters.

Controllers can render views, and redirect to different routes. Controllers also have some basic functionality for dealing with web requests such as checking for POST data.

 

Automated PHP file-inclusion

Because this is designed to be an MVC framework for small projects, the framework uses a custom autoload function to automatically include any PHP files when you call a new Class. So, rather than using Namespaces, every PHP file will be included automatically at the moment it is needed. For large-scale projects this might cause problems with naming conflicts, but for a library that’s designed to be quick to use and build with, it’s perfectly serviceable.

What’s next

The next two features that need to be implemented are the Database class, and the first of the Helper classes to aid in quick form-building. The Database class will be a wrapper class for PHP’s PDO extension, providing easy-to-use methods for standard database CRUD operations, and will handle variable binding automatically for the highest security and less coding.

The FormHelper class will aid in building HTML forms programmatically, automatically handling the form action, various input types and options, and binding the model attributes to the form.

Once the FormHelper and Database class are complete, I think the project will be complete enough to release on GitHub for anyone who wishes to use it.

Tokenizer, a simple lexer in PHP to extract tokens

Tokenizer V1.0.0

Recently, after discovering Emmet for Sublime Text 3, my interest in parsing grammars and generating my own basic programming language and syntax was rekindled. Having the ability to use a simple, easy to understand syntax to quickly generate common boilerplate code (or, in the case of Emmet, html) is a tempting prospect.

Why build a Lexer?

Although most modern PHP IDEs do have snippet support; the ability to create re-usable sections of code, they’re not grammars. You can’t use them to construct code from many little building blocks or keywords. Just one at a time. Snippets are useful, though. If you find yourself writing for loops on a regular basis, then having a keyword you can type into your editor that quickly expands into a for loop ready for programming is a life saver.

But what if you wanted nested for loops? Or a for loop within a for loop, with three nested if statements inside it, followed by a while loop proceeding the first for loop? Yes, you could use snippets, but they wouldn’t be quite as fast. It would be nice to have a syntax as simple as Emmet’s, but designed specifically for PHP.

My first attempt at creating a Lexer was all-too basic, and I found myself trying to write an ever-more complex regular expression to try and extract all the tokens I wanted from my string. Which is why I decided to build a simple Lexer class, instead.

Tokenizer in action

Output:

This is a basic example of the tokenizer in action. You create a series of patterns to match using regular expressions, and the tokenizer will take an input string and extract the tokens from it. If the tokenizer encounters any problems, it will report where in the patterns array the error occurred.

Why PHP?

Why not? As a scripting language, PHP makes it much easier to focus on developing the language itself than getting too bogged down in the syntax of a more complex programming language. This may be at a performance cost due to PHP being an interpreted language, though. However, one of the benefits of an interpreted language like PHP, Javascript or Python is the function eval(). This function interprets a string as inline code, and then processes it as code. Although some people will tell you eval() is evil, I think it’s just misunderstood. Let’s say you wanted to a parse a mathematical expression in your new programming language, and return the result. You could write your own math parser. Going through the process of adding in operator precedence, including parsing expressions in brackets first, or..

However, if you had performance in mind, but still wanted to maintain the ability to have some of the work done for you, then you could look at Lua and ChaiScript, two scripting languages you can use within C++. This gives you the performance of a compiled language, and the flexibility of a scripting language, all in one.

What next?

There is of course much more to creating a programming language than just recognising the individual tokens the syntax is made of. Once you have your tokens, you’ll need to parse them with a parser which can then interpret the tokens as a grammar, and then perform actions based on that grammar. One common approach is creating what is known as an abstract syntax tree. This can be accomplished by using the Interpreter design pattern, for example.

There are also pre-built lexers and parsers out there if you want a good head start, such as ANTLR and Bison, however you may find building your own will give you a much better understanding of how grammars can be built. I recommend looking into Chomsky hierarchy and Backus–Naur Form as they’re a good place to start.

If you’re looking for a light introduction into building a simple programming language, howCode have an excellent set of tutorials on their youtube channel. The playlist can be found here. The tutorials are written in Python, but the techniques can be applied to a variety of different imperative programming languages such as PHP, C++, Java and even Javascript.

Download Tokenizer on Github

The example.php file on github includes a more fleshed out example file to get you started on creating your own programming language.