PHP: Hypertext PreprocessorPHP 7.2.0 Beta 1 Released (20.7.2017, 00:00 UTC)
The PHP development team announces the immediate availability of PHP 7.2.0 Beta 1. This release is the first beta for 7.2.0. All users of PHP are encouraged to test this version carefully, and report any bugs and incompatibilities in the bug tracking system. THIS IS A DEVELOPMENT PREVIEW - DO NOT USE IT IN PRODUCTION!PHP 7.2.0 Beta 1 builds on previous releases with:The much anticipated Sodium extensionOpcache improvementsCountable support for DOMNodeList and DOMNamedNodeMapImproved handling for invalid UTF8 in json_decode()And many bugfixes... For more information on the new features and other changes, you can read the NEWS file, or the UPGRADING file for a complete list of upgrading notes. These files can also be found in the release archive. For source downloads of PHP 7.2.0 Beta 1 please visit the download page, Windows sources and binaries can be found at windows.php.net/qa/. The second beta will be released on the 3rd of August. You can also read the full list of planned releases on our wiki. Thank you for helping us make PHP better.
Link
Federico CargneluttiNode.js: How to mock the imports of an ES6 module (18.7.2017, 21:58 UTC)

The package mock-require is useful if you want to mock require statements in Node.js. It has a simple API that allows you to mock anything, from a single exported function to a standard library. Here’s an example:

app/config.js

function init() {
    // ...
}

module.exports = init;

app/services/content.js

import config from '../../config.js';

function load() {
    // ...
}

module.exports = load;

test/services/content_spec.js

import {assert} from 'chai';
import sinon from 'sinon';
import mockRequire from 'mock-require';

describe('My module', () => {

    let module; // module under test
    let configMock;

    beforeEach(() => {
        configMock = {
            init: sinon.stub().returns("foo")
        };

        // mock es6 import (tip: use the same import path)
        mockRequire("../../config.js", configMock);

        // require es6 module
        module = require("../../../app/services/content.js");
    });

    afterEach(() => {
        // remove all registered mocks
        mockRequire.stopAll();
    });

    describe('Initialisation', () => {

        it('should have an load function', () => {
            assert.isFunction(module.load);
        });

    });

});

Filed under: Node.js, Programming
Link
Paul M. JonesDomain Logic and Email Templates (18.7.2017, 12:00 UTC)

From an email conversation with a reader:

Hi Paul,

I’ve been following your writing and examples about the ADR pattern for some time now. It’s taken me awhile to wrap my head around it but ADR has really added a lot of structure to my code and I’m thankful for your work!

One dilemma that I’ve been struggling with is how to organize emails that are sent out by my service classes. Currently my business logic dictates when to send an email and most of them contain html and text templates. It just feels wrong to include those email templates within the Domain. Do you have any recommendations? Any help you can provide would be greatly appreciated.

In a somewhat related question – Recently I’ve been organizing my “views” folders within the folders of their parents (Http, Mail). I think I based it on your ADR example on github. Do you still prefer this method or do you lean towards organizing within a “resources” folder?

My intuition is that you are right to keep the email templates out of the domain.

In a way, sending an email as part of a web request/response cycle is like sending two responses: the normal HTTP response, and the email response. With that in mind, it might make sense to think of the HTML + Text email templates as part of a presentation layer. Or, as a combination of infrastructure (the email-sending client) plus presentation (the templates). That would be how to think about the separation of concerns there.

Here’s an example of what that separation of concerns might look like in a package directory structure:

resources/
    templates/
        web/
            # web page templates
        email/
            message-1/
                message-1.html
                message-1.txt
            message-2/
                message-2.html
                message-2.txt
src/
    Domain/
        AppService/
            FooAppService.php
            BarAppService.php
        EmailInterface.php
        # ... other domain classes
    Infrastructure/
        DataSource/
            # ... mappers, tables, etc
        Emailer.php # implements Domain\EmailInterface
    Web/
        Foo/
            FooAction.php
            FooResponder.php
        Bar/
            BarAction.php
            BarResponder.php

The specifics of directory structure are not important, as long as you see that the Emailer class is separated from the Domain application services (or use cases, or whatever).

