PHP Community

Cursors and the Aggregation Framework

Derick Rethans - Wed, 09/04/2014 - 10:29
Cursors and the Aggregation Framework

With MongoDB 2.6 released, the PHP driver for MongoDB has also seen many updates to support the features in the new MongoDB release. In this series of articles, I will illustrate some of those.

In this article, I will introduce command cursors and demonstrate how they can be applied to aggregations. I previously wrote about the Aggregation Framework last year, but since then it has received a lot of updates and improvements. One of those improvements relates to how the Aggregation Framework (A/F) returns results. Before MongoDB 2.6, the A/F could only return one document, with all the results stored under the results key:

<?php
$m = new MongoClient;
$c = $m->demo->cities;

$pipeline = [
     [ '$group' => [
          '_id' => '$country_code',
          'timezones' => [ '$addToSet' => '$timezone' ]
     ] ],
     [ '$sort' => [ '_id' => 1 ] ],
];

$r = $c->aggregate( $pipeline );
var_dump( $r['result'] );
?>

This code would output something like:

array(242) {
  [0] =>
  array(2) {
     '_id' => string(2) "AD"
     'timezones' => array(1) { [0] => string(14) "Europe/Andorra" }
  }
  [1] =>
  array(2) {
     '_id' => string(2) "AE"
     'timezones' => array(1) { [0] => string(10) "Asia/Dubai" }
  }
  [2] =>
  array(2) {
     '_id' => string(2) "AF"
     'timezones' => array(1) { [0] => string(10) "Asia/Kabul" }
  }
  …

MongoCollection::aggregate() is implemented under the hood as a database command. The method in the PHP driver merely wraps this, but you can also call A/F through the MongoDB::command() method:

<?php
$m = new MongoClient;
$d = $m->demo;

$pipeline = [
     [ '$group' => [
          '_id' => '$country_code',
          'timezones' => [ '$addToSet' => '$timezone' ]
     ] ],
     [ '$sort' => [ '_id' => 1 ] ],
];

$r = $d->command( [
     'aggregate' => 'cities',
     'pipeline' => $pipeline,
] );
var_dump( $r['result'] );
?>

Because a database command only returns one document, the result is limited to a maximum of 16MB. This is not a problem for my example, but it can can certainly be a limiting factor for other A/F queries.

MongoDB 2.6 adds support for returning a cursor for an aggregation command. With the raw command interface, you simply add the extra cursor element:

$r = $d->command( [
     'aggregate' => 'cities',
     'pipeline' => $pipeline,
     'cursor' => [ 'batchSize' => 1 ],
] );
var_dump( $r );

Instead of a document with all results inline, you get a cursor definition back:

array(2) {
  'cursor' =>
  array(3) {
     'id' => class MongoInt64#5 (1) {
          public $value => string(12) "392201189815"
     }
     'ns' => string(11) "demo.cities"
     'firstBatch' => array(1) {
       [0] =>
       array(2) {
          '_id' => string(2) "AD"
          'timezones' => array(1) { [0] => string(14) "Europe/Andorra" }
       }
     }
  }
  'ok' => double(1)
}

The cursor definition contains the cursor ID (in id), the namespace (ns), and whether the command succeeded (in ok). The definition also a portion of the results. The number of items in firstBatch is configured by the value given to batchSize in the command.

To create a cursor that you can iterate over in PHP, you need to convert this cursor definition to a MongoCommandCursor object. You can do that with the MongoCommandCursor::createFromDocument() factory method. This factory method takes three arguments: the MongoClient object ($m in my example), the connection hash, and the cursor definition that was returned. The hash is required so that we can fetch new results from the same connection that executed the original command.

To obtain the connection hash, we need to include a by-ref variable as the third argument to MongoCollection::command():

<?php
$m = new MongoClient;
$d = $m->demo;

$pipeline = [
     [ '$group' => [
          '_id' => '$country_code',
          'timezones' => [ '$addToSet' => '$timezone' ]
     ] ],
     [ '$sort' => [ '_id' => 1 ] ],
];

$r = $d->command(
     [
          'aggregate' => 'cities',
          'pipeline' => $pipeline,
          'cursor' => [ 'batchSize' => 1 ],
     ],
     null,
     $hash
);
var_dump( $hash );

The hash looks like localhost:27017;-;.;26415. Together with the result, you can now construct a MongoCommandCursor:

$cursor = MongoCommandCursor::createFromDocument( $m, $hash, $r );

