<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>OriginalBrownbear</title>
    <description>...
</description>
    <link>http://obrown.io/</link>
    <atom:link href="http://obrown.io/feed.xml" rel="self" type="application/rss+xml"/>
    <pubDate>Mon, 26 Dec 2016 13:44:48 +0100</pubDate>
    <lastBuildDate>Mon, 26 Dec 2016 13:44:48 +0100</lastBuildDate>
    <generator>Jekyll v3.3.1</generator>
    
      <item>
        <title>How to Use Docker Containers for Builds</title>
        <description>&lt;h2 id=&quot;docker-containers-and-builds&quot;&gt;Docker Containers and Builds&lt;/h2&gt;

&lt;p&gt;The one thing, that you simply cannot go without when running builds, is 100%
stability in the build environment. Docker is the obvious tool choice for achieving
this in 2016. A few crucial things should be kept in mind when setting these things up though.&lt;/p&gt;

&lt;h2 id=&quot;avoid-host-volumes&quot;&gt;Avoid Host-Volumes&lt;/h2&gt;

&lt;p&gt;Host-Volumes, that is volumes created by mounting a host path into the container
are your natural enemy when trying to achieve stability and portability for your
build. They introduce the host environment into the container and this is not a
theoretical issue at all!
Just look at this recent &lt;a href=&quot;http://stackoverflow.com/questions/33575351/docker-machine-on-mac-cannot-see-mounted-volumes-on-docker-host-docker-machine/&quot;&gt;question&lt;/a&gt; about running your MySQL database from a host
volume and the hoops, I had to advise the author to go through, to make it work.
Another classic issue arising from using host volumes is that the container will
often run as the root user or at least a different user than your currently logged in
user. This means that files created by the container, that you may want to retrieve
from the volume later, will belong to root and will have to get their owner changed
before you do anything else with them. Again, this requires actions on the host,
impeding portability and hence long term stability of the build (reinstalling the host machine, switching cloud provider … you name it!).&lt;/p&gt;

&lt;p&gt;The worst part though is, that using host volumes will not work with remote Docker hosts.
Only if the machine you’re starting the build from is also running the Docker daemon,
will you be able to use host volumes. Otherwise your build steps will need to include explicitly
uploading the necessary files to the host before starting the container. Often times
cloud providers of Docker daemons like Amazon ECS will not even offer this option.&lt;/p&gt;

&lt;h2 id=&quot;lock-in-version-numbers&quot;&gt;Lock in Version Numbers&lt;/h2&gt;

&lt;p&gt;This next point I cannot stress enough. When setting up build environments people
often add things like:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-docker&quot; data-lang=&quot;docker&quot;&gt;RUN apt-get install ruby&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;into their Dockerfile and it works just fine for them, … until it stops working.
Adding a statement like the above to the Dockerfile tells Docker (technically apt in this case …)
to install the latest Ruby version available for the Linux distribution used.
Especially in the Ruby world this will lead to issues quickly in many cases, 
as a result of Ruby seemingly often favoring innovation over backwards compatibility.
Eventually the ruby version installed by this might jump from 1.8.x to 1.9.x and all of a sudden your build
will inexplicably break. This case might be somewhat easy to debug, but let me give
you an example of how bad it can get:&lt;/p&gt;

&lt;p&gt;A while back I created a build environment for running Selenium based tests against a
very complex setup of multiple web applications. It took a while to set things up,
but eventually 4 web server containers where being tested in the craziest spots imaginable,
still the build was stable over hundreds of runs and me and the client were happy.
What I did was specify installing the latest Selenium version to be installed
instead of properly locking in the version.
A few weeks later the client made some design changes to one of his sites and asked me to adjust the tests
after his developers failed to do so and now one test case was failing erroneously.
So I rebuild the setup from the Dockerfiles on my Laptop that I had previously deleted
it from already to save some disk space and started working on it.
To my surprise not only one, but more than half of the tests were failing right off the bat.
At first I thought, maybe the client had recently broken something in the development versions
of his apps, so I reverted to versions I knew to have passed the tests before.
But no change, the same tests still kept breaking. I went at it debugging things,
making some adjustments to the Dockerfiles, adjusting the tests, still I could not find
the reason for things to have broken in the first place.
The errors I saw indicated Selenium clicking the wrong elements where it had previously
clicked the right ones thousands if not millions of times. 
Eventually I got a little tired of my laptop building Docker images a lot slower than
the EC2 instance I developed this on initially, so I moved to working on that again.
To my surprise tests instantly started passing again on the EC2 instance and then it hit me,
the EC2 instance still had the old images. Something in the versions must have changed …
I quickly found out Selenium had made a change breaking backward compatibility when it came to hovering elements,
I locked in the version using the known to work Selenium version in the Dockerfile and things started working fine on my laptop
too.&lt;/p&gt;

&lt;p&gt;The moral of the story: &lt;strong&gt;Not locking in versions means having to troubleshoot tests and production code simultaneously.&lt;/strong&gt;
You should be able to trust your tests, the easiest way to achieve this is to simply make the build 100% deterministically.
Lock in the version of you base Docker image, lock in the versions for everything you put into it and you’ll be fine.
Whenever your tests break, you know it’s the code now thanks to your tests being stable and frozen in time.&lt;/p&gt;

&lt;h2 id=&quot;a-clean-build-has-two-or-four-steps&quot;&gt;A Clean Build has Two Or Four Steps&lt;/h2&gt;

&lt;h1 id=&quot;build-image&quot;&gt;Build Image&lt;/h1&gt;

&lt;p&gt;The first step of a clean build should simply be sending a build context to the Docker daemon.
You can send a tarball compressed by various methods of choice and the daemon will extract it’s contents
and build the image.
When deciding on how to setup your images you should try your best to keep things homogeneous
in terms of paths across your projects to avoid headache with documentation and
configuration.
An example of how to do this can be found in this &lt;a href=&quot;https://github.com/OnTheGoSystems/wp-cucumber-watir/tree/master/res/docker&quot;&gt;skeleton&lt;/a&gt; I created for a former employer.
You can see a few folders each holding the build context for one container.
All of which who require a default command different from their base image simply get this in the form of a &lt;code class=&quot;highlighter-rouge&quot;&gt;run.sh&lt;/code&gt; bash script,
that is then always added to the final image in the exact same way and at the end of the build via this snippet:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-docker&quot; data-lang=&quot;docker&quot;&gt;COPY run.sh /run.sh
RUN chmod +x /run.sh
CMD [&quot;/bin/bash&quot;, &quot;-lc&quot;, &quot;/run.sh&quot;]&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Also you should ensure that if your run.sh produces any output, say a .jar, coverage reports
or compiled documentation is saved to a specific folder. My suggestion would be &lt;code class=&quot;highlighter-rouge&quot;&gt;/out&lt;/code&gt;.
Read on to find out why :)&lt;/p&gt;

&lt;p&gt;From the commandline building your container now simply becomes:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;docker build -t username/tagname /path/to/build/context&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h1 id=&quot;run-command&quot;&gt;Run Command&lt;/h1&gt;

&lt;p&gt;The next step is to run the container we just built.
In the commandline this simply turns into running for the case of you only requiring the stdOut by &lt;code class=&quot;highlighter-rouge&quot;&gt;run.sh&lt;/code&gt;:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;docker run --rm -t username/tagname&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h1 id=&quot;you-may-need-more-than-stdout&quot;&gt;You May Need More than StdOut!&lt;/h1&gt;

&lt;p&gt;Oftentimes just getting StdOut means that you get the exit status of your build and it’s direct console output,
say the list of failed and passed tests. But what about that nice code coverage html report for example ?
Files you will need to retrieve from the container after it exited.
Also in this case you cannot use the &lt;code class=&quot;highlighter-rouge&quot;&gt;--rm&lt;/code&gt; flag on the container run, given you don’t want to remove but access it once it has stopped.&lt;/p&gt;

&lt;p&gt;So our run command in bash would come out to just:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;docker run -t username/tagname&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Also, let’s give the container a name so it’s easier to track the individual container
once it stopped and we still want to access it:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;docker run -t --name container_name username/tagname&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h1 id=&quot;optional-download-files&quot;&gt;Optional: Download Files&lt;/h1&gt;

&lt;p&gt;Downloading files from a container using the CLI is almost as easy as copying files
in a shell using the &lt;a href=&quot;https://docs.docker.com/engine/reference/commandline/cp/&quot;&gt;docker cp&lt;/a&gt; command.
Assuming whatever your previously created &lt;code class=&quot;highlighter-rouge&quot;&gt;run.sh&lt;/code&gt; produced as output went to the &lt;code class=&quot;highlighter-rouge&quot;&gt;/out&lt;/code&gt; folder in the container,
you can now simply download the contents of it via:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;docker cp container_name:/out /local/target/path/&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h1 id=&quot;optional-delete-container&quot;&gt;Optional: Delete Container&lt;/h1&gt;

