PHP: Hypertext PreprocessorPHP 7.1.18 Released (25.5.2018, 00:00 UTC)
The PHP development team announces the immediate availability of PHP 7.1.18. All PHP 7.1 users are encouraged to upgrade to this version. For source downloads of PHP 7.1.18 please visit our downloads page, Windows source and binaries can be found on windows.php.net/download/. The list of changes is recorded in the ChangeLog.
Link
Voices of the ElePHPantInterview with Karen Baker (23.5.2018, 11:30 UTC)

Show Notes

 

This episode is sponsored by Nexcess.

The post Interview with Karen Baker appeared first on Voices of the ElePHPant.

Link
Paul M. JonesAtlas.Query: Simple. Sensible. SQL. (22.5.2018, 12:00 UTC)

I am happy to announce that Atlas.Query is now stable and ready for production
use! Installaton is as easy as composer require atlas/query ~1.0.

With Atlas.Query and any PDO instance, you can build and execute your queries in a single fluent series of method calls:

use Atlas\Query\Select;

$rows = Select::new($pdo)
    ->columns('*')
    ->from('posts')
    ->where('id IN ', $ids)
    ->fetchAll();

foreach ($rows as $row) {
    // ...
}

If you prefer, you can exercise fine control over your PDO connection, use a query factory, or build your queries in smaller steps:

use Atlas\Pdo\Connection;
use Atlas\Query\QueryFactory;

$connection = Connection::new(
    'mysql:host=localhost;dbname=testdb',
    'username',
    'password'
);

$queryFactory = new QueryFactory();

$select = $queryFactory->newSelect($connection);
$select->columns('*');
$select->from('posts');
$select->where('id = ', $id);

$row = $select->fetchOne();

Atlas.Query provides the full power of SQL at your fingertips …

$select
    ->columns(...)
    ->from(...)
    ->join(...)
    ->where(...)
    ->groupBy(...)
    ->having(...)
    ->orderBy(...)
    ->limit(...)
    ->offset(...);

… along with UNIONs, paging, sub-selects, inline value binding, and all sorts of fetch and yield styles.

Atlas.Query comes with INSERT, UPDATE, and DELETE builders as well:

use Atlas\Query\Insert;

$insert = Insert::new($pdo);

// insert a row ...
$insert->into('posts')
    ->columns([
        'title' => $title,
        'body' => $body,
    ])
    ->raw('created_at', 'NOW()')
    ->perform();

// ... and get back the autoincrement value:
$post_id = $insert->getLastInsertId();

Do you work on different project with different datbase backends? Atlas.Query lets you use the same interface for them all, while not restricting you to a common subset of functionality. MySQL, PostgreSQL, SQLite, and SQL Server are all supported explicitly.

And if you discover you need more than just a query system, you’ll have a clear refactoring path towards Atlas.Orm. If you are looking for a modern, stable, easy-to-use query system, try Atlas.Query in your project!


You can read the Reddit commentary on this post here.

Link
Matthias NobackBook review: Fifty quick ideas to improve your tests - Part 2 (22.5.2018, 06:05 UTC)

This article is part 2 of my review of the book "Fifty quick ideas to improve your tests". I'll continue to share some of my personal highlights with you.

Replace multiple steps with a higher-level step

If a test executes multiple tasks in sequence that form a higher-level action, often the language and the concepts used in the test explain the mechanics of test execution rather than the purpose of the test, and in this case the entire block can often be replaced with a single higher-level concept.

When writing a unit test for some complicated object, you may be collecting some data first, then putting that data into value objects, maybe wrapping them in other value objects, before you can finally pass them to the constructor of the value object. At that point you may have to call several methods on the object before it's in the right state. The same goes for acceptance tests. You may need quite a number of steps before you get to the point where you can finally write a 'When' clause.

I find that often the steps leading up to the 'When' clause (or to the 'Act' part of a unit test), can be summarized as one thing. This is meant by the "single higher-level concept". So instead of enumerating everything that has happened to the system, you look for a single step that described what your starting point is. For instance, instead of:

