It’s been a while since I wanted to create a dependency injection mechanism using PHP but nerver took the time. I wanted it as simple as possible. This morning I woke up and decided it was time! So here is Klass. Only one class which other classes can extend to get their properties injected or it can be use independently. It also provides automatic getters and setters when sublclassed.

Dependency Injection (DI) is described on Wikipedia as:

Dependency Injection (DI) in computer programming refers to the process of supplying an external dependency to a software component.

Klass uses annotations for a smoother coding style. No lines of declarations needed. Just use the @Inject tag on properties where their value should be injected. Use the @Dependency tag on classes that should be injected into properties.
When using the @Inject tag, you must specify the type of the value to be injected. It can be done between parentheses after the tag or using the @var tag (see php documentor). It is also possible to change the type under which a class registers itself as a dependency. It is done the same way as with @Inject.
When the property where @Inject is used is not public, Klass will try to use a setter method.

Dependency injection can also be used on class not subclassing Klass. Using the Klass::create() method, you can create instances of any class that will profit of the injection mechanism. It is also possible to inject objects using Klass::inject(). To register an object as a dependency, use Klass::registerDependency().

class Employee extends Klass
{
    /**
     * @Inject
     * @var Boss
     */
    public $boss;
}
/** @Dependency */
class Boss extends Employee
{
}
class Freelance
{
    /** @Inject(Boss) */
    public $boss;
}
 
$boss = new Boss();
$employee = new Employee();
$freelance = Klass::create('Freelance');
assert($employee->boss === $boss); // true
assert($freelance->boss === $boss); // true

Klass also provides automatic generation of accessors (getters, setters, …) for properties. This can be only done on classes subclassing Klass. Properties that should have accessors must have the @Accessors tag in their doc comment. There is three type of accessors supported: get, set and is. By default, all properties with the tag will have the get and set accessors. is is available with boolean values. It is however possible to enable only specific accessors. Specify them between parentheses and sperated by comasafter the @Accessors tag.
If the property name begins with an underscore, it will be removed.

class Employee extends Klass
{
    /** @Accessors */
    protected $_name;
}
 
$employee = new Employee();
$employee->setName('Peter');
assert($employee->getName() == 'Peter'); // true

The @Accessors and @Inject tags can be used at the same time.

I hope this little class will help some of you. This kind of mechanism is very well suited for architecture with many components interacting between each other. I tried to comment the code as much as possible so it can be understand by anyone.

Download klass.zip (with an example) (only 4Kb)

PS: From now on, I will try (and I said try!) to post more articles. If you would like to see articles about a specific subject, don’t hesitate to send an email (see the resume section).

Posted in Development, PHP at December 20th, 2008. Comments.

I don’t know if you’ve seen the news, but yesterday John Resig released FireUnit, a unit testing utility for javascript integrated to Firebug.It seems a great piece of software and it immediately got me thinking about integrating it to Harmony!

Some times ago I read a comment about Harmony on onGWT about the fact that frameworks mimicking GWT for other languages were going to harm GWT because they’re of lesser quality. It is clear that Harmony is a microbe compare to GWT (and I’m not talking about quality – I think Harmony is “pretty good” when following PHP standards) but I want it to grow!

Adding unit testing would be a great step forward! So when I saw the news of FireUnit, it strikes me: it must be integrated into Harmony. Thus, I’m going to start a new package named Harmony_Test which will provide unit testing in php as well as in javascript. You will be able to test your classes in both language so you’re sure the translation process has gone well.
I hope this new package will show my determination to build an enterprise class framework.

I also started a new package yesterday called Harmony_Zend which will facilitate integration between Harmony and the Zend Framework. For the moment, I’m mostly in a refactoring process. I hope to release the first beta before the end of the year…

Posted in Development, Harmony, PHP at December 19th, 2008. Comments.

As Harmony Framework is greatly shaping up (I’m near beta 1), I would like to present you one of its latest component: Harmony_Style. I developed this component a while ago but never published it. Harmony_Parser originally comes from this package. I decided to integrate it into the framework because I think it’s a great fit. But what is Harmony_Style ? In few words, it’s an enhance version of CSS. It provides new features over traditional stylesheets. The great thing about it, it’s that the syntax does not change so it’s easy to learn and compatible will all existing stylesheets.

Nested rules

This is probably one of the most annoying missing feature! You often have to write long selectors where it would be so natural to use nested rules. Using Harmony_Style, simply create rules in other rule definition. The parent selector will be prepended to child rules.

ul.my-list {
    list-style-type: none;
    li {
        margin: 20px;
    }
}

Will output:

ul.my-list {
    list-style-type: none;
}
ul.my-list li {
    margin: 20px;
}

Inheritance

When mutliple rules share the same properties, classes can be used. However in some situations, the targeted element does not have the needed class. Inheritance allows you to add all properties of an existing rule to another one. It’s done using the < character, followed by a selector pointing to the rule to copy. Multiple selectors can be used by separating them using comas.

.my-class {
    color: red;
}
#my-element-without-my-class < .my-class {
    margin: 20px;
}

Will output:

.my-class {
    color: red;
}
#my-element-without-my-class {
    color: red;
    margin: 20px;
}

