Skip to content →

Category: Laravel

Laravel file logging based on severity

Per default anything logged in a Laravel application will be logged to the file: storage/logs/laravel.log, this is fine for getting started, but as your application grows you might want something that’s a bit easier to work with.

Laravel comes with a couple of different loggers:

single
Everything it logged to the same file.
daily
Everything is logged to the same file, but the file is rotated on a daily basis so you have a fresh file every day
syslog
Log to syslog, to allow the OS to handle the logging
errorlog
Pass error handling to the web server

Having different handlers included provides some flexibility, but sometimes you need something more specific to your situation. Luckily Laravel has outsourced it’s logging needs to Monolog, which provides all the flexibility you could want.

In our case, logging to files was enough, but having all of our log entries in one file made it impossible to find anything. Monolog implements the Psr-3 specification which defines 8 severity levels, so we decided to split our logging into one dedicated file per severity level.

To add your own Monolog configuration, you just call Illuminate\Foundation\Application::configureMonologUsing() from your bootstrap/app.php.

To add a file destination for each severity level, we simply loop through all available severity levels and assign a StreamHandler to each level.

Simple as that.

Later we decided to also send all errors should also be sent to a Slack channel, so we could keep an eye on it, and react quickly if required. Luckily Monolog ships with a SlackHandler, so this is easy as well.

So with just a few registered handlers, we’ve tailored our error logging to a level that we feel suits our needs at the current time.

Notice how we only log to Slack when we’re not in debug mode, to filter out any errors thrown while developing.

Leave a Comment

Lazy loading, eager loading and the n+1 problem

In this article I’ll look into a few data loading strategies, namely:

I’ll talk a bit about the pros and cons of each strategy, and common issues developers might run into. Especially the n+1 problem, and how to mitigate it.

The examples in the post are written using PHP and Laravel syntax, but the idea is the same for any language.

Lazy Loading

The first loading strategy is probably the most basic one. Lazy loading means postponing loading data until the time where you actually need it.

Lazy loading has the advantage that you will only load the data you actually need.

The n+1 problem

The problem is with lazy loading is what is known as the n+1 problem. Because the data is loaded for each user independently, n+1 database queries is required, where n is the number of users. If you only have a few users this will likely not be a problem, but this means that performance will degrade quickly when the number of users grows.

Eager Loading

In the eager loading strategy, data loading is moved to an earlier part of the code.

This will solve the n+1 problem. Since all data is fetched using a single query, the number of queries is independent of the number of items fetched.

One problem with eager loading is that you might end up loading more data than you actually need.

Often data is fetched in a controller and used in a view, in this case, the two will become very tightly coupled, and every time the data requirements of the view changes, the controller needs to change as well requiring maintenance in several different places.

Lazy-eager loading

The lazy-eager loading combines both of the strategies above; loading of data is postponed until it is required, but it is still being prepared beforehand. Let’s see an example.

As usual, a simple example like this only shows part of the story, but the $users list would usually be loaded in a controller, away from the iterator.

In this case, we’re keeping related code close together which means you’ll likely have fewer places to go to handle maintenance, but since the data is often required in templates we might be introducing logic into our templates giving the template more responsibilities. This can both make maintenance and performance testing harder.

Which strategy to choose?

This article has introduced three different data loading strategies, namely; lazy loading, eager loading and lazy-eager loading.

I’ve tried to outline som pros and cons of each strategy, as well as some of the issues related to each of them.

Which strategy to choose depends on the problem you’re trying to solve, since each strategy might make sense in their own cases.

As with most other problems I’d usually start by implementing whichever strategy is simplest and fastest to implement, to create a PoC of a solution to my problem. Afterwards I’d go through a range of performance tests, to see where the bottlenecks in my solution appears, and then look into which alternate strategy will solve that bottleneck.

Leave a Comment

Wrapping up Laracon EU 2016

Last week I spend some days in Amsterdam attending Laracon EU 2016. It was two very interesting days, and I think the general level of the talks was very high compared to other conferences I’ve attended. The location and the catering was also really good, and I was impressed with how smooth it all seemed to go, at least for us as participants. Good job!

Here I’ve tried to gather up some of my notes from the talks I saw. It’s mainly meant to serve as my personal notes, but I also try to give some recommendations as to which talks are worth watching when the videos are released.

The event can be found at joind.in. The videos havn’t been released yet, but you can find the Laracon US videos.

Taylor Otwell – Keynote / Laravel 5.3

Taylor continued his Laracon US keynote, and highlighted some of the other new features Laravel 5.3 will bring.

