Benchmarking Proem

by trq

I just pushed the bootstrap mechanism for Proem to GitHub and thought I might take a look at it’s current memory usage.

This is just a very simple benchmark of the bootstrap process. Keep in mind nothing really happens during this call to init(). It’s just the infrastructure. The Filter chain is setup and filled with Response, Request, Route & Dispatch inBound & outBound events. These events then trigger a further 4 events each. It is these further triggered “Events” that the framework (and any applications) will eventually listen for and take action on to build a response.

The script is simple:

proem.php

#!/usr/bin/php
<?php
 
function convert($size)
{
    $unit = array('b','kb','mb','gb','tb','pb');
    return @round($size/pow(1024,($i=floor(log($size,1024)))),2).' '.$unit[$i];
}
 
echo convert(memory_get_usage(true)) . "\n";
 
require_once 'src/proem/lib/Proem/Autoloader.php';
 
echo convert(memory_get_usage(true)) . "\n";
 
$loader = new Proem\AutoLoader();
$loader->registerNamespaces([
    'Proem' => 'src/proem/lib'
])->register();
 
echo convert(memory_get_usage(true)) . "\n";
 
(new Proem\Proem)->init();
 
echo convert(memory_get_usage(true)) . "\n";

And the results:

trq@proem.dev[~]+ time ./proem.php 
256 kb
512 kb
512 kb
1.25 mb
 
real	0m0.015s
user	0m0.007s
sys	0m0.007s

First milestone completed.

by trq

Well, it’s been about six weeks in the making but I finally got the first milestone (0.1.0) complete on the Proem Framework. This marks the implementation of allot of the basic infrastructure that the rest of the framework will be built on top of.

This infrastructure includes:

  • An Autoloader which implements the PSR-0 standard.
  • An Options Component enabling a type of named arguments implementation.
  • An Cascading Filesystem enabling framework classes and traits to be easily overridden.
  • An Asset component used to handle dependency injection via DI containers.
  • A Filter Chain which will be used to control the bootstrap and execution flow of the framework.
  • An Events component making it easy to integrate the concept of plugins and modules.

At this stage it’s still pretty difficult for someone just looking at the code to invision how it will all tie together, but this should become allot clearer as work begins on the 0.2.0 milestone. In fact within the next few days I will be working on the Proem object which will be responsible for bootstrapping the framework as well as the default Chain events which are used to configure all required Assets.

I am already starting to get a little bit of interest in the project but would of course appreciate all the help I can get. Over the next few weeks things should become allot easier to understand as a whole, so if your interested, Fork Proem and give me a hand. I also have PHP5.4 sandboxes available via ssh if need be.

Further prototyping Options

by trq

Ok, it’s getting pretty late here so this post wont be too detailed. I’m just further prototyping my Options trait and I think it’s getting pretty close to being ready to implement into Proem.

You can see my original post here. There where a few things that bugged me about the original implementation. My main quibble was that it completely wiped out all the benefits provided by type hinting. Hence, I decided to try to implement something where I could actually validate the options as they come in.

This is what I have come up with. It should be pretty self explanatory.

<?php
 
class Something {}
 
trait Options
{
    private $options = array();
 
    private function setDefaults($options)
    {
        $this->options = $options;
    }
 
    private function setOptions(array $options)
    {
        foreach ($options as $key => $value) {
            if (isset($this->options[$key])) {
                $this->options[$key]->setValue($value);
            } else {
                $this->options[$key] = new Option($value);
            }
        }
 
        foreach ($this->options as $key => $value) {
            try {
                $value->validate();
                $this->options[$key] = $value->getValue();
            } catch (Exception $e) {
                throw new \Exception($key . $e->getMessage());
            }
        }
    }
 
    private function getOption($key)
    {
        if (isset($this->options[$key])) {
            return $this->options[$key];
        }
    }
}
 
class Option
{
    private $value;
    private $is_required = false;
    private $is_object = false;
    private $obj_type = null;
 
    public function __construct($value = null) {
        $this->value = $value;
    }
 
    public function setValue($value) {
        $this->value = $value;
        return $this;
    }
 
    public function getValue() {
        return $this->value;
    }
 
    public function required() {
        $this->is_required = true;
        return $this;
    }
 
    public function object($obj) {
        $this->is_object = true;
        $this->obj_type = $obj;
        return $this;
    }
 
    public function validate() {
        if ($this->is_required) {
            if (!isset($this->value)) {
                throw new Exception(' is required');
            }
        }
 
        if ($this->is_object) {
            if (!is_object($this->value)) {
                if (!is_a($this->value, $this->obj_type)) {
                    throw new Exception(' is required to be of type ' . $this->obj_type);
                }
            }
        }
        return true;
    }
}
 
class Foo
{
    use Options;
 
    public function __construct(array $options = array())
    {
        $this->setDefaults([
            'foo' => (new Option('foo')),
            'bar' => (new Option())->required(),
            'boo' => (new Option())->required()->object('Something')
        ]);
 
        $this->setOptions($options);
    }
}
 
$f = new Foo([
    'bar' => 'blahblahblah',
    'boo' => new Something,
    'bob' => 'this is bob'
]);
var_dump($f);

It’s still a little rough, but it works and can be fine tuned as it is used. This prototype only validates required options, and that they are of a specific object type. An actual implementation would validate for arrays, integers, strings and most likely regex pattern matches.

The entire validation process is currently really rough, but that will definitely and will definitely be refactored and extended. I’m also not overly happy with how the setOptions() method is designed within the Options trait, but again, that can and will be refactored.

It’s the Foo class where the actual usage syntax takes place. I think it’s reasonably tidy for the amount of work that is being done.

I’d be really keen to get some feedback on the concept so any comments are more than welcome.

edit:

Actually, thinking about this a bit more, I can do away with the extra dependency on some Option object *and* tidy the end syntax up a little by using an array instead.

The end result will end up looking something like:

<?php
class Foo 
{
    use Options;
 
    public function __construct(array $options = array())
    {   
        $this->setDefaults([
            'foo' => 'foo',
            'bar' => ['required'],
            'boo' => ['required', 'object' => 'Something']
        ]); 
 
        $this->setOptions($options);
    }   
}

All the validation would the occur within the Options trait itself.