Posts tagged with php

Upcoming changes in PHP 7.1

Amo Chohan wrote a rundown of the big changes coming tot PHP 7.1

  • Catching multiple exception types
  • Curl HTTP/2 server push support
  • Support class constant visibility
  • Void return types
  • Generalize support of negative string offsets
  • Allow specifying keys in list() and square bracket syntax for array destructuring
  • Warn about invalid strings in arithmetic
  • Deprecate and remove mcrypt()
https://medium.com/@amo.chohan/upcoming-changes-in-php-7-1-76ebea53b820#.2udxw3qfe

Read more

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.

Short list syntax for array destructuring approved

On dotdev.co Eric L. Barnes explains a new feature that is coming in PHP 7.1

With the accepted proposal it creates an alternative to using “list” for destructuring an array. In all previous versions of PHP this works like this: list($a, $b, $c) = array(1, 2, 3); Now you can extract using a square bracket just as you do for assignment: [$a, $b, $c] = [1, 2, 3]; ["a" => $a, "b" => $b] = ["a" => a, "b", => 2];
https://dotdev.co/php-unanimously-approves-short-list-syntax-for-array-destructuring-887208b661af#.58zwoz85l

Read more

PHP Session Garbage Collection: The unknown performance bottleneck

Here is one performance setting in your PHP configuration you probably haven't thought about much before: How often does PHP perform random garbage collection of outdated session data in your application? Did you know that because of the shared nothing architecture PHP randomly cleans old session data whenever session_start() is called? An operation that is not necessarily cheap.
https://tideways.io/profiler/blog/php-session-garbage-collection-the-unknown-performance-bottleneck

Read more

How to setup and use the Google Calendar API original

by Freek Van der Herten – 4 minute read

For a project I'm working on I needed to interact with a Google Calendar. If you've ever worked with some API's by Google then you know their documentation can be very confusing. It's not that they don't have documentation, but code examples of common use cases are simply not present. You must wade…

Read more

The magic behind Laravel Valet

Mohamed Said peeked behind the curtains and explains on his blog how Laravel Valet works behind the scenes.

The idea behind Valet is that it configures PHP's built-in web server to always run in the background when the operating system starts, then it proxies all requests to a given domain to point to your localhost 127.0.0.1
http://themsaid.github.io/magic-behind-laravel-valet-20160506/

If you want to keep Homestead around for some projects, know that your can also use dnsmasq to point an entire domain to your Homestead installation.

Read more

In Search of an Anonymous Class Factory

Mark Baker tried creating an Anonymous Class Factory.