&lt;p&gt;Once you got your build result from the container, all you need to do is delete it.
Otherwise it’s file system will still be kept on the Docker daemon host 
and quickly eat up its disk space.
In the commandline you can simply do this by running:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;docker rm -v container_name&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;the &lt;code class=&quot;highlighter-rouge&quot;&gt;-v&lt;/code&gt; flag should not be forgotten here, since many base images your build
could depend on have &lt;code class=&quot;highlighter-rouge&quot;&gt;VOLUME&lt;/code&gt; statements in their Dockerfile. If you fail to explicitly
delete any volumes that may have been created by these containers, you’ll create
dangling volumes eating up disk space and being hard to remove.&lt;/p&gt;
</description>
        <pubDate>Sat, 20 Feb 2016 00:00:00 +0100</pubDate>
        <link>http://obrown.io/2016/02/20/docker-build.html</link>
        <guid isPermaLink="true">http://obrown.io/2016/02/20/docker-build.html</guid>
        
        <category>Docker</category>
        
        <category>CI</category>
        
        
      </item>
    
      <item>
        <title>Privileged Docker Containers</title>
        <description>&lt;h1 id=&quot;that-privileged-flag-looks-pretty-practical&quot;&gt;That –privileged Flag Looks Pretty Practical&lt;/h1&gt;

&lt;p&gt;Quite some time ago Docker in September 2013/Docker 0.6 &lt;a href=&quot;http://blog.docker.com/2013/09/docker-can-now-run-within-docker/&quot;&gt;announced&lt;/a&gt; proudly,
that it is now possible to run Docker from within Docker.
This was made possible by the new –privileged flag feature.
An explanation, I posted as a Stackoverflow answer, on how you can do this you can find &lt;a href=&quot;http://stackoverflow.com/questions/34302096/sharing-devices-webcam-usb-drives-etc-with-docker/34472148#34472148&quot;&gt;here&lt;/a&gt;. 
This feature allowed bypassing a prior constraint of using containers, they were unable to access the host system’s devices.
A possible use case for this, aside from running Docker inside Docker, was allowing you to trivially use things like your web-cam and such from within Docker.&lt;/p&gt;

&lt;h1 id=&quot;devices-and-standard-containers-safe-and-secure&quot;&gt;Devices and Standard Containers (Safe and Secure)&lt;/h1&gt;

&lt;p&gt;You can get a quick idea of the degree of containerization for a standard container by just running a standard Debian container bash and checking the visible hard disks and devices.&lt;/p&gt;

&lt;p&gt;Just open a standard bash shell:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;run -it debian:jessie /bin/bash -l
root@e4746be1718c:/#&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Then check what devices are hard drives to you in there.
On my trusty old Linux laptop I see something like this:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;gp&quot;&gt;root@e4746be1718c:/# &lt;/span&gt;df -h
Filesystem                                                                                        Size  Used Avail Use% Mounted on
/dev/mapper/docker-8:1-28836281-7f45eabc67f92f0e056275f099a943bcf104c0b915e95b96fd31ba9144327b5c   99G  197M   94G   1% /
tmpfs                                                                                             7.7G     0  7.7G   0% /dev
tmpfs                                                                                             7.7G     0  7.7G   0% /sys/fs/cgroup
/dev/sda1                                                                                         440G  364G   54G  88% /etc/hosts
shm                                                                                                64M     0   64M   0% /dev/shm&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;So even the standard container is able to see my hard drive on /dev/sda1 apparently.
If I check the contents of /dev though, this is what I get:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;gp&quot;&gt;root@e4746be1718c:/# &lt;/span&gt;ls /dev
console  fd  full  fuse  kcore	mqueue	null  ptmx  pts  random  shm  stderr  stdin  stdout  tty  urandom  zero&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;The hard-drive at /dev/sda1 is not there, which in almost all conceivable use cases for Docker, is a very good and important thing, you’ll see!&lt;/p&gt;

&lt;h1 id=&quot;devices-and-privileged-containers--youre-running-something-as-root-you-better-know-what-youre-doing-&quot;&gt;Devices and Privileged Containers ( You’re running something as root, you better know what you’re doing! )&lt;/h1&gt;

&lt;p&gt;So let’s move on to the privileged case. In all of this please remember, the Docker daemon always runs as root!
As pointed out in &lt;a href=&quot;https://github.com/docker/docker/issues/1034&quot;&gt;this Github ticket&lt;/a&gt; for the Docker project, there is no way around that!
Even if you can run Docker commands as non-root, the daemon is always running as root and that’s what matters here!
You simply cannot set the daemon to run as a non-root process for technological reasons. 
So lets see what we allow the privileged container, running from a process owned by root, to see and do on our host system.&lt;/p&gt;

&lt;p&gt;Again open a standard bash shell, but this time run it in a privileged container:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;run -it --privileged debian:jessie /bin/bash -l
root@8f766733df83:/#&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;So far so good, so lets see what we get for our hard drives this time around:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;gp&quot;&gt;root@8f766733df83:/# &lt;/span&gt;df -h
Filesystem                                                                                        Size  Used Avail Use% Mounted on
/dev/mapper/docker-8:1-28836281-59c1349e06bfd1b6939dfa667e0203cacaf1466eaf50c56001d767028326504e   99G  197M   94G   1% /
tmpfs                                                                                             7.7G     0  7.7G   0% /dev
tmpfs                                                                                             7.7G     0  7.7G   0% /sys/fs/cgroup
/dev/sda1                                                                                         440G  364G   54G  88% /etc/hosts
shm                                                                                                64M     0   64M   0% /dev/shm&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;No changes here, but lets look at what devices we have available now:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;gp&quot;&gt;root@8f766733df83:/# &lt;/span&gt;ls /dev
  autofs		 dm-6	  kvm		mem		    rfkill    stdout  tty2   tty32  tty45  tty58  uhid	      vcs7	   watchdog
  bsg		 dm-7	  loop-control	memory_bandwidth    rtc0      tty     tty20  tty33  tty46  tty59  uinput      vcsa	   watchdog0
  btrfs-control	 dm-8	  loop0		mqueue		    sda       tty0    tty21  tty34  tty47  tty6   urandom     vcsa1	   zero
  bus		 dri	  loop1		ndctl0		    sda1      tty1    tty22  tty35  tty48  tty60  vboxdrv     vcsa2
  console		 fb0	  loop2		net		    sda2      tty10   tty23  tty36  tty49  tty61  vboxdrvu    vcsa3
  cpu		 fd	  loop3		network_latency     sda5      tty11   tty24  tty37  tty5   tty62  vboxnetctl  vcsa4
  cpu_dma_latency  full	  loop4		network_throughput  sg0       tty12   tty25  tty38  tty50  tty63  vboxusb     vcsa5
  cuse		 fuse	  loop5		null		    sg1       tty13   tty26  tty39  tty51  tty7   vcs	      vcsa6
  dm-0		 hidraw0  loop6		port		    shm       tty14   tty27  tty4   tty52  tty8   vcs1	      vcsa7
  dm-1		 hidraw1  loop7		ppp		    snapshot  tty15   tty28  tty40  tty53  tty9   vcs2	      vfio
  dm-2		 hpet	  mapper	psaux		    snd       tty16   tty29  tty41  tty54  ttyS0  vcs3	      vga_arbiter
  dm-3		 input	  mcelog	ptmx		    sr0       tty17   tty3   tty42  tty55  ttyS1  vcs4	      vhci
  dm-4		 kcore	  media0	pts		    stderr    tty18   tty30  tty43  tty56  ttyS2  vcs5	      vhost-net
  dm-5		 kmsg	  mei0		random		    stdin     tty19   tty31  tty44  tty57  ttyS3  vcs6	      video0&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Bam, that looks a little different from before doesn’t it ?
Now our hard drive isn’t only there in name. We can actually access the device!
This means, we should be able to mount it inside the container. Lets try it:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;gp&quot;&gt;root@8f766733df83:/# &lt;/span&gt;mkdir /mountedhd
&lt;span class=&quot;gp&quot;&gt;root@8f766733df83:/# &lt;/span&gt;mount /dev/sda1 /mountedhd/&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;And …&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;gp&quot;&gt;root@8f766733df83:~# &lt;/span&gt;ls /mountedhd/
app  boot  dev	home	    initrd.img.old  lib32  libx32      media  opt   root  sbin	       src  sys  usr  vmlinuz
bin  data  etc	initrd.img  lib		    lib64  lost+found  mnt    proc  run   screenshots  srv  tmp  var  vmlinuz.old&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;we got the host file system mounted inside the “container”, making it not a container at all!&lt;/p&gt;

