Matthew Weier O'PhinneyOn PSR7 and HTTP Headers (28.7.2015, 14:00 UTC)

Yesterday, a question tagged #psr7 on Twitter caught my eye:

#psr7 Request::getHeader($name) return array of single string instead of strings in #Slim3? cc: @codeguy pic.twitter.com/ifA9hCKAPs

@feryardiant (tweet)

The image linked provides the following details:

When I call $request->getHeader('Accept') for example, I was expected that I'll get something like this:


Array(
    [0] => text/html,
    [1] => application/xhtml+xml,
    [2] => application/xml,
)
  

but, in reallity I got this:


Array(
    [0] => text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
)
  

Is it correct?

In this post, I'll explain why the behavior observed is correct, as well as shed a light on a few details of header handling in PSR-7.

Headers in PSR-7

When creating the PSR-7 specification, we had to juggle a fair number of details from the various HTTP specifications. Headers are one area that is particularly difficult, due to the flexibility and ambiguity in the specification.

The root of the ambiguity is that headers are allowed to have multiple values. Headers may have multiple values, but it's up to the specification for any given header.

Additionally how multiple values are represented is up to the given header. The HTTP specifications allow using multiple invocations for the same header:


X-Foo-Bar: baz
X-Foo-Bar: bat

The above would mean that the X-Foo-Bar header has two values, baz and bat. Assuming the header allows multiple values at all; if it doesn't, then it has a single value, and the last representation wins (bat, if you're paying attention).

The other way to represent multiple values is using a separator. The specifications indicate that if you want to have multiple values in the same header line, you should use a comma (,) as a separator. However, you may use any other separator you want. The SetCookie header is a prime example of a header allowing multiple values that uses a completely different separator (semicolon)!

So, to summarize:

  • A header may or may not allow multiple values.
  • Headers may be emitted more than once. If a header allows multiple values, then its value is the aggregate of each representation. If the header only allows one value, the last representation is the canonical value for that header.
  • Headers may use a separator character in a single line in order to separate multiple values. That character is suggested to be a comma, but it can vary per-header.

The other big ambiguity in the specification is that the specification is extensible, and specifically allows for custom headers.

This means that any general-purpose code representing HTTP, such as PSR-7, cannot possibly know the entire ruleset governing all possible HTTP messages, as it cannot know all potential header types, including whether they allow multiple values or not.

With these two facts in mind — headers may have multiple values, and custom headers are allowed — we made the following decisions with PSR-7:

All headers are collections

All headers are assumed to have multiple values. This gives consistency of usage, and puts the onus of knowing the semantics of any given header to the consumer.

For that reason, the most basic access for a given header, getHeader($name), returns an array. That array can have the following values:

  • It can be empty; this means the header was not, or will not be, present in the representation.
  • A single string value.
  • More than one string value.

Naive Concatenation

Since the majority of headers only allow single values, and since most existing libraries that parse headers only accept strings, we provided another method, getHeaderLine($name). This method guarantees return of a string:

  • If the header has no values, the string will be empty.
  • Otherwise, it concatenates the values using a comma.

We chose not to provide an argument indicating the separator to use, as the specifica

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

Link
Rob AllenChecking your code for PSR-2 (28.7.2015, 06:45 UTC)

Most of the projects that I work on follow the PSR-2 coding style guidelines. I prefer to ensure that my PRs pass before Travis or Jenkins tells me, so let's look at how to run PSR-2 checks locally.

PHP_CodeSniffer

My preferred tool for checking coding styles in PHP is PHP_CodeSniffer. This is command line tool, phpcs, that you can run against any file.

PHP_CodeSniffer can test against a number of standards. The default is PEAR, so you must use the command line switch --standard=PSR2 in order for it to check against the right one.

Let's take an example from joind.in's web2 project:

$ phpcs --standard=PSR2 BaseApi.php 

FILE: ...joind.in/joindin-vm/joindin-web2/app/src/Application/BaseApi.php
----------------------------------------------------------------------
FOUND 1 ERROR AFFECTING 1 LINE
----------------------------------------------------------------------
 11 | ERROR | [x] Expected 1 space after closing parenthesis; found 9
----------------------------------------------------------------------
PHPCBF CAN FIX THE 1 MARKED SNIFF VIOLATIONS AUTOMATICALLY
----------------------------------------------------------------------

Time: 70ms; Memory: 6Mb

This is the code that's wrong:

if (isset($config['apiUrl']))
{
    $this->baseApiUrl = $config['apiUrl'];
}

The opening brace is in the wrong place.

If there is a note that PHPCBF can fix some validations automatically, then you can run the phpcbf command line tool to automatically fix your code:

$ phpcbf --standard=PSR2 BaseApi.php 
Changing into directory .../joindin-vm/joindin-web2/app/src/Application
Processing BaseApi.php [PHP => 1452 tokens in 186 lines]... DONE in 52ms (1 fixable violations)
        => Fixing file: 0/1 violations remaining [made 3 passes]... DONE in 163ms