And iterate over it:

foreach ( $cursor as $result )
{
     echo $result['_id'], ': ', join( ', ', $result['timezones'] ), "\n";
}
?>

As this is all a bit cumbersome, we have also added a helper method for this: MongoCollection::aggregateCursor. This internally does the whole MongoCommandCursor creation dance, and simplifies the previous example to:

<?php
$m = new MongoClient;
$c = $m->demo->cities;

$pipeline = [
     [ '$group' => [
          '_id' => '$country_code',
          'timezones' => [ '$addToSet' => '$timezone' ]
     ] ],
     [ '$sort' => [ '_id' => 1 ] ],
];

$r = $c->aggregateCursor( $pipeline );

foreach ( $r as $result )
{
     echo $result['_id'], ': ', join( ', ', $result['timezones'] ), "\n";
}
?>

This helper also automatically sets the initial batch size to 101. You can change the batchSize for subsequent batches by using the MongoCommandCursor::batchSize() method, and for the initial batch by specifying an option to MongoCollection::aggregateCursor:

$options = [ 'cursor' => [ 'batchSize' => 5 ] ];

$r = $d->cities->aggregateCursor( $pipeline, $options );
$r->batchSize( 25 );

In general, you probably should not change the default batch sizes.

The Aggregation Framework has some other new features in MongoDB 2.6 as well. Please refer to the release notes for more information. I might write another post on some of those features later, too.

Categories: Open Source, PHP Community

My HHVM talk slides from yesterday's Webtuesday

Planet-PHP - Wed, 09/04/2014 - 08:39

Yesterday I gave a talk about HHVM and Hack at the monthly webtuesday here in Zurich. The slides can be found here

It was a great evening, thanks to Netcetera for hosting it, thanks to Joel and the webtuesday crew for organizing it and also thanks to Johannes for chiming in when we talked about PHP internals.

If you have any question abut HHVM or related things, just ask in the comments, contact me on twitter or meet me personally, if you're nearby (aka in Switzerland).

Categories: Open Source, PHP Community

Three Great New Speakers!

Planet-PHP - Wed, 09/04/2014 - 02:24

This summer’s Crafting Code Tour is coming together, and we have confirmed three speakers to come along to various locations!

We are proud to announce that Adam Culp will be joining the tour for stops in Tampa Bay, Atlanta and Nashville. Adam will be speaking on Refactoring 101, offering up his wisdom on how to refactor legacy applications.

Paul M. Jones will be joining the tour for Dallas, Austin, Oklahoma and Kansas City, speaking about code modernization, a great talk that he’s given at numerous conferences in the past year.

And Larry Garfield will join the tour for Minneapolis, Milwaukee and Cincinnati. He’ll be doing a reprise of his SunshinePHP keynote, so if you missed it, don’t miss it on these stops!

Plus, we are pleased to announce that Mandrill will be providing pizza for all the tour stops.

Categories: Open Source, PHP Community

Mastering Zend Framework: Building and Executing SQL Queries In Zend

PHPDeveloper.org - Tue, 08/04/2014 - 19:18

The Mastering Zend Framework site (from Matthew Setter) has a new post today showing you how to execute SQL queries directly in a Zend Framework v2 application.

Whilst there are many ways for building and executing SQL queries in Zend Framework 2, the two that I usually use, and which are also used in the ZF2 manual, are closures and the selectWith function. I previously wrote a three part series, showing how to get started using the ZendDbSql classes with Zend Framework 2, but I didn't cover how to actually run them. So in today's tutorial, let's do that.

He gives examples of these two methods starting with closures in a "tableGateway" select call. He shows how to add on parts of the query like "wheres" and an "order by" as well as some basic formatting. He then gets into the "selectWith" examples, showing the same criteria just added a different way. He also includes an example of the "tableGateway" objects used for the examples and how they're configured.

Link: http://www.masterzendframework.com/php/building-and-executing-sql-queries-in-zend

AWS PHP Development: Testing Webhooks Locally for Amazon SNS

PHPDeveloper.org - Tue, 08/04/2014 - 18:33

In a previous post the AWS for PHP blog showed how to set up webhooks for handling the callbacks from their SNS messaging service. In this next part of the series they continue the process, showing how you can test these hooks locally without needing to actually send the messages. This eliminates the need to deploy to a public-facing server just to test the hooks every time you need an update.