&lt;p&gt;Depending on your Docker host configuration you might even be able to see the contents of proc/1/ns/pid and simply nsenter into
a shell in the host. And well … if things aren’t configured as the container likes … the container should have an easy time making the config a little
more pleasing to it’s nefarious plans.&lt;/p&gt;

&lt;h1 id=&quot;bottom-line&quot;&gt;Bottom Line&lt;/h1&gt;

&lt;p&gt;Don’t use privileged containers unless you treat them the same way you treat any other process running as root.
Newer Docker versions allow you more fine grained control over the containers device access anyhow, check &lt;a href=&quot;https://docs.docker.com/engine/reference/commandline/run/#full-container-capabilities-privileged&quot;&gt;this&lt;/a&gt; out for more documentation on container capabilities and rights management.&lt;/p&gt;

&lt;h1 id=&quot;corner-cases&quot;&gt;Corner Cases&lt;/h1&gt;

&lt;p&gt;If you want to try this out on EC or a VM additional steps might be needed to make the device descriptor appear.
On EC2 all you need to do is run:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;gp&quot;&gt;root@8f766733df83:/# &lt;/span&gt;file -s /dev/xvda1&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;and you got a descriptor of the host’s hd that you can mount.&lt;/p&gt;

&lt;p&gt;On Virtualbox/Boot2Docker you need to make the logical volumes appear as proper devices:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;gp&quot;&gt;root@8f766733df83:/# &lt;/span&gt;vgchange -ay&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;is your friend here. If this doesn’t work you might need to activate the needed kernel module for handling logical volumes the way we want it here:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;gp&quot;&gt;root@8f766733df83:/# &lt;/span&gt;modprobe dm-mod&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;The fact that this actually works should scare you straight enough to not use privileged containers unless you have to btw ;)&lt;/p&gt;

</description>
        <pubDate>Mon, 15 Feb 2016 00:00:00 +0100</pubDate>
        <link>http://obrown.io/2016/02/15/privileged-containers.html</link>
        <guid isPermaLink="true">http://obrown.io/2016/02/15/privileged-containers.html</guid>
        
        <category>Docker</category>
        
        <category>Security</category>
        
        
      </item>
    
      <item>
        <title>It's not PHPUnit, PHP, Legacy Code or Obscure APIs ... it's you!</title>
        <description>&lt;h1 id=&quot;introduction--stop-making-excuses--the-actual-reason-you-dont-write-tests-&quot;&gt;Introduction … Stop Making Excuses … The actual reason you don’t write tests …&lt;/h1&gt;

&lt;p&gt;It seems weird doesn’t it? You barely find any Ruby on Rails codebase not containing at least an attempt at a test suit, while a large number of PHP projects seem to run PHPUnit like vampires from sunlight.&lt;/p&gt;

&lt;p&gt;So, how did this come about? Maybe unit-testing PHP is harder than re-writing WordPress in pure C?
Not really … people just don’t know what they’re doing, that’s all … you’ll see.
But … let’s look at the psychology behind this first.&lt;/p&gt;

&lt;h2 id=&quot;the-nice-explanation&quot;&gt;The Nice Explanation&lt;/h2&gt;

&lt;p&gt;Ok, let’s start this out the nice way. PHP simply came before say Ruby on Rails in terms of being popular. For the sake of argument say … PHP was hyped a lot around 2000-2002.
Back in those days, PHPUnit wasn’t even around. According to &lt;a href=&quot;https://en.wikipedia.org/wiki/PHPUnit&quot;&gt;Wikipedia&lt;/a&gt; it had it’s initial release in March 2004.&lt;/p&gt;

&lt;p&gt;So a reasonable argument could simply go along the lines of many PHP developers not having been introduced to unit-testing when they started out and the lack of adoption of TDD and the like in PHP projects is simply a collective bad habit I guess.&lt;/p&gt;

&lt;h2 id=&quot;the-not-so-nice-way-of-putting-it-&quot;&gt;The not so nice way of putting it …&lt;/h2&gt;

&lt;p&gt;Honestly … I don’t buy the above. The problem is much different in my opinion, at least with some people. PHP simply is an incredibly easy language. It neither suggests nor enforces many good practices.
When setting up your Rails project, Rails at least gives you a folder structure suggesting proper separation of your models, views, controllers and whatnot.
PHP and many popular frameworks built on it, like say WordPress do not do that. You’re free to do whatever the hell you want!
No clue on programming beyond trivial control flow … No Problem!&lt;/p&gt;

&lt;p&gt;Just write some HTML, and whenever you feel like adding some dynamic behavior throw in the good old &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;?php //crappy code ?&amp;gt;&lt;/code&gt; every now and then and feel like a developer.
This will work out surprisingly well up to a certain project size. Sooner or later though you’ll find yourself going back and forth between random bug A rendering some box in one corner of the screen wrong and random bug B throwing a notice every now and then.
Your project simply will hit that point, no matter how careful you are. Some people can delay the onset of this longer by being paranoid and conscientious … others with bad concentration will hit it sooner.&lt;/p&gt;

&lt;p&gt;Eventually the all have to face one fairly obvious fact, their skill-set simply does not allow for a project beyond a certain size X.
This is not PHP’s fault, it’s the programmers fault, I’m sorry ( not really ) … it’s true.&lt;/p&gt;

&lt;h1 id=&quot;you-can-test-it-all--just-watch-and-learn-&quot;&gt;You can test it all … just watch and learn …&lt;/h1&gt;

&lt;p&gt;So, lets look at some of the general issues people are having with this and see how you can work around them in the real world.&lt;/p&gt;

&lt;h2 id=&quot;example-one-crappy-global-function-in-the-api&quot;&gt;Example One: Crappy Global Function in the API&lt;/h2&gt;

&lt;p&gt;So lets assume you’re working with “WeirdoCMS”. WeirdoCMS has a fun little public function in it’s API that does some crazy magic, eventually accessing 21 different tables just to return you the number of FOOs …whatever those may be.
Let’s call that function &lt;code class=&quot;highlighter-rouge&quot;&gt;FooCount&lt;/code&gt;.
Now you got yourself the task of fixing this thing in your WeirdoPlugin:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;evenNumberOfFoo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(){&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;bool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;FooCount&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Damn … someone wasn’t even able to find the 2 on his keyboard it seems :/ Wouldn’t it be great if we could turn that 3 into the correct 2, while also preventing this from ever happening again with a test?
It sure would be …&lt;/p&gt;

&lt;h3 id=&quot;how-to-do-it-wrong&quot;&gt;How to do it wrong&lt;/h3&gt;

&lt;p&gt;So people generally do this when faced with the above illustrated issue of having a trivial thing to test, but no idea of how to test it on account of the API interfacing with their code being all but trivial (remember 21 tables).
The more motivated ones within the incompetent population might actually try to tackle this by actually setting up those 21 tables correctly only to run their example like so:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;CrappyTest&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;\PHPUnit_Framework_TestCase&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;TestEvenNumberOfFoo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(){&lt;/span&gt;
		&lt;span class=&quot;c1&quot;&gt;// 200 lines of code only the creator of this will ever understand but actually sets up 11 Foos
&lt;/span&gt;		&lt;span class=&quot;nv&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;assertFalse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;evenNumberOfFoo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;());&lt;/span&gt;
		&lt;span class=&quot;c1&quot;&gt;// Another 200 lines of the above kind ... actually setting up 12 Foos
&lt;/span&gt;		&lt;span class=&quot;nv&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;assertTrue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;evenNumberOfFoo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;());&lt;/span&gt;
	&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;	
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;After actually having gone through this pain once, they’ll probably also not do it again and simply state that their project does not have the time and budget for unit-testing.
Most will probably not even get this far, they’ll simply give up without shelling out those hundreds of lines of weird and crappy test code.&lt;/p&gt;

&lt;h3 id=&quot;how-to-get-it-right&quot;&gt;How to get it right&lt;/h3&gt;

&lt;h4 id=&quot;step-1-drop-the-procedural-programming-weve-entered-the-oop-era-quite-some-time-ago-&quot;&gt;Step 1: Drop the Procedural Programming, we’ve entered the OOP era quite some time ago …&lt;/h4&gt;

&lt;p&gt;So let’s encapsulate our function in an object first, many will try this step anyways … just because everyone seems to be doing it.
And let’s also try being a little full of ourselves and “apply correct OOP principles” while talking out of our behinds mostly … to put it mildly.&lt;/p&gt;

&lt;p&gt;So instead of &lt;code class=&quot;highlighter-rouge&quot;&gt;evenNumberOfFoo&lt;/code&gt; we now use:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;FooChecker&lt;/span&gt; 
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;evenNumber&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
	&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;bool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;FooCount&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;That didn’t really accomplish much except for turning&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;$even&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;evenNumberOfFoo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;into the more verbose&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;$even&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;FooChecker&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;evenNumber&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Apart from making the code longer we accomplished exactly nothing so far I fear … also the code is now a little slower with all that object instantiation overhead.