You can of course override any properties.

Constants

Constants allow you to store values that you can reuse in your stylesheets. For example, it can be a list of colors, sizes, fonts… Constants won’t appear on the final stylesheet. They start using the dollar sign. There are two types of constants: single value and standard rules. The first one stores only one scalar value. It is defined as follow:

$my-font = arial;
$my-color = #FF0000;

The second type behaves the same way as normal rules:

$sizes {
    small: 10px;
    normal: 12px;
    big: 16px;
}

Rule-like constants can also contain nested rules:

$conf {
    sizes {
        small: 10px;
        /* ... */
    }
    colors {
        red: #FF0000;
        /* ... */
    }
}

You can use constants for inheritance and constants can inherit of any other rules. Now the big question is WTF if I can’t use these constants in property values? Here comes embedded queries.

Embedded queries

Embedded queries allow you to fetch any value from any rules. It’s normal selectors place between square brackets. It can be used in property and at-rules values.

#my-div {
    color: [$conf colors red];
}
#my-2nd-div {
    color: [#my-div color];
}

Property namespace

This is simply some syntaxic sugar. Some properties have what we could called a namespace or prefix, like font or border. These properties have many “sub” properties like font-size or border-right-color. Rather than always typing the whole property name, you can use curly braces to group them.

#my-div {
    border: {
        size: 2px;
        color: red;
        bottom: {
            size: 0px;
        }
    }
}

Will output:

#my-div {
    border-size: 2px;
    border-color: red;
    border-bottom-size: 0px;
}

Not as cool as previous features I have to say but wait for the next one.

Custom at-rules

Harmony_Style allows you to register custom at-rules. The component comes with three rules: @include, @target and @unpack.
@include works like @import but the inclusion is resolved server-side. Furthermore, rules from the included stylesheet can be used in embedded queries and with inheritance in the including stylesheet.

@include url("conf.css");
#my-div {
    color: [$conf colors red];
}

@target allows you to target rules based on HTTP headers. Rules nested in the @target will be rendered only if the HTTP header match the filter. @target takes two parameters: the header’s name and a regexp to match with its value. The name can be omitted. If so, the “User-Agent” header will be used. The parameters have to be placed just after the @target. The regexp must be placed between slashes. PHP modifiers can be used after the last slash.

/* will be rendered if the browser is Firefox */
@target /firefox/i {
    ul {
        list-style-type: none;
    }
}
/* will be rendered if the browser language is french */
@target Accept-Language /fr/ {
    #flag-fr {
        display: none;
    }
}

Finally the @unpack at-rule can be used to import nested rules in the global scope. It takes only one parameter, the selector of the rule to unpack. Embedded queries can be used to dynamically unpack rules.

$blue {
    div {
        background-color: blue;
    }
}
@unpack $blue;

Will output:

div {
    background-color: blue;
}

We’ve seen the different features provided in the language. Harmony_Style also allows you to manipulate stylesheets from PHP. The API to load stylesheets is very simple:

$stylesheet = new Harmony_Style();
$stylesheet->load('style.css');
echo $stylesheet->render();

If any error occurs, an exception will be triggered. There is also a loadCss() method to load from a string rather than a file. Both methods can take as second argument an array of parameters. These parameters can be accessed in the stylesheet using the $params constant.

#my-div {
    color: [$params color];
}
$stylesheet->load('style.css', array('color' => 'red'));

The API also provide two methods to query the stylesheet using selectors: querySelector() and querySelectorAll(). The first one returns the first match rule, the second all match rules. You can also query for properties, simply by appending them at the end of the selector. Full documentation about the API will be available with the release of Harmony.

Finally, I would like to show an example of a way to use Harmony_Style: creating themes.

$blue {
    div {
        color: blue;
    }
}
$red {
    div {
        color: red;
    }
}
@unpack [$params theme];

In your php code:

$stylesheet = new Harmony_Style();
$stylesheet->load('style.css', array('theme' => $_GET['theme']));
echo $stylesheet->render();

Only rules from $red or $blue will be rendered depending on the GET parameter named theme!

Harmony_Style was not part of the Harmony first preview so it’s not available for download on the official website. Thus, I created an archive with all the needed files to try it. You can download it by using the link below.

Download Harmony_Style.zip

Posted in Development, PHP at December 15th, 2008. Comments.

Hi everybody, it’s been a while but I’m fairly busy these times.
I would like to make a little note about Harmony Framework. The news of the first preview release has been around for some time now and I have seen some good and bad reactions. Most of them is about the usefulness of the framework.

I would like to remind that  Harmony is inspired and has the same goal as GWT (Google Web Toolkit). Their goal is to translate Java to Javascript and it’s a great library, very useful and helpful. I don’t see why Harmony’s goal should be seen differently. And I’m speaking about the goal only, I’m totally ok with the fact that some people may think it’s bad written, crap and anything else.
Some people appears to think that the goal is to port php applications to javascript. This is NOT it! The goal is to use PHP on the server AND on the client. The server logic should stay on the server.

I think there is a real usefulness to Harmony. It’s a young project and I’m actively developing it. I hope next versions and a manual will clear these doubts about it.

Posted in Unclassified at December 5th, 2008. Comments.