In a recent post, I talked about Receiving Amazon SNS Messages in PHP. I showed you how to use the SNS Message and MessageValidator classes in the AWS SDK for PHP to handle incoming SNS messages. The PHP code for the webhook is easy to write, but can be difficult to test properly, since it must be deployed to a server in order to be accessible to Amazon SNS. I'll show you how you can actually test your code locally with the help of a few simple tools.

Using PHP's own built-in webserver and a tool called ngrok to tunnel from the public internet to a local server. He includes the commands to set up the PHP script directory, the code to intercept the POSTed data from the request, validate it and send the subscription confirmation request. He helps you create an SNS "topic" through the management console and walks you through a sample test request while tailing the logs.

Link: http://blogs.aws.amazon.com/php/post/Tx2CO24DVG9CAK0/Testing-Webhooks-Locally-for-Amazon-SNS

Sameer Borate: Calculating descriptive statistics in MySQL

PHPDeveloper.org - Tue, 08/04/2014 - 17:46

Sameer Borate has shared some examples of how to generate some meaningful statistics about the contents of your database in a new post to his site today.

Descriptive statistics can be quite useful for simple analysis of records in a database. For example, to calculate average numbers of sales or products for a particular duration, or the Variance of sales for a month etc. We can easily calculate standard descriptive statistic measures in MySQL such as MEAN, SUM, STANDARD DEVIATION, VARIANCE, MIN and MAX using built-in functions.

He includes both the SQL and a bit of PHP code showing how to get these statistics (based on a simple data set of student scores). The PHP is required to more correctly evaluate the median and mode values as it's easier to evaluate those in PHP.

Link: http://www.codediesel.com/data/calculating-descriptive-statistics-in-mysql

SitePoint PHP Blog: PHP Extension Development with PHP-CPP: Object Oriented Code

PHPDeveloper.org - Tue, 08/04/2014 - 16:11

The SitePoint PHP blog has posted the second part of their look at the PHP-CPP tool and how to use it for developing PHP extensions. In this second part of the series Taylor Ren builds on what was learned in part one and talks more about the OOP features of the tool.

In this part, we further elaborate its OO features. We will mimic a complex number (in the form of 3+4i) class to demonstrate some more useful and powerful sides of the PHP-CPP library.

He walks you though a few changes to the environment files (the .ini configuration file and the Makefile) to set things up. He then gets into the C++/PHP constructor and getters and setters for private class variables, much like PHP's __get and __set. His example shows a set of methods that do some mathematical calculations including one to show the result in a "more friendly way". He includes the code for registering these functions and, finally, the steps to compile, install and test the extension.

Link: http://www.sitepoint.com/php-extension-development-php-cpp-object-oriented-code

Finally! 1.1.0-RC1

Planet-PHP - Tue, 08/04/2014 - 06:00

Once we released 1.0, we did not sit idle. Instead we immediately began work on improving the CMF. In fact there was such a continuous stream of good ideas and things that felt like a must have, that we let ourselves slip quite far from our defined release process. Or lets say we had every intention of aliging ourselves with the Symfony2 core release cycle by releasing within 1-2 months of core which would have meant a 1.1 release in January. Instead it tooks us 6 months to get to RC1, which on the upside is inline with what we intended for future releases.

As we feared, it turns out that we had to do a few minor BC breaks which we tried to document as much as possible in the CHANGELOG.md files in the respective packages. We also have updated the documentation already with lots of details on the new features we added. Unfortunately due to limitation in the current symfony.com website, we cannot provide a rendered version just yet. So for now please review the dev branch. Hopefully we will eventually also be able to provide multiple versions of the CMF documentation just like it is possible for the core documentation.

Let me briefly highlight some of the key improvements that are coming with 1.1:

  • A lot of effort was spend in making the CMF more resilent towards edge cases and given better more helpful error messages.
  • Support for newer version of Jackalope and PHPCR ODM, that bring lots of bug fixes, speed improvements, and better debugging and profiling (including Symfony2 debug toolbar support).
  • The routing system was made even more flexible, meaning there is even less code to write when implementing a new storage backend. As a result much less code is now needed in SimpleCmsBundle for routing.
  • The menu system has seen several tweaks, most noteably it is now possible to configure a fetch depth, which can give drastic performance improvements for deeply nested menu structures.
  • A new Bundle was added for handling SEO meta data.
  • A totally reworked Standard Edition that is based on the core Standard Edition to make it easier to understand what is necessary to add to a Symfony2 application to integrate the CMF.