That can’t be it with those OOP principles … this seems to make things even worse than before. We still can’t test this and now it’s longer and slower …&lt;/p&gt;

&lt;h4 id=&quot;step-2-learn-the-word-mocking-&quot;&gt;Step 2: Learn the word “Mocking” …&lt;/h4&gt;

&lt;p&gt;Now after some googling around you finally figure it out, you’re not the first person to run into the above issue. As a matter of fact, it seems half the PHP dev population has too.
So you learn that using that magic Mocking thing, you can actually force &lt;code class=&quot;highlighter-rouge&quot;&gt;FooCount()&lt;/code&gt; to return whatever you want it to apparently. But … again life is fll of disappointments :/ … seems you can only do this with actual class methods.
Your API is given to you in the form of a men old global function though. You might start torturing Google a little more, but eventually you’ll find out … there is absolutely no way of mocking those global functions.&lt;/p&gt;

&lt;p&gt;No unit-testing using WeirdoCMS it seems, it has it’s API presented to you in the form of global functions and there is just no way of mocking it and since that’s so unit-testing is just way too hard, impossible or time-consuming.
You can even tell your boss that it’s not your fault, all those bugs suck … but hey WeirdoCMS apparently does not allow you to unit-test, so on to the next 40 regressions in your bug-tracker …&lt;/p&gt;

&lt;p&gt;Sounds like you :)? Check out the next step, you’ll see … it’s gonna be all better soon :)&lt;/p&gt;

&lt;h4 id=&quot;step-3-learn-how-to-mock&quot;&gt;Step 3: Learn how to “mock”&lt;/h4&gt;

&lt;p&gt;Well, it doesn’t take a genius to figure out that if you can only mock and hence fake the return of your number of Foos when it’s given to you by a non-static class method, then you simply have to return it by a non-static class method.
In come wrapping and dependency injection :)&lt;/p&gt;

&lt;p&gt;So let’s wrap that function call in the form of a method call, lets do it like this:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;MyWeirdCMSApiWrapper&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;FooCount&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(){&lt;/span&gt;
		&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;FooCount&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
	&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;So with this we could turn out Class into this I suppose:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;FooChecker&lt;/span&gt; 
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;evenNumber&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
	&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;bool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)((&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;MyWeirdCMSApiWrapper&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;FooCount&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Still you simply can’t seem to figure out how to mock the FooCount … after all it seems you can only mock the return of the method on specific instances of the MyWeirdCMSApiWrapper and not on all instances.
But as you’re only instantiating those object when calling the method you’re trying to test, your test setup simply cannot force them to return anything specific.&lt;/p&gt;

&lt;p&gt;In comes dependency injection to the rescue. Something had to come to the rescue right? I mean … if you think about it, your &lt;code class=&quot;highlighter-rouge&quot;&gt;new MyWeirdCMSApiWrapper()&lt;/code&gt; essentially is just a different public method being called. You just moved the issue, you did not fix it!&lt;/p&gt;

&lt;p&gt;So, what is this dependency injection thing?
Well, it just means that you do not instantiate objects inside of your methods (with exceptions obviously … otherwise you would never get any instances of anything I guess :)) or use global variables for the objects you’re trying mock,
but just inject them via the constructor of your to be tested classes.&lt;/p&gt;

&lt;p&gt;So instead of creating an instance of your API wrapper, you just pass it to the constructor of your class like so:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;FooChecker&lt;/span&gt; 
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$apiWrapper&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;	

	&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;__construct&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$apiWrapper&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;){&lt;/span&gt;
		&lt;span class=&quot;nv&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;apiWrapper&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$apiWrapper&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;	

	&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;evenNumber&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
	&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;bool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;apiWrapper&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;FooCount&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Now instead of a crappy test, we can actually make a nice test, by mocking that &lt;code class=&quot;highlighter-rouge&quot;&gt;$apiWrapper&lt;/code&gt; we’re passing in.
Enjoy the beauty of proper OOP design and testing :)&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;GoodTest&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;\PHPUnit_Framework_TestCase&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;TestEvenNumberOfFoo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(){&lt;/span&gt;
		&lt;span class=&quot;nv&quot;&gt;$apiMock&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getMockBuilder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'MyWeirdCMSApiWrapper'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getMock&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// create our naked Mock, it will return null for all public methods at this point!
&lt;/span&gt;		&lt;span class=&quot;nv&quot;&gt;$apiMock&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;method&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'FooCount'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;willReturn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;11&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// Make it return an odd Number, let's use 11. This is the actual mocking btw :)
&lt;/span&gt;		&lt;span class=&quot;nv&quot;&gt;$subject&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;FooCount&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$apiMock&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// now create an instance of your to be tested Class. Let's call it subject, it being the subject of tests and all :)
&lt;/span&gt;		&lt;span class=&quot;nv&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;assertFalse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$subject&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;evenNumber&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;());&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// 11 is not even, we want it to return false and write our test accordingly.
&lt;/span&gt;
		&lt;span class=&quot;c1&quot;&gt;// Now lets do the even case too, just for completeness sake :)
&lt;/span&gt;		&lt;span class=&quot;nv&quot;&gt;$apiMock&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getMockBuilder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'MyWeirdCMSApiWrapper'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getMock&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;We&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;need&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;fresh&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;mock&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;here&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;the&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;old&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;one&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;cannot&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;be&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;altered&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;
		&lt;span class=&quot;nv&quot;&gt;$apiMock&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;method&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'FooCount'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;willReturn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;12&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// 12 is even :)
&lt;/span&gt;		&lt;span class=&quot;nv&quot;&gt;$subject&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;FooCount&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$apiMock&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// get us a fresh subject ... the old one is still suffering from always getting the 11 for the FooCount ...
&lt;/span&gt;		&lt;span class=&quot;nv&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;assertTrue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$subject&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;evenNumber&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;());&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// 12 is in fact even, we want it to return true and again write our test accordingly.
&lt;/span&gt;	&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;	
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;BAM! Sure the above suffers from duplicate code, but for now … this is a much nicer test than expected isn’t it and trivial to create too!&lt;/p&gt;

&lt;p&gt;Working from this you could obviously start substituting your globals for injected dependencies, your singletons for class you can actually instantiate freely and wrap APIs nicely and well …
you might actually stop bitching and start testing :)&lt;/p&gt;

&lt;h1 id=&quot;to-be-continued-&quot;&gt;To be continued …&lt;/h1&gt;

&lt;p&gt;Example Two soon … though seriously … the above should give you all the material you need to circumvent all those crappy and tricky testing spots shouldn’t it ? :)&lt;/p&gt;
</description>
        <pubDate>Sun, 03 Jan 2016 00:00:00 +0100</pubDate>
        <link>http://obrown.io/2016/01/03/its-you-not-phpunit.html</link>
        <guid isPermaLink="true">http://obrown.io/2016/01/03/its-you-not-phpunit.html</guid>
        
        <category>PHP</category>
        
        <category>PHPUnit</category>
        
        <category>Testing</category>
        
        
      </item>
    
      <item>
        <title>vld.obrown.io - Fun with PHP Op-Codes</title>
        <description>&lt;h1 id=&quot;vldobrownio&quot;&gt;VLD.OBROWN.IO&lt;/h1&gt;

&lt;p&gt;After googling around for a bit, trying to find a nice and easy to use PHP Opcode compiler, I found Derick Rethan’s &lt;a href=&quot;https://pecl.php.net/package/vld&quot;&gt;Vulcan Logic Disassembler&lt;/a&gt;.
It did exactly what I wanted it to, but setup and use might not be for everyone and as I was looking to use this for educational purposes mostly, I created a quick web app for it. You can find it here: &lt;a href=&quot;http://vld.obrown.io&quot;&gt;vld.obrown.io&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Nothing spectacular so far, but I’ll try to find time to add a little more content to it soon.
So far it’s simply&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;Put PHP code into the left text-box&lt;/li&gt;
  &lt;li&gt;Click compile&lt;/li&gt;
  &lt;li&gt;Get opcode on the right after a few seconds&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;All presented nicely :P&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/vld.png&quot; /&gt;&lt;/p&gt;
</description>
        <pubDate>Wed, 23 Dec 2015 00:00:00 +0100</pubDate>
        <link>http://obrown.io/2015/12/23/vld-php.html</link>
        <guid isPermaLink="true">http://obrown.io/2015/12/23/vld-php.html</guid>
        
        <category>php</category>
        
        <category>docker</category>
        
        
      </item>
    
      <item>
        <title>Dockerize PhpUnit and Force Idea/PhpStorm to Use it!</title>
        <description>&lt;h2 id=&quot;why&quot;&gt;Why???&lt;/h2&gt;

&lt;p&gt;Well … say you want to run your unit-tests against multiple PHP versions and still enjoy the comfort of your IDE + Xdebug :P&lt;/p&gt;

