Exploring the Webiny Framework: The StdLib Component

By Bruno Skvorc

There’s an adage about a developer’s career cycle:

  1. Doesn’t use frameworks
  2. Discovers frameworks
  3. Writes his own framework
  4. Doesn’t use frameworks

Point 4, of course, referring to the newfound ability to use Composer to build your own framework from various battle tested third party components.

We all know there’s no shortage of frameworks in the PHP ecosystem, so it surprised me quite a bit to see another pop up rather recently.

The framework is called Webiny, and, while packed to the brim with wheel reinventions they deem necessary, there are some genuinely interesting components in there that warrant taking a look. In this introductory post, we won’t be focusing on the framework as a whole, but on the most basic of its components – the StdLib.

Webiny StdLib

No, not that “std”. StdLib stands for Standard Library and is at the core of every other sub-component of the framework. It’s kind of like adding a dependency or two to a random PHP project and before you know what’s happening, Symfony/Yaml is somehow already in there.

Among other things, StdLib, like many others before it, makes dealing with scalars significantly simpler by adding a fluent object oriented interface on top and some helper methods. For example, there’s a lightweight URLObject which contains some helper methods for dealing with redirection, schemes, ports, etc. Besides helping out with OO wrappers, the library also offers some basic validation, methods that help with building other Webiny components, a simple singleton trait, and more.

Where StdLib differs significantly, is in the fact that it’s implemented as a set of Traits – a vastly underused part of modern PHP development. For example, the aforementioned URLObject is instantiated like so: $this->url('');, because the StdObject trait is added to any class that needs this functionality. Most of the other components of the Webiny framework are implemented as Traits as well due to their isolated nature – the team chose this approach in order to simplify the hierarchy structure of classes, aiming for as few extends as possible.

StdLib is usable as a standalone package and can be cloned or “Composered” directly, or it can be pulled in as part of the entire framework. Let’s see what it offers, shall we?


Internally, the StdLib consists of two sub-libs. One is the Exception set which is to be used only if you intend to build additional Webiny components (more on that in future tutorials). The other is the StdObject lib which contains the functionality we talked about before.

Aside from that, the library contains traits that utilize these sub-libs.


The ComponentTrait is only useful if you’re building additional Webiny components – something we won’t be dealing with just yet. For now, we’ll skip it.


The FactoryLoaderTrait is useful in summoning class instances that have been dynamically defined. For example:

$className = 'myNameSpace\myClass';
$argument1 = 'Hello';
$argument2 = 'World';
$mustBe = 'myNameSpace\mySubClass';

To instantiate myClass with the arguments “Hello” and “World” while making sure the instance is of the mySubClass type, you can take the following two approaches:

// standard PHP