I was intrigued by a request to find a way of dynamically applying Traits to a class at run-time. With time on my hands as I was sitting in the airport, I considered the problem; and my first thought was to build an Anonymous class, extending the requested class (so that it would still contain all the base properties and functionality, and could be type-hinted, but also applying the requested Trait or set of Traits.

https://markbakeruk.net/2016/05/03/in-search-of-an-anonymous-class-factory/

Read more

Route model binding using middleware

Our team is currently working on a Spark app. Spark makes is real easy to add an API that can be consumed by the users of the app. The generation of API tokens and authentication middleware comes out of the box. It all works really great.

In our API the a team owner can fetch information on every member on the team and himself. The url to fetch info of a user looks something like this: /users/<id-of-user>. Nothing too special. But we also want to make fetching a user's own information as easy as possible. Sure, the user could look op his own userid and then call the aforementioned url, but using something like /users/me is much nicer. In this way the user doesn't have to look op his own id. Let's make that possible.

In our app we use these functions to get the the current user and team:

/**
 * @return \App\Models\User|null
 */
function currentUser()
{
    return request()->user();
}

/**
 * @return \App\Models\Team|null
 */
function currentTeam()
{
    if (!request()->user()) {
        return;
    }

    return request()->user()->currentTeam();
}

The route look something to get the user data looks something like this:

Route::post('/users/{userId}', 'UserController@show');

My first stab to get /users/me working was to leverage route model binding. In the RouteServiceProvider I put this code:

$router->bind('userId', function ($userId) {
   if ($userId === "me") {
      return currentUser();
   }

   $user = currentTeam()->users->where('id', $userId)->first();

   abort_unless($user, 404, "There's no user on your team with id `{$id}`");

   return $user;
});

Unfortunately this does not work. When Laravel is binding route parameters the authentication has not started up yet. At this point currentUser and currentTeam will always return null.

Middleware comes to the rescue. Route-middleware is processed at a moment when authentication has started up. To make /users/me work this middleware can be used:

namespace App\Http\Middleware;

use Closure;

class BindRouteParameters
{
    public function handle($request, Closure $next)
    {
        if ($request->route()->hasParameter('userId')) {
            $id = $request->route()->parameter('userId');

            $user = $this->getUser($id);

            abort_unless($user, 404, "There's no user on your team with id `{$id}`");

            $request->route()->setParameter('userId', $user);
        }

        return $next($request);
    }

    public function getUser(string $id)
    {
        if ($id === 'me') {
            return currentUser();
        }

        return currentTeam()->users->where('id', $id)->first();
    }
}

There are two things you must do to use this middleware. First: it's route middleware so you such register it as such at the http-kernel.

// app/Http/Kernel.php

...
/**
 * The application's route middleware.
 *
 * These middleware may be assigned to groups or used individually.
 *
 * @var array
 */
protected $routeMiddleware = [
...
'bindRouteParameters' => \App\Http\Middleware\BindRouteParameters::class,
]

Second: you must apply the middleware to certain routes. In a default Spark app you'll find all api-routes in a file at app/Http/api.php. That file starts with this line:

Route::group(['prefix' => 'api', 'middleware' => ['auth:api']], function () {
...

Just add the bindRouteParameters middleware to the group:

Route::group(['prefix' => 'api', 'middleware' => ['auth:api', 'bindRouteParameters']], function () {
...

I'm currently using the above solution in my app. You could make a solution that's more generic by checking if the parameters ends with orMe. Here's an example how that might work:

namespace App\Http\Middleware;

use Closure;

class BindCurrentUserRouteParameter
{
    public function handle($request, Closure $next)
    {
        collect($request->route()->parameters())
            ->each(function ($value, $parameterName) use ($request) {
                if (!ends_with($parameterName, 'orMe')) {
                    return;
                }

                if ($value === 'me') {
                    $request->route()->setParameter($parameterName, currentUser());
                }
            });

        return $next($request);
    }

If you have any questions about this approach or have any ideas how to make it better, let me know in the comments below.

Read more

Don't use illuminate/support in framework agnostic packages

In our framework agnostic packages we sometimes pull in illuminate/support. This package that's part of the core of Laravel provides some nice string and collection functions. But unfortunately a lot of other stuff gets pulled in as well. In a post on his blog Matthew Allen explains the downsides of requiring illuminate/support.

A lot of framework agnostic Composer packages (PHP) pull in illuminate/support, which contains helper functions and general purpose code used by the Laravel framework. Usually it’s because the support package has nice helper functions like array_get, or because of the nice collection class.

The helpers functions are nice, but I don’t think developers appreciate the ramifications of choosing to pull that package in. Everyone is afraid to get criticized for reinventing the wheel, so packages are pulling in 6000+ lines of code to avoid writing isset($arr[$k]) ? $arr[$k] : null themselves.

http://mattallan.org/2016/dont-use-illuminate-support/

One of the most useful functions of illuminate/support is the Collection class. In a thread on Reddit Taylor Otwell, the creator of Laravel, seems to agree that requiring illuminate/support isn't a good idea and that the Collection class could be extracted to it's own package. Let's hope that'll happen in the near future.

In the new major versions of our framework agnostic packages we'll swap out illuminate/support in favor of packages like the ones mentioned at the end of Matthew's post.

EDIT: Meanwhile Tighten has released a Collections-only split from Laravel's Illuminate Support.

Read more

Using Github authentication for login with Laravel Socialite

Laravel hero Matt Stauffer has a new article on his blog where he talks about using a social network site login as the primary login for your application.

Laravel's Socialite package makes it simple to authenticate your users to Facebook, Twitter, Google, LinkedIn, GitHub and Bitbucket. You can authenticate them for the purpose of connecting their pre-existing user account to a third-party service, but you can also use it as your primary login mechanism, which we'll be talking about here.

I'm working on a new little micro-SaaS that is purely dependent on GitHub in order to operate, so there's no reason to set up any user flow other than just GitHub. Let's do it.

https://mattstauffer.co/blog/using-github-authentication-for-login-with-laravel-socialite

Read more

Cleaning Up Form Input with Transpose

Adam Wathan has another excellent article on using collections. This time he tackles the less used transpose-function.

Transpose is an often overlooked list operation that I first noticed in Ruby.

The goal of transpose is to rotate a multidimensional array, turning the rows into columns and the columns into rows.

http://adamwathan.me/2016/04/06/cleaning-up-form-input-with-transpose/

Personally, I can't wait until the release of his book: Refactoring To Collections.

Read more

Easily integrate MailChimp in Laravel 5 original

by Freek Van der Herten – 2 minute read

Today we released a new major version of our laravel-newsletter package. This package makes it easy to integrate MailChimp in your Laravel app. Under the hood V3 of the MailChimp API is used. If you're used the older version of our package be sure to upgrade by the end of this year: MailChimp will…

Read more

Common files in PHP packages

Jordi Boggiano researched which files are common in PHP packages.

I queried GitHub's API for the file listing (only the root directory) of all PHP packages listed on packagist.org.

What this let me do is look at what files are commonly present (and not), which is quite interesting to get a picture of the whole ecosystem.

In total, this includes file listings from 78'992 packages (no GitHub API was harmed in the making of this blog post though). And here are a few interesting things that surfaced:

https://seld.be/notes/common-files-in-php-packages

Read more

Concurrent HTTP requests without opening too many connections

Hannes Van De Vreken shows what awesome async things you can do with Guzzle promises.

Now what happens if you need to perform a large number of concurrent requests? If you don’t control the number of requests you might end up with a dangerously large amount of open TCP sockets to a server. You’ll need to use some sort of dispatching to have a limited number of concurrent requests at any given time.

Let’s show you how to do that.

https://blog.madewithlove.be/post/concurrent-http-requests/

Read more

Dissecting a spammer’s spam script

Let’s take a look at a PHP script used to send spam. These types of scripts run on servers all over the world and might give you some insight into a spammer’s dedication to annoy the hell out of you. ... One of the WordPress sites on a shared hosting web server I manage was infected by a spam script. Fortunately, the script was unable to do any real damage and was detected within half an hour of infection. I thought it would be fun to show you the script and dissect it, to find out exactly how these things work and make thousands of email administrators’ lives a living hell.
https://jelleraaijmakers.nl/2016/04/dissecting-spammers-spam-script

Read more

Upgrading PHP 5.6 to 7.0 on a Forge provisioned server

If you've read some posts before on this blog, then you'll probably know that I'm a big fan of Forge. The service makes it very easy to set up and administer servers. At my company we've been using it since it launched.

We currently have 80 provisioned servers. Most of them are small droplets. We have a policy of running every site on it's own droplet. This approach has many benefits, but that's maybe something for a future post.

The bulk of our servers are on PHP 5.6. That's not too bad, but once you have some sites on PHP 7, the sites running on those servers feel a bit slow. It's amazing how fast you get used to the speed that PHP 7 offers. That's why I experimented a bit with upgrading the PHP version on a Forge provisioned server. My gut feeling was that upgrading the PHP version is less work that setting up a new server and moving a site to it.

To not mess up a live site I created a snapshot and used that to set up a server to toy around with. With a little bit of research I came up with these instructions to upgrade the PHP version.

sudo add-apt-repository ppa:ondrej/php

sudo apt-get update

sudo apt-get install php7.0

sudo apt-get install php7.0-fpm

Depending on your project you will need less or more php extensions, but these were the ones relevant for my site:

sudo apt-get install php7.0-gd

sudo apt-get install php7.0-mysql

sudo apt-get install php-memcached

sudo apt-get install php7.0-mcrypt

sudo apt-get install php-curl

sudo apt-get install php-imagick

Next, in the nginx configuration of the site I replaced unix:/var/run/php5-fpm.sock with unix:/var/run/php/php7.0-fpm.sock

The final adjustment I made was to make sure nginx would spawn the php processes under the forge. This will make sure that a php process can write to sites previously created by Forge:

// in the file /etc/php/7.0/fpm/pool.d/www.conf
...
user = forge
group = forge
...

After that I rebooted the server (maybe just restarting nginx is enough) and enjoyed browsing a site that was four times as fast. ?

If you decide to try this out for your server, be aware that what works for me doesn't necessarily work for you. Every site is a bit different. But I'm sure the instructions from this post will get you pretty far. Happy upgrading!

EDIT: Meanwhile DigitalOcean also published a guide on how to upgrade to PHP 7.

Read more

A great evening at PHPGent

Yesterday, after a winter sleep, PHPGent awoke and held a meetup at the offices of In The Pocket. It was nice to see some familiar and some new faces.

I had the honor of being the first speaker. My talk was titled "Backing up with Laravel". I started off with some best practices regarding backups and demonstrated the laravel-backup package which was released a few weeks ago.

Here are my slides:

https://speakerdeck.com/freekmurze/backing-up-with-laravel

phpgent_2016-Apr-14

Next up was Wouter Sioen of SumoCoders. He talked about building maintainable software. He showed how using the solid principles help to clean up the code of his home brew json to html converter. Then he continued with explaining object calisthenics: a few simple rules to greatly improve the readability of your code. Wouter's slides can found on github.io.

wouter

These two very beautiful graphic summaries of the talks were made by Peter Decuyper:

https://twitter.com/sgrame/status/720674134041235456

https://twitter.com/sgrame/status/720690758265778176

If you attended the meetup be sure to leave Wouter and me some feedback on joind.in so we can improve our speaking skills.

Visiting your local PHP user group is one of the best ways to learn new stuff and to getting to know the community. If you've never visited a user group, use this site to lookup the closest one to your home. If there isn't one close by, start one yourself.

Screen Shot 2016-04-14 at 23.43.52

Read more

Laravel medialibrary hits v4 original

by Freek Van der Herten – 2 minute read

Today we tagged a new major version of laravel-medialibrary. In case you're not familiar with this package here's a quick rundown of what it can do. The package can associate all sorts of files with Eloquent models. It provides a simple, fluent API to work with. Here's a quick example: $newsItem =…

Read more