SitePoint PHPHow to Synchronize WordPress Live and Development Databases (31.3.2017, 19:30 UTC)

Developing WordPress themes is considerably easier with real content. Unexpected situations begin to arise when people add pages, posts, media and comments. Your beautiful template can break when:

  • editors use assets which are too big or small for your breakpoints to handle
  • managers introduce a new menu item which doesn't fit at lower screen sizes
  • your theme implements a two-level menu hierarchy which fails to cater for the inevitable third-level page
  • long or deeply-nested comments become unreadable.

Ideally, your development server should have a snapshot of your live production server's database. Your workflow can be improved further if content is automatically synchronized when changes occur.

Synchronization Snags

One-way WordPress database replication can be more challenging than you expect. There are good reasons why few coders live in this development dreamland…

Continue reading %How to Synchronize WordPress Live and Development Databases%

Link
SitePoint PHPProcedurally Generated Game Terrain with ReactJS, PHP, and Websockets (31.3.2017, 16:00 UTC)

Last time, I began telling you the story of how I wanted to make a game. I described how I set up the async PHP server, the Laravel Mix build chain, the ReactJS front-end, and the Web Sockets connecting all this together. Now, let me tell you about what happened when I starting building the game mechanics with this mix of ReactJS, PHP, and Websockets...

The code for this part can be found at: github.com/assertchris-tutorials/sitepoint-making-games/tree/part-2. I've tested it with PHP 7.1 and in a recent version of Google Chrome.

Final image

Making A Farm

"Let's start simple. We have a 10 by 10 grid of tiles, filled with randomly generated stuff."

I decided to represent the farm as a Farm, and each tile as a Patch:

namespace App\Model;

class Farm
{
    private $width
    {
        get { return $this->width; }
    }

    private $height
    {
        get { return $this->height; }
    }

    public function __construct(int $width = 10,
        int $height = 10)
    {
        $this->width = $width;
        $this->height = $height;
    }
}

This is from app/Model/FarmModel.pre

I thought it would be a fun time to try out the class accessors macro by declaring private properties with public getters. For this I had to install pre/class-accessors (via composer require).

I then changed the socket code to allow for new farms to be created on request:

namespace App\Socket;

use Aerys\Request;
use Aerys\Response;
use Aerys\Websocket;
use Aerys\Websocket\Endpoint;
use Aerys\Websocket\Message;
use App\Model\FarmModel;

class GameSocket implements Websocket
{
    private $farms = [];

    public function onData(int $clientId,
        Message $message)
    {
        $body = yield $message;

        if ($body === "new-farm") {
            $farm = new FarmModel();

            $payload = json_encode([
                "farm" => [
                    "width" => $farm->width,
                    "height" => $farm->height,
                ],
            ]);

            yield $this->endpoint->send(
                $payload, $clientId
            );

            $this->farms[$clientId] = $farm;
        }
    }

    public function onClose(int $clientId,
        int $code, string $reason)
    {
        unset($this->connections[$clientId]);
        unset($this->farms[$clientId]);
    }

    // ...
}

This is from app/Socket/GameSocket.pre

I noticed how similar this GameSocket was to the previous one I had; except instead of broadcasting an echo I was checking for new-farm and sending a message back only to the client that had asked.

"Perhaps it's a good time to get less generic with the ReactJS code. I'm going to rename component.jsx to farm.jsx."

import React from "react"

class Farm extends React.Component
{
    componentWillMount()
    {
        this.socket = new WebSocket(
            "ws://127.0.0.1:8080/ws"
        )

        this.socket.addEventListener(
            "message", this.onMessage
        )

        // DEBUG

        this.socket.addEventListener("open", () => {
            this.socket.send("new-farm")
        })
    }
}

export default Farm

This is from assets/js/farm.jsx

In fact, the only other thing I changed was sending new-farm instead of hello world. Everything else was the same. I did have to change the app.jsx code though:

