Matthew Weier O'PhinneyDeployment with Zend Server (Part 4 of 8) (18.9.2014, 13:30 UTC)

This is the fourth in a series of eight posts detailing tips on deploying to Zend Server. The previous post in the series detailed a trick I learned about when to execute a chmod statement during deployment.

Today, I'm sharing a tip about securing your Job Queue job scripts.

Tip 4: Secure your job scripts

In the second tip, I detailed when to register job scripts, but not how to write them. As it turns out, there's one very important facet to consider when writing job scripts: security.

One issue with Job Queue is that jobs are triggered... via the web. This means that they are exposed via the web, which makes them potential attack vectors. However, there's a simple trick to prevent access other than from Job Queue; add this at the top of your job scripts:

if (! ZendJobQueue::getCurrentJobId()) {
    header('HTTP/1.1 403 Forbidden');

While the jobs are invoked via HTTP, Zend Server has ways of tracking whether or not they are being executed in the context of Job Queue, and for which job. If the ZendJobQueue::getCurrentJobId() returns a falsy value, then it was not invoked via Job Queue, and you can exit immediately. I like to set a 403 status in these situations as well, but that's just a personal preference.

Next time...

The next tip in the series is builds on this one, and gives some best practices to follow when writing your job scripts.

Other articles in the series

Matthew Weier O'PhinneyDeployment with Zend Server (Part 6 of 8) (18.9.2014, 13:30 UTC)

This is the sixth in a series of eight posts detailing tips on deploying to Zend Server. The previous post in the series detailed setting job script status codes.

Today, I'm sharing some tips around setting up page caching, and jobs for clearing the Zend Server page cache.

Tip 6: Page caching

Zend Server offers page caching. This can be defined per-application or globally. I typically use global rules, as I most often define server aliases; application-specific rules are based on the primary server name only, which makes it impossible to cache per-hostname.

I define my rules first by setting up my rules using regular expressions. For instance, for my current site, I have this for the host:


This allows me to match with or without the www. prefix.

After that, I define regular expressions for the paths, and ensure that matches take into account the REQUEST_URI (failure to do this will cache the same page for any page matching the regex!).

When I deploy, or when I run specific jobs, I typically want to clear my cache. To do that, I have a Job Queue job, and in that script, I use the page_cache_remove_cached_contents() function defined by the page cache extension in Zend Server.

This function accepts one argument. The documentation says it's a URL, but in actuality you need to provide the pattern from the rule you want to match; it will then clear caches for any pages that match that rule. That means you have to provide the full match -- which will include the scheme, host, port, and path. Note the port -- that absolutely must be present for the match to work, even if it's the default port for the given scheme.

What that means is that in my example above, the argument to page_cache_remove_cached_contents() becomes http://(www\.)?mwop\.net:80/resume. If I allow both HTTP and HTTPS access, then I also will need to explicitly clear https://(www\.)?mwop\.net:443/resume. Note that the regexp escape characters are present, as are any conditional patterns.

My current cache clearing script looks like this:

chdir(__DIR__ . '/../../');

if (! ZendJobQueue::getCurrentJobId()) {
    header('HTTP/1.1 403 Forbidden');

$paths = [

foreach ($paths as $path) {
        'http://(www\.)?mwop\.net:80' . $path


If I wanted to get more granular, I could alter the script to accept rules and URLs to clear via arguments provided by Job Queue; see the Job Queue documentation for information on passing arguments.

I queue this script in my post_activate.php deployment script, but without a schedule:

$queue->createHttpJob($server . '/jobs/clear-cache.php', [], [
    'name' => 'clear-cache',
    'persistent' => false,

This will schedule it to run immediately once activation is complete. I will also queue it from other jobs if what they do should result in flushing the page cache; I use the exact same code when I do so.

Note on cache clearing

The Zend Server PHP API offers another function that would appear to be more relevant and specific: page_cache_remove_cached_contents_by_uri(). This particular function accepts a rule name, and the URI you wish to clear, and, as documented, seems like a nice way to clear the cache for a specific URI as a subset of a rule, without clearing caches for all pages matching the rule. However, as of version 7.0, this functionality does not work properly (in fact, I was unable to find any combination of rule and url that resulted in a cache clear). I recommend using page_cache_remove_cached_contents() only for now, or using full page caching within your framework.

Next time...

The next tip in the series discusses using the Zend Server SDK for deploying your application from the command line.

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

Matthew Weier O'PhinneyDeployment with Zend Server (Part 7 of 8) (18.9.2014, 13:30 UTC)

This is the seventh in a series of eight posts detailing tips on deploying to Zend Server. The previous post in the series detailed setting up and clearing page caching.

Today, I'm sharing how to use the Zend Server SDK to deploy your Zend Server deployment packages (ZPKs) from the command line.

Tip 7: zs-client

Zend Server has an API, which allows you to interact with many admin tasks without needing access to the UI, and in an automated fashion. The API is extensive, and has a very complex argument signing process, which makes it difficult to consume. However, this is largely solved via zs-client, the Zend Server SDK.

The first thing you need to do after downloading it is to create an application target. This simplifies usage of the client for subsequent requests, allowing you to specify --target={target name} instead of having to provide the Zend Server URL, API username, and API token for each call.

This is done using the addTarget command:

$ zs-client.phar addTarget \
> --target={unique target name} \
> --zsurl={URL to your Zend Server instance} \
> --zskey={API username} \
> --zssecret={API token} \
> --http="sslverifypeer=0"

The zsurl is the scheme, host, and port only; don't include the path. You can find keys and tokens on the "Administration > Web API" page of your Zend Server UI, and can even generate new ones there.

Note the last line; Zend Server uses self-signed SSL certificates, which can raise issues with cURL in particular -- which the SDK uses under the hood. Passing --http="sslverifypeer=0" fixes that situation.

Once you've created your target, you need to determine your application identifier. Use the applicationGetStatus command to find it:

$ zs-client.phar applicationGetStatus --target={unique target name}

Look through the list of deployed applications, and find the of the application.

From here, you can now deploy packages using the applicationUpdate command:

$ zs-client.phar applicationUpdate \
> --appId={id} \
> --appPackage={your ZPK} \
> --target={unique target name}

In sum: the Zend Server SDK gives us the tools to automate our deployment.

Next time...

The next tip in the series details automating deployments using zf-deploy and zs-client.

Other articles in the series

Matthew Weier O'PhinneyDeployment with Zend Server (Part 8 of 8) (18.9.2014, 13:30 UTC)

This is the final in a series of eight posts detailing tips on deploying to Zend Server. The previous post in the series detailed using the Zend Server SDK to deploy your Zend Server deployment packages (ZPKs) from the command line.

Today, I'll detail how I automate deployment with zf-deploy and zs-client (the Zend Server SDK), and wrap up the series with some closing thoughts.

Tip 8: Automate

Over the course of the series:

  • I've defined Job Queue scripts for scheduled tasks I want to run.
  • I've defined deployment scripts to automate deployment tasks on the server, including scheduling the above Job Queue scripts, as well as to prep the environment for my application.
  • I'm using zf-deploy to create ZPK packages to push to the server, which contain the above scripts, as well as my deployment configuration.
  • I'm using the Zend Server SDK to deploy our ZPK.

But it's a bunch of manual steps. What if I could automate it?

There are a ton of tools for this sort of thing. I could write a shell script. I could use Phing.

I personally like to use make for this (yeah, I'm a dinosaur). As an example:

PHP ?= $(shell which php)
VERSION ?= $(shell date -u +"%Y.%m.%d.%H.%M")
CONFIGS ?= $(CURDIR)/../site-settings
ZSCLIENT ?= zs-client.phar
ZSTARGET ?= mwop

COMPOSER = $(CURDIR)/composer.phar

.PHONY : all composer zpk deploy clean

all : deploy

composer :
        @echo "Ensuring composer is up-to-date..."
        -$(COMPOSER) self-update
        @echo "[DONE] Ensuring composer is up-to-date..."

zpk : composer
        @echo "Creating zpk..."
        -$(CURDIR)/vendor/bin/zfdeploy.php build mwop-$(VERSION).zpk --configs=$(CONFIGS) --zpkdata=$(CURDIR)/zpk --version=$(VERSION)
        @echo "[DONE] Creating zpk."

deploy : zpk
        @echo "Deploying ZPK..."
        -$(ZSCLIENT) applicationUpdate --appId=20 --appPackage=mwop-$(VERSION).zpk --target=$(ZSTARGET)
        @echo "[DONE] Deploying ZPK."

clean :
        @echo "Cleaning up..."
        -rm -Rf $(CURDIR)/*.zpk
        @echo "[DONE] Cleaning up."

The above ensures my ZPKs have versioned names, allowing me to keep the last few in the working directory for reference; the clean target will remove them for me when I'm ready. Using make also gives me some granularity; if I want to build the ZPK only, so I can inspect it, I can use make zpk.

Of course, if there's any other pre- or post-processing I want to do as part of my build process, I can do that as well. (In my actual script, I do some pre-processing tasks.)

The main takeaway, though, is: automate the steps. This makes it trivial for you to deploy when you want to, and the more trivial you make deployment, the more likely you are to push new changes with confidence.

Closing Thoughts

I've been quite happy with my experiments using Zend Server, and have become quite confident with the various jobs and deployment scripts and jobs I've written. They make deployment trivial, which is something I'm quite happy with. I'm even happier having my site on AWS, as it gives me some options for scaling should I need them later.

With the tricks and tips in this series, hopefully you'll find yourself successfully deploying your applications to Zend Server!

Other articles in the series

PHP: Hypertext PreprocessorPHP 5.5.17 is available (18.9.2014, 00:00 UTC)
The PHP development team announces the immediate availability of PHP 5.5.17. Several bugs were fixed in this release. All PHP 5.5 users are encouraged to upgrade to this version. For source downloads of PHP 5.5.17 please visit our downloads page, Windows binaries can be found on The list of changes is recorded in the ChangeLog.
PHP: Hypertext PreprocessorPHP 5.4.33 Released (18.9.2014, 00:00 UTC)
The PHP development team announces the immediate availability of PHP 5.4.33. 10 bugs were fixed in this release. All PHP 5.4 users are encouraged to upgrade to this version. This release is the last planned release that contains regular bugfixes. All the consequent releases will contain only security-relevant fixes, for the term of one year. PHP 5.4 users that need further bugfixes are encouraged to upgrade to PHP 5.6 or PHP 5.5. For source downloads of PHP 5.4.33 please visit our downloads page, Windows binaries can be found on The list of changes is recorded in the ChangeLog.
Ben RamseyLearning a New Codebase (17.9.2014, 22:30 UTC)

A few days ago, my friend Ed Finkler started a new job. Earlier this week, he posted on Twitter:

First days humble us all.


Having begun a new job myself, I shared Ed’s sentiment. Last weekend, while at the Madison PHP Conference, we were discussing what developers can do during the interview process to get an idea of the kind of codebase a company has. After all, the developer is interviewing potential employers just as much as they are being interviewed as a potential employee. It would suck to be hired only to find the code is in shambles. Short of signing an NDA and asking to see the their code, what can you do?

Here are a few tips I think go a long way in helping determine the state of a company’s codebase. If you have other ideas, feel free to leave them in the comments.

  1. Ask what coding standards the company follows. Can they articulate those standards well? Grill them on specifics. Be sure to ask this of the developers and not the managers. Otherwise, you might not get a good picture of how standards factor into their practices.

    For PHP projects, you should hear something about PSR-2 and PSR-1. If not, then at least the old PEAR coding standards should come up.

  2. Ask whether the company uses a dependency/package management tool. Answers to this question are a good indication of whether the company subscribes to a not invented here (NIH) philosophy. Companies that reuse code from a variety of third-party packages tend to—in my experience—have better structured and cleaner codebases. I’m not sure why this is, but I suspect it’s because the developers have more exposure to how others are doing things and pick up on best practices in this way.

    For PHP projects, you should hear the company talk about their use of Composer. At the very least, they should mention PEAR, but PEAR is waning.

  3. Ask how much of the code is covered by tests. There are unit tests, functional tests, integration tests, and acceptance tests. Maybe there are others that I’m not aware of. Start a conversation about which testing strategies the company uses and how many tests they have.

    For PHP and web projects, there are many different testing tools available. At the least, I would expect to hear a company talk about PHPUnit, but even if they don’t, there are plenty of other unit testing frameworks for PHP, so they may have chosen to use something else. If so, ask why. Questioning a company’s decisions isn’t important, but I think it is enlightening to understand what factors go into their decisions.

  4. Ask to have the company’s deployment process described. As a developer, will you deploy code, or is that handled by different people/teams? Will you be able to push code on your first day or in your first week? The timing isn’t as important as the processes around deploying, though. Try to get a sense for whether it’s a clean and straightforward process versus a haphazard and error-prone catastrophe.

As a follow-up, after you join a company, you are now faced with the daunting task of learning a new codebase. This morning, Ed asked in the #phpmentoring IRC channel on Freenode:

<funkatron> How do you deal with coming in to a huge code base you’re not familiar with?

Here are the two tips I offered from my experiences:

  1. Go through existing bug reports, fixing bugs. This helps you learn the code base, while feeling productive.
  2. Write tests. If they don&rsq

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

SitePoint PHPZgPHP Conference 2014 – Free Entry (17.9.2014, 16:00 UTC)

For almost three years now, there has been a regular and well attended monthly PHP meetup in Zagreb, Croatia. October 2nd 2014 marks the third anniversary of this meetup, and in the spirit of last year, a one-day conference has been organized to commemorate the event.

This year’s conference, however, will be a bit different.

Continue reading %ZgPHP Conference 2014 – Free Entry%

labs @ Qandidate.comThere is a microservice for that (17.9.2014, 13:59 UTC)

At we recently shifted our development process towards building microservices. We’re constantly looking to improve our way of writing software. For example, moving from CRUD applications to event-sourced applications and using Kanban to manage our process. Microservices seem to be the next step.

So far we encountered a number of advantages of working with microservices, and we would like to share our findings with you. Note that we don't run many microservices in our production environment yet. Who knows how we will be developing software in six months!

∞ labs @ Permalink

Qafoo - PHPTesting Micro Services (16.9.2014, 05:21 UTC)
I recently had a short exchange with Ole Michaelis on Twitter about how to end-to-end test micro services. Since I didn't have time to make my whole case, Ole suggested that I blog about this, which I'm happily doing now.The idea behind micro service architecture was discussed by Martin Fowler in a nice to read blog post, so I won't jump on that topic in detail here.
LinksRSS 0.92   RDF 1.
Atom Feed   100% Popoon
PHP5 powered   PEAR
ButtonsPlanet PHP   Planet PHP
Planet PHP