Today DigitalOcean lost our entire server original
This morning I got a mail from the support department of DigitalOcean, which hosts most sites for my company Spatie. (If you're not familiar with DO-speak, "droplet" is just a synonym for "server")
This morning I got a mail from the support department of DigitalOcean, which hosts most sites for my company Spatie. (If you're not familiar with DO-speak, "droplet" is just a synonym for "server")
A few days ago Toon Verwerft gave an uncon talk at PHP Benelux Conference about a new code quality checking tool he has been developing. It's called GrumPHP. It can automatically perform various code quality checks when you try to commit some code.
Sick and tired of defending code quality over and over again? GrumPHP will do it for you! This composer plugin will register some git hooks in your package repository. When somebody commits changes, GrumPHP will run some tests on the committed code. If the tests fail, you won't be able to commit your changes. This handy tool will not only improve your codebase, it will also teach your co-workers to write better code following the best practices you've determined as a team.https://github.com/phpro/grumphp
The slides of Toon's talk can be found on speakerdeck.
Join 9,500+ smart developers
Get my monthly newsletter with what I learn from running Spatie, building Oh Dear, and maintaining 300+ open source packages. Practical takes on Laravel, PHP, and AI that you can actually use.
No spam. Unsubscribe anytime. You can also follow me on X.
"Always fresh, useful tips and articles. Carefully selected community content. My favorite newsletter, which I look forward to every time."
At the PHP Benelux conference James Titcumb did a presentation on the BetterReflection library he's working on. You can view the slides of his presentation on SlideShare.
The BetterReflection library has a few advantages over PHP's native reflection capabilities (copied from the docs):
Consider this class:
class MonkeyPatchMe
{
function getMessage() : string
{
return 'hello everybody';
}
}
The body of the getMessage-function can be replaced using this code:
$classInfo = ReflectionClass::createFromName('MonkeyPatchMe');
$methodInfo = $classInfo->getMethod('getMessage');
$methodInfo->setBody(function() {
return 'bye everybody';
});
$monkeyPatchedClass = new MonkeyPatchMe();
$monkeyPatchedClass->getMessage() // returns 'bye everybody'
Behind the scenes this voodoo works by copying the original class to another file, doing a replacement of the function body there and loading up that class.
I'll be keeping my eye on how the BetterReflection library evolves. You can read all about it's current functionality in the docs on GitHub.
Matthias Noback published the second article in his programming guidelines series. This time he explains why using null in a function isn't a good idea. In my opinion it's great advice that most devs can immediately apply in their projects.
It's certainly a good idea to get rid of the uncertainty and vagueness that null brings to your code. Besides, most of the time when you encounter an actual null value in your program, you probably weren't expecting it. You just call a method on it, thinking that it is an object and PHP will rightfully let your program crash.https://www.ibuildings.nl/blog/2016/01/programming-guidelines-php-developers-part-2-getting-rid-null...
Every particular null situation requires a different solution, but at least I'll list several common solutions for you.
Yesterday our local user group, PHP Antwerp, held it's third meetup. There were two excellent speakers and a bunch of familiar faces.
First up was Gabriel Somoza who talked about his project Baleen. It's goal is to provide an intuitive framework to migrate almost anything. You can view his slides on Speakerdeck.
The second speaker was Marco Pivetta, better known on the interwebs as Ocramius. He is a member of the Doctrine core team. His talk was about best practices when using Doctrine. His slides can be found on GitHub. Here's the video of the talk:
https://youtu.be/j4nS_dGxxs8?t=6m44s
Spatie, of which I'm a partner, sponsored the meetup. Before Marco's talk I got the opportunity to talk a bit myself about why my company is sponsoring the local user group. My short talk can be viewed on YouTube.
The organisers announced that the next meetup will be held at the end of March. If you're living in the vicinity of Antwerp, you should definitely attend.
Jack McDade, who designed the laravel.com and laracasts.com sites, shares some tips on how to make composer and npm much faster.
Whenever I run `composer install` or `npm install` I feel like an old man yelling at young punks to get off my lawn. Especially ever since `npm3`. I’ll save you the bitter diatribe and just get to the solution. But first, the problem.http://jackmcdade.com/blog/tired-of-waitingCreating, distributing, maintaining, and consuming third-party dependencies was supposed to make us more productive and our lives easier. Instead, I feel like I spend more time waiting than coding.
So I dug and dug until I found solutions, as one does, and now I’m sharing them with you.
This Friday the PHP Benelux Conference will kick off. It has an excellent line up and I'll probably blog about the sessions I will see there.
Last year the keynote of the conference was given by Yitzchok Willroth aka Coderabbi. He emphasizes on the power of the community. It was a great talk, I even dare to use the word "inspirational". In the weeks and months after his talk numerous PHP user groups were formed in my home country, Belgium. I believe this was no coincidence.
A few days ago a video of this talk (given at another conference) was published. You can watch it below.
Adam Wathan posted another excellent article on testing on his blog. This time he talks about creating test doubles. Adam demonstrates that creating your own fake can result in a much more readable test than using mocks or spies.
You'll learn to create an InMemoryMailer like this:
public function test_new_users_are_sent_a_welcome_email()
{
$mailer = new InMemoryMailer;
Mail::swap($mailer);
$this->post('register', [
'name' => 'John Doe',
'email' => 'john@example.com',
'password' => 'secret',
]);
$this->assertTrue($mailer->hasMessageFor('john@example.com'));
$this->assertTrue($mailer->hasMessageWithSubject('Welcome to my app!'));
}
That seems like a pretty readable test to me. Read (or view) the whole tutorial here: http://adamwathan.me/2016/01/25/writing-your-own-test-doubles/
I know what you’re thinking. WAT?! Didn’t Gulp just kill Grunt? Why can’t we just be content for a few minutes here in JavaScript land? I hear ya, but… I’ve found Gulp and Grunt to be unnecessary abstractions. npm scripts are plenty powerful and often easier to live with.https://medium.com/@housecor/why-i-left-gulp-and-grunt-for-npm-scripts-3d6853dd22b8
I use Slack for many things and it's great to see how many integrations are available out of the box. But building integrations yourself is extremely easy using Incoming Web Hooks.http://sandrinodimattia.net/posting-successful-ssh-logins-to-slack/Wouldn't it be nice if you could see a message in Slack each time a user connects to one of your machines over SSH? Yes it would!
(I found this via cron.weekly. If you haven't subscribed yet, you're missing out)
Whoops is an error handler framework for PHP. It's easy to integrate into a lot of frameworks, including Laravel 5. I prefer using Whoops over the default Laravel behaviour because Whoops displays the lines of code where the error/exception occurred. The maintainer Dennis Sokolov recently released a new major version which features a new beautiful design.
Marko Lekić explains how he used Blackfire.io to solve a performance problem in one of his long running Laravel console commands.
https://medium.com/@marlek/getting-rid-of-laravel-models-to-improve-performance-of-the-command-blackfire-io-profiling-53884fa6573eThe command worked, but very slowly. We left it working like that for some time until we finished critical stuff in the system and had time to go back and refactor some slow running code.
We ran the command with Blackfire.io and saw some interesting information when we ordered functions by percentage of exclusive time.
Sandi Metz on her blog:
If you find yourself passing parameters and adding conditional paths through shared code, the abstraction is incorrect. It may have been right to begin with, but that day has passed. Once an abstraction is proved wrong the best strategy is to re-introduce duplication and let it show you what's right. Although it occasionally makes sense to accumulate a few conditionals to gain insight into what's going on, you'll suffer less pain if you abandon the wrong abstraction sooner rather than later.http://www.sandimetz.com/blog/2016/1/20/the-wrong-abstraction
Typically my applications have a UI and authentication is done through a simple login page. Obviously for a RESTful API, having a login page isn't ideal. Instead, my hope was to have users append an api_token to the end of their query string and use that to authenticate their request. I was happy to find that 5.2 also ships with a TokenGuardlink class that allows you to do exactly that, but the documentation on getting it to work was a bit thin, so here you go.https://gistlog.co/JacobBennett/090369fbab0b31130b51
Composer really needs no introduction. At this point the PHP community pulled in billions of packages. Here are some Composer options that are not so well known.
You can view the versions of all the packages in your project by running composer show -i. Let's try it out in our Blender Laravel template:
Want to see all the dependencies of the installed packages in a tree? Then run composer show -t:
If you need help using a specific package then you can open it's documentation in a browser using composer. Try running composer home spatie/laravel-fractal to see it in action.
Know some other nice Composer tricks? Let me know in the comments below.
Chris Fidao posted a good tutorial on how to use some lesser known built-in Laravel methods to handle content negotiation.
An HTTP client, such as your browser, or perhaps jQuery's ajax method, can set an `Accept` header as part of an HTTP request.http://fideloper.com/laravel-content-negotiationIt's up to the server to follow the rules of HTTP. When a request comes to our application, it's pretty easy to ignore these rules, as our frameworks generally let us return whatever we want.
Laravel provides a nice, easy way to check if a request "wants json".
Last week Jan Oris gave a talk on creating your own development tools at the Limburg PHP User Group. He touches on the why and how of creating packages as well. I hope some of you will start creating packages too after seeing this.
https://youtu.be/KTdA7kf2cUM?t=1m21s
Homestead is a pre-packaged Vagrant box that includes a good development environment. It was made and is maintained by Taylor Otwell, the creator of Laravel. In this post I'd like to share some tips regarding this box.
folders:
- map: ~/dev/sites
to: /home/vagrant/sites
192.168.10.10 url-to-your-homested-project.com #default ip of the homestead box
You can avoid having to edit the hosts file by using a xip.io-url. Xip.io is a special domain created by Basecamp. The nameserver of that domain will resolve all urls to the ip-address that is specified inside the url. For example: "myproject.192.168.10.10.xip.io" will resolve to 192.168.10.10. If you use such an url in your homestead configuration there's no need to edit your hosts file.
sites
- map: spatie.192.168.10.10.xip.io #no need to put this url in your hosts file
to: /home/vagrant/sites/spatie.be/public
The downside of using a xip.io-url is that such url's are quite long. This can be improved by installing a local dns server. The local dns server will resolve all lookups of a given top level domain to the ip address of the homestead box. Here's a nice article that explains how to resolve all *.dev requests to a specified ip adress.
On OSX these steps can be used to install and configure dnsmasq to point all *.dev requests to homestead.
# Install dnsmasq
brew install dnsmasq
# Copy the default configuration file.
cp $(brew list dnsmasq | grep /dnsmasq.conf.example$) /usr/local/etc/dnsmasq.conf
# Copy the daemon configuration file into place.
sudo cp $(brew list dnsmasq | grep /homebrew.mxcl.dnsmasq.plist$) /Library/LaunchDaemons/
# Start Dnsmasq automatically.
sudo launchctl load /Library/LaunchDaemons/homebrew.mxcl.dnsmasq.plist
echo "address=/dev/192.168.10.10" >> /usr/local/etc/dnsmasq.conf
#restart dnsmaq
sudo launchctl stop homebrew.mxcl.dnsmasq
sudo launchctl start homebrew.mxcl.dnsmasq
#make osx use dnsmasq
sudo mkdir -p /etc/resolver
sudo tee /etc/resolver/dev >/dev/null <<EOF
nameserver 127.0.0.1
EOF
After performing these steps you need to restart your mac. If you know some better way to active dnsmasq besides rebooting, let me know.
When your mac comes back up try pinging a random .dev domain.
With dnsmasq up and running you can .dev domains can be used in the homestead yaml file:
sites
- map: spatie.dev #no need to put this url in your hosts file
to: /home/vagrant/sites/spatie.be/public
function vm() {
cd ~/homestead
command="$1"
if [ "$command" = "edit" ]; then
open ~/.homestead/homestead.yaml
else
if [ -z "$command" ]; then
command="ssh"
fi
eval "vagrant ${command}"
fi
#switch back to directory where command was performed in
cd -
}
When this function is loaded these commands can be executed from every directory.
folders
- map: ~/.dotfiles
to: /home/vagrant/.dotfiles
Syncing the folder is not enough. The steps you need to perform to load the dotfiles on the host machine should be executed in homestead as well. In case of my dotfiles, the minimum that should be done is symlinking the .zshrc-file
ln -s $HOME/.dotfiles/shell/.zshrc $HOME/.zshrc
This is the result when using my dotfiles:
[caption id="attachment_1937" align="alignnone" width="1224"]
My custom zsh promt is visible inside homestead. The "a"-alias (short for "php artisan" is working)[/caption]
Do you have some homestead tips to share? Let me know in the comments below.
Over at Laravel News Mike Bronner wrote some tips on how to achieve an A+ rating for your HTTPS website.
Let’s take a few extra minutes to optimize your server and help it perform faster and be more secure. In this tutorial we will look at using SSL session caching, HTTP Strict Transport Security (HSTS), and Hypertext Transfer Protocol 2 (HTTP/2).https://laravel-news.com/2016/01/optimizing-ssl-laravel-forge/
Matthias Noback, author of "Principles of Package Design", published the first article in a new series on programming best practices on the iBuildings blog. The subject of the first article is reducing complexity.
Inside your method or function bodies, reduce complexity as much as possible. A lower complexity leads to a lower mental burden for anyone who reads the code. Therefore, it will also reduce the number of misunderstandings about how the code works, how it can be modified, or how it should be fixed.https://www.ibuildings.nl/blog/2016/01/programming-guidelines-php-developers-part-1-reducing-complexity