So what is still left until we can go stable? For now we want to give at least 2 weeks from now to allow the community to do some testing and to focus on bringing all the documentation up to date. So expect a stable release at the earliest towards the end of April at the latest sometime in May. Other than this the main areas where we might still see some changes are:

To get an idea of what is needed to update to 1.1, have a look at the PR to update this website to the new version. Also note that the CMF sandbox has also already been upgraded to 1.1.

We are also very happy with the growing eco-system around PHPCR. Most noteably there is now a PHPCR shell to interact with a PHPCR repository as well as finally a PHPCR GUI that supports reading and writing via a web interface!

Categories: Open Source, PHP Community

Getting Started with PHP Extension Development via Zephir

Planet-PHP - Mon, 07/04/2014 - 19:00

Thien Tran Duy explains how we can get started with PHP Extension development through Zephir, the new language and direct competition to Hack and HHVM from the Phalcon team

Continue reading %Getting Started with PHP Extension Development via Zephir%

Categories: Open Source, PHP Community

Composer-Assisted Two-Stage Configuration in Aura

Planet-PHP - Mon, 07/04/2014 - 18:06

After a long period of consideration, research, and experiment, we have found a non-static solution for programmatic configuration through a DI container. It is part of a two-stage configuration process, implemented through a ContainerBuilder.

The two stages are “define” and “modify”:

  • In the “define” stage, the Config object defines constructor params, setter method values, and services. This is the equivalent of the previous single-stage Solar and Aura v1 configuration system.

  • The ContainerBuilder then locks the Container so that its definitions cannot be changed, and then begins the “modify” stage. In this second stage, we retrieve service objects from the Container and modify them programmatically.

So now, instead of each Aura package carrying a pair of define and modify includes in a subdirectory named for the config mode, we have a single class file for each config mode. The class file is in a subnamespace _Config under the package namespace. Here are two examples, one from the Aura.Web_Kernel package, and one from the Aura.Web_Project package.

Because they are classes, you can call other methods as needed, subclass or inherit, use traits, create instance properties and local variables for configuration logic, and so on. You could even call include in the methods if you wanted, keeping the class as a scaffold for much larger configuration files. This gives great flexibility to the confguration system.

To make sure the Aura project installation can find all the package config files, we use the {"extra": {"aura": { ... } } } elements of the composer.json in each package to provide a mapping from the config mode to the config class.

Read the whole article at Composer-Assisted Two-Stage Configuration.

Categories: Open Source, PHP Community

Did You Mean Advanced Email Validation in PHP

Planet-PHP - Mon, 07/04/2014 - 14:25
By Manuel Lemos
When you take users' email addresses, for instance in a site sign-up form, there are great chances that the addresses may be incorrect because of a typing mistake or it is not possible to deliver the message to the specified address for some reason.

This e-mail validation package can detect and prevent that users enter incorrect addresses even before you accept them.

Read this article to learn how to use this package to detect incorrect email addresses and get suggestions for the correct addresses so the users can fix them with a single click.

This article is about doing it with PHP but it also points to a similar solution to achieve the same in Node.js.
Categories: Open Source, PHP Community

For whom should you vote?

Planet-PHP - Sun, 06/04/2014 - 22:24

No, I won’t tell you who is the better candidate in the upcoming Quebec elections. I just want to give you some perspective.

Are you able to reduce your expenses while at the same time buying a new car and a perfect house? If you had the choice to do that by putting everything on a credit card and then leave the bill for your kids, would you do it? Running a household is not so easy. You make compromises.

Running a whole province is even harder. The government cannot give you more of everything and have a perfectly healthy budget. When a candidate makes promises, don’t think “why is this other thing not on the list?” Think rather “will these things help us improve in the long run?” Here are a few things that I consider:

  • Do promises sound ridiculously and unjustifiably expensive?
  • Do they align with my priorities in the next 4 years?
  • How many people will they help? How many people will they hurt?
  • Are they actually useful or just fun to debate?

I mentioned priorities. Here are mine:

  • More doctors.
  • Fix crumbling roads and bridges.
  • Promote productivity and competency.
  • Reduce bureaucracy.
  • Start paying the 265 Billion dollar debt. more on the debt

When you vote tomorrow, remember what is most important to you. Pick a few items and see which candidate aligns best with these priorities.

Categories: Open Source, PHP Community

Abstract File Systems with Flysystem