&lt;h2 id=&quot;how-&quot;&gt;How ???&lt;/h2&gt;

&lt;p&gt;Easy once you know how, but a little fiddly the first time around :)&lt;/p&gt;

&lt;h1 id=&quot;step-1-create-a-docker-image-with-your-dependencies&quot;&gt;Step 1: Create a Docker Image with your Dependencies&lt;/h1&gt;

&lt;p&gt;As an example I’ll use a typical WordPress unit-test setup here. In my case I wanted to be able to run my Unittests with PHP7,
but not have to pollute my Debian Jessie/Stretch install, with a non apt-packaged PHP7 alongside the PHP 5.6.16 that currently
comes with it. Still I wanted this to run nicely from IDEA :)&lt;/p&gt;

&lt;p&gt;All the code for the following can be found in &lt;a href=&quot;https://github.com/original-brownbear/php-cli-docker&quot;&gt;here&lt;/a&gt; on GitHub.&lt;/p&gt;

&lt;p&gt;So since we’re gonna be playing with WordPress we’ll need a few extensions on top of our standard PHP7 CLI docker image from the official repo. Also we need PHPUnit and XDebug. Lastly we are going to use the composer installation of PHPUnit, so we need composer also.&lt;/p&gt;

&lt;p&gt;The resulting Dockerfile comes out to something like this:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-docker&quot;&gt;FROM php:7-cli
MAINTAINER Armin Braun

RUN apt-get update &amp;amp;&amp;amp; apt-get install -y mysql-client libmysqlclient-dev curl git \
    libfreetype6-dev libjpeg62-turbo-dev libmcrypt-dev libpng12-dev \
    &amp;amp;&amp;amp; docker-php-ext-install iconv mcrypt \
    &amp;amp;&amp;amp; docker-php-ext-configure gd --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/ \
    &amp;amp;&amp;amp; docker-php-ext-install gd \
    &amp;amp;&amp;amp; docker-php-ext-install zip \
    &amp;amp;&amp;amp; docker-php-ext-install mysqli \
    &amp;amp;&amp;amp; docker-php-ext-install opcache \
    &amp;amp;&amp;amp; docker-php-ext-install mbstring 

#COMPOSER 
RUN curl -sS https://getcomposer.org/installer | php
RUN mv composer.phar /usr/local/bin/composer

#PHPUNIT
RUN composer global require &quot;phpunit/phpunit&quot;
ENV PATH /root/.composer/vendor/bin:$PATH
RUN ln -s /root/.composer/vendor/bin/phpunit /usr/bin/phpunit

#XDEBUG
RUN pecl install xdebug-2.4.0RC3 
RUN echo &quot;zend_extension=xdebug.so\nxdebug.cli_color=1\nxdebug.remote_autostart=1\nxdebug.remote_connect_back=1&quot; &amp;gt; /usr/local/etc/php/conf.d/xdebug.ini
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;So far so good :) We can now build this thing ( which I already did for you here: &lt;a href=&quot;https://hub.docker.com/r/originalbrownbear/php/tags/&quot;&gt;DockerHub&lt;/a&gt; under Tag: 7-cli-phpunit-xdebug ).&lt;/p&gt;

&lt;p&gt;The import part in this is that you correctly link phpunit to be in the path. This is done in this part:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-docker&quot; data-lang=&quot;docker&quot;&gt;RUN ln -s /root/.composer/vendor/bin/phpunit /usr/bin/phpunit&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;… just trivially sym-linking the docker executable to something that is in the path for sure.&lt;/p&gt;

&lt;p&gt;Also, and this is where it gets a little hacky for the time being unfortunately, we need to setup the networking for XDebug and the container itself. The XDebug part is where we need to force XDebug to send requests, via us echoing:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ini&quot; data-lang=&quot;ini&quot;&gt;&lt;span class=&quot;py&quot;&gt;xdebug.remote_autostart&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;1&lt;/span&gt;
&lt;span class=&quot;py&quot;&gt;xdebug.remote_connect_back&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;1&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;into the xdebug.ini.&lt;/p&gt;

&lt;h1 id=&quot;step-2-create-our-new-php-executable&quot;&gt;Step 2: Create our new PHP-executable&lt;/h1&gt;

&lt;p&gt;What we now need is for our dockerized PHP executable to behave as similarly as possible to a plain standard PHP executable on the host system.&lt;/p&gt;

&lt;p&gt;This can be done via the following bash script, that you can fine &lt;a href=&quot;https://github.com/original-brownbear/php-cli-docker/blob/master/phpunit7-xdebug&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;docker run -i --rm -v &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;PWD&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;:&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;PWD&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; -v /tmp/:/tmp/ -w &lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;PWD&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt; --net&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;host --sig-proxy&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;true&lt;/span&gt; --pid&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;host originalbrownbear/php:7-cli-phpunit php &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$@&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;What this does is:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Mount the current working directory into the container.&lt;/li&gt;
  &lt;li&gt;Make the container use the host’s pid space&lt;/li&gt;
  &lt;li&gt;Make the container use the host’s network adapter&lt;/li&gt;
  &lt;li&gt;Mount the hosts tmp folder into teh container, as PHPStorm copies a file there in some cases&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If you’re using your own version and not one provided by me in GitHub, you need to make sure to&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;chmod +x &lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;it so that PHPStorm can run it like any other executable.&lt;/p&gt;

&lt;h1 id=&quot;step-3-setup-phpstormidea-correctly&quot;&gt;Step 3: Setup PHPStorm/Idea correctly&lt;/h1&gt;

&lt;p&gt;This is relatively easy fortunately. Just point the PHP Interpreter setting at your bash script that you crated above,
like this for example:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/phpstormxdebug.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;… and ignore the warning. This is nothing to worry about, the ini file is simply in the container and not accessible by PHPStorm.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/phpstormxdebug2.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Also set your PHPUnit settings like in the above and you’re pretty much there and should be able to run phpunit.xml files like with any other PHP + PHPUnit setup, while being able to easily jump around PHP versions.&lt;/p&gt;

&lt;p&gt;The only difference in behavior I am currently seeing is, that I still need to manually make PHPStorm listen for incoming XDebug connections via the telephone icon set like this:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/phpstormxdebug3.png&quot; /&gt;&lt;/p&gt;

&lt;h1 id=&quot;pro-tip-skip-xdebug-unless-you-actually-need-it&quot;&gt;Pro Tip: Skip XDebug unless you actually need it!&lt;/h1&gt;

&lt;p&gt;In case you’re running most of your test runs without XDebug ( as you probably should … different topic though ),
you shouldn’t necessarily use a container that has XDebug even installed for performance reasons. Even if the .so extension is loaded,
but disabled otherwise the performance hit can be 50%+ easily for most applications!&lt;/p&gt;

&lt;p&gt;In this case simply delete the XDebug part of the image build and create another bash script to run the second image without XDebug.
All this can be found worked out in examples in the GitHub repo.&lt;/p&gt;

&lt;h1 id=&quot;update-how-to-make-this-work-on-mac-at-last-&quot;&gt;Update: How to Make This Work on Mac at Last :)&lt;/h1&gt;

&lt;p&gt;On mac our nice and easy bash script from above unfortunately turned out to not work, as discussed in the comments.
Fortunately this could be resolved easily, like so:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;#!/usr/bin/env bash&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# beginning of &quot;docker-machine env default&quot; output&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;export &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;DOCKER_TLS_VERIFY&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;1&quot;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;export &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;DOCKER_HOST&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;tcp://192.168.99.100:2376&quot;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;export &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;DOCKER_CERT_PATH&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;/Users/brownbear/.docker/machine/machines/default&quot;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;export &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;DOCKER_MACHINE_NAME&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;default&quot;&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# End of &quot;docker-machine env default&quot; output&lt;/span&gt;
/usr/local/bin/docker run -i --rm -v &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;PWD&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;:&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;PWD&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; -w &lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;PWD&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt; --net&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;host --sig-proxy&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;true&lt;/span&gt; --pid&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;host originalbrownbear/php:7-cli-phpunit php &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$@&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;simply paste the output of&lt;/p&gt;

&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;docker machine env default
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;before the original version of the bash call and you’re good :)
Only other thing you need to keep in mind is that:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Every directory you mount into a Docker container on a Mac needs to be in your users home folder!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;… anything else just won’t work for permissions reasons it turns out.&lt;/p&gt;
</description>
        <pubDate>Wed, 23 Dec 2015 00:00:00 +0100</pubDate>
        <link>http://obrown.io/2015/12/23/phpunit-docker-phpstorm.html</link>
        <guid isPermaLink="true">http://obrown.io/2015/12/23/phpunit-docker-phpstorm.html</guid>
        
        <category>phpstorm</category>
        
        <category>idea</category>
        
        <category>phpunit</category>
        
        <category>docker</category>
        
        
      </item>
    
      <item>
        <title>PHP Performance - Inlining Redundancies</title>
        <description>&lt;h1 id=&quot;micro-optimization-and-php-&quot;&gt;Micro-Optimization and PHP ???&lt;/h1&gt;