Given the user logged in
  And they have created a purchase order
  And they added product A to it, with a quantity of 10
  And they placed the purchase order
 When the user cancels the purchase order
 Then ...

You could summarize the 'Given' steps as follows:

Given a placed purchase order for product A, with a quantity of 10
 When the user cancels the purchase order
 Then ...

Once you start looking for ways to make things smaller and simpler, easier to follow and read, you'll find that many of the details you previously added to the smaller steps are completely irrelevant for the higher-level step. In our case, the product and the quantity may be completely irrelevant for the scenario that deals with cancelling the purchase order. So the final version may well be:

Given a placed purchase order
 When the user cancels the purchase order
 Then ...

When implementing the step definition for this single, simplified step, you still need to provide sensible default data. But it happens behind the scenes. This technique hides the details that are irrelevant, and only shows the relevant ones to the person reading the scenario. It will be a lot easier to understand what's being tested with this particular scenario.

I find that this approach works really well with unit tests too. One test case may show how a complicated object can be constructed, another test case won't just repeat all those steps, but will summarize it properly (like we did for the above scenario). This often requires the introduction of a private method in the test class, which wraps the individual steps. The method is the abstraction, its name the higher-level concept.

Specification, acceptance tests, living documentation

When creating your artifacts, remember the three roles they must serve at different times: now as a specification, soon as acceptance tests, and later as living documentation. Critique the artifact from each perspective. How well does it serve each distinct role? Is it over-optimised for one role to the detriment of others?

In workshops I often point out that testing is a crucial part of the development workflow. You need it to verify that the unit of code you've been working works as expected. To improve this perspective on writing tests, you could aim for not just verifying correctness of a unit, but specifying it. This implies some kind of test-first approach, where you specify expected behavior. The next level would be to consider the future. What happens when you're done writing this code? Could someone else still understand what's going on? Do you only have technical specifications, or also domain-level specifications?

For unit tests, the danger is that you'll be doing only technical verifications. You may be testing methods, arguments and return values instead of higher-level behaviors. It happens when you're just repeating the logic of the class inside its unit test. You find yourself looking into the box (white box testing), instead of treating the box as an object with proper boundaries.

The best thing you can do is to think hard about

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

Link
SitePoint PHPHow to Fix Magento Login Issues with Cookies and Sessions (21.5.2018, 06:00 UTC)

This article was created in partnership with Ktree. Thank you for supporting the partners who make SitePoint possible.

In this article are looking at how Magento cookies can create issues with the login functionality of both the customer-facing front-end and admin back-end, the reason it occurs and how it should be resolved.

This is also known as the looping issue, as the screen redirects itself to the same screen, even though the username and password is correct.

A script is provided at the end of the article which can help detect a few of the issues. Feel free to use and modify as per your needs.

What is a Cookie?

A cookie is a piece of text that a web server can store on a user's hard drive, and can also later retrieve it. Magento uses cookies in Cart & Backend Admin functionalities, and they may be the source of a few problems when unable to login to Magento.

What is a Session?

A session is an array variable on the server side, which stores information to be used across multiple pages. For example, items added to the cart are typically saved in sessions, and when the user browses the checkout page they are read from the session.

Sessions are identified by a unique ID. Its name changes depemnding on the programming language — in PHP it is called a 'PHP Session ID'. As you might have guessed, the same PHP Session ID needs to be stored as a cookie in the client browser to relate.

Magento's storage of Sessions

Magento can store sessions via multiple session providers and this can be configured in the Magento config file at app/etc/local.xml. These session providers can be chosen here.

File