import React from "react"
import ReactDOM from "react-dom"
import Farm from "./farm"

ReactDOM.render(
    <Farm />,
    document.querySelector(".app")
)

This is from assets/js/app.jsx

It was far from where I needed to be, but using these changes I could see the class accessors in action, as well as prototype a kind of request/response pattern for future Web Socket interactions. I opened the console, and saw {"farm":{"width":10,"height":10}}.

"Great!"

Then I created a Patch class to represent

Truncated by Planet PHP, read more at the original (another 4270 bytes)

Link
Matthew Weier O'PhinneyUsing Anonymous Classes to Write Middleware (30.3.2017, 18:20 UTC)

I faced an interesting question recently with regards to middleware: What happens when we go from a convention-based to a contract-based approach when programming?

Convention-based approaches usually allow for duck-typing; with middleware, it means you can write PHP callables — usually closures — and just expect them to work.

Contract-based approaches use interfaces. I think you can see where this is going.

PSR-7 Middleware

When PSR-7 was introduced, a number of middleware microframeworks adopted a common signature for middleware:

use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;

function (
    ServerRequestInterface $request,
    ResponseInterface $response,
    callable $next
) : ResponseInterface

where $next had the following signature:

use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;

function (
    ServerRequestInterface $request,
    ResponseInterface $response
) : ResponseInterface

This approach meant that you could wire middleware using closures, which makes for a nice, succinct, programmatic interface:

// Examples are using zend-stratigility
use Zend\Diactoros\Response\TextResponse;
use Zend\Stratigility\MiddlewarePipe;

$pipeline = new MiddlewarePipe();

$pipeline->pipe(function ($request, $response, callable $next) {
    $response = $next($request, $response);
    return $response->withHeader('X-ClacksOverhead', 'GNU Terry Pratchett');
});

$pipeline->pipe(function ($request, $response, callable $next) {
    return new TextResponse('Hello world!');
});

Easy-peasey!

This convention-based approach was easy to write for, because there was no need to create discrete classes. You could, but it wasn't strictly necessary. Just throw any PHP callable at it, and profit.

