Matthew Weier O'PhinneyRunning cronjobs via an Openswoole timer (21.1.2022, 15:16 UTC)

Sites I build often utilize cronjobs to periodically pull in data from other sources. For example, I might want to poll an API once a day, or scrape content from another website once a month. Cronjobs are a perfect fit for this.

However, cron has a few problems:

  • If the job is writing information into the file tree of your web application, you need to ensure permissions are correct, both at the filesystem level, and when writing the cronjob (e.g., running it as the same user, or changing permissions on completion).
  • If you are running console tooling associated with your PHP application, you may need to worry about whether or not particular environment variables are in scope when you run the job.
  • In containerized environments, usage of cron is strongly discouraged, as it means running another daemon. You can get around this with tools such as the s6-overlay, but it's another vector for issues.

Since most sites I build anymore use mezzio-swoole, I started wondering if I might be able to handle these jobs another way.

Task workers

We introduced integration with Swoole's task workers in version 2 of mezzio-swoole. Task workers run as a separate pool from web workers, and allow web workers to offload heavy processing when the results are not needed for the current request. They act as a form of per-server message queue, and are great for doing things such as sending emails, processing webhook payloads, and more.

The integration in mezzio-swoole allows you to decorate PSR-14 EventDispatcher listeners in mezzio-swoole Mezzio\Swoole\Task\DeferredListener or DeferredServiceListener instances; when that happens, the decorator creates a task with the Swoole server, giving it the actual listener and the event. When the schedule process the task, it then calls the listener with the event.

The upshot is that to create a task, you just dispatch an event from your code. Your code is thus agnostic about the fact that it's being handled asynchronously.

However, because tasks work in a separate pool, this means that the event instances they receive are technically copies and not references; as such, your application code cannot expect the listener to communicate event state back to you. If you choose to use this feature, only use it for fire-and-forget events.

I bring all this up now because I'm going to circle back to it in a bit.

Scheduling jobs

Swoole's answer to scheduling jobs is its timer. With a timer, you can tick: invoke functionality each time a period has elapsed. Timers operate within event loops, which means every server type that Swoole exposes has a tick() method, including the HTTP server.

The obvious answer, then, is to register a tick:

// Intervals are measured in milliseconds.
// The following means "every 3 hours".
$server->tick(1000 * 60 * 60 * 3, $callback);

Now I hit the problems:

  • How do I get access to the server instance?
  • What can I specify as a callback, and how do I get it?

With mezzio-swoole, the time to register this is when the HTTP server starts. Since Swoole only allows one listener per event, mezzio-swoole composes a PSR-14 event dispatcher, and registers with each Swoole HTTP server event. The listeners then trigger events via the PSR-14 event dispatcher, using custom event types internally that provide access to the data originally passed to the Swoole server events. This approach allows the application developer to attach listeners to events and modify how the application works.

To allow these "workflow" events to be separate from the application if desired, we register a Mezzio\Swoole\Event\EventDispatcherInterface service that returns a discrete PSR-14 event dispatcher implementation. I generally alias this to the PSR-14 interface, so I can use the same instance for application events.

I use my own phly/phly-event-dispatcher implementation, which provides a number of different listener providers. The easiest one is Phly\EventDispatcher\AttachableListenerProvider, which defines a single listen() method for attaching a listener to a given event class.

On top of that, Mezzio and Laminas have a concept of delegator factories. These allow you to "decorate" the creation of a service. One us

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

Voices of the ElePHPantInterview with Matthew Setter (18.1.2022, 12:45 UTC)

Listen as host Cal Evans talks to Matthew Setter about his new book “Docker Essentials”. Matthew talks about how his book helps PHP developers grasp the concepts of how to “dockerize” your PHP applications and deploy to production with ease.

This episode is sponsored by
RingCentral Developers

The post Interview with Matthew Setter appeared first on Voices of the ElePHPant.

Derick RethansXdebug Update: December 2021 (11.1.2022, 08:54 UTC)