<session_save><![CDATA[files</session_save>
<session_save_path>
    <![CDATA[/tmp/session
</session_save_path>

Database

Allowing sessions to store themselves in the database is done in /app/etc/local.xml by adding <session_save><![CDATA[db</session_save>.

Magento applications store sessions in the Core\_session table.

Redis

<session_save>db</session_save>
    <redis_session>
             <host>127.0.0.1</host>
        <port>6379</port>
    </redis_session>

MemCache

session_save><![CDATA[memcache</session_save>
<session_save_path>
<![CDATA[tcp://localhost:11211?persistent=1&weight=2&timeout=10&retry_interval=10
</session_save_path>

Magento Usage

Magento uses two different cookies named 'frontend' and 'adminhtml'. The first one is created when any page is browsed. The same cookie is also updated whenever the customer logs in, and the next one is created when a backend user is logged in. You can check whether the cookies have been created by clicking Inspect Element > Application, as in the below picture (from Chrome):

Cookies are configured in Magento via the Configuration admin menu - System > Configuration > General > Web.

Problem: Login Fails & Redirects to Login Page

If you haven't experienced this problem, then you haven't worked with Magento long enough!

This is how it typically happens: when you login by entering your username and password, you will be redirected to the same login page and URL, and your browser is appended with nonce id. This happens for both the customer front-end and the Magento back-end login.

Let's look at a few reasons why this happens, and how we should resolve those issues.

Reason #1: Cookie domain does not match server domain

Let's say your Magento site is example.com and the cookie domain in Magento is configured as xyz.com.

In this scenario both Magento cookies will set Domain Value as xyz.com, but for validating the session Magento will consider the domain through which the site was accessed — in this case example.com. Since it won't be able to find an active ses

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

Link
Nomad PHPPHP-1701-A (18.5.2018, 17:55 UTC)

August - US
Presented By

Adam Culp
August 23, 2018
20:00 CDT

The post PHP-1701-A appeared first on Nomad PHP.

Link
Nomad PHPBuilding Lego Robots with PHP (18.5.2018, 04:02 UTC)

August - EU
Presented By

Christopher Pitt
August 23, 2018
20:00 CEST

The post Building Lego Robots with PHP appeared first on Nomad PHP.

Link
Voices of the ElePHPantInterview with Margaret Staples (15.5.2018, 11:30 UTC) Link
Jordi BoggianoPHP Versions Stats - 2018.1 Edition (15.5.2018, 08:00 UTC)

It's stats o'clock! See 2014, 2015, 2016.1, 2016.2, 2017.1 and 2017.2 for previous similar posts.

A quick note on methodology, because all these stats are imperfect as they just sample some subset of the PHP user base. I look in the packagist.org logs of the last month for Composer installs done by someone. Composer sends the PHP version it is running with in its User-Agent header, so I can use that to see which PHP versions people are using Composer with.

PHP usage statistics May 2018 (+/- diff from November 2017)

All versions Grouped PHP 7.2.4 7.54% PHP 7.1 35.02% (-1.61) PHP 7.1.16 7.41% PHP 7.0 23.02% (-7.74) PHP 7.0.28 5.54% PHP 7.2 20.18% (+20.18) PHP 7.1.15 4.11% PHP 5.6 16.48% (-6.8) PHP 7.2.3 3.85% PHP 5.5 3.50% (-2.61) PHP 7.1.14 3.79% PHP 5.4 1.04% (-0.47)

A few observations: PHP 7.1 is still on top but 7.2 is closing real quick with already 1/5th of users having upgraded. That's the biggest growth rate for a newly released version since I have started collecting those stats. Ubuntu 18.04 LTS ships with 7.2 so this number will likely grow even more in the coming months. 78% of people used PHP 7+ and almost 95% were using a PHP version that is still maintained, it sounds too good to be true. PHP 5.6 and 7.0 will reach end of life by late 2018 though so that's 40% of users who are in need of an upgrade if we want to keep these numbers up!

Here is the aggregate chart covering all my blog posts and the last five years.

PHP requirements in Packages

The second dataset is which versions are required by the PHP packages present on packagist. I only check the require statement in their current master version to see what the latest requirement is, and the dataset only includes packages that had commits in the last year to exclude all EOL'd projects as they don't update their requirements.

PHP Requirements - Recent Master - May 2018 (+/- diff from Recent Master November 2017)

5.21.16% (-0.12) 5.315.9% (-2.85) 5.416.59% (-3.7) 5.515.52% (-3.55) 5.619.57% (-0.83) 7.019.47% (4.62) 7.111.15% (5.83) 7.20.64% (0.61)

This is as usual lagging behind a little but PHP 7 is finally seeing some real adoption in the OSS world which is nice.

Link
Matthias NobackBook review: Fifty quick ideas to improve your tests - Part 1 (15.5.2018, 07:11 UTC)

Review

After reading "Discovery - Explore behaviour using examples" by Gáspár Nagy and Seb Rose, I picked up another book, which I bought a long time ago: "Fifty Quick Ideas to Improve Your Tests" by Gojko Adzic, David Evans, Tom Roden and Nikola Korac. Like with so many books, I find there's often a "right" time for them. When I tried to read this book for the first time, I was totally not interested and soon stopped trying to read it. But ever since Julien Janvier asked me if I knew any good resources on how to write good acceptance test scenarios, I kept looking around for more valuable pointers, and so I revisited this book too. After all, one of the author's of this book - Gojko Adzic - also wrote "Bridging the communication gap - Specification by example and agile acceptance testing", which made a lasting impression on me. If I remember correctly, the latter doesn't have too much practical advice on writing goods tests (or scenarios), and it was my hope that "Fifty quick ideas" would.

First, a few comments on the book, before I'll highlight some parts. I thought it was quite an interesting book, covering several underrepresented areas of testing (including finding out what to test, and how to write good scenarios). The book has relevant suggestions for acceptance testing which are equally applicable to unit testing. I find this quite surprising, since testing books in general offer only suggestions for a specific type of test, leaving a developer/reader (including myself) with the idea that acceptance testing is very different from unit testing, and that it requires both a different approach and a different testing tool. This isn't true at all, and I like how the authors make a point of not making a distinction in this book.

The need to describe why

As a test author you may often feel like you're in a hurry. You've written some code, and now you need to quickly verify that the code you've written actually works. So you create a test file which exercises the production code. Green light proves that everything is okay. Most likely you've tested some methods, verified return values or calls to collaborating objects. Writing tests like that verifies that your code is executable, that it does what you expect from it, but it doesn't describe why the outcomes are the way they are.

In line with our habit of testing things by verifying outputs based on inputs, the PhpStorm IDE offers to generate test methods for selected methods of the Subject-Under-Test (SUT).

Generate test methods

I always cry a bit when I see this, because it implies two things:

  1. I've determined the API (and probably wrote most of the code already) before worrying about testing.
  2. I'm supposed to test my code method-by-method.
  3. A generated name following the template test{NameOfMethodOnSUT}() is fine.

At the risk of shaming you into adopting a test-first approach, please consider how you'll test the code before writing it. Also, aim for the lowest possible number of methods on a class. Make sure the remaining methods are conceptually related. The SOLID principles will give you plenty of advice on this topic.

Anyway, if we're talking about writing tests using some XUnit framework (e.g. JUnit, PHPUnit), don't auto-generate test methods. Instead:

Name the test class {NameOfConcept}Test, and add public methods which, combined, completely describe or specify the concept or thing. I find it very helpful to start these method names with "it", to refer to the thing I'm testing. But this is by no means a strict rule. What's important is that you'll end up with methods you can read out loud to anyone interested (not just other developers, but product owners, domain experts, etc.). You can easily check if you've been successful at it by running PHPUnit with the --testdox flag, which produces this human-readable description of your unit.

Rules and examples

There's much more to it than following this simple recipe though. As the book proposes, every scenario (or unit test case), should first describe some rule, or acceptance criterion. The steps of the test itself should then provide a clear example of the consequences of this rule.

Rules are generic, abstract. The examples are specific, concrete. For instance, a rule could be: "You can't schedule

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

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