Patched 1 file
Time: 246ms; Memory: 8Mb

And phpcbf has changed the code to be compliant:

if (isset($config['apiUrl'])) {
    $this->baseApiUrl = $config['apiUrl'];
}

Obviously, not all violations can be automatically fixed, but a good number can be.

Automating with Phing

Generally you want to be able to run phpcs across all your source files without too much effort and also get your CI tool to do the same. My preferred choice here is to use Phing.

Each command within a Phing build.xml file is called a target. The PHP_CodeSniffer target for the web2 project is:

<target name="phpcs">
 <phpcodesniffer standard="PSR2"
      description="Run PSR2 standards over the codebase"
      haltonerror="true">
   <fileset dir="${basedir}/app">
     <include name="**/*.php"/>
   </fileset>
   <fileset dir="${basedir}/tests">
     <include name="**/*.php"/>
   </fileset>
   <formatter type="full" usefile="false"/>
 </phpcodesniffer>
</target>

With this target we run phpcs over all PHP files in the `app` and `tests` directories. We run it like this:

$ phing phpcs

As Phing is simply a build tool, the error output is the same format as earlier.

Editor integration

I use Vim and Sublime Text 3, which both have plugins for checking syntax.

Syntastic for Vim

Syntastic is a great plugin for Vim that checks syntax for any language that you can think of. Install it using your preferred method and then for PHP linting and PSR-2 checking set up in your .vimrc like this:

" Syntastic
let g:syntastic_php_checkers=['php', 'phpcs']
let g:syntastic_php_phpcs_args='--standard=PSR2 -n'

You can also add Syntastic summary information to the status line using %{SyntasticStatuslineFlag()}.

The display looks like this (Yes, I like white backgrounds for editing, sorry!):

Syntastic PSR2 checking

When you save the file, Syntactic runs the checkers that you've set up, php -l and phpcs --standard=PSR2 -n in this case and displays any errors with a red S> in the gutter and if you've enabled it, a summary in the status line. When your cursor is on that line, then the error is displayed at the very bottom.

SublimeLinter for Sublime Text 3

The SublimeLinter project does for Sublime Text 3. You need to install "SublimeLinter",

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

Link
Cal EvansPHP South Coast Wrap-up (28.7.2015, 05:00 UTC) Link
PHP ClassesReview: Symfony Certification (28.7.2015, 04:41 UTC)
Symfony Certification
Title
Reviewer
Joseluis Laso
Category
PHP books
Publisher
Leanpub
Author
Raúl Fraile
Summary
Symfony Certification self-study is a well structured book, if can say, following all the subjects proposed by SensioLabs in their official site.

Like the author, I was in the same certification exam, getting so nervous but having a great desire of learning from that experience.

Years later and after having worked intensively in several Symfony2 projects, I still remember how scared I was looking at those questions in front of the very own Fabien Potencier.

Now that I finished this book review, I am looking forward to get my hands dirty and read each of the more than 250 questions and their detailed explanations.

This time I have the goal that I will be able to get the Symfony certification, without doubts, much better prepared when compared with the last time I tried it years ago.
Link
SitePoint PHPSpeeding up Existing Apps with a Redis Cache (27.7.2015, 16:00 UTC)

We’ve gone through the basics of Redis in PHP before, but it’s time to cover a real life use case. In this tutorial, we’ll add it to an already deployed application to give the app the appearance of speed.

Redis Logo

You can easily follow along by cloning the 0.6 release of the app.

The Problem

Before applying a solution, we need to have a clear definition of the problem.

The application in question, when executing a query, runs off to Diffbot’s API and makes it query the dataset. The subset is then returned and displayed. This can take up to 5 or so seconds, depending on the busyness of Diffbot’s servers. While the situation will undoubtedly improve as they expand their computational capacity, it would be nice if a query executed once were remembered and reused for 24 hours, seeing as the collection is only refreshed that often anyway.

“But what good is caching a single query?” you might wonder. It’s not like most people will search for one and the same thing often.

Well… as a matter of fact, not only has research shown that they will often search for one and the same thing (React is trending? Sudden influx of “react” queries), they will also very reliably search for prolific authors (or themselves). Considering the fact that implementing this cache costs us literally nothing (and actually reduces costs by reducing strain on the servers), adding it in is an easy win, even if it weren’t used as often as one would hope. There is no reason not to add it - it can only benefit us.

With the problem clearly defined, let’s handle the prerequisites.

Continue reading %Speeding up Existing Apps with a Redis Cache%

Link
PHP ClassesHow to Render 3D Surfaces in PHP using 2D Contour Plots (27.7.2015, 07:32 UTC)
By Dan Thanh
Contour plots are graphics that render lines that connect points in a geographic region that have the same value, for instance points in a terrain with the same altitude. They are useful for instance to represent 3D features of a terrain in a 2D image.

