Thomas WeinertFluentDOM 6.0 - What's New (24.12.2016, 19:29 UTC)

FluentDOM 6.0 is released.

So a major version jump means that here are backwards compatibility breaks and major new features. File loading has changed to improve security. FluentDOM\Query has got a major overhaul to improve the integration of alternative formats. This affected the interfaces and usage. I tried to keep the breaks to a minimum and easily fixable.

Loading Files

To load a file you will now have to explicitly allow it using the options argument. Here are two options. FluentDOM\Loader\Options::ALLOW_FILE basically restores the previous behaviour. The loader still checks if it is a file or string and will load both. FluentDOM\Loader\Options::IS_FILE means that only a file will be loaded. This has to be implemented into to respective loader. So if you notice that some loader behaves differently, please drop me a note.

All loading functions allow you to provide the option.

$fd = FluentDOM($file, 'xml', [ FluentDOM\Loader\Options::ALLOW_FILE => TRUE ]);
$document = FluentDOM::load($file, 'xml', [ FluentDOM\Loader\Options::IS_FILE => TRUE ]);

Fragment Loading / Query Content Types

Several loaders now support fragment loading. It is used by methods like FluentDOM\\Query::append(). It allows the Query API to keep the content type that you loaded. So if you load HTML, the fragment are expected to be html, if you load XML the fragments are expected to be XML, if you load JSON ... well you get the picture. :-)

$fd = FluentDOM('<form></form>', 'text/html')->find('//form');
$fd->append('<input type="text" name="example">');
echo $fd;

You can change the behaviour by setting the content type. It works with additional loaders, so if you install fluentdom/html5 you get transparent support for HTML5.

$fd = FluentDOM('<form></form>', 'text/html5')->find('//html:form');
$fd->append('<input type="text" name="example">');
echo $fd; 

The changes mean that all existing loaders need to be updated for FluentDOM 6.0.

Serializers

Serializers need to register itself on the FluentDOM class. It allows the FluentDOM\Query objects to output the same content type it loaded. Additionally you can use FluentDOM::getSerializerFactories()->createSerializer(); to get a serializer for a node by content type. I am thinking about adding something like a FluentDOM::save() function as a shortcut for that, but I am not sure about the name and implementation yet. If you have a suggestion please add it to the Issue.

Replace Whole Text

Character nodes (Text nodes and CDATA sections) have a property $wholeText. It returns the text content and the sibling character nodes. It even resolves entity references for that. The property is read only, but DOM Level 3 specifies a method replaceWholeText() as a write method for it. FluentDOM 6.0 implements that method in its extended DOM classes now.

$document = new FluentDOM\Document();
$document->loadXML(
  '<!DOCTYPE p ['."\n".
  '  <!ENTITY t "world">'."\n".
  ']>'."\n".
  '<p>Hello &t;<br/>, Hello &t;</p>'
);
/** @var \FluentDOM\Text $text */
$text = $document->documentElement->firstChild;
$text->replaceWholeText('Hi universe');
echo $document->saveXML();

Examples

The examples directory did grow a little confusing over the years. I restructured and refactored it. Some examples got removed, because the features are shown by newer examples.

What's Next?

I still have to updated some of the plugin repositories (loaders, serializers) and add some more documentation to the wiki. After that I plan to take a look into DOM Level 4. If you have suggestions please add a ticket to the issue tracker

Link
PHP ClassesPHP and JavaScript Innovation Award Report December 2016 Edition - September 2016 nominees (23.12.2016, 15:40 UTC)
By Manuel Lemos
This is the December edition of the Innovation Award podcast hangout recorded by Manuel Lemos and Arturs Sosins to comment on the outstanding features of all the past month nominees and winners PHP and JavaScript packages, the prizes that the authors earned, starting with the nominees from the month of September 2016.

Listen to the podcast, or watch the hangout video to learn why the nominated packages were considered to be innovative, as well the current rankings of the Innovation Award Championship by author and by country.
Link
Nomad PHPDecember 2016 Newsletter (22.12.2016, 17:55 UTC)

Word for the Herd 2016-12 New Beginnings Each new year is a new beginning, a fresh start. A chance to reboot. What will you make of your new beginning? Is there a new skill you want to learn? Is there a new habit you want to start? A project that has been on your “Build …

The post December 2016 Newsletter appeared first on Nomad PHP.

Link
Nomad PHPSessionz (22.12.2016, 17:10 UTC)

Our good friend and recent Nomad PHP speaker, Eric Mann, (Monkeys in the Machine) has recently released his latest PHP project, Sessionz. (You know it’s cool because it ends in a Z) “Sessionz is a middleware-inspired session management stack that works for any PHP application running on PHP 5.6 or better. 2 Like a request …

The post Sessionz appeared first on Nomad PHP.

Link
Paul M. JonesEfficient use of mysqli_result::$num_rows (22.12.2016, 15:35 UTC)

I frequently see this pattern in legacy applications using mysqli:

