
My PHP Development Setup - prostoalex
https://johnmackenzie.co.uk/post/my-modern-php-development-setup/
======
tylerjwilk00
Glad to see modern PHP getting more coverage on HN. For anyone interested in
how the latest version performance compares to similar languages checkout vs
Python [1] and the vs Ruby [2] pages from the benchmarks game team.

[1] [https://benchmarksgame-
team.pages.debian.net/benchmarksgame/...](https://benchmarksgame-
team.pages.debian.net/benchmarksgame/faster/php.html)

[2] [https://benchmarksgame-
team.pages.debian.net/benchmarksgame/...](https://benchmarksgame-
team.pages.debian.net/benchmarksgame/faster/php-yarv.html)

~~~
Zak
Aside from doing well on synthetic benchmarks, what case would you make for
starting a new project in PHP in 2019? What are its strengths?

~~~
furicane
PHP recently received an extension that exposes an asynchronous programming
framework, called swoole. It's extremely promising (but not perfect). Here's
the link [https://www.swoole.co.uk/](https://www.swoole.co.uk/) and it
produces some very, very, very interesting results - both in synthetic
benchmarks AND real world. Link:
[https://www.techempower.com/benchmarks/#section=data-r17](https://www.techempower.com/benchmarks/#section=data-r17)

In certain use cases, it literally annihilates Golang for example and leaves
node.js way, way, way behind.

Now, ignoring the numbers, there are many things you can do using PHP:

\- web applications

\- background services

\- queue systems

Imagination is the limit (but that applies to any language these days)

There's plenty options to choose from, from web-related frameworks to
community provided libraries, even the command line interface received a ton
of cool libraries to play with. I can't state that you can do X in PHP but
can't do the same in Y, Y being another language. However, frameworks such as
Laravel make it trivial to bootstrap a project, create an API, create a nice
UI using Vue (Laravel comes with excellent Vue tooling) and deploy the whole
thing in a few easy steps to popular hosting providers.

Granted, it's not language specific, there was a huge community effort behind
everything PHP related: from standards, to package manager, to tooling,
utilities and so on so the ecosystem is quite healthy and progressing.

The nice thing about it, ultimately, is that it's really fast enough and keeps
getting faster, with new (useful) language features.

If you're after a tldr version and don't care about the wall of text above:

Strenghts:

\- excellent ecosystem [http://www.packagist.org](http://www.packagist.org),
[http://www.getcomposer.org](http://www.getcomposer.org)

\- excellent *nix support, easy installation:
[https://launchpad.net/~ondrej/+archive/ubuntu/php](https://launchpad.net/~ondrej/+archive/ubuntu/php)

\- great object oriented model that supports strong typing:
[http://php.net/oop](http://php.net/oop)

\- excellent choice of web-app frameworks:
[https://laravel.com/](https://laravel.com/),
[https://lumen.laravel.com/](https://lumen.laravel.com/),
[https://symfony.com/](https://symfony.com/)

\- big choice of extensions that expose additional functionality, such as
swoole: [https://www.swoole.co.uk/](https://www.swoole.co.uk/) or zeromq:
[https://github.com/mkoppanen/php-zmq](https://github.com/mkoppanen/php-zmq)

\- great performance for an interpreted language

\- easy scaling due to php-fpm
[http://php.net/manual/en/install.fpm.php](http://php.net/manual/en/install.fpm.php)
(this has been available for a decade)

~~~
aasasd
Async programming was there for a long time in the form of ReactPHP. With the
caveat, of course, that comparatively few people know of it because of
peculiarities of PHP's target audience. It's hard for something non-standard
to gain traction in PHP.

------
stunt
PHP community did an exceptionally excellent job to improve standards in the
past few years. A lot of features has been added to the language itself as
well as huge performance improvement.

Many complain about PHP is from the past. Still a lot of developers just
hacking around but it is not hard to find decent PHP developers anymore.

~~~
gnulinux
Any sources for modern PHP? I kinda started programming in PHP (completely
self taught from internet as a kid in grade school) and my first internship
was in PHP. When I started learning other languages, and technologies I
basically realized PHP is nothing but an eternal hell. This was 10 years ago.
To be _very_ honest, PHP was so bad back then I hardly believe it's passable
now. But I'd like to explore it a little, to see that I'm wrong and they
somehow saved PHP. Is there a source that can give me what modern PHP has to
offer and how it diverged from its (famously) "fractal of bad design' nature?

~~~
thefork
PHP: The Right Way
([https://phptherightway.com/](https://phptherightway.com/)) is a maintained
resource which I frequently recommend.

Additionally, JetBrains has good resources. The PHPStorm IDE is worth your
time, as well as the blog PHP Annotated Monthly:
[https://blog.jetbrains.com/phpstorm/category/php-
annotated-m...](https://blog.jetbrains.com/phpstorm/category/php-annotated-
monthly/)

~~~
wyclif
PHP: The Right Way has helped me immensely. It is the best of "The Right Way"
sites because it's maintained by people who know what they're talking about,
it gives you the most important resources and documentation you should read,
refer to, and understand.

------
franciscop
> Most developers use Makefiles

I disagree. I'll argue that most of the new crop of developers are self-
taught/bootcamp-trained/career-switching and they straight to the web. For
RoR, Node.js, Python, Go, etc. it's not a common setup and those are the
languages being learned today.

Now if we are talking about the public who has a "I remember when I started
with PHP" nostalgic feeling while reading this article I might agree, but that
is not "most developers" :)

~~~
jrockway
I agree with you. I am not sure "convenience Makefiles" like these really
accomplish much, other than letting you put 6 shell scripts in one file. The
cost, of course, is that you can't run anything on Windows. If you have a
native Make-like, I would just use that instead (npm lets you define them in
packages.json, for example.)

These convenience Makefiles ultimately don't get to the root of the problem of
building a dependency graph for your project, and result in much overbuilding.
For example, I have a Go backend + Vue/Typescript frontend. "make all" will
re-webpack the frontend when you modify the backend because make was not
taught the dependency graph. It doesn't understand the dependencies between
input and output because it was not told that. Telling it that involves
reverse-engineering your language's internal dependency management (go already
knows what it has cached, for example), so nobody does it. If you _do_ decide
to rewrite your language's dependency management to make make do incremental
builds correctly, you will get it wrong and then _underbuild_, which is why
"just run make clean!" is such a common remark. To me, underbuilding is worse
than overbuilding, but both are bad. If you can't solve that problem (by using
something like Bazel), I would not bother with make. (We all dream of the days
when _.c became_.o and your binary was just all the *.o files linked with some
libraries. But that is not how newer programming languages work at all.)

For the case where the author is just using docker-compose, I would say... you
have two docker-compose files, one for local development, one for production.
You build your development docker-compose approximately once, have it running,
and tell your web framework thingie to rebuild when the code changes (mounted
in the container with a volume). Meanwhile, your CI system builds a container
without any of that dynamic recompilation stuff for production. Not great, but
not horrible either. You will need some glue to run your unit tests inside the
container. Probably a shell script that the Windows users on your team will
port to Powershell for their own use. All in all, not ideal, but not super bad
either. (I personally think I will move in the direction of ksync/telepresence
and minikube, so the shell scripts to do things like run the tests or wipe the
database are run inside the dev container, and nobody has to pretend their
local machine matters for anything but "minikube start". But it is more work
than docker-compose, for sure.)

~~~
bpicolo
> other than letting you put 6 shell scripts in one file

They make working in the repository as a newcomer abundantly better.

------
Kovah
Uhm... I didn't know that makefiles are that easy. Last one I looked at one it
looked like it could run a spaceshuttle. Lot's of crazy stuff. Thought it
would be super complicated, but now.. well.. will try this out.

~~~
btbuildem
I'll take make anytime over grunt / gulp / whatever flavor of the day JS build
chain nightmare is popular today.

~~~
52-6F-62
I was just having that discussion this morning.

Early in my re-entry to web I was using grunt to manage the build processes,
but that fell away fast—

I'll either write a Makefile or a shell script to manage those builds and
processes now—and I'm far more productive for it. No need for a number of
plugins and yet more dependencies to manage.

Though, I have to say I've seen less and less of Grunt and Gulp (etc) in
modern JavaScript (especially TypeScript)

------
tonysickpony
I really enjoy articles like this. In fact if anyone know some high quality
resources of modern PHP, please give me some pointers. I am somewhat
proficient in programming, and a recent project requires me to work in PHP. I
know people in the industry likes to make fun of php's design flaws and
quirks, but a few weeks in, I feel it is alright. The community around it are
making solid improvements. The only frustrator is that once too often when I
search something the top results are all W3C school tutorials from 2004.

~~~
moray
I work a lot with Laravel, it is a hell of a framework, documentation is
amazing, it's clean, very well done, super extensible, there are a lot of
extensions (just have a look at the Spatie library) and allows me to build up
a website/webapp backend with a good API, basic authentication and other basic
features in minutes.

Also, and this is a really strong point, can manage assets super easily, React
and Vue stacks are supported out of the box with laravel-mix.

And if you need something lighter (for building just an API for instance)
Lumen is the light version of it.

I have a lot of experience with PHP and Python frameworks, Laravel comes as
absolute top for me.

[https://laravel.com/](https://laravel.com/)

[https://spatie.be/open-source](https://spatie.be/open-source)

[https://lumen.laravel.com/](https://lumen.laravel.com/)

~~~
chiefalchemist
As someone who recently took on the Laravel learning curve, be aware that
Laravel moves atypically fast. That is, something in say version X.Y might be
different in X.Y+1 or Y+2. That ends up manifesting itself as a lot of noise
when you're asking The Google for help.

It can be frustrating. When you're on a deadline it can be unnerving and then
some.

~~~
tomschlick
That's true for additional features, but rarely does documented behavior
change in a point release. That usually only happens when there is a security
bug.

~~~
CleanShirt
That’s not true. It happens quite often. Variables, classnames, php targets
are changed on a whim.

------
FraaJad
I don't know why people get so bent about Makefiles. Its a way to preserve
muscle memory using a universally (well most *nix systems, anyway) available
software.

It allows you to have package your often used shell commands into one well
known (even a 30 year manual will teach you how to read/use a makefile) file.

------
Jaruzel
I'm doing it in a really weird way, and I'm probably alone in this setup:

1\. Various IDEs on my Windows machine writing PHP & HTML/CSS.

2\. Saving all files over Samba to a Debian Web Server running Apache.

3\. Once the code is complete and signed off, it's migrated to a production
server.

4\. Have a global error hook via 'set_error_handler' in each PHP file that
'echos' out the problem into the Browser. This doesn't help me with syntax
errors though.

I'm fairly new to PHP development (Previously .NET dev), so I'm probably doing
many things wrong here, and I'm totally open to suggestions, however I DO have
to stick with Windows as my dev machine.

~~~
oblio
Well, generally the modern day approach would be to:

1\. Use source control. A good idea in general.

2\. Have an automated deployment system that does the "saving files over
Samba" for you.

3\. Use a proper logging system and access the log files to see the errors.

~~~
Jaruzel
Already do #1 (kinda), do you have any suggestions for #2 and #3?

~~~
stef25
1\. Do it propery :) Here's a good guide:
[https://nvie.com/posts/a-successful-git-branching-
model/](https://nvie.com/posts/a-successful-git-branching-model/)

2\. Gitlab has solutions, Atlassian Bamboo, Buddy, FTPloy, Jenkins, etc.

3\. Monolog
[https://github.com/Seldaek/monolog](https://github.com/Seldaek/monolog)

------
efficax
Makefile for essentially a bundle of shell aliases? Weird flex for PHP but ok.

~~~
tylerjwilk00
I am guessing the Makefile helps with "portability" aspect. Where as aliases
would need to be "installed" on end user's machine outside of cloning a repo.

~~~
frou_dh
That kind of anaemic Makefile in the article can be expressed as a single case
statement in a plain POSIX shell script:

    
    
        #!/bin/sh
        set -e
    
        case "$1" in
            up)
                docker-compose up -d
                ;;
    
            build)
                docker-compose rm -vsf
                docker-compose down -v --remove-orphans
                docker-compose build
                docker-compose up -d
                ;;
            *)
                echo "unknown verb: $1"
                ;;
        esac
    

I honestly think there's a phenomenon where, since the bash man page is too
bloated, looking up shell syntax has become a no-no. So if people don't
already know the syntax for what they want to do, they treat shell scripting
as a lost cause.

~~~
trm42
The idea of your shell script and Makefile are the same. For me it doesn't
matter which one is used but source code should have some kind of easily
usable list of common development tasks. Otherwise developers are doing this
and that and the easier ways of doing repeatable stuff are not getting
propagated to everybody.

~~~
frou_dh
Yes indeed. My comment was only tangential to that aspect.

------
thibran
Modern PHP is much better than the old one. One feature I miss from Kotlin are
Infix-Functions:
[https://kotlinlang.org/docs/reference/functions.html#infix-n...](https://kotlinlang.org/docs/reference/functions.html#infix-
notation)

Even the newest PHP feels somewhat dated, Infix-Functions could reduce a lot
of typing by making library and custom wrapper code – which almost always
exists – resemble more.

    
    
      function foo(String $s) {...}
      // current function call syntax 
      foo('hiho');
    
      // just syntactic sugar - below code is the same as above
      function String.foo(String $s) {...}
      'hiho'->foo();

~~~
Something1234
Why is this a useful syntactic sugar?

EDIT: I'm dumb. The syntactic sugar is just operator overloading. The better
question is why would you ever give that to a PHP developer? I've been digging
through some of it, and it's just annoying to untangle some of the code people
write, as compared to other languages.

~~~
thibran
For example you can't just write [1, 2, 3]->map(...) in PHP.

Right now the best is to use something like Laravel's collect, e.g.
collect([1, 2, 3])->map(...). Oftentimes all you want is to add one method to
an object. Right now you would have to sub-class it or write an ugly wrapper
function.

Infix-Functions are one way to "extend" functionality without messing with
inheritance – with other words, you can easier express what you mean with less
code in an consistent way. In Android dev, Kotlin and Infix-Functions are
quite popular. Too often in PHP you have to write some_function($object). The
other thing is that PHP has a lot of strange function names and Infix-
Functions could help to give the language designers a second chance to come up
with better names, even if the Infix-Functions just call the existing code.

~~~
Something1234
I would be fan of adding some kind of in-place map as a method on an array to
php, but other that that I don't see much benefit to it.

------
GrumpyNl
Mine is a a lot simpeler, install Xampp with desired php/mysql version and im
ready to go.

------
xd
I've struggled for years for a decent PHP IDE, I've used everything from nano,
to vi to Eclipse, I even developed my own in PHP using wxwidgets (wxphp) which
fell to the wayside when PHP7 came along and the support for wxwidgets was
dropped. I used PHPStorm a couple of times but had various issues and finally
I have settled on Atom[1] which in the almost 20years I've been developing in
PHP must say is hands down the best IDE for PHP yet... and it's free.

[1] [https://atom.io](https://atom.io)

~~~
ehnto
I swear by PHPStorm, it has everything I need in one spot, and a built in
terminal window for everything else. Saves so much cognitive load on context
switching. Instead of flicking through four different windows and losing my
train of thought constantly, it's just the browser on one screen and an all in
one tool in the other.

PHPStorm's XDebug integration is second to none, it has full MySQL
integration, and it's autocomplete and click-through intelligence is
incredibly smart.

I have tried atom, but I miss too many of PHPStorm's features. There is so
much it can do, and so much intelligent functionality, but it all stays out of
the way until you call upon it.

~~~
furicane
I second this.

Without going into what I've tried and yadda yadda yadda, white noise, my
credentials and so on - PHPStorm id _the_ IDE. No Atom / VSCode or whatever
can't compare. You get ctrl+click go to definition, you get ssh terminal, you
get XDebug integration, it plays with Vue/ES6/React, you get MySQL
integration, Vagrant integration, extensions to get VIM bindings and so on.
Next to proper keyboard, monitor and mouse - buying PHPStorm is hands down one
best money spent when it comes to what I work with every day.

I'm NOT saying "you can't get X with Y editor which is free" \- sure, I
believe you can, but this thing completely satisfies my every requirement and
I don't have to spend time looking for integration extension or whatever. It
saved me a ton of time so far, it will do so in future - I approve it, however
I don't think anyone's editor "sucks and you should go with PHPStorm".
Everyone should go for what they think brings them the best experience /
value.

~~~
busterarm
Third it.

I'm not even an IDE -- I'm a strict Vim user, but when I had to work in PHP I
found the experience to be very nice. Especially integrating with the
debugger.

JetBrains' stuff is top notch and I will buy their IDE for any language I work
in, even if I don't use it very often.

------
Scullwm
Really nice article! Didn't know about the .editorconfig file. Thanks for the
tips! Just wondering how are you deploying your php apps now ?

~~~
petecoop
Hey, I didn't write the article but work with John... we deploy through a
CI/CD pipeline using Concourse CI. Which builds the docker containers and
eventually deploys them onto a Rancher cluster

------
s3nnyy
Is Php becoming popular again?

~~~
tjpnz
No but if your job requires you use it it's nice that there are people out
there trying to make the experience more tolerable.

~~~
s3nnyy
Aren't the new versions of PHP quite good?

~~~
furicane
They are, quite good and the performance keeps improving with every new
version. We're expecting another huge performance boost with version 7.4

~~~
AdrianB1
Just curious: in what scenarios did you see performance problems with PHP? In
all my projects performance was more than adequate, even with 5.6 that was a
few times slower than 7.x. All my current projects are 7.2, at some point I
will get on 7.4 but not because I need more performance, just for bug fixes
and security updates in the supported period.

------
juddlyon
Modern PHP is light years ahead of the procedural spaghetti-fest of
yesteryear.

Craft CMS is fantastic, built atop Yii 2:

[https://craftcms.com/](https://craftcms.com/)

[https://www.yiiframework.com/](https://www.yiiframework.com/)

------
thunderbong
Another commentator mentioned xampp.

For developers on Windows, I think Uniform Server[0] is really good. It's
completely portable and gives the full stack as well.

[0][http://www.uniformserver.com/](http://www.uniformserver.com/)

~~~
andrejuseu
There's [https://laragon.org/](https://laragon.org/) not only for PHP, easy to
manage. Using it for last 1,5 year now.

~~~
thunderbong
This looks very interesting. Have to try it.

------
kingosticks
Is this all in use in some private repos? I went poking around on the author's
github for some examples (I've never used docker compose before, what on earth
is that 'app' thing?) but I can't find anything like what is described.

------
llIIllIIllIIl
I doubt there's any other programming language here that did such a tremendous
job over the last decade on improving developer experience, language speed and
syntax with consistency. ps. i was writing my first sites with php3.

------
pachico
Nice to see more PHP coverage. I personally think people should move along and
stop this "why would I choose PHP for a new project" nonsense. It's time to
get over it.

------
Kiro
> jumpin is just me being lazy saving me typing docker exec -it <container-id>
> bash

The command uses run though? Is that a typo? (Really eager to try this setup.)

------
dan_m2k
Good piece, and nice to see a local lad on here. _waves from Park Square_

------
BozeWolf
Anyone else has problems with the usage of the word “modern”?

“Modern x written in y” etcetera. To me this often is a sign to not having to
read it. As if you would make or do something new in oldfashioned style
without mentioning it. Eg: “what my php setup was on amiga in 1985”.

Just call it “my take on a good php setup in 2019” or something. The setup is
retro in januari 2020.

Anyways, I accept the down votes.

To me this is just another setup which slapped together a bunch of fancy pancy
tools. Why is docker required? I use docker a lot, but to build containers and
deploy apps with it. The way it is intended to be uses. Running (python) web
projects works fine without docker for development. Most team mates use macos,
which is linuxy/unixy enough until you do something specific.

Make is quite an old useful tool, but certainly not modern. As are linters.

.editorconfig is a thing now.

~~~
black-tea
Yes, "modern" is in vogue right now. During the 90s I remember the word got so
overused that designers turned to the word "contemporary" to mean exactly the
same thing. We'll probably start seeing that word used for software soon.

~~~
nerflad
To me (not a designer), modern connotes modernism. But contemporary just means
"current" or "present day". I could be totally wrong about this, but I always
try to use contemporary unless I'm specifically referring to modernist
art/design philosophy.

(SenHeng beat me to it)

~~~
wwweston
Contemporary is a good word to use in discussions like these, because it's
halfway to acknowledging that the choices of the moment may be as much fashion
/ aesthetics of a sort as they may reflect new heights of engineering quality.

------
8lall0
> Use a Makefile and make good use of it

Srsly?

------
iends
Would you ever choose PHP over Node.js if you don't care about hosting on
shared hosting?

~~~
petecoop
Hiring/skillset of the existing team, existing legacy codebases that need to
be worked on, simplicity... things aren't as black and white of you must use
this technology over another, there are a lot of reasons involved

------
willand31
I upgraded my PHP dev setup a few years ago. The most effective thing I did
was to stop developing in PHP.

------
mychael
Wrapping docker/docker-compose with makefiles or bash aliases is an anti-
pattern, particularly on team projects.

It's a convenience to you, but it's a loss for newbies because they'll just
learn that abstraction only. It's also a loss to experienced people because
you're forcing your own opinions on them. I would git ignore that file.

~~~
yakshaving_jgt
There's really nothing wrong with it.

An anti-pattern because beginners won't understand the commands abstracted
over? Come on. When I was a beginner I certainly didn't want to learn all the
quirks of DOM manipulation in JavaScript, and jQuery held my attention long
enough for me to build a career in this industry.

If it's your job to build a product, there's not much ROI on memorising the
docker and docker-compose flags, which often don't match and are chosen quite
arbitrarily.

I _know_ what commands I intend to run when I use NixOps, but it doesn't
matter. I'll still wrap them in easier-to-remember Make tasks. I'll even use
tasks that just delegate to shell scripts. Here's an example from one project
I'm working on:

    
    
      .PHONY: deploy-prod deploy-staging cachix
    
      build:
      	nix-shell -p nodePackages.npm nodejs --run "npm run build"
      	touch src/Settings/StaticFiles.hs
      	nixops modify -d moneygains services.nix aws.nix
      
      deploy-prod: build
      	nixops deploy -d moneygains --include moneygains
      
      deploy-staging: build
      	nixops deploy -d moneygains --include staging
      
      cachix:
      	./cachix.sh
    

> It's also a loss to experienced people because you're forcing your own
> opinions on them

Nobody is _forced_ to use those abstractions…

~~~
maccard
You're replacing arbitrary docker commands with arbitrary make commands,
you're just moving the goalpost really.

> Nobody is forced to use those abstractions…

Oh come on. You know that these scripts become canon, and anyone who deviates
from them and has an error will just be told to use the build scripts. You're
not forced in the same way nobody forced you to use docker, the app just won't
work without it.

~~~
Gigablah
> anyone who deviates from them and has an error will just be told to use the
> build scripts

Good.

It's either:

\- Throw all the commands into the README and force people to copy and paste

\- Throw all the commands into a bash script and re-implement all the command
parsing and prerequisite logic that Makefile syntax provides

\- Be docker / docker-compose CLI tech support

\- Write a Makefile