Read this article to learn more about contour plots and how to render them using the PHP Contour Plot package.
Link
Michelangelo van DamSpeeding up database calls with PDO and iterators (26.7.2015, 14:14 UTC)
Image source: Wikipedia.org
When you review lots of code, you often wonder why things were written the way they were. Especially when making expensive calls to a database, I still see things that could and should be improved.

No framework development

When working with a framework, mostly these database calls are optimized for the developer and abstract the complex logic to improve and optimize the retrieval and usage of data. But then developers need to build something without a framework and end up using the basics of PHP in a sub-optimal way.

$pdo = new \PDO(
$config['db']['dsn'],
$config['db']['username'],
$config['db']['password']
);

$sql = 'SELECT * FROM `gen_contact` ORDER BY `contact_modified` DESC';

$stmt = $pdo->prepare($sql);
$stmt->execute();
$data = $stmt->fetchAll(\PDO::FETCH_OBJ);

echo 'Getting the contacts that changed the last 3 months' . PHP_EOL;
foreach ($data as $row) {
$dt = new \DateTime('2015-04-01 00:00:00');
if ($dt->format('Y-m-d') . '00:00:00' < $row->contact_modified) {
echo sprintf(
'%s (%s)| modified %s',
$row->contact_name,
$row->contact_email,
$row->contact_modified
) . PHP_EOL;
}
}
Above example code is a most common way to retrieve data. At first sight, this code is clean and looks good, but looking more closely you will discover a couple of points to improve.

  • Above code is not reusable, so whenever you need a similar functionality you're stuck with duplicating existing code.
  • Even though you're fetching an object with $stmt->fetchAll(\PDO::FETCH_OBJ); you still face the issue you're using an array of objects which will consume too much memory when fetching lots of data.
  • Filtering is done within the routine, which also means that if you have other filtering conditions you need to modify existing logic, making it hard for maintenance and expanding functionality.

Iterators

Most of the modern frameworks are using Iterators for their data retrieval, because they're fast and reusable. But also they allow other Iterators to filter and modify the retrieved results. Building an application without a framework still gives you the option to use Iterators as they're part of PHP since Version 5.0.0 Beta 2.

So lets assume you continue to use PDO for your data retrieval, we can choose between two options:
  1. Use PDOStatement::fetchAll() to retrieve all data in a single go
  2. Use PDOSTatement::fetch() to retrieve a single row per iteration

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

Link
blog.phpdevCustom Callbacks with Invoke (26.7.2015, 12:59 UTC)

In putting the Invoke library to use I noticed something. While I could tell it to check for groups and permissions on the current user and limit HTTP methods on the request, there were more complex things I needed to check that weren’t part of these defaults. Now, I could just extend invoke to include match types for everything I needed (injecting a custom match class based on my needs) but I wanted something a bit more generic that I could use to call my own logic and return the pass/fail result.

So, I added in the “object.callback” match type that allows you to call a static method in your own code and perform the evaluation yourself. Here’s how it works. Say you have this configuration in your routes.yml file:

/foo:
  protected: on
  callback: \App\MyUser::test

This tells Invoke that when the user requests the /foo URL, the protection should kick in. It then goes into the checks portion of the process. This sees the special callback option and looks the class and method to call. In this case, we’ve told it to try calling the test method \App\MyUser. This class needs to be autoloadable so that Invoke can directly call it and its static method. Yep, that’s right – it needs to be a static method but you’ll be provided with everything about the request in the incoming $data variable. Here’s what the method should look like:

public static function test(\Psecio\Invoke\Data $data)
{
  /* perform your evaluation here and return a boolean */
}

In the $data variable there, you’ll have access to the context of the application via some object properties:

  • user: The current InvokeUser instance (ideally where your user lies too)
  • resource: The resource that was requested (includes access to the requested URI)
  • route: This is the route match from Invoke’s configuration the current request matches. This contains the route regex match, the configuration options and any additional parameters passed along

For example, say you needed to get the parameters from the request to do further evaluation. You could fetch them through $data->resource->getParams() and get the associative array back.

Adding these callbacks makes the Invoke system a lot more flexible and allows you to create those custom match types without having to have whole other classes just to perform your checks.


Link
SitePoint PHPConsole Wars – PHP CLI Libraries (25.7.2015, 16:00 UTC)

I have always been a big fan of console commands and I try to provide a command line interface (CLI) as much as possible in most of my PHP projects. In this article, I’ll briefly compare three PHP console command libraries: The Symfony console component (symfony/Console) The Hoa console (hoa/console) The Webmozart console (webmozart/console) Origin […]

Continue reading %Console Wars – PHP CLI Libraries%

Link
Official Blog of the PEAR Group/PEAR PresidentPEAR 1.10.0dev1 brings PHP 7 compatibility! (25.7.2015, 13:36 UTC)

We’ve released PEAR installer version 1.10.0dev1, which brings support for PHP 7 while dropping support for PHP 4 – 5.3.

See the announcement post @ cweiske.de for more information.

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