$result = $mysqli->query("
    SELECT *
    FROM table_name
    WHERE conditions = 'whatever'
");
if ($result && $result->num_rows > 0) {
    return;
}

The developer’s intent here is to see if there are any rows at all in the database that match a certain condition. He does so by issuing a query, then asking the result object how many rows it has. The developer doesn’t actually want any data from the result, and doesn’t care about the actual row-count itself; this is just a check to see if at least one row exists in the database.

This is a poor conservation of resources. The database does the work needed to select all the columns for all the rows matching the conditions, allocates memory for them, and returns them. But the developer discards all that immediately.

To accomplish the same end, it is less resource-intensive and just as effective to query for a single column and limit the results to a single row:

$result = $mysqli->query("
    SELECT col_name
    FROM table_name
    WHERE conditions = 'whatever'
    LIMIT 1
");
if ($result && $result->num_rows > 0) {
    return;
}

Now the database only does the work needed for a single column and a single row.

(As a side note, I find it interesting that I have not seen this pattern at all in projects using PDO. I’m not sure why this would be. Perhaps there is some originating example code for mysqli somewhere that has gained a life of its own through copying and reuse.)

UPDATE: Perhaps a better way to conserve resources, courtesy of Reddit user marcjschmidt, is to use a COUNT() in the query, then fetch the count of rows, something more like this …

$result = $mysqli->query("
    SELECT COUNT(*)
    FROM table_name
    WHERE conditions = 'whatever'
");
if ($result && $result->fetch_array()[0] > 0) {
    return;
}

… thereby avoiding the use of mysqli_result::$num_rows completely.

UPDATE 2: Lots of commentary in the above Reddit thread. To summarize this blog post: selecting all columns of all rows, then examining $num_rows, and then discarding the result set, is a terrible way of determining if there are any matching rows at all in the database. It is trivially easy to something much better, whether by using a LIMIT 1 and $num_rows, or some form of COUNT(), or perhaps some other approach.

Link
Paul M. JonesPHP-PDS: Interview on Voices of the ElePHPant (21.12.2016, 20:46 UTC)

My good friend Cal Evans interviewed me about the PHP-PDS initiative and its first offering, pds/skeleton last week; here it is for you to enjoy.

(Via https://voicesoftheelephpant.com/2016/12/20/interview-paul-m-jones/.)

While we’re here, you might want to check out his virtual user group Nomad PHP, and the series of one-day virtual training conferences at DayCamp4Developers, because you’ll probably learn something useful there.

Link
Nomad PHPPHP 7.1 in 10 Minutes (21.12.2016, 17:04 UTC)

Speaker: Ian Litmann @iansltx PHP 7.1 is hot off the presses. But what’s so different about it? I’ll touch on the highlights, from list-related syntactic sugar to better callables, constant visibility, iterables and more! I’ll also include a few important notes on backward compatibility breaks, so you know how much work it’ll take to upgrade …

The post PHP 7.1 in 10 Minutes appeared first on Nomad PHP.

Link
PHP ClassesHow to Create a PHP Secure Login and Registration System in 2016 with PDO, AJAX with jQuery, Bootstrap and password_hash (21.12.2016, 17:00 UTC)
By Ashraf Gheith
Over time PHP has been adding features that promote the development of secure applications, as well deprecated or removed features that made it easy to write insecure code.

Read this tutorial to learn how to create a modern login and registration system that takes advantage of PHP security-focused features and uses jQuery to send AJAX requests and Bootstrap to provide a fast and nice user interface that can work regardless if you use other frameworks or not.
Link
SitePoint PHPSourceHunt Xmas 2016 – Give the Gift of Open Source Prestige (21.12.2016, 17:00 UTC)

We're at this year's precipice, and it couldn't have been a better one. How about we make it even better for some packages and libraries in dire need of contributors and stars? This Xmas, let's give the gift of open source prestige!

Sourcehunt logo


frickelbruder/kickoff [24 ★]

KickOff is a continuous website monitoring tool.

On single-launch, it'll use a configuration file to check for some common requirements in regards to SEO and performance, like title length, valid redirects, and so on.

The caveat is that such things can only be checked for after a site has already been deployed, so while it is possible to integrate KickOff into your typical continuous deployment pipeline, it'll require some trickery if you want it integrated with zero downtime.

Since it's after-deployment, this means a build failing the KickOff test will go live before errors can be detected to stop it. Since the KickOff command returns the number of errors (apart from generating a JUnit report compatible with PHPUnit's), you can:

  • set up a "test" subdomain for your project, run your test on that, and propagate to production only after KickOff returns 0 errors on the test site
  • create a rollback script in your CD pipeline which returns the page to the previous version if KickOff returns an error number above 0

The former is definitely the more user friendly approach.

KickOff has failed to kick off properly, so we're hoping we'll give it some followers and contributors by mentioning it here - it's definitely an interesting and useful tool.


Continue reading %SourceHunt Xmas 2016 – Give the Gift of Open Source Prestige%

Link
Voices of the ElePHPantInterview with Paul M. Jones (20.12.2016, 19:32 UTC) Link
LinksRSS 0.92   RDF 1.
Atom Feed   100% Popoon
PHP5 powered   PEAR
ButtonsPlanet PHP   Planet PHP
Planet PHP