Xdebug Update: December 2021

In this monthly update I explain what happened with Xdebug development in this past month. These will be published on the first Tuesday after the 5th of each month.

Patreon and GitHub supporters will get it earlier, around the first of each month.

You can become a patron or support me through GitHub Sponsors. I am currently 46% towards my $2,500 per month goal. If you are leading a team or company, then it is also possible to support Xdebug through a subscription.

In December, I worked on Xdebug directly for only about 26 hours, with funding being around 21 hours. Please become a supporter of Xdebug through Patreon or GitHub.

Xdebug 3.1 and further

On the first of the month, I released Xdebug 3.1.2.

It addresses a few crash bugs related to PHP 8.1 fibers, a crash bug when Xdebug can't write a profiler file, and an issue with Xdebug's var_dump() not using the magic __debugInfo method.

The full list of changes can be found on the updates page on the Xdebug website.

Since Xdebug 3.1.2 I have fixed a few more bugs, which are not yet in a released version. One fix pertains to the debugger generating not-well-formed XML, and another one improves performance with long strings in the debugger.

I spend most of my time in December to investigate issues that have not yet been solved. One of them turned to be a change in PHP behaviour between PHP 8.0 and 8.1. In PHP 8.0 and earlier, the $_GLOBALS[] superglobal also had a key GLOBALS, which PHP 8.1 no longer has. PhpStorm was reading values for its watch feature, from the GLOBALS context, but also added the extra (unnecessary) GLOBALS array element to read out the real variables. Fixing this in Xdebug is complex, so hopefully this will be addressed in the next version of PhpStorm itself.

The second issue turned out to be an issue with PHP-FPM, which is not strictly following PHP's processing model. This can cause a discrepancy between PHP-FPM's control and worker processes, where they do not agree what the value of the xdebug.mode INI setting is. Ideally this should get fixed in PHP-FPM, but there are further issues that both PHP-FPM and Xdebug probably need changes for.

Xdebug Cloud

To help with funding my work on Xdebug, I have a paid-for-service, called Xdebug Cloud.

Xdebug Cloud is the Proxy As A Service platform to allow for debugging in more scenarios, where it is hard, or impossible, to have Xdebug make a connection to the IDE. It is continuing to operate as Beta release.

Packages start at £49/month, and revenue will be used to further the development of Xdebug.

If you want to be kept up to date with Xdebug Cloud, please sign up to the mailinglist, which I will use to send out an update not more than once a month.

Xdebug Videos

I did not create any new Xdebug videos this month on my YouTube channel. But I am working on a more thought out set of instructional videos. Stay Tuned!

If you would like to suggest a topic for a 5 to 15 minute long video, feel free to request them through this Google Form.

Business Supporter Scheme and Funding

In December, two new business supporter signed up:

Thank you!

If you, or your company, wou

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

Evert PotHello 2022! (6.1.2022, 04:08 UTC)

Yesterday I received an email from a reader asking ‘Are you ok?’.

It’s been nearly 8 months since the last time I wrote here. In that last post I celebrated blogging on this website for 15 years with some consistency, so perhaps it’s a bit ironic for that to be immediately followed by complete silence.

The last big gap in blogging for me was in 2017, the year I joined Yelp. This experience was so depressing, every day I was done work I had no creative energy left for anything else.

2021 was a bit different though. 2 years back I started a software development agency, which grew from 2 to 5 people in the last year. The stakes have increased quite a bit, and it’s taken up a lot of my emotional reserves.

I’ve also made the mistake of not taking any vacation all year. There was just not much gas left in the tank. This is so stupid. Less time off doesn’t result in more productivity. I know this, but the last 2 years there’s been little travel or activities due to lockdowns and restrictions. Every day looks the same and it kind of just flew by.