try {
    $instance = new $className($argument1, $argument2);
    if (!($instance instanceof $mustBe)) {
        throw new Exception("Instances don't match!");
} catch (Exception $e) {
    // Handle exception
// FactoryLoaderTrait approach

try {
    $instance = $this->factory($className, $mustBe, [$argument1, $argument2]);
} catch (Exception $e) {
    // Handle exception

As you can see, the second way is slightly shorter. Granted, the usefulness of this trait is questionable at best, especially considering that dynamic class names aren’t something one should use all that much, but when you take into account the level of standardization such a feature can bring across your entire organization/framework, the benefits become apparent. This trait’s approach is little more than a “coding standard” in dynamic class instantiation, but it can be a valuable one.


The SingletonTrait instantly turns your class into a singleton. There are extensive discussions all around the web about the “bad” nature of singletons – not just ancient scriptures like these but even some of our own old posts discuss this – but on the off chance you need one and can’t have a decent DI container implementation to use instead, it’s here.

One thing to keep in mind is the __construct conflicts. This particular trait doesn’t implement its own __construct method, meaning it can be used in both classes that have one of their own and those that don’t, unlike some other solutions, but it also means that you should adapt your class’ constructor to fit the singleton pattern if you choose to use this trait.

If you’re new to singletons, this post might help.

Another thing worth mentioning in this implementation is the fact that the trait implements a public init method and a protected _init method, executed in that order after the instance is created.

This is useful because you can use it as a post-creation initialization mechanism to further set up your singleton instance without having to rely on its constructor – maybe your class already has a defined constructor, and all you need is to turn it into a singleton, but the singleton mode of work needs some more tweaking? Perfect for init.


This trait is a combination of StdObjectTrait and ValidatorTrait. By itself, the StdLibTrait contains some json encode and decode helpers which are rather bare-bones right now, as well as a serialize and unserialize method which do essentially the same things as PHP’s counterparts. This may have been the place in which to instead use Symfony’s Serializer as a battle tested and multi-format supporting component.


Starting with ValidatorTrait, it’s a simple collection of native PHP methods for checking type, but rewritten so they’re part of a class. I’m not sure of the reasoning behind this, as the API remains almost completely identical (self::isArray() vs is_array()), but I assume it has something to do with keeping the component extensible – being able to update these native methods without having to change the API lib-wide is guaranteed to be a priceless perk later on.

In one part, the validator makes use of the StdObjectWrapper which is a part of the StdObject sub library – it uses the Webiny OO wrappers for scalars and the url format to provide a fluent interface for checking these types.


This is the core of the StdLib component, the main part. It provides the class that uses this trait with the ability to spawn ArrayObject, UrlObject, StringObject and DateTimeObject instances by means of an appropriate helper method.


Arguably the simplest of the bunch, this object allows you to use strings as objects.

$string = $this->str("My string");

The instance will natively contain an encoding constant (defaulting to UTF8) and some helper methods like length, wordCount and subStringCount, all of which are demonstrably useful, as well as some native PHP functions once again wrapped into class methods. Via a ManipulatorTrait, common to all the StdObjects, the StringObject also has access to methods that change it – trim being the most familiar one but also featuring those for appending, prepending, adding slashes, and much, much more.

An enormous advantage of this approach is not only the ability to chain calls to the string object, but also the autocomplete such an interface provides for your IDE:

$string = $this->str("This is a string");
echo $string->hash()->padLeft(45, "testing");

In one line, we hash the string and pad the remaining character slots on the left of it with the word “testing” until there are 45 characters. The result is testif72017485fbf6423499baf9b240daa14f5f095a1. It hardly gets simpler than that, and it’s extremely readable.

As another example, see this one from the docs:

$string = new StringObject('Some test string.');
$string->caseUpper()->trimRight('.')->replace(' test'); // SOME STRING

Of course, the object implements the __toString method so that it’s directly usable as a string. Coincidentally, all other objects in the StdLib also implement this method, and are directly printable, producing the output you’d expect their non-object counterparts to generate.

The methods that are exposed are too numerous to name, so take a look at the file to find out about all of them.


Similar to StringObject, the ArrayObject offers an easy interface to array manipulation. Naturally, it’s iteration-friendly so you can just loop through it as through any array with a foreach, behaving almost like a native array.

$array = new ArrayObject(['one', 'two', 'three']);
$array->first(); // StringObject 'one'
$array->append('four')->prepend('zero'); // ['zero', 'one', 'two', 'three', 'four']

Note that getting elements from this array format produces StdObjects, not actual scalars. The return value will always be of the StdObjectAbstract type. Strings produce StringObject, arrays produce ArrayObject, and numbers, curiously and somewhat both inconsistently and consistently produce an instance of StdObjectWrapper with the _value property set to the actual number. If the element is a class, that class gets wrapped with the wrapper, too. For example:

$array = $this->arr([1, "2", new myClass(1, 2)]);

This gives us:

I’m not sure how I feel about this. On one hand, this is super consistent, making sure we always get the StdObjectWrapper in some shape or form, but on the other, if I’m dealing with an array of classes, I couldn’t care less about this wrapper. There is, of course, a way to get the real value out of any of the Webiny StdLib objects – each has a val method which pulls out the underlying value contained within.

For all the various manipulative methods that arrays have access to by using this trait, see the manipulator. I find the chainable level syntax particularly useful – being able to go down into a multidimensional array by using key1.key2.key3 as an index is quite the impressive timesaver:

$array = [
            'k1' => 'test',
            'k2' => [
                'k3' => [
                    'k4' => 'deepest'
$a = new ArrayObject($array);
$a->keyNested('k2.k3.k4', 'webiny');
$a->keyNested('k2.k3.k5', 'anotherElement');

echo $a->keyNested('k2.k3.k4'); // webiny
echo $a->keyNested('k2.k3.k5'); // anotherElement


The URL object is here to make dealing with URL syntax easier. It supports some common response codes, methods for dealing with query params, ports, and other variables and can also be manipulated easily – switch out scheme, hosts, domains etc with a single line of reliable code.

What’s strange is that URLObject doesn’t extend the StringObject. To me, extending would make sense seeing as they’re both, essentially, strings in this case and the former would benefit from the manipulative methods of the latter. There are also much better URL manipulation libraries out there, so I don’t see the benefit of using this one. One example that springs to mind is the excellent PHP League URL library which does all this and much, much more, with the added advantage of being fully tested and actively maintained by over a dozen of highly capable developers.


Finally, there’s the DateTimeObject. With helper methods bursting at the seams, the DateTime object provides a more fluent, natural interface to PHP’s native DateTime class and helps you deal with time-related problems:

$dt = new DateTimeObject('3 months ago');
echo $dt; // 2013-02-12 17:00:36
$dt->add('10 days')->sub('5 hours'); // 2013-02-22 12:00:36

In and of itself, the DateTimeObject trait is very handy if you’re already using StdLib in a project, but for any more complex DateTime manipulations, I would recommend Carbon with some Period added in for flavor.

That’s not to say the DateTimeObject doesn’t have its use – it supports default time zones, easy date format outputs of various shapes and sizes, simple and easy diffs as a lighter alternative to Period, human readable “X time ago” outputs, offsetting to different timezones, and much more.


By doing all this, the Webiny framework makes sure no developer coming into the project deals with native PHP types. They all have their appropriate wrappers and they all behave exactly as the developers want them to behave. Is this overly ambitious? Maybe. But I see it as an interesting approach akin to defining a coding standard before you start working on a project – the problems encountered during further stages of development will be domain specific exclusively, most likely saving time in the long run. The only big con I can see here is having to use the trait in every single class you want to give StdObject support to.

The Webiny project is an ambitious and interesting one. The scope of the framework is impressive and the ground its components cover vast – but whether or not they’re actually necessary, I’ll leave that up to you to decide. If you’re curious as to why I’m paying so much attention to this framework as to warrant a post (or several), it’s because I enjoy playing with new things, but also because I contributed to it a little bit and am curious as to where they can take it.

In some future posts, we’ll be looking at more Webiny components and even build a sample event driven application with the framework to take it for a proper spin and gauge its effectiveness. Until then, I encourage you to play around with its various aspects and tell us about your experiences.



For when you want to spend 8 hours/day trying to find and decode fan-fiction documentation, learning new rebus-like syntaxes, hammering squares into round holes and working around arbitrary artificial limitations.

...instead of 8 hours/day just coding stuff that works.


I completely disagree with that statement. Several frameworks have excellent documentation such as; Symfony and Laravel. As for limitations I always find that as a cop out answer for those people who don't like using frameworks. At the end of the day if you can view source there are no limitations only the ones you impose. Not to mention using open source projects and contributing back enriches the community in general. When you chose to use open source frameworks over rolling your own you also provide more value for a client because the transition to other developers has less of a learning curve. For all these reasons I mentioned I truly believe that people who think like you to be very selfish individuals not enriching the community or helping the ecosystem which they are apart of. You're also doing clients a disservice because if you get hit by a bus chances are that your documentation pales in comparison to that of most open source projects back by a community. The community will live on for large projects where as if something happens to the individual responsible for a custom system everything "dies" with them.

Every project I've worked on which has been custom code the idea of documentation has been basically no documentation. I don't buy it for one minute that those rolling their own code are writing better documentation than that of Symfony of Laravel. What "people" like you are doing is building something that may be great but will be a nightmare to maintain by another individual and have huge costs associated with onboarding others. I'm not going to say open source code, frameworks, modules, plugins aren't without their flaws but I tend to believe they have much fewer flaws than a single individuals code. Not to mention if a bug is found in one it can always be fixed and is a pull request away typically from helping others fix the same problem.

I also think that the article had it a bit backwards. It seems like everyone and their brother starts with building their own framework. However, it takes a true professional to recognize the available resources within the ecosystem that are available and use those instead of selfishly reinventing wheels. Also accepting the fact that open source code will have problems having enough humanity to fix and contribute back to the community. Once you know a programming language in and out that is the next step not building yet another framework but providing solutions to common problems that can be contributed back to the community that leverage the existing ecosystem. Being able to put ego aside and just enrich the community while also working for a client is stardum within our industry. Those that have the mentality that their code is better than everyone else are living in a fantasy land. Even if it is than you should be contributing back to the community and making people better around you and much of that starts with becoming involved and using thriving open source projects.


I think an unsung truth about those individuals against using open source code is that they are scared. Scared to have to deal with something besides their own outside their comfort zone. I don't think it has anything to with control, flexibility, etc but simply comes down to being scared, plain and simple. Those individuals rather stay in their comfort zone than have to deal with something unknown.The disservice this does to the community though is astonishing in terms of both knowledge sharing and standardizing the ecosystem to decrease the onboarding efforts.


Does anyone use webiny? Can someone share their experience with it? From my point of view it
- tries to fix PHP itself
- is not malleable to one's needs because it depends on a ton of traits and static calls and
- is hard to read because of it's coding style (mix of camelCase and underscores), static/trait jungle smiley and strange method names

$this->eventManager()->listen('some.event')->handler(new YourHandler())->method('customHandle');
// a method is called 'method'?

I can hardly imagine using it in a project. Finally this method makes me feel like it was year 2005. Why should a "data type" access super globals? Why should a data type try to set http headers (whithout calling headers_sent()) and even call die()?



Framework author here, thanks for your feedback!

We value everyone's constructive criticism and are constantly looking to improve, so definitely keep it coming. We actually do use the framework to power our own site and some other experiments currently in beta, but I understand if that's not too convincing, yet : )

To answer what I can.

Tries to fix PHP itself

  • it doesn't really, the StdLib component is more of helper to some common operations

Is not malleable to one's needs because it depends on a ton of traits and static calls and

  • actually the public API is rather simple, only one trait, but if you think it can we done better, please propose us the solution

Is hard to read because of it's coding style (mix of camelCase and underscores), static/trait jungle

  • we do follow the PSR coding standard, with the exception of defining the private and protected methods with a starting underscore (will probably drop that in the next release)

Why should a "data type" access super globals?
Why should a data type try to set http headers (without calling headers_sent()) and even call die()?

  • they shouldn't you're right, we'll address that in the next patch

If you do notice anything else, feel free to open a github issue on our account.

As I said, we are at the very start, our framework is not to compete with Symfony, or something like that, it's designed for a different purpose, but we still decided to open-source it, 'cause we think we have created couple of useful tools for the community, and to get feedback.


What is the purpose of the design? Maybe if other devs knew about the purpose and understood it, they can also use the framework the way it was intended to be used.:-)



Learn Coding Online
Learn Web Development

Start learning web development and design for free with SitePoint Premium!

Get the latest in PHP, once a week, for free.