The Emailer class, for its part, might be a facade [1] that coordinates between a “real” emailer (e.g. Swiftmailer or PhpMailer) and a template class, to put together and then send the email. You could configure the Emailer class with the template location (resources/templates/email/*) and inject it into your application service (which depends on the EmailInterface).

Now, sending emails inline as part of the web request might be fine in a lower-traffic situation. But as volume scales up, this kind of separation will make it easy to extract all email-sending to a workers. Then the Emailer can queue emails to the workers instead of sending them inline with the web request; the email-sending can become the job of a queue worker, and the template work will go there instead.

As far as where to put templates for views:

The extended example ADR code on GitHub is a few years old at this point. I still think it’s a reasonable setup, especially for people transitioning out of pseudo-MVC toward ADR, but it might do well to receive an update (or some examples of variations).

I don’t prefer any particular method or structure on where to put templates. Sometimes it makes sense to keep templates near the things using them, sometimes it makes sense to collect them all one place. The needs of the system, and the prior experiences of the developer(s), will be the deciding factor as far as I’m concerned. I had PHP-PDS on the brain when I replied, so the pds/skeleton with its “resources” directory was at hand.


[1] A real facade, not a Laravel one.

Link
thePHP.ccWhy Developers Should Not Code (18.7.2017, 07:00 UTC)
Link
Sammy Kaye Powers04: Debugging failed tests (17.7.2017, 17:26 UTC)

So far we've learned how to create .phpt tests and run them with run-test.php. But what do we do when a test fails? Today we dig in and debug failed tests.

Make a test fail

We started by making our trusty echo_basic.phpt test fail by appending a smile emoticon to the end of the --EXPECT-- section and looked at each of the files that run-tests creates when a test fails.

$ make test TESTS=echo_basic.phpt
$ ls | grep echo
echo_basic.diff
echo_basic.exp
echo_basic.log
echo_basic.out
echo_basic.php
echo_basic.phpt
echo_basic.sh

  • .out The actual output that the PHP code from the --FILE-- section generated
  • .exp The output we expected from the --EXPECT-- section
  • .diff A diff file with the actual output compared to the expected output
  • .log Both actual and expected output in one file
  • .php The --FILE-- section as a PHP file
  • .sh A bash script that runs the PHP file in the same environment that run-tests ran it (more on this later)

Create a more complex example

In order to see the power of the .sh file that gets generated, we created a more complicated test.

$ vi upload_ini_basic.phpt

--TEST--
upload_max_filesize basic test
--INI--
upload_max_filesize=1337M
--FILE--
<?php
$max = ini_get('upload_max_filesize');
echo "Your max upload is {$max}\n";
?>
--EXPECT--
Your max upload is 1337M

If we run it through run-tests, it passes.

$ make test TESTS=upload_ini_basic.phpt

But when we run it as a plain-old PHP file, we see it outputs unexpected output in the --FILE-- section.

$ sapi/cli/php upload_ini_basic.phpt
--TEST--
upload_max_filesize basic test
--INI--
upload_max_filesize=1337M
--FILE--
Your max upload is 2M
--EXPECT--
Your max upload is 1337M

The --FILE-- part outputs "Your max upload is 2M" which is not what we want. So why did it pass in run-tests? Because we added the --INI-- section which run-tests will parse and set any ini settings for us.

Seeing what run-tests sees

Sometime it's handy to see what run-tests sees right in the console so we checked for output options using --help on run-tests.

$ sapi/cli/php run-tests.php --help

We saw that we could use the --show-all flag to output what run-tests sees straight to the console. But since we're running the tests through make, we didn't have a way to pass in the flag.

So we looked at the Makefile and saw that the TESTS variable was just being appended to the end of the command that executes run-tests, so we just added the flag to the TESTS variable.

$ make test TESTS="--show-all upload_ini_basic.phpt"

Doing this we can see that run-tests clearly sees the expected, "Your max upload is 1337M" output in the PHP code.

Running the test as run-tests ran it

We made the test fail by appending another smile face at the end of the --EXPECT-- section and looked at the output files that run-tests generated.

$ make test TESTS=upload_ini_basic.phpt
$ ls | grep upload

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

Link
Sammy Kaye Powers03: All about .phpt files (14.7.2017, 15:50 UTC)

Now that we know how to run the test suite with run-tests, let's create our first .phpt file.

Create a basic test

We started by creating a basic test file that tested that echo could take a list of arguments. We created a new file in the root php-src directory called echo_basic.phpt.

$ vi echo_basic.phpt

--TEST--
echo - basic test for echo language construct
--FILE--
<?php
echo 'This works ', 'and takes args!';
?>
--EXPECT--
This works and takes args!

Then we ran the basic test with make.

$ make test TESTS=echo_basic.phpt

We talked about the section names a bit.

  • --TEST-- A very brief description of the test; if you need more room use the --DESCRIPTION-- section
  • --FILE-- The PHP code we want to test (make sure to include the closing ?>)
  • --EXPECT-- The literal output that the PHP code should generate

Testing non-deterministic output

We learned that --EXPECT-- isn't the best section to use when our test generats non-deterministic output. We created an error test for the filemtime() function to illustrate this. We tried to set the --EXPECTF-- section to the following warning.

Warning: filemtime() expects exactly 1 parameter, 0 given in /usr/src/php-src/filemtime_error.phpt on line 5

But we ran into the problem where the line number and file name in the output would change so we used --EXPECTF-- instead so that we could insert substitution characters.

$ vi filemtime_error.phpt

Note: This contrived example is essentially just testing that ZPP works (which is already very well tested) so this isn't a real-world test you'd want to create.

--TEST--
filemtime() - test error case
--FILE--
<?php
echo filemtime();
?>
--EXPECTF--
Warning: filemtime() expects exactly 1 parameter, 0 given in %s on line %d

Skipping tests

We discovered that there are situations where tests weren't able to run. This issue came up when we tried to create a test for the curl_init() function but we didn't have the curl extension installed. We implemented the --SKIPIF-- section to alleviate this.

$ vi curl_init_basic.phpt

--TEST--
curl_init() - creates a resource
--SKIPIF--
<?php if(!extension_loaded('curl')) die('skip ext/curl required');  ?>
--FILE--
<?php
$ch = curl_init();
var_dump(is_resource($ch));
curl_close($ch

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

Link
SitePoint PHPRe-Introducing Eloquent’s Polymorphic Relationships (14.7.2017, 15:40 UTC)

You've probably used different types of relationships between models or database tables, like those commonly seen in Laravel: one-to-one, one-to-many, many-to-many, and has-many-through. But there's another type of relationship that's not so common: polymorphic. So what is a polymorphic relationship?

A polymorphic relationship is where a model can belong to more than one other model on a single association.

To clarify this, let's create an imaginary situation where we have a Topic and a Post model. Users can leave comments on both topics and posts. Using polymorphic relationships, we can use a single comments table for both of these scenarios. Surprising, yeah? This seems a bit impractical since, ideally, we'd have to create a post_comments table and a topic_comments table to differentiate the comments. With polymorphic relationships, we don't need two tables. Let's look into polymorphic relationships through a practical example.

What We'll Be Building

We'll be creating a demo music app which has songs and albums. In this app, we'll have the option to upvote both songs and albums. Using polymorphic relationships, we'll use a single upvotes table for both of these scenarios. First, let's examine the table structure required to build this relationship:

albums
    id - integer
    name - string

songs
    id - integer
    title - string
    album_id - integer

upvotes
    id - integer
    upvoteable_id - integer
    upvoteable_type - string

Let's talk about the upvoteable_id and upvoteable_type columns which may seem a bit foreign to those who've not used polymorphic relationships before. The upvoteable_id column will contain the ID value of the album or song, while the upvoteable_type column will contain the class name of the owning model. The upvoteable_type column is how the ORM determines which "type" of owning model to return when accessing the upvoteable relation.

Generating the Models Alongside Migrations

I am assuming you already have a Laravel app that's up and running. If not, this premium quick start course might help. Let's start by creating the three models and migrations, then edit the migrations to suit our needs.

php artisan make:model Album -m
php artisan make:model Song -m
php artisan make:model Upvote -m

Note, passing the -m flag when creating models will generate migrations associated with those models as well. Let's tweak the up method in these migrations to get the desired table structure:

{some_timestamp}_create_albums_table.php

public function up()
    {
        Schema::create('albums', function (Blueprint $table) {
           $table->increments('id');
            $table->string('name');
            $table->timestamps();
        });
    }

{some_timestamp}_create_songs_table.php

public function up()
    {
        Schema::create('songs', function (Blueprint $table) {
            $table->increments('id');
            $table->string('title');
            $table->integer('album_id')->unsigned()->index();
            $table->timestamps();

            $table->foreign('album_id')->references('id')->on('album')->onDelete('cascade');
        });
    }

{some_timestamp}_create_upvotes_table.php

public function up()
    {
        Schema::create('upvotes', function (Blueprint $table) {
            $table->increments('id');
            $table->morphs('upvoteable'); // Adds unsigned INTEGER upvoteable_id and STRING upvoteable_type
            $table->timestamps();
        });
    }

We can now run the artisan migrate command to create the three tables:

php artisan migrate

Continue reading %Re-Introducing Eloquent’s Polymorphic Relationships%

Link
Christian WeiskeJsonMapper v1.2.0 (14.7.2017, 06:38 UTC)

Yesterday I released JsonMapper version 1.2.0, adding support for multi-dimensional arrays: int[][][].

One month ago I got a big pull request that added two features and adjust some configuration. After my vacation I had a look at the code and manually split out the configuration changes and the multi-dimensional feature and merged it.

The second feature - correctly resolving class names in docblocks by inspecting use clauses in the files - was too complex for me. I'd rather have that code in a separate library, or rather use a library that implements that.

That was the reason I rejected the second feature. Maybe someone else steps up and makes a clean patch. Thanks to Thomas Hansen anyway.


If you contribute patches, please make one commit per feature. Do not mix multiple features, bug fixes and code style changes. This makes it hard to review and merge them separately.

Link
Ben RamseyAnnouncing PHP TestFest 2017 (13.7.2017, 18:00 UTC)

For those who’ve been around the PHP community for a while, you’ll recall the successful PHP TestFest events that began after a discussion at PHP Quebec in 2008. Many user groups and mentors signed on to host and help with events, and a lot of folks became first-time contributors to the PHP project, helping improve our code coverage. It ran strong in a global sense from 2008 to 2010. After that, various groups (particularly the Brazilian groups) have continued the tradition.

A few months ago, at php[tek] in Atlanta, I mentioned to Michelangelo that I’d love to bring back PHP TestFest. Sammy had given an excellent talk on writing PHPT tests, and Gemma tweeted a link to the old PHP TestFest wiki page. From there, things snowballed.

We’re bringing back PHP TestFest!

The PHP TestFest will run for 4 months this year: September through December. This should give groups plenty of time to plan and prepare one or more local events. In early January, we will award prizes; if your organization/company is interested in offering products or services as prizes, let us know (send email to sponsors@phptestfest.org).

Wooble

This time around, I’ve set up a dedicated website at PHPTestFest.org and Google Group for discussion. We also have the #phptestfest channel on Freenode IRC. All are encouraged to contribute to the website and tools repository. We need technical tutorials, as well as tutorials from veteran TestFest organizers on how to lead successful PHP TestFest events. Additionally, I’ve provided a stub for a console application in the repository, and I’d love to see that evolve into a robust tool for helping people write and contribute PHPT tests.

I’ll be updating the “Getting Started” page on the PHP TestFest website soon with this information and more, so keep posted.

Let’s get to work on improving code coverage of the PHP language!


Special thanks to Sammy for letting us use “Wooble” as a testing mascot.

This announcement was cross-posted to the php-qa, ug-admins, and phptestfest mailing lists.

is a web craftsman, author, and speaker. He is a software architect at ShootProof, where he builds a platform for professional photographers. He enjoys organizing user groups and contributing to open source software. Ben blogs at benramsey.com and is @ramsey on Twitter.

“Announcing PHP TestFest 2017” was originally published at benramsey.com and is Copyright © 2017 Ben Ramsey. It is licensed for use under a Creative Commons Attribution-ShareAlike license.

Link
Sammy Kaye Powers02: Running the test suite (13.7.2017, 17:14 UTC)

Now that we've compiled PHP from source, we need to learn how to run the tests using PHP's black-box testing tool called run-tests.php.

Where the test files live

The test files live in various places throughout the PHP source code.

  • ext/{extension-name}/tests/ Extension tests
  • sapi/{sapi-name}/tests/ SAPI tests
  • Zend/tests/ Zend engine tests
  • tests/ More Zend engine tests

Running a test as plain-old PHP

We looked at the basic test at tests/basic/001.phpt and saw it was a normal PHP file so we ran it with our compiled binary.

$ sapi/cli/php tests/basic/001.phpt

Running the test suite

The two primary ways of running the test suites are 1) directly through run-tests.php and 2) the make target test.

Running run-tests directly

We first invoked the help screen for run-tests.

$ sapi/cli/php run-tests.php --help

The run-tests tool won't run unless we specify the PHP binary that will run the tests. There are three primary ways of specifying a PHP binary.

  1. You can set the environment variable TEST_PHP_EXECUTABLE.
$ export TEST_PHP_EXECUTABLE=`pwd`/sapi/cli/php
$ sapi/cli/php run-tests.php

  1. You can set the -p flag.
$ sapi/cli/php run-tests.php -p `pwd`/sapi/cli/php

  1. You can set the -P flag.
$ sapi/cli/php run-tests.php -P

By default run-tests will run the entire test suite so we specified a single test by passing it as an argument.

$ sapi/cli/php run-tests.php -P tests/basic/001.phpt

You can also specify a directory or list other tests or directories.

$ sapi/cli/php run-tests.php -P tests/basic/ ext/standard/tests/random/

Running run-tests with make

The easiest way to run run-tests is with the make target test.

$ make test

We specify the tests we want to run with TESTS.

$ make test TESTS=ext/standard/tests/random/
$ make test TESTS="ext/standard/tests/random/ ext/standard/tests/password"

Test statuses

After running the tests, run-tests will mark the test as one of the following statuses:

  • Passed The test passed
  • Failed The test failed
  • Borked Invalid test file (this shouldn't happen out of the box)
  • Warned A warning was raised from the --SKIPIF-- section (more on this later)
  • Leaked A memory leak was detected (Valgrind must be enabled with the -m flag)
  • XFailed The test failed, but it was expected to (weird)
  • Slow Test took longer than timeout (defaults to 60 seconds or 300 seconds if testing for memory leaks; timeout can be customized with --set-timeout)

Resources

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

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