The emphasis on his talk was on:

  • Echo – Which makes it easy to provide real-time push notifications to online users of your app, for example straight to the website, or through notifications on your phone. One major advantage in this update is the easy of setting up private notification channels.
  • Notifications – An easier interface for pushing user notifications to various service like Slack and email. The interface makes it easy to create integrations to new services.

Hannes van de Vreken – IoC Container Beyond Constructor Injection

Hannes did an interesting talk on IoC containers. The first part of the talk was a general introduction to dependency injection and IoC containers and the purpose of both concepts. Afterwards he dove into some more advances subjects like contextually binding interfaces to implementations and container events which can be used to lazy load services or changing the settings of a service before injection.

He also talked about lazy loading services by using method injection and using closures for lazy loading services, not only when the requiring service is instantiated, but all the way to the point where the injected service is actually being used, like it’s done in Illuminate\Events\Dispatcher::setQueueResolver().

The talk definitely gave me some takeaways I want to look more into.

Mitchell van Wijngaarden – The past is the future

Mitchell did a talk on event sourcing, a topic I had only recently heard about for the first time. It was an interesting talk with a lot of bad jokes and puns to keep you awake (or whatever the purpose was) which gave a nice introduction to the subject, how it could be utilized and some of the pros of using it.

I think event sourcing is a pretty interesting concept, and I’d like to see it used in a larger project to see how it holds up. To me it sounds like overkill in many situations, but I’ve definitely done projects where knowing about it would have helped simplify both the architecture and the logic a great deal.

An interesting talk for developers working with transaction-based domains or who just wants some new inspiration.

Lily Dart – No excuses user research

Lily talked about the importance of user research and the importance of knowing what your users actually want, instead of just guessing. It would have been nice with some actual examples of projects where it had been used, how and the results of the research, but I’m already pretty convinced that data as proof is better than anyones best guess so this talk only served to make this belief stronger.

She provided some easy ways to start collection data about your customers wants and behaviour that I think could be interesting to look into:

  • Bug reports – Bug reports contain a wealth of knowledge about what your users are struggling with. Often we as developers can have a tendency to push aside reports, big or small, as simply being because the user didn’t understand how something works, but this is often caused by usability issues in the system they’re using. Lily suggested started tagging all bug reports, to provide an overview of which parts of your system that maybe should be easier to understand.
  • Transactional audits – Transactional audits are the small feedback forms we sometimes meet after completing a transaction. Many help systems, for instance, include a small form at the bottom of each help section asking the simple question “Did this page answer your question?”, where if we answer no, we’re asked what was missing, or what we were actually looking for.
  • Search logs – If your website has a search engine, logging all searches can also provide some interesting knowledge, both about what your users actually want to know more about, but also about what they are struggling to find out more about. This can give you an idea about things like features that are hard for the user to understand, or issues in your site architecture that makes it hard to find certain information in your website, or maybe even tell you more about what subjects people would like your website to expand more about.

A really interesting talk I’d recommend to anyone working with websites (developers, marketing, managers etc).

Evan You – Modern frontend development with vue.js

Evan gave an introduction to the vuejs framework, where it came from and some of the architecture decisions it’s based on. It was a very theoretical talk that provided some good background knowledge, but I had hoped for a more hands-on approach, and some more code, but I believe he did that at his Laracon US talk so I should probably watch that as well. Even so the talk still provided some good insights that I’m sure will help me when I’ll start looking into using Vue, which will hopefully happen soon.

It was an interesting talk if you’d like some background for Vue and it’s structure, but if you just want to learn how to get started using it, there’s probably better talks out there, like the ones from Laracon US.

Matthias Noback – Please understand me

Matthias gave a talk to remind us all that working as a developer isn’t only about developing software. On the personal side it’s important to work in a place where you feel appreciated and respected, and that you have access to the tools you need to do your work.

On the other hand you also need to do your part to make the job meaningful. Try to figure out who the customers are, and what they think about and want. Knowing who you’re doing the job for, and why they need it, will help you understand what actually needs to be done, and will help you make better decisions about your product. In the same way it’s useful to get to know your manager, that will make communication easier when the deadlines draw closer.

If you really want to be taken serious you also need to take yourself and your job serious. Take responsibility for your job. Show up, set deadlines and meet them, and deliver high quality work. Take your colleagues, managers and customers seriously, don’t be a ‘developer on a throne’.

There was nothing particularly new in the talk, but I believe it serves as a good reminder of some things that many either ignore or take for granted. A good talk to watch for any developer or people managing developers.

Abed Halawi – The lucid architecture for buiding scalable applications

Abed talked about what he described as lucid architecture and the general thoughts about the problem him and his team were building. He described an architecture as a an expression of a view point that is used to communicate structure and should hopefully help eradicate homeless code by providing every piece of code with one obvious unquestionable place to reside.

