Profiling PHP with xDebug Oct 02, 2015

In my previous post I wrote about using xDebug with Laravel Homestead and Sublime Text for debugging PHP.

Today I would like to add to that topic by showing you how to use xDebug to profile your application.

Homestead comes with easy install for Blackfire which is basically a nice web GUI around xDebug. I found it very slow as my connection are spotty at times, so I thought I would just profile locally.

Enable profiling

Append the following to /etc/php5/fpm/conf.d/20-xdebug.ini:

xdebug.profiler_enable_trigger = 1;
xdebug.profiler_output_dir = "/home/vagrant/xdebug"

The first line will allow you to use the chrome extension from last post to enable profiling when you need it. Don’t run your app with xDebug profiling on all the time, it can slow it down considerably.

The second line will output the result of the profiling to a folder you specify.

Setup a shared folder for outputs

In your Homestead.yaml add a folder entry for the folder you specified in your xdebug config.

This will allow you to view the files on your host OS.

Reading the output

The only tool I found to read the output is kcachegrind which coincidentally is pretty similar to blackfire.

It’s easy to install:

brew install qcachegrind
brew install graphviz

Read an output file:

qcachegrind filename

For help on reading the output I found this to be a good resource.

Sources

Debugging PHP with xDebug Oct 01, 2015

I think it’s common for a lot of developers in the PHP community to debug using var_dump or dd. I do this as well, it’s so ingrained in my workflow, nothing wrong with it really, but it’s fun how we choose to ignore actual debugging tools.

Back when I was working with Objective-C and C# I used the debugger exclusively, don’t really know why xDebug never stuck in my workflow for PHP.

One reason is that Sublime Text has poor support for it. But the other day I needed to debug something that dd just wasn’t the right tool for.

Homestead and xDebug

Homestead (the default vagrant box for larval projects) supports xDebug out of the box.

And the settings are located in /etc/php5/fpm/conf.d/20-xdebug.ini, which should look like this:

   zend_extension=xdebug.so
   xdebug.remote_enable = 1
   xdebug.remote_connect_back = 1
   xdebug.remote_port = 9000
   xdebug.max_nesting_level = 250
Note: If you have blackfire setup in your Homestead.yaml file xDebug will be disabled. If this is the case simply create above file.

xDebug in Sublime Text

You need to install the xDebug Client for Sublime Text.

Next open your PHP project and go to the “Project” menu. Click “Save Project As…” and save it in the root of your project. You will need to edit it for xDebug to work from a vagrant box.

{
    "folders":
    [
        {
            "follow_symlinks": true,
            "path": "."
        }
    ],
    "settings": {
        "xdebug": {
             "url": "http://homestead.app/",
             "path_mapping": {
                "/home/vagrant/homestead" : "/path/to/your/project/"
             }
        }
    }
}

You should now be able to use xDebug from Sublime Text.

Sublime Text xDebug: Hitting a breakpoint

Sublime Text xDebug: Keyboard Shortcuts

Screenshot and keyboard shortcuts

Google Chrome Plugin

Normally when using xDebug you need to append a query param to every url, like so “http://homestead.dev/?XDEBUG_SESSION_START=sublime.xdebug". This is a cumbersome and b it creates problems when you want to debug POST requests.

To fix this you can install this excellent chrome plugin

Now if you want to start a debug session you can just click the icon in your menu bar.

Google Chrome xDebug Plugin

Sources

Production Ready Asset Pipeline with Elixir Sep 29, 2015

For past laravel projects I’ve been maintaining my own package for setting up grunt and gulp in an instant. Laravel-asset was nothing special but it got the work done and saved me a lot of time when spinning up new projects.

Laravel Elixir has been out for a while and is solving the same issue but in a different way. Instead of giving you long example files that a preconfigured to do everything you normally would want out of the box, they opted to create a new api for gulp that is far more simple. Making building the same functionality that laravel-asset offered very simple.

I thought I would share how to get the same functionality in Elixir and decomission laravel-asset officially.

Features we need to setup:

  • Compile sass
  • Concatenate js with browserify
  • Minify css
  • Minify js
  • Minify images
  • Add cache busting hashes to each url
  • Start LiveReload (now BrowserSync)

Our gulp.js file:

elixir(function(mix) {
    mix.copy('resources/assets/fonts', 'public/fonts');
    mix.browserify('app.js');
    mix.sass('app.scss');
    mix.imagemin();
    mix.version(['css/app.css', 'css/app.js']);
    mix.browserSync();
});

In your blade files as per the Elixir documentation, for cache busting to work you need to reference your css and js files using the Elixir function like so:

<link rel="stylesheet" href="{{ elixir('css/all.css') }}">
<script src="{{ elixir('js/app.js') }}"></script>

As of right now Elixir does not support imagemin and browserSync out of the box. For this reason you will need to install 3rd party elixir tasks.

npm install --save-dev laravel-elixir-imagemin

And require them on the top of your gulp.js file.

require('laravel-elixir-imagemin');

BrowserSync

For BrowserSync to work you need to use port 3000 when accessing your app http://homestead.app:3000.

If you’re using a custom domain you will need to configure BrowserSync like so:

mix.browserSync({proxy: 'custom.app'});

Also given we are using BrowserSync in conjunction with versioning the build in elixir() function will cause us some problems. I sent a pull request to Taylor, but in the meantime define a similar function and use it in your views like so:

/**
 * Get the path to a versioned Elixir file.
 *
 * @param  string  $file
 * @return string
 *
 * @throws \InvalidArgumentException
 */
function eelixir($file)
{
	if (App::environment('local')) {
		return $file;
	}

	return elixir($file);
}

Update

Got my pull request for BrowserSync support in Elixir accepted, so less I’ve updated the post to reflect this.

Who am I and why am I writing? Sep 27, 2015

For what will most likely be my first and last post on this blog (realistically speaking) I would like to introduce my self.

Who am I?

Andreas Heiberg. I’m many things not sure how to express it without hitting too many cliches. Down to the bone I’m and entrepreneur who loves to code and takes great pleasure in design as a spectator. I currently live in London working for Powaband as a Senior Developer.

Stepping back a bit I just moved here from San Francisco where I ran my own startup Kanler. 14 months prior to that I moved from my birth city Copenhagen. It’s been a wild year and a half, which I might or might not write a post about some time.

Why am I writing this blog?

I actually used to write this blog on a different domain many years ago, with some success. But after years of neglect the domain was bought by someone else :(

I’ve chosen to get it up and running again. Not really a big writer nor a fan of writing, so why am I doing it?

Every year I read and learn about a ridiculous amount of stuff. This blog is more or less just a dump of some of those things. It’s a nice visualization of progress that is otherwise easy to oversee. If you gain some value from it as some did from it’s predecessor that’s great!

What will I blog about?

I’m coding the majority of my week which is usually reflected in the posts. On my mind right now is Debugging PHP, Speeding up Homestead (Vagrant), Caching and E-Tags, BrowserSync and Elasticsearch.

Can’t promise some of my traveling, design interests and general thoughts won’t slip in here, but I will try and keep it tech related.