Planet-PHP - Sun, 06/04/2014 - 18:00

Reading and writing files is an integral aspect of any programming language, but the underlying implementation can vary enormously. For example, the finer details of writing data to the local filesystem compared to uploading over FTP is very different - yet conceptually, it’s very similar.

In addition to old warhorses like FTP, online storage is increasingly ubiquitous and inexpensive - with scores of services available such as Dropbox, Amazon’s S3 and Rackspace’s Cloud Files - but these all use subtly different methods for reading and writing.

That’s where flysystem comes in. It provides a layer of abstraction over multiple file systems, which means you don’t need to worry where the files are, how they’re stored, or need be concerned with low-level I/O operations. All you need to worry about are the high-level operations such as reading, writing and organizing into directories.

Such abstraction also makes it simpler to switch from one system to another without having to rewrite vast swathes of application code. It also provides a logical approach to moving or copying data from one storage system to another, without worrying about the underlying implementation.

You can use Dropbox, S3, Cloud Files, FTP or SFTP as if they were local; saving a file becomes the same process whether it’s being saved locally or transferred over the network. You can treat zip archives as if they were a bunch of folders, without worrying about the nitty gritty of creating and compressing the archives themselves.

Continue reading %Abstract File Systems with Flysystem%

Categories: Open Source, PHP Community

PHP Extension Development with PHP-CPP: Object Oriented Code

Planet-PHP - Sat, 05/04/2014 - 18:00

PHP-CPP Part 2: The OO side

In my Part 1 on building a PHP extension with PHP-CPP, we have seen some basics in using PHP-CPP to create our first skeleton PHP extension and covered some important terminologies.

In this part, we further elaborate its OO features. We will mimic a complex number (in the form of 3+4i) class to demonstrate some more useful and powerful sides of the PHP-CPP library.

Continue reading %PHP Extension Development with PHP-CPP: Object Oriented Code%

Categories: Open Source, PHP Community

Optimizing MySQL Bottlenecks

Planet-PHP - Fri, 04/04/2014 - 18:00

This entry is part 3 of 3 in the series Optimizing MySQL Introduction MySQL is one of the most used databases in conjunction with PHP. Making sure that your MySQL databases are running at their best is one of the most important aspects you have to consider whenever your web application grows. In this series […]

Continue reading %Optimizing MySQL Bottlenecks%

Categories: Open Source, PHP Community

PHP 5.4.27 Released

php.announce - Fri, 04/04/2014 - 08:39
Categories: PHP Community, PHP.net

PHP.net: PHP 5.5.11 is released

PHPDeveloper.org - Thu, 03/04/2014 - 20:02

PHP.net has announced the latest release in the PHP 5.5.x series today - PHP 5.5.11.

The PHP development team announces the immediate availability of PHP 5.5.11. Several bugs were fixed in this release, some bundled libraries updated and a security issue has been fixed : CVE-2013-7345. We recommend all PHP 5.5 users to upgrade to this version.

Fixes in this release include:

  • Updates to core
  • Fixes in the cURL extension
  • Bugs corrected in the GD extension
  • A fix for the CVE-2013-7345 security issue in Fileinfo

You can download this latest release directly from the downloads page (Windows users here and you can find the full list of changes in the Changelog.

Link: http://www.php.net/archive/2014.php#id2014-04-02-1

NetTuts.com: Refactoring Legacy Code: Part 2 - Magic Strings & Constants

PHPDeveloper.org - Thu, 03/04/2014 - 19:47

NetTuts.com has posted the second part of their "Refactoring Legacy Code" series today continuing on from their beginning of the series. They continue the refactor of their "trivia" application.

Old code. Ugly code. Complicated code. Spaghetti code. Jibberish nonsense. In two words, Legacy Code. This is a series that will help you work and deal with it. We first met our legacy source code in our previous lesson. [...] The time for the first changes have come and what better way to understand a difficult code base than start to extract magic constants and strings into variables? These seemingly simple tasks will give us greater and sometimes unexpected insights into the inner workings of legacy code. We will need to figure out the intentions of the original code author and find the proper names for the pieces of code that we've never seen before.

They talk about refactoring out things like "magic strings" and other hard-coded return values and checks. They mention updating the tests to reflect these changes while keeping an eye out for "magic constants" as well.

Link: http://code.tutsplus.com/tutorials/refactoring-legacy-code-part-2-magic-strings-constants--cms-20527
Syndicate content