The requirements for Abed’s team’s architecture was that it should kill legacy code, define terminology, be comprehensive without limitations, complement their framework’s design and perform at scale.

The lucid architecture consists of 3 parts

  • Features – Each feature fulfills one business requirement. Features are grouped into domains, and a feature works by running a range of jobs in order. CreateArticleFeature could be a feature name.
  • Jobs – Each job handles one step required to fulfill a feature ie. validation. SaveArticleJob could be a job name. Each job can be used by several different features.
  • Service – A service is a collection of features. Features are net reused between services. The website service and the API service would each have their own CreateArticleFeature. Jobs can be reused, though.

In lucid architecture controllers are VERY slim, each controller serves one feature, and does nothing else, everything from validation to domain object creation/updating and response preparation are handled by different jobs launched by the feature.

I found the idea pretty interesting, especially since it removes some of the overlap of different concepts by providing a specific use case for each domain level. I also like how all logic is handled in specific and clearly separated jobs making it easy to move jobs to queues if necessary. It looks a bit like the direction that we’re currently taking our code base at my job, though we’re not quite so radical in our approach.

An interesting talk to watch if you want some new inspiration regarding architecture.

Gabriela D’Avila

Gabriela talked about some of the changes coming to MySQL in version 5.7. A lot of the talk went a bit over my head since I’m not a database specialist, but it was interesting and gave some good pointers for things to look more into.

MySQL 5.7 enables the NO_ZERO_DATE option by default, which might have implications for our application since we actually use zero dates.

MySQL has a concept of virtual columns, that can calculate values based on the value of other columns, like concatenating a first_name and a last_name column into a full_name. Iirc it can also get attribute values from the new JSON type columns, which would be pretty cool.

Jeroen V.D. Gulik – How to effectively grow a development team

Jeroen gave a talk about developer culture in teams, and how he had built his developer team at Schiphol airport. He talked a lot about what culture is, what developer culture is and how to foster a positive culture, and how that culture is related to developer happiness. He had a lot of good points, too many to note here, and I’d recommend anyone interested in company culture to watch this talk, it’s relevant to anyone from developers through developer managers to higher level managers in technology focused companies.

Adam Wathan – Curing the common loop

The last talk I saw was Adam Wathan’s talk about using loops when programming, versus using higher order functions, which is functions that takes other functions as parameters and/or returns functions. The base of the talk was the 3 things Adam claims to hate:

  • Loops
  • Conditionals
  • Temporary variables

I can see the point about the code getting a lot more readable and I like how the approach requires a radically different thought process compared to how I’d normally do things, I’d definitely recommend any developer to watch this talk.

Leave a Comment

Demagicfying Laravel: Model properties; getters and setters

I mostly enjoy working with Laravel. It provides a range of tools that makes it really fast to create a proof of concept of an idea, allowing you to test out your ideas without spending too much time on ideas before knowing if they are actually worth spending time on.

When you’re starting out with Laravel a lot of what’s going on behind the scene can feel like magic. This is really nice in the sense that you don’t often have to worry about what is actually going on, but on the other hand, it can make things pretty hard to debug, it is not clear what is causing a bug when you’re not sure what is going.

In this post I’ll look into Eloquent models’ object properties, and how Laravel’s Eloquent ORM handles getting and setting property values.

Table of content

Setting up

To have an example to work with, we’ll start by setting up a database table for a simple Todolist.

The Todolist is pretty simple, it has a unique auto-incrementing ID, a string name, a text description, and Eloquent’s default timestamps. The most interesting part of the migration file is the up() method, where we define the table.

Besides the migration, we need to create our Todolist model.

This gives us a basic model class, that we can use to create Todolist objects. The full class looks like this:

That’s pretty much as bare bones as it gets.

Setting object properties

This saves the model object with its fancy new name and description. But how does this happen? How does Laravel know which properties to save, when the properties isn’t even defined on the object? Let’s look at our object:

We see that our data is set in an array named $properties, and not as standard object properties. Let’s look into this.

We start by looking at our Todolist model. This is just an empty class, so nothing happens here. The Todolist class extends the Eloquent Model, so let’s look at that one. In a standard Laravel application, you’ll find it in

Obviously our model specific properties aren’t defined here either, since Laravel can’t predict what we need, so something else is going on.

We can see that Laravel uses magic methods, in this case the __set() magic method.

In PHP the __set() magic method is used as a catch all, that is called when trying to set an inaccessible object property, which means a property that either isn’t defined, or that is inaccessible due to being defined with a protected or private scope.

The method in the Eloquent Model class is defined as:

__set() is passed 2 arguments, $key is the name of the property to be accessed, and $value is the value we’re trying to set on the property.