(I'll note that some libraries, such as Stratigility, codified at least the middleware via an interface as well, though implementation of the interface was strictly optional.)

The big problem, however, is that it can lead to subtle errors:

  • what happens if you expect more arguments than the middleware dispatcher provides?
  • what happens if you expect different arguments and/or argument types than the middleware dispatcher provides?
  • what happens if your middleware returns something unexpected?

Essentially, a convention-based approach has no type safety, which can lead to a lot of subtle, unexpected, runtime errors.

PSR-15 Middleware

The proposed PSR-15 (HTTP Server Middleware) is not convention-based, and instead proposes two interfaces:

namespace Interop\Http\ServerMiddleware;

use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;

interface MiddlewareInterface
{
    /**
     * Docblock annotations, because PHP 5.6 compatibility
     *
     * @return ResponseInterface
     */
    public function process(ServerRequestInterface $request, DelegateInterface $delegate);
}

interface DelegateInterface
{
    /**
     * Docblock annotations, because PHP 5.6 compatibility
     *
     * @return ResponseInterface
     */
    public function process(ServerRequestInterface $request);
}

This leads to type safety: if you typehint on these interfaces (and, typically, for middleware dispatchers, you're only concerned with the MiddlewareInterface), you know that PHP will have your back with regards to invalid middleware.

However, this also means that for any given middleware, you must create a class!

Well, that makes things more difficult, doesn't it!

Or does it?

Anonymous classes

Starting in PHP 7, we now have the ability to declare anonymous classes. These are similar to closures, which can be thought of as anonymous functions (though with quite a lot more semantics and functionality!), applied at the class level.

Interestingly, anonymous classes in PHP allow for:

  • Extension
  • Interface implementation
  • Trait composition

In other words, they behave just like any standard class declaration.

Let's adapt ou

Truncated by Planet PHP, read more at the original (another 4877 bytes)

Link
SitePoint PHPHow Can I Use Laravel Envoyer or Deployer with SemaphoreCI? (30.3.2017, 16:00 UTC)

Test automation, continuous integration, and continuous delivery are quite widespread in the community now. This brought to life multiple services trying to make the process more enjoyable and less overwhelming for developers, so they can focus on delivering software instead of building/configuring tools to do that. One of those services is SemaphoreCI.

In this article, we're going to cover how to use our own deploy scripts and tools to continue the deployment process after a successful test.

We will be using SemaphoreCI for continuous delivery and Deployer to push our code to the DigitalOcean production server. If you're not familiar with Deployer, we recommend you check out this introduction.

Combination of SemaphoreCI and Deployer logos

Demo Application

We'll be using a 500px application that loads photos from the marketplace. It was built using Laravel and you can read the full article about its building process here, and find the repo on GitHub.

Creating a Deployer Script

The way Deployer works is by us defining servers, and then creating tasks that handle the process of deploying the application to those servers. Our deploy.php script looks like this:

<?php

require_once "recipe/common.php";

set('ssh_type', 'native');
set('default_stage', 'staging');
env('deploy_path', '/var/www');
env('composer_options', 'install --no-dev --prefer-dist --optimize-autoloader --no-progress --no-interaction');
set('copy_dirs', [
    'app/commands',
    'app/config',
    'app/controllers',
    'app/database',
    'app/lang',
    'app/models',
    'app/src',
    'app/start',
    'app/tests',
    'app/views',
    'app/filters.php',
    'app/routes.php',
    'bootstrap',
    'public',
    'composer.json',
    'composer.lock',
    'artisan',
    '.env',
]);

set('shared_dirs', [
    'app/storage/cache',
    'app/storage/logs',
    'app/storage/meta',
    'app/storage/sessions',
    'app/storage/views',
]);
set('writable_dirs', get('shared_dirs'));
set('http_user', 'www-data');

server('digitalocean', '174.138.78.215')
    ->identityFile()
    ->user('root')
    ->stage('staging');

task('deploy:upload', function() {
    $files = get('copy_dirs');
    $releasePath = env('release_path');

    foreach ($files as $file)
    {
        upload($file, "{$releasePath}/{$file}");
    }
});

task('deploy:staging', [
    'deploy:prepare',
    'deploy:release',
    'deploy:upload',
    'deploy:shared',
    'deploy:writable',
    'deploy:symlink',
    'deploy:vendors',
    'current',// print current release number
])->desc('Deploy application to staging.');

after('deploy:staging', 'success');

You should read the Deployer article if you'd like to learn more about what this specific script does. Our next step is to set up a SemaphoreCI project. Please read the crash course article if you've never tried SemaphoreCI before, and do that.

Continue reading %How Can I Use Laravel Envoyer or Deployer with SemaphoreCI?%

Link
SitePoint PHPUpgrading from PThreads v2 to V3: What to Look out For (29.3.2017, 16:00 UTC)

A fair amount has changed for the pthreads extension with the release of pthreads v3. This article aims to cover the necessary information for those who are looking to upgrade their applications from pthreads v2 to v3.

If you're unfamiliar with pthreads, check out my introduction to pthreads instead!

A big thank you to Joe Watkins for proofreading and helping to improve my article!

Abstract image of parallel tracks with superimposed numbers 2 and 3, indicating version change

Generic Changes

There have been a few general changes made in pthreads v3. The first, and perhaps most prominent, is that pthreads cannot be used in any environment other than the command line interface. It was never meant to be used in a web server environment (i.e. in an FCGI process) due to safety and scaling concerns, so the advice from pthreads v2 has now been enforced.

There have also been some changes to workers. Previously, there was a need to keep track of the work objects given to workers, otherwise if they were destroyed before having been executed by the worker thread, a segmentation fault would occur. This was well-known behavior and was demonstrated succinctly in the Multi-Threading in PHP with pthreads gist with the following snippet:

class W extends Worker {
    public function run(){}
}
class S extends Stackable {
    public function run(){}
}
/* 1 */
$w = new W();
/* 2 */
$j = array(
    new S(), new S(), new S()
);
/* 3 */
foreach ($j as $job)
    $w->stack($job);
/* 4 */
$j = array();
$w->start();
$w->shutdown();

This is no longer an issue because the workers themselves now track the stacked work objects.

Furthermore, there have been some changes around the meaning of method modifiers in pthreads v3. In pthreads v2, method modifiers had a special meaning in the context of Threaded objects. Specifically, protected methods had implicit synchronized access (enabling for them to be safely executed by multiple contexts), and private methods could only be executed by the context they were tied to. These differing semantics have now been removed due to reliability concerns.

For example, take the following snippet:

class ExampleThread extends Thread {
    public $value = 0;

    public function run()
    {
        $this->exclusive();
    }

    protected function exclusive()
    {
        for ($i = 0; $i < 10000; ++$i) {
            ++$this->value;
        }
    }
}

class Test extends ExampleThread {
    public function callExclusive()
    {
        $this->exclusive();
    }
};

$thread = new Test();
$thread->start();
$thread->callExclusive();
$thread->join();

var_dump($thread->value);

In pthreads v2, calling the ExampleThread::exclusive method from both the main context and the new thread context was safe. The value output at the end of the script would always be int(20000). But in pthreads v3, this value can be anything from 1 to 20000 due to race conditions between the two unsynchronized for loops.

In order to achieve the exact same behavior in pthreads v3, we must explicitly synchronize access using the built-in Threaded::synchronized method. This need only be applied to the body of the ExampleThread::exclusive method:

protected function exclusive()
{
    $this->synchronized(function () {
        for ($i = 0; $i < 10000; ++$i) {
            ++$this->value;
        }
    });
}

Continue reading %Upgrading from PThreads v2 to V3: What to Look out For%

Link
Christian WeiskeDebugging TYPO3 crawler, or: The tale of many "why?" (29.3.2017, 12:54 UTC)

I spent the last couple of days at work integrating REST API data into the search result list of TYPO3's indexed_search extension. Yesterday I wanted to run a last test on my development machine to see if everything worked as it should and if API data would be indexed correctly. It did not work.

Why didn't it work?

After several hours I found out that the crawler extension did indeed process the page with my special crawling configuration, but stops in the middle.

Why did it stop?

The crawler catches an exception and stops processing. Unfortunately it did not tell anyone about that. The exception was "HTTP/1.1 404 Not Found", from the API connector.

Why did the API connector throw an exception?

Our crawler hook thought it was running on the live (production) system and queried the production API. The new API methods had not yet been deployed to the production API system, and it returned a 404.

Why did crawler think we are on prod?

The docker container has an environment variable TYPO3_CONTEXT=Development, which tells the TYPO3 instance to use the development configuration. That variable was not set.

Why was the environment variable not set?

To make the crawler process run correctly (write access to temporary directories + files), it must be run as the same user that the nginx web server runs under, www-data. I switched to the www-data user as I always do:

$ su - www-data -s /bin/bash

The - resets all environment variables. TYPO3_CONTEXT was thus not set anymore.

After 6 hours, I removed that minus and everything worked as it should.

Link
Nomad PHPThe Power of the Soft Skill (29.3.2017, 09:00 UTC)

Speaker: Kenneth Schabrechts @Agilix_ Speaker: @Agilix_ Every day developers ask themselves what they can do to improve their technical expertise. Which comes to no surprise seeing the nature of this industry. However it is important to focus some of your time on training and learning to use your soft skills. This will help you be …

The post The Power of the Soft Skill appeared first on Nomad PHP.

Link
PHP ClassesBoosting the Visibility of Your PHP Projects with Data Mining and Business Intelligence (28.3.2017, 13:35 UTC)
By Manuel Lemos
If you ever tried to get attention to your Open Source software work but it did not get very far, now you can learn how to fix that.

Thanks to basic data mining techniques on search engine traffic statistics and business intelligence methods, it is possible to help you to optimize the content that you publish to promote your Open Source work beyond the traditional methods of publishing the code in a repository and waiting to see what happens.

Read this article and watch a demo video about search engine optimization tool that is being used to optimize the content of many Open Source projects to leverage the number of interested users.
Link
Voices of the ElePHPantInterveiw with Thomas Gamble (28.3.2017, 10:00 UTC) Link
SitePoint PHPGame Development with ReactJS and PHP: How Compatible Are They? (27.3.2017, 16:00 UTC)

"I'd like to make a multiplayer, economy-based game. Something like Stardew Valley, but with none of the befriending aspects and a player-based economy."

Stardew valley

I started thinking about this the moment I decided to try and build a game using PHP and ReactJS. The trouble is that I knew nothing about the dynamics of multiplayer games, or how to think about and implement player-based economies.

I wasn't even sure that I knew enough about ReactJS to justify using it. I mean, the initial interface – where I focus heavily on the server and economic aspects of the game – is perfectly suited for ReactJS. But what about when I start to make the farming /interaction aspects? I love the idea of building an isometric interface around the economic system.

I once watched a talk, by dead_lugosi, where she described building a medieval game in PHP. Margaret inspired me, and that talk was one of the things that lead to me writing a book about JS game development. I became determined to write about my experience. Perhaps others could learn from my mistakes in this case, too.

The code for this part can be found at: github.com/assertchris-tutorials/sitepoint-making-games/tree/part-1. I've tested it with PHP 7.1 and in a recent version of Google Chrome.

Setting Up The Back-end

The first thing I searched for was guidance on building multiplayer economies. I found an excellent StackOverflow thread in which folks explained various things to think about. I got about half-way through it before realizing I may be starting from the wrong place.

"First things first; I need a PHP server. I'm going to have a bunch of ReactJS clients, so I want something capable of high-concurrency (perhaps even Web Sockets). And it needs to be persistent: things must happen even when players aren't around."

I went to work setting up an async PHP server – to handle high concurrency and support web sockets. I added my recent work with PHP preprocessors to make things cleaner, and made the first couple of endpoints:

$host = new Aerys\Host();
$host->expose("*", 8080);

$host->use($router = Aerys\router());
$host->use($root = Aerys\root(.."/public"));

$web = process .."/routes/web.pre";
$web($router);

$api = process .."/routes/api.pre";
$api($router);

This is from config.pre

I decided to use Aerys for the HTTP and Web Socket portions of the application. This code looked very different compared to the Aerys docs, but that's because I had a good idea about what I needed.

The usual process for running an Aerys app was to use a command like:

vendor/bin/aerys -d -c config.php

That's a lot of code to keep repeating, and didn't handle the fact that I wanted to use PHP preprocessing. I created a loader file:

return Pre\processAndRequire(__DIR__ . "/config.pre");

This is from loader.php

...and installed my dependencies:

"require": {
    "amphp/aerys": "dev-amp_v2",
    "amphp/loop": "dev-master",
    "amphp/parallel": "dev-master",
    "league/container": "^2.2",
    "league/plates": "^3.3",
    "pre/short-closures": "^0.3.0"
},
"require-dev": {
    "phpunit/phpunit": "^6.0"
},

This is from composer.json

I wanted to use amphp/parallel, to move blocking code out of the async server, but it wouldn't install with a stable tag of amphp/aerys. That's why I went with the dev-amp_v2 branch.

Continue reading %Game Development with ReactJS and PHP: How Compatible Are They?%

Link
LinksRSS 0.92   RDF 1.
Atom Feed   100% Popoon
PHP5 powered   PEAR
ButtonsPlanet PHP   Planet PHP
Planet PHP