&lt;p&gt;Yes really!&lt;/p&gt;

&lt;p&gt;Gotten to the point where adding that next caching for some database query simply stopped being helpful?&lt;/p&gt;

&lt;p&gt;No clue why your crappy WordPress plugin takes up 50% or more of the page load time, even though you cut the database queries down to next to no query time?&lt;/p&gt;

&lt;p&gt;This is for you …&lt;/p&gt;

&lt;h1 id=&quot;when-to-micro-optimize-&quot;&gt;When to Micro-Optimize ???&lt;/h1&gt;

&lt;p&gt;Easy … whenever there is no other way out of your performance problem. 
Sure hardware is a ton cheaper than developer time … but every now and then your project simply does not allow for that hardware upgrade for whatever reason …&lt;/p&gt;

&lt;p&gt;Shipping your product to a bunch of customers maybe?&lt;/p&gt;

&lt;p&gt;Already running the fastest CPU out there?&lt;/p&gt;

&lt;p&gt;Your developers love you and work for free?&lt;/p&gt;

&lt;p&gt;… so many possible reasons for why you might be reading this …&lt;/p&gt;

&lt;p&gt;So let’s get to it …&lt;/p&gt;

&lt;h1 id=&quot;no-free-lunch-&quot;&gt;No Free Lunch …&lt;/h1&gt;

&lt;p&gt;So you did it … your static code analysis tool is finally happy. All methods are less than 40 lines or whatever arbitrary maximum method length you though will make your code look nice.&lt;/p&gt;

&lt;p&gt;Everything is nicely encapsulated in a million classes, every action your code takes fires of a trivial to understand series of small objects interacting all nice and readable … unfortunately your customers started to brutalize Google for a leaner competitor meanwhile … those ungrateful simpletons … not showing the least bit of appreciation for your code quality, for your readability … not even for your separation of concerns …&lt;/p&gt;

&lt;p&gt;What did you think … that the load time of your site is just those darn database queries ?&lt;/p&gt;

&lt;p&gt;… or maybe those darn regular expressions ?&lt;/p&gt;

&lt;p&gt;… or is it all in your caching now? All those serialize/unserialize operations getting the best of you?&lt;/p&gt;

&lt;p&gt;Sure those things are slow at times … we’ll look into those some other time though.
For now, let’s try to find out how much we’re actually paying for all those tiny functions, methods, objects and redundant variables that make everything so nice and readable.&lt;/p&gt;

&lt;p&gt;… those aren’t free … not at all.&lt;/p&gt;

&lt;h1 id=&quot;getting-down-to-it-&quot;&gt;Getting down to it …&lt;/h1&gt;

&lt;h2 id=&quot;step-1-so-not-free-eh-how-much-are-they-then--gathering-data-&quot;&gt;Step 1: So not free eh? How much are they then? ( Gathering Data )&lt;/h2&gt;

&lt;p&gt;Well it depends … let’s gather some data I guess …&lt;/p&gt;

&lt;p&gt;Since we might be dealing with the case of a broad and very heterogeneous user population, lets gather that data across multiple PHP versions.
While we’re at it, we can also stop you from using all that crazy profiling I suppose … so lets also play with XDebug while we’re at it …&lt;/p&gt;

&lt;p&gt;So multiple setups … good thing it’s 2015 and we have Docker to play with now.&lt;/p&gt;

&lt;p&gt;So help yourself to some working docker daemon and the code we’re gonna be using here.&lt;/p&gt;

&lt;p&gt;Hint:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;git clone https://github.com/original-brownbear/php-performance-demos.git&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;So once we have that code, let’s run it. Since we’re mostly concerned with the effects of inlining ( or rather not inlining ) things here. That .sh file seems like a good start.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;./inline.sh&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Bam! … that’s enough data for one day I guess …&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;PHP 5.4


It took 1.4025449752808 s without inlining the &lt;span class=&quot;k&quot;&gt;function &lt;/span&gt;and with redundant &lt;span class=&quot;nb&quot;&gt;local &lt;/span&gt;variables inside the &lt;span class=&quot;k&quot;&gt;function
&lt;/span&gt;It took 0.84425115585327 s without inlining the &lt;span class=&quot;k&quot;&gt;function &lt;/span&gt;and without redundant variables inside the &lt;span class=&quot;k&quot;&gt;function
&lt;/span&gt;It took 0.80232501029968 s with inlining the &lt;span class=&quot;k&quot;&gt;function &lt;/span&gt;and with redundant &lt;span class=&quot;nb&quot;&gt;local &lt;/span&gt;variables
It took 0.51220011711121 s with inlining the &lt;span class=&quot;k&quot;&gt;function &lt;/span&gt;and without redundant &lt;span class=&quot;nb&quot;&gt;local &lt;/span&gt;variables
It took 2.572212934494 s with using a class method and with redundant &lt;span class=&quot;nb&quot;&gt;local &lt;/span&gt;variables
It took 1.9973518848419 s with using a class method and without redundant &lt;span class=&quot;nb&quot;&gt;local &lt;/span&gt;variables
It took 2.8596611022949 s with using a class method with method parameters and with redundant input variables
It took 2.8738570213318 s with using a class method with method parameters and without redundant input variables
It took 5.4805200099945 s with using a class method with constructor parameters and without property declarations
It took 4.4061641693115 s with using a class method with constructor parameters and with private property declarations
It took 4.3610110282898 s with using a class method with constructor parameters and with protected property declarations
It took 4.3442859649658 s with using a class method with constructor parameters and with public property declarations

PHP 5.4 + XDebug


It took 6.619166135788 s without inlining the &lt;span class=&quot;k&quot;&gt;function &lt;/span&gt;and with redundant &lt;span class=&quot;nb&quot;&gt;local &lt;/span&gt;variables inside the &lt;span class=&quot;k&quot;&gt;function
&lt;/span&gt;It took 6.9019331932068 s without inlining the &lt;span class=&quot;k&quot;&gt;function &lt;/span&gt;and without redundant variables inside the &lt;span class=&quot;k&quot;&gt;function
&lt;/span&gt;It took 2.0546748638153 s with inlining the &lt;span class=&quot;k&quot;&gt;function &lt;/span&gt;and with redundant &lt;span class=&quot;nb&quot;&gt;local &lt;/span&gt;variables
It took 1.1751098632812 s with inlining the &lt;span class=&quot;k&quot;&gt;function &lt;/span&gt;and without redundant &lt;span class=&quot;nb&quot;&gt;local &lt;/span&gt;variables
It took 9.0551729202271 s with using a class method and with redundant &lt;span class=&quot;nb&quot;&gt;local &lt;/span&gt;variables
It took 8.1946280002594 s with using a class method and without redundant &lt;span class=&quot;nb&quot;&gt;local &lt;/span&gt;variables
It took 10.072288990021 s with using a class method with method parameters and with redundant input variables
It took 9.2914588451385 s with using a class method with method parameters and without redundant input variables
It took 19.139733076096 s with using a class method with constructor parameters and without property declarations
It took 15.34263086319 s with using a class method with constructor parameters and with private property declarations
It took 15.49893116951 s with using a class method with constructor parameters and with protected property declarations
It took 15.300618171692 s with using a class method with constructor parameters and with public property declarations

PHP 5.5


It took 1.4747610092163 s without inlining the &lt;span class=&quot;k&quot;&gt;function &lt;/span&gt;and with redundant &lt;span class=&quot;nb&quot;&gt;local &lt;/span&gt;variables inside the &lt;span class=&quot;k&quot;&gt;function
&lt;/span&gt;It took 0.86752104759216 s without inlining the &lt;span class=&quot;k&quot;&gt;function &lt;/span&gt;and without redundant variables inside the &lt;span class=&quot;k&quot;&gt;function
&lt;/span&gt;It took 0.95179986953735 s with inlining the &lt;span class=&quot;k&quot;&gt;function &lt;/span&gt;and with redundant &lt;span class=&quot;nb&quot;&gt;local &lt;/span&gt;variables
It took 0.52045392990112 s with inlining the &lt;span class=&quot;k&quot;&gt;function &lt;/span&gt;and without redundant &lt;span class=&quot;nb&quot;&gt;local &lt;/span&gt;variables
It took 2.7302191257477 s with using a class method and with redundant &lt;span class=&quot;nb&quot;&gt;local &lt;/span&gt;variables
It took 2.0185148715973 s with using a class method and without redundant &lt;span class=&quot;nb&quot;&gt;local &lt;/span&gt;variables
It took 2.8453660011292 s with using a class method with method parameters and with redundant input variables
It took 2.8968069553375 s with using a class method with method parameters and without redundant input variables
It took 5.2499659061432 s with using a class method with constructor parameters and without property declarations
It took 4.3478300571442 s with using a class method with constructor parameters and with private property declarations
It took 4.1988000869751 s with using a class method with constructor parameters and with protected property declarations
It took 4.214898109436 s with using a class method with constructor parameters and with public property declarations