When calling the code:

$key will have the value ‘name’, and $value will have the value ‘My new list’.

In this case, __set() is only used as a wrapper for the setAttribute()-method, so let’s have a look at that one.

This is an important part of the Laravel setter magic, so lets go through it step by step.

The first thing that happens is a check whether a set mutator method exists for the given property.

In an Eloquent context a set mutator is an object method on the form set[Property]Attribute, so for our name attribute, that would be setNameAttribute(). If a method with that name is defined, Laravel will call it with our value. This makes it possible to define our own setter methods, overriding the standard Laravel behavior.

If no setter method is defined, Laravel checks whether the property name is listed in the class’ $dates array, or if it should be cast to a Date or DateTime object, according to the class’ $casts property. If Laravel determines that the value is a datetime type, it will convert the value into a time string, to make sure it is safe to save the value to the database.

The last check determines whether the value should be encoded as a JSON string in which case it is converted to a json string, to make sure it’s ready to be saved to the database.

As the last thing, the method saves the value, which may or may not have been cast to a different type, into the object’s $attributes properties. This is an array where the object’s current state is saved.

Getting object properties

Now that we have an idea what’s happening when setting properties, let’s look into getting the data back out.

Produces the output:

Just like __set($name, $value) is PHP’s fallback when trying to set a property that doesn’t exist, PHP has a magic get method, called __get($name). This method is called when trying to read the value of a property that hasn’t been defined.

Again, our Todolist class doesn’t have a $name property. Trying to read it will call PHP’s __set() method, which again is defined on the base Eloquent Model class.

Illuminate\Eloquent\Model::__set() itself is just a wrapper for the class’ getAttribute() method.

The last part of the method relates to Eloquent relationships. I might go into this in another post, but I will skip it for this post.

The interesting part of the method is a check for whether the property name exists in the object’s $attributes property. This is where you’ll find it if it’s been set with the default Eloquent property setter, or if it has been loaded from a database.

If the property doesn’t exist in the $attributes array, a check is made to see if a get mutator exists. Like Laravel setters are in the form set[Property]Attribute(), getters are in the form get[Property]Attribute(). Ie. when trying to read our $name property, Laravel will check for the existense of a method called getNameAttribute().

The getAttributeValue() works like a reverse version of the setAttributeValue() discussed earlier. It’s main purpose being to get a stored value, cast it to something useful, and return it. Let’s go through it step by step.

The first thing that happens is that the property’s value is fetched, if the property exists in the $attributes array.

If the class has a property mutator, the property value is run through it, and returned.

If the property name is specified in the $casts array, the property’s value is cast to the specified type and returned.

If the property is listed as a date property in the $dates array, the value is converted to a DateTime object, and returned.

And lastly, if the property shouldn’t be changed in any way, the raw value is returned.

Summary

Eloquent uses PHP’s magic __get($name) and __set($name, $value) methods to save and get data on model objects. During this process it provides a couple of ways to manipulate the data.

So far we’ve identified 3 ways to manipulate property values set on and gotten from Eloquent model objects.

  • Accessor and mutator methods
  • The $casts array
  • The $dates array

Accessor and mutator methods

The most flexible way to manipulate Eloquent data on getting and setting is using accessor and mutator methods. These and named on the form get[Property]Attribute() and set[Property]Attribute().

Examples

The $casts array

The casts array is an array property where casts are specified for object properties. If no accessor or mutator is defined for a property, and it’s specified in the $casts array Eloquent will handle casting the value.

Example

The $dates array

Since it’s very common to work with dates and times, Eloquent provides a very easy way to specify which properties should be cast as date objects.

Example

By default, the properties will be cast to Carbon objects when getting the property.

Common pitfalls

I’ve seen a couple of common errors developers make when working with Eloquent getters and setters, that cause issues.

  • Defining the object properties
  • Forgetting to set $attributes

Defining the object properties

Many OO programmers prefer to define their object properties in their class files, both to make it instantly visible which properties are available on class objects, and to allow PHP to make various optimizations. But since Laravel’s Eloquent ORM relies on the magic PHP getter and setter methods, defining the class properties will make Eloquent unable to mutate the data, as well as preventing the data from being set in the $attributes array, preventing it from being saved to the database.

Defining the object property like this prevents Eloquent from saving the name attribute to the database.

In this example the ‘name’ key doesn’t exist in the $attributes array, hence it doesn’t exist in the database.

Forgetting so set $attributes

Another common pitfall is to override a mutator method to manipulate the property value, but forgetting to add the data to the $attributes array.

In this example the value will never be saved to the database, and cannot be read using an accessor.

The example will echo an empty string.

Leave a Comment