Over the last holidays I’ve taken an actual break though, and have since started several new projects and buzzing with new ideas. I’m still motivated to work on Curveball and Ketting (we use it every day for almost every customer!), and I’ve also started a series of live streams in which I build a Time Tracking application with Hypermedia on

If this sounds interesting, the first few episodes are up on my youtube channel, but I’ll share more on this blog later.

I’m also preparing for a tech talk on January 19th for Toronto JS. It’s online and free!

So am I ok? I think I am? This year is off to a good start. I just have to make sure I don’t forget to take it easy.

Happy stupid new year! I hope it sucks less!

Larry GarfieldAdvent of Functional PHP: Review (30.12.2021, 01:10 UTC)
Advent of Functional PHP: Review

Over the last few weeks, I've been following Advent of Code 2021, using Functional PHP as an approach. It's been a fun and educational process, at least for me and apparently for a few other people, at least given how popular the articles have been.

For reference, the full list of articles in this series is here:

Larry 29 December 2021 - 7:10pm
Larry GarfieldAdvent of Functional PHP: Day 10 (25.12.2021, 01:14 UTC)
Advent of Functional PHP: Day 10

For the 10th Day of Advent of Code, we're asked to solve a matching braces problem. This is a common parser exercise, but it's made a bit more complex in this case by using multiple types of braces. Specifically, we're handling a series of lines that contain ( and ), but also < and >, [ and ], and { and }.

The story jazzes it up as being the code of our submarine's navigational computer, which consists entirely of braces in a sort of eldritch horror version of brainfuck, but that's mostly just a distraction.

Larry 24 December 2021 - 7:14pm
Larry GarfieldAdvent of Functional PHP: Day 9 (23.12.2021, 17:21 UTC)

Advent of Functional PHP: Day 9

Submitted by Larry on 23 December 2021 - 11:21am

Day 9 of this year's Advent of Code revolves around grid interpretation. Specifically, we are given a grid of numbers and want to find the low points, that is, the numbers that are smaller than any of their orthogonal neighbors. (We're told to ignore diagonals in part 1.)

After finding the low points, we need to do a bit of math on each one, and add them up. As usual, this last step is mostly just to produce a single verification number at the end. That part is easy as usual, but how do we find the low points?

Continue reading this post on PeakD.

platform.shPHP 8.1 lays new ground on (21.12.2021, 00:00 UTC)
Every year, the PHP foundation releases a new version of PHP that includes updated features for users. These new releases offer a sweet way to kick off every holiday season for developers and application makers (like me). Just days after its official release, we made PHP 8.1 available for all projects on our Grid plans. Now, you can take advantage of the long-awaited PHP 8.1 features on Features that accelerate performance The new PHP 8.
Larry GarfieldAdvent of Functional PHP: Day 8 (20.12.2021, 16:06 UTC)
Advent of Functional PHP: Day 8

Advent of Code Day 8 was, to put it mildly, a pain in the ass. There's a couple of reasons for that. It's a naturally tricky problem, it's hard to genericize, and it's explained fairly badly. It took a while but with some help from others I was finally able to figure out (and refactor to) a good, functional solution to it. So let's dive in.

The problem boils down to one of encryption. Our input is several lines that all look like this:

acedgfb cdfbe gcdfa fbcad dab cefabd cdfgeb eafb cagedb ab | cdfeb fcadb cdfeb cdbaf

Where each letter corresponds to one segment in an LED display for a number. Each number appears once on the left side, which is enough for you to figure out what letter corresponds to what segment. Then we need to use that knowledge to decode the numbers on the right and figure out what the number is.

Larry 20 December 2021 - 10:06am
Voices of the ElePHPantInterview with The PHP Foundation (17.12.2021, 05:15 UTC)

Listen as hosts Cal Evans and Khayrattee Wasseem talk with Sara Golemon, Joe Watkins, and Sebastian Bergmann about the newly formed PHP Foundation.

This episode is sponsored by
RingCentral Developers

The post Interview with The PHP Foundation appeared first on Voices of the ElePHPant.

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