PHP 5.5 + XDebug


It took 6.2536900043488 s without inlining the &lt;span class=&quot;k&quot;&gt;function &lt;/span&gt;and with redundant &lt;span class=&quot;nb&quot;&gt;local &lt;/span&gt;variables inside the &lt;span class=&quot;k&quot;&gt;function
&lt;/span&gt;It took 4.9655790328979 s without inlining the &lt;span class=&quot;k&quot;&gt;function &lt;/span&gt;and without redundant variables inside the &lt;span class=&quot;k&quot;&gt;function
&lt;/span&gt;It took 2.0919289588928 s with inlining the &lt;span class=&quot;k&quot;&gt;function &lt;/span&gt;and with redundant &lt;span class=&quot;nb&quot;&gt;local &lt;/span&gt;variables
It took 1.2138221263885 s with inlining the &lt;span class=&quot;k&quot;&gt;function &lt;/span&gt;and without redundant &lt;span class=&quot;nb&quot;&gt;local &lt;/span&gt;variables
It took 8.6731350421906 s with using a class method and with redundant &lt;span class=&quot;nb&quot;&gt;local &lt;/span&gt;variables
It took 7.4445428848267 s with using a class method and without redundant &lt;span class=&quot;nb&quot;&gt;local &lt;/span&gt;variables
It took 8.8504319190979 s with using a class method with method parameters and with redundant input variables
It took 8.0068590641022 s with using a class method with method parameters and without redundant input variables
It took 15.685569047928 s with using a class method with constructor parameters and without property declarations
It took 14.428926944733 s with using a class method with constructor parameters and with private property declarations
It took 14.412018060684 s with using a class method with constructor parameters and with protected property declarations
It took 14.306435108185 s with using a class method with constructor parameters and with public property declarations

PHP 5.6


It took 1.4295959472656 s without inlining the &lt;span class=&quot;k&quot;&gt;function &lt;/span&gt;and with redundant &lt;span class=&quot;nb&quot;&gt;local &lt;/span&gt;variables inside the &lt;span class=&quot;k&quot;&gt;function
&lt;/span&gt;It took 0.85520005226135 s without inlining the &lt;span class=&quot;k&quot;&gt;function &lt;/span&gt;and without redundant variables inside the &lt;span class=&quot;k&quot;&gt;function
&lt;/span&gt;It took 0.74695014953613 s with inlining the &lt;span class=&quot;k&quot;&gt;function &lt;/span&gt;and with redundant &lt;span class=&quot;nb&quot;&gt;local &lt;/span&gt;variables
It took 0.49425292015076 s with inlining the &lt;span class=&quot;k&quot;&gt;function &lt;/span&gt;and without redundant &lt;span class=&quot;nb&quot;&gt;local &lt;/span&gt;variables
It took 2.4544260501862 s with using a class method and with redundant &lt;span class=&quot;nb&quot;&gt;local &lt;/span&gt;variables
It took 1.9607548713684 s with using a class method and without redundant &lt;span class=&quot;nb&quot;&gt;local &lt;/span&gt;variables
It took 2.6875011920929 s with using a class method with method parameters and with redundant input variables
It took 2.6686630249023 s with using a class method with method parameters and without redundant input variables
It took 5.1677548885345 s with using a class method with constructor parameters and without property declarations
It took 4.1540579795837 s with using a class method with constructor parameters and with private property declarations
It took 4.1646270751953 s with using a class method with constructor parameters and with protected property declarations
It took 4.131668806076 s with using a class method with constructor parameters and with public property declarations

PHP 5.6 + XDebug


It took 6.1721510887146 s without inlining the &lt;span class=&quot;k&quot;&gt;function &lt;/span&gt;and with redundant &lt;span class=&quot;nb&quot;&gt;local &lt;/span&gt;variables inside the &lt;span class=&quot;k&quot;&gt;function
&lt;/span&gt;It took 4.9106600284576 s without inlining the &lt;span class=&quot;k&quot;&gt;function &lt;/span&gt;and without redundant variables inside the &lt;span class=&quot;k&quot;&gt;function
&lt;/span&gt;It took 2.1572380065918 s with inlining the &lt;span class=&quot;k&quot;&gt;function &lt;/span&gt;and with redundant &lt;span class=&quot;nb&quot;&gt;local &lt;/span&gt;variables
It took 1.2649810314178 s with inlining the &lt;span class=&quot;k&quot;&gt;function &lt;/span&gt;and without redundant &lt;span class=&quot;nb&quot;&gt;local &lt;/span&gt;variables
It took 8.7360029220581 s with using a class method and with redundant &lt;span class=&quot;nb&quot;&gt;local &lt;/span&gt;variables
It took 7.3417930603027 s with using a class method and without redundant &lt;span class=&quot;nb&quot;&gt;local &lt;/span&gt;variables
It took 8.9390790462494 s with using a class method with method parameters and with redundant input variables
It took 8.3251278400421 s with using a class method with method parameters and without redundant input variables
It took 15.677669048309 s with using a class method with constructor parameters and without property declarations
It took 14.916995048523 s with using a class method with constructor parameters and with private property declarations
It took 14.911762952805 s with using a class method with constructor parameters and with protected property declarations
It took 14.528133869171 s with using a class method with constructor parameters and with public property declarations

PHP 7


It took 0.55066180229187 s without inlining the &lt;span class=&quot;k&quot;&gt;function &lt;/span&gt;and with redundant &lt;span class=&quot;nb&quot;&gt;local &lt;/span&gt;variables inside the &lt;span class=&quot;k&quot;&gt;function
&lt;/span&gt;It took 0.23726606369019 s without inlining the &lt;span class=&quot;k&quot;&gt;function &lt;/span&gt;and without redundant variables inside the &lt;span class=&quot;k&quot;&gt;function
&lt;/span&gt;It took 0.37661790847778 s with inlining the &lt;span class=&quot;k&quot;&gt;function &lt;/span&gt;and with redundant &lt;span class=&quot;nb&quot;&gt;local &lt;/span&gt;variables
It took 0.10790801048279 s with inlining the &lt;span class=&quot;k&quot;&gt;function &lt;/span&gt;and without redundant &lt;span class=&quot;nb&quot;&gt;local &lt;/span&gt;variables
It took 1.2261588573456 s with using a class method and with redundant &lt;span class=&quot;nb&quot;&gt;local &lt;/span&gt;variables
It took 0.92833209037781 s with using a class method and without redundant &lt;span class=&quot;nb&quot;&gt;local &lt;/span&gt;variables
It took 1.3132491111755 s with using a class method with method parameters and with redundant input variables
It took 1.2214460372925 s with using a class method with method parameters and without redundant input variables
It took 2.2280390262604 s with using a class method with constructor parameters and without property declarations
It took 1.7811279296875 s with using a class method with constructor parameters and with private property declarations
It took 1.8180849552155 s with using a class method with constructor parameters and with protected property declarations
It took 1.8068678379059 s with using a class method with constructor parameters and with public property declarations

PHP 7 + XDebug


It took 5.1429510116577 s without inlining the &lt;span class=&quot;k&quot;&gt;function &lt;/span&gt;and with redundant &lt;span class=&quot;nb&quot;&gt;local &lt;/span&gt;variables inside the &lt;span class=&quot;k&quot;&gt;function
&lt;/span&gt;It took 3.9954431056976 s without inlining the &lt;span class=&quot;k&quot;&gt;function &lt;/span&gt;and without redundant variables inside the &lt;span class=&quot;k&quot;&gt;function
&lt;/span&gt;It took 1.5582900047302 s with inlining the &lt;span class=&quot;k&quot;&gt;function &lt;/span&gt;and with redundant &lt;span class=&quot;nb&quot;&gt;local &lt;/span&gt;variables
It took 0.64883804321289 s with inlining the &lt;span class=&quot;k&quot;&gt;function &lt;/span&gt;and without redundant &lt;span class=&quot;nb&quot;&gt;local &lt;/span&gt;variables
It took 6.7732870578766 s with using a class method and with redundant &lt;span class=&quot;nb&quot;&gt;local &lt;/span&gt;variables
It took 5.6968550682068 s with using a class method and without redundant &lt;span class=&quot;nb&quot;&gt;local &lt;/span&gt;variables
It took 6.8934459686279 s with using a class method with method parameters and with redundant input variables
It took 6.4292969703674 s with using a class method with method parameters and without redundant input variables
It took 12.728615045547 s with using a class method with constructor parameters and without property declarations
It took 11.849714994431 s with using a class method with constructor parameters and with private property declarations
It took 12.050687074661 s with using a class method with constructor parameters and with protected property declarations
It took 11.997341871262 s with using a class method with constructor parameters and with public property declarations&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;So how did we do that? … we just ran this script leveraging Docker’s awesomeness.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;PHP_VERSION &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;5.4&quot;&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;5.5&quot;&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;5.6&quot;&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;7&quot;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;do
	&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; -e &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;PHP &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;PHP_VERSION&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
	docker run -t --rm -v &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$PWD&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;:/src php:&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;PHP_VERSION&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;-cli php /src/inline.php
	&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; -e &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;PHP &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;PHP_VERSION&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; + XDebug&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
	docker run -t --rm -v &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$PWD&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;:/src originalbrownbear/php:&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;PHP_VERSION&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;-cli-xdebug php /src/inline.php
&lt;span class=&quot;k&quot;&gt;done&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Mount the current working dir containing the inline.php test script into various docker containers and execute it in exactly the same way on each of them.&lt;/p&gt;

&lt;p&gt;The test script itself just does one simple thing in various ways, it concatenates the strings ‘a’ and ‘b’ a bunch of times and depending on the test either very directly or buried deep in the stack …&lt;/p&gt;

&lt;p&gt;So, what can we learn from this, let’s see …&lt;/p&gt;

&lt;h2 id=&quot;step-2--wtf-is-this---making-sense-of-the-data-&quot;&gt;Step 2: … WTF is This ??? ( Making Sense of the Data )&lt;/h2&gt;

&lt;h3 id=&quot;step-21-turn-off-xdebug-&quot;&gt;Step 2.1: Turn off XDebug …&lt;/h3&gt;

&lt;p&gt;Without even going into the details of each test run, you should be able to see why XDebug is probably the worst thing to have running while optimizing performance.
It significantly skews the relative performance of various solutions to the same problem.&lt;/p&gt;

&lt;p&gt;A few examples from the above data for PHP 5.6:&lt;/p&gt;

&lt;p&gt;Using redundant local variables comes with a 1.43/0.86 ~ 1.66 times slower execution for concatenating ‘a’ and ‘b’ when running:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class=&quot;nv&quot;&gt;$a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'a'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;$b&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'b'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;nv&quot;&gt;$a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;instead of outright running:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class=&quot;s1&quot;&gt;'a'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'b'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;… &lt;strong&gt;when XDebug is not loaded&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Load XDebug and the advantage of removing those redundant variable assignments goes down to 6.17/4.91 ~ 1.26 speedup/slowdown.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The trouble with XDebug is not that it slows down overall execution, the trouble is it skewing relative performance relative to production systems! Either avoid using its profiling when micro-optimizing or at least be mindful of this effect!&lt;/strong&gt;&lt;/p&gt;

&lt;h3 id=&quot;step-22-understand-the-data-&quot;&gt;Step 2.2: Understand the data …&lt;/h3&gt;

&lt;h4 id=&quot;step-221-redundant-local-variables-are-slow-and-hard-to-read&quot;&gt;Step 2.2.1 Redundant Local Variables are Slow and Hard to Read&lt;/h4&gt;

&lt;p&gt;Lets not get into the readability thing here … this is settled anyhow … You use the variable only once ? So why use a variable ? Why would you want me, the poor dude having to read your code, to be forced to understand that you’re just using that variable as a long-winded way of adding a comment? You don’t need to save that data to anywhere, you’re only using it once … so please make the code tell me that when I read it …&lt;/p&gt;

&lt;p&gt;Also … apart from me being able to better understand your code … more importantly your PHP interpreter will be able to better understand it …&lt;/p&gt;

&lt;p&gt;Just by the numbers the above example of adding pointless variable assignment to the concatenating of those two strings comes with a slowdown, depending on the PHP version of:&lt;/p&gt;

&lt;p&gt;PHP 5.4: 66%&lt;/p&gt;

&lt;p&gt;PHP 5.5: 68%&lt;/p&gt;

&lt;p&gt;PHP 5.6: 66%&lt;/p&gt;

&lt;p&gt;PHP 7.0: 139%!&lt;/p&gt;

&lt;p&gt;So why is that so … everyone on StackOverflow tells me that these assignments are ‘optimized away’ anyhow?&lt;/p&gt;

&lt;p&gt;First off … guess who does that optimizing and needs time for it … yes your CPU …&lt;/p&gt;

&lt;p&gt;Second of all … PHP is constantly optimizing things behind the scenes and getting ever better at it as time goes by. Now it’s relatively trivial to see ‘a’ . ‘b’ and figure out that this will always come out to ‘ab’, reserve the respective amount of memory and get all the other crazy weird things behind the scenes right. But thing about optimizing $a . $b … there’s nothing to optimize there unless the interpreter knows what $a and $b are beforehand. It cannot know this without executing the code though for obvious reasons … ( &lt;em&gt;cough … Halting problem&lt;/em&gt; )
Good thing you’re a human and know what’s going on in your code better than the machine … be so kind and tell it all that you know as directly as you can. It might reciprocate and help your customers as quickly as it can at some point down the line :)&lt;/p&gt;

&lt;h4 id=&quot;step-222-function-calls-aint-free-&quot;&gt;Step 2.2.2 Function Calls ain’t Free …&lt;/h4&gt;

&lt;p&gt;The next thing to understand is, that function calls are not free at all compared to just running code line by line. Someone has to find out and keep track of what function means what …
Sure this is all in some hash table with very fast lookup and very strong scaling behavior … then again if you do this a few thousand times it does add up …&lt;/p&gt;

&lt;p&gt;So lets start out with the numbers on how using some function like&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;concat_function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(){&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'a'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'b'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;compares to just good old …&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class=&quot;s1&quot;&gt;'a'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'b'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Depending on the PHP Version the slow down comes out to:&lt;/p&gt;

&lt;p&gt;PHP 5.4: 65%&lt;/p&gt;

&lt;p&gt;PHP 5.5: 67%&lt;/p&gt;

&lt;p&gt;PHP 5.6: 73%&lt;/p&gt;

&lt;p&gt;PHP 7.0: 118%!&lt;/p&gt;

&lt;p&gt;Again … the newer your PHP version the more of the under the hood progress made on the interpreter is wasted by adding additional function calls that mess up optimizations.&lt;/p&gt;

&lt;p&gt;This is not to say that you should get carried away creating monstrous functions spanning hundreds of lines, rather see if that small function inside some long loop really needs to even be a function/method ? Maybe it can be inlined since it’s used in one spot only anyhow?&lt;/p&gt;

&lt;p&gt;Also for even more obvious reasons … at least stop doing this to your coworkers:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;foo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(){&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;bar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Seriously … why is this still happening in so many projects on this planet? … Sure sometimes it’s just an outright compatibility/needing that alias thing … mostly this is just stupid though ..&lt;/p&gt;

&lt;h4 id=&quot;step-223-objects-do-cost-a-lot&quot;&gt;Step 2.2.3 Objects do cost a lot!&lt;/h4&gt;

&lt;p&gt;Given you know about the expenses incurred from redundant variable assignments and function calls this shouldn’t come as a surprise to you,
object instantiation and class methods come at a significant cost. More on this some other time, just keep above numbers in mind when coding your long loops.&lt;/p&gt;

&lt;p&gt;Something like the below example ( obviously way over the top ), surely won’t be an issue used like 10 times throughout your app.
Use it in that 10k iterations loop and it will show though …&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ConcaterConstructParamDeclared&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;__construct&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;){&lt;/span&gt;
		&lt;span class=&quot;nv&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
		&lt;span class=&quot;nv&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;concat&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(){&lt;/span&gt;
		&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h3 id=&quot;step-3-uff--wont-do-it-again--promise--avoiding-overhead-when-it-matters-&quot;&gt;Step 3: Uff … won’t do it again … Promise! ( Avoiding Overhead when it matters )&lt;/h3&gt;

&lt;p&gt;Just knowing the above should give you a strong starting point to optimize away some of the demonstrated overhead from your code where it matters.&lt;/p&gt;

&lt;p&gt;Instead of going overboard with these things though … keep your code clean, keep things modular … when the time comes to speed up those long loops or whatever, you’ll find them in no time.&lt;/p&gt;

</description>
        <pubDate>Sat, 19 Dec 2015 00:00:00 +0100</pubDate>
        <link>http://obrown.io/php/2015/12/19/php-performance-inlining.html</link>
        <guid isPermaLink="true">http://obrown.io/php/2015/12/19/php-performance-inlining.html</guid>
        
        <category>PHP</category>
        
        <category>WIP</category>
        
        <category>Performance</category>
        
        
        <category>PHP</category>
        
      </item>
    
  </channel>
</rss>
