2015年4月30日星期四

Site News: Blast from the Past - One Year Ago in PHP

Here's what was popular in the PHP community one year ago today:

Acquia Blog: PHP Reset, PHP Renaissance: Unify everything in PHP with Composer


On the Acquia blog there's a new post today with another of Jeffrey A. "jam" McGuire's interviews with a member of the PHP community. In this latest interview he talks with Jordi Boggiano, a lead developer on the Composer project that's changed the way people use and install PHP packages.



It was great to get the chance to sit down and talk with Jordi Boggiano at SymfonyCon Madrid 2014. Jordi is responsible for Composer, one of the most important pieces of technology that is driving PHP interoperability and the PHP "renaissance" of the last couple of years. He's also on the Symfony2 core team.


Jeffrey gives a brief overview of some of the main points that Jordi makes in his interview including the suggestion of "using what you know" and thinking of the people/users of the tool, not just the technology of it. He also mentions Jordi's response to the "PHP Renaissance" (and note that he sees it as more of a PHP Reset instead). You can watch the full interview video either through the embedded player or on YouTube, You can also use the in-page audio player or download the mp3 if you'd like an audio-only version.


Link: http://www.acquia.com/resources/podcasts/acquia-podcast-192-php-reset-renaissance-unify-everything-composer

SitePoint PHP Blog: PHP7 Resource Recap


With all the talk about PHP7 and the features that are coming with it, it's easy to get lost in the mound of information. Thankfully, the SitePoint PHP blog is here to help. They've posted a roundup of several PHP7-related resources you can use to sort things out (or start learning about) what's to come.



PHP 7 is well on its way. RFCs are being implemented and polished, projects are being tested, libraries upgraded. Extensions are being modified, and the word is spreading. All that remains is getting the shared hosts on the upgrade bandwagon - the arguably most difficult part of improving the global state of PHP. In this article, we'll take a look at some of the most important PHP 7 related resources and tips you should go through in preparation for the new version.


Mentions in their list include both tutorials and tools including the PHP7 Vagrant box provided by Rasmus Lerdorf and the Go PHP7 Extensions effort to update extensions to be PHP7 ready. Following this there's serveral links to other important reading about what to expect and results of testing done with this upcoming version.


Link: http://www.sitepoint.com/php7-resource-recap/

Vincent Composieux: Run a Symfony application using Docker and docker-compose (English)


Vincent Composieux has put together a new tutorial showing you how to get a Symfony2 application up and running inside of a Docker virtual machine for development and testing.



Why boot a full virtual machine when you can only run Docker containers of what you need to develop your Symfony applications ? This is one question asked by Jeremy Derusse at his "Docker dans le développement l'intégration continue" talk during Symfony Live Paris 2015. Those slides are really interesting, I invite you to take a look. They demonstrate the power of Docker and docker-compose but are waiting for practice in order to well understand. So I enjoyed a rainy week-end for further study!


He then outlines the components needed for a simple Symfony2 application: Nginx, PHP (well, PHP-FPM), MySQL and, of course, the code for the application. He includes the full contents for the "docker-compose.yml" configuration file to generate this Docker instance. He walks through each of the components it requires and talks about what they contain and how to define each of them as an image. Following this, he creates the containers with a "docker build" and brings it all up and working with one "docker up" command. He also includes a few other helpful commands for getting memory/CPU usage as well as removing all containers and images with a single command.


Link: http://vincent.composieux.fr/article/run-a-symfony-application-using-docker-and-docker-compose

ServerGrove Blog: Satis: building your own Composer repository


Composer has definitely made a huge impact on how PHP packages and libraries are integrated into other applications. Sometimes, though, it makes more sense for you to keep your code internal to the organization rather than have it public where Composer can install it. In this case, using some thing like Satis (a self-hosted Packagist-ish server) makes more sense.



We all love Composer. It changed dramatically the way we build PHP applications, based on small and reusable components, but this creates new challenges, especially when we have a single point of failure (SPO). With Satis, the deployment process can be made robust by adding redundancy in all potential SPOFs (Packagist and GitHub). Let's see how it works.


They start with a brief look at how Composer works for those not familiar, making the connection with Packagist and ultimately the public repository. In the context of the "single point of failure" they talk about Packagist being down and it preventing the install (or deployment!) of your application. Satis is prefect to help prevent this. The article then shows how to install Satis (via Composer, naturally) and how to set up the configuration file to define the repositories. The server is then built and can be run using the built-in PHP server on the port of your choice. They include a screenshot of the end result and a quick example of how to use it via your project's Composer configuration.


Link: http://blog.servergrove.com/2015/04/29/satis-building-composer-repository/

How to build your web design career

So you want to be a web designer. Or perhaps you already are and don’t know what your next step should be. Either way you will have tons of questions. This is the place to ask them.

Hardly a week goes past without me receiving an email from somebody wanting advice about their career. They are unsure of what to do next. Should they go to University? Should they setup by themselves or try and get a job? They just have so many questions. I figured it was time we tried to answer them.


On the 21st May the Boagworld Show is back for its 12th season. This time we are going to be looking at building your web design business. We will be discussing everything from winning pitches to work/life balance. Best of all we will be discussing these questions with some of the biggest names from web design.


We want to start the season by looking more broadly at your web design career. We want to discuss questions about how to start or what type of job to get. Should you work in-house or would agency life suit you better? If you have a question about your career we want to hear it.


But more than that we want your answers to. Take a moment to look at the questions below and share your thoughts based on your own experience. Did you make a mistake in your career that you want to warn others about? If so please share it with us.


The comments are open, get posting!








The fact that this generation Apple Watch has a sc…


The fact that this generation Apple Watch has a screen that is off by default is going to seem ridiculous in a couple of years.


Related: trying to turn my wrist the right way to …


Related: trying to turn my wrist the right way to trigger the screen to come on is my biggest annoyance with the Apple Watch so far.


2015年4月29日星期三

Community News: Recent posts from PHP Quickfix

Recent posts from the PHP Quickfix site:

Dan Miller: Comparing the PHP 7 and Hack Type Systems


Dan Miller, a core platform engineer at Etsy, has a new post on his personal site sharing his results from a comparison of the variable typing systems between the Hack language (created by Facebook) and what's coming in PHP7.



One of the exciting things about PHP 7, aside from the incredible performance improvements, is the introduction of scalar type hintingHack. I wanted to find out if you could execute the same code in PHP 7 and Hack, and what the differences in execution might be. Here's what I found out.


He starts by describing his setup (the versions of PHP7 and HHVM he's using) and shares a few simple examples. He uses the same(ish) code in both and points out some of the differences in what happens when each is executed. He also points out some of the differences in the features between the two (such as Hack not allowing for default arguments with a value of null). He tries a few more complicated things too, like mixing strict and non-strict files, and the findings. He ends the post with some of his overall thoughts of his results and his excitement about what the future holds for PHP7 and the hinting it will provide.


Link: http://www.dmiller.io/blog/2015/4/26/comparing-the-php7-and-hack-type-systems

Engine Yard Blog: Composer & Continuous Integration


In a new post to the Engine Yard blog Nils Adermann provides an overview of using Composer with continuous integration, its role in the overall process and some good practices to follow in its use.



Continous Integration (CI) is the practice of continuously (and automatically) testing every change a developer makes. So automated tests become an integral part of the development process providing direct feedback on changes made. [...] Davey Shafik's article on Composer's Lock File explains the typical usage of composer install and update. The key takeaway is that developers should run composer update manually to explicitly update individual dependencies while composer install should be used in automated processes. This principle includes automated test environments.


He points out that using the lock file method reproduces the vendor directory exactly as it is in production and what it means for failures in your automated tests. He also talks about methods to improve the build performance to reduce time spent during the generation of the environment, including the use of the Composer cache data. He includes a few flags you can pass to Composer to reduce not only the libraries it installs but also how it fetches their contents.


Link: https://blog.engineyard.com/2015/composer-continuous-integration

Run Geek Radio: Episode 002 - Approaching speakers, new running shoes, feeling stupid, S3 log [...]


Run Geek Radio, with host and PHP community member Adam Culp, has posted their latest episode: "Episode 002 - Approaching speakers, new running shoes, feeling stupid, S3 log side project, consultant travel, and technical debt".



In this episode we speak about PHP community and approachability of conference speakers, new running shoes and typical miles that can be run on a pair of shoes before replacing them as well as wear patterns, feeling stupid in skills if they aren't used often enough, new s3-logs-analyzer side project created to monitor podcast downloads (but can be used for any files on S3), typical travel as a consultant, and what is technical debt and how to tackle it as well as when an application rewrite is OK.


You can listen to this latest episode either through the in-page player or downloading the mp3. If you enjoy the episode, be sure to subscribe to their feed too.


Link: https://rungeekradio.com/episode002/

SitePoint PHP Blog: Inspecting PHP Code Quality with Scrutinizer


The SitePoint PHP blog has a recent tutorial showing you how to use the Scrutinizer service to evaluate the quality and "pain points" in your PHP code, be it a library or full application.



We've gone through a decent number of tutorials about code quality, inspections, auto-build systems and so on here at SitePoint. [...] In this article, we'll take a look at Scrutinizer CI - a continuous integration tool that's quite expensive and closed to private projects, but very handy for public ones.


He starts with a quick comparison of Scrutinizer versus (and really plus) the popular CI service Travis CI. He then walks you through the setup of Scrutinizer to evaluate your application automatically when code is pushed to GitHub. He then gets into the configuration options the service provides including filters, specific checks to evaluate and other tools to execute in the evaluation build. The article then gets into examples of the reports that are provided and a bit of detail about what each view provides. There's also options to hide certain errors that you know aren't actually problems and the "follow up" links it provides for the issues you may not understand.


Link: http://www.sitepoint.com/inspecting-php-code-quality-scrutinizer/

Henrik Warne: Lessons Learned in Software Development


In this recent post to his site Henrik Warne has shared a list of advice around software development and some good practices he's picked up along the way.



Here is my list of heuristics and rules of thumb for software development that I have found useful over the years.

His list includes several points related to a few main categories:



  • Development
  • Troubleshooting
  • Cooperation (personal, not code)
  • Other Miscellaneous Tips


Each main topic has a few sub-topics and each of those includes a brief description (with twenty-two tips in the list overall). There's some great advice in the list as well as some good contributions in the comments, so be sure to read through those too.


Link: http://henrikwarne.com/2015/04/16/lessons-learned-in-software-development/

2015年4月28日星期二

Community News: Latest PECL Releases for 04.28.2015

Latest PECL Releases:
  • msgpack 0.5.6
    - support str8 type (wudikua)
    - Fix a warning and a possible crash (Mike)
    - Fix crash with memcached (Mike)


  • timezonedb 2015.4
    Updated to version 2015.4 (2015d)


  • apfd 1.0.1
    * Fix bug where non-POST payloads with mixed case boundaries would not be parsed


  • mongodb 0.5.1
    * PHPC-241: Don't try to use local timezone
    * PHPC-241: mongodb.debug improvements
    * PHPC-270: Several test fail because of missing enableTestCommands
    * PHPC-270: add TESTCOMMANDS() skipif to confirm mongod is running with required options
    * PHPC-269: Fix travis setup
    * PHPC-268: Update tests to declare which environments they need
    * PHPC-268: Add NEEDS() function to check if that environment is available
    * PHPC-247: Remove 'faker' as prerequisite from running our full test suite
    * PHPC-247: Remove on-the-fly composer generated fixtures
    * PHPC-247: Use the bundled pregenerated fixtures
    * PHPC-89: Bundle generated fixtures and make them easily loadable
    * PHPC-260: Allow/use "object" in setTypeMap() as alias/preferred for "stdclass"
    * PHPC-267; _id generated on embedded document
    * PHPC-265: BSON encoding unsupoprted types (Resource) should fail
    * PHPC-266: Add MongoDBDriverUnexpectedValueException
    * PHPC-75: Improve code coverage
    * PHPC-258: make all filed needed for test as role="test"
    * PHPC-259: add --with-libbson option


  • gmagick 1.1.7RC3
    setImagePage() and getImagePage() added


  • couchbase 2.0.7
    This is a patch update to the PHP 2.0 SDK.

    Changes:
    * PCBC-339: Add support for using N1QL with CB Server 4.0.0.
    * PCBC-343: Added missing touch method to CouchbaseBucket.


  • mongodb 0.5.0
    * PHPC-241: Include lib versions and uri in the logs
    * PHPC-240: Rely on libmongoc for command cursor iteration
    * PHPC-240: Regression tests for command cursor getmore
    * PHPC-254: Remove unused RINIT and RSHUTDOWN handlers
    * PHPC-253: bump mongoc after CDRIVER-611 fix
    * PHPC-249: empty array should be serialized as array
    * PHPC-248: Allow ->setTypeMap() to set 'array' and 'stdclass'
    * PHPC-245: Allow embedding objects in updates
    * PHPC-245: executeUpdate() converts objects to arrays
    * PHPC-244: Cannot use object of type Person as array
    * PHPC-243: Manager->executeUpdate() option is supposed to be 'multi'
    * PHPC-239: Cursor refcount issues
    * PHPC-237: Update PHP version requirement in package.xml


Voices of the ElePHPant: Interview with Chris Tankersley


The Voices of the ElePHPant podcast has posted their latest episode in theri community interview series. This time host Cal Evans talks with Chris Tankersly, regular conference speaker and



Chris and Cal talk some about Chris' experience with devops and what kind of services that entails. He also does PHP development, but provides support and setup of systems and servers. They also talk some about what Chris sees as some of the major problems between devs and operations. Cal also asks Chris for some advice to developers so they can be more successful on their understanding of the servers their applications run on. There's also a brief mention of WurstCon, an impromptu "conference" that started around just getting some hotdogs.



You can listen to this latest episode either through the in-page audio player or by downloading the mp3 directly. If you enjoy the interview, be sure to subscribe to their feed for more great episodes.


Link: https://voicesoftheelephpant.com/2015/04/28/interview-with-chris-tankersley-2/

SitePoint PHP Blog: Generating PHP Documentation with Sami


The SitePoint PHP blog has a new tutorial posted today showing you how to generate API documentation with Sami, a "Friends of PHP" project that's currently used to generate API documentation similar to what the Symfony project provides. In this case "API" refers to your class and method structures, not something like a REST API.



Documenting your methods, classes, and functions is becoming second nature for everyone, so it makes sense to have a way to generate a separate documentation instead of navigating through the source code. In this article, I'm going to introduce you to Sami, the new API documentation generator.


He starts with a brief introduction to the DocBlock commenting methods and why you might want to choose Sami over other document generation tools (like phpDocumentor). He then helps you get Sami installed as a phar archive and how to use it to generate the document output for the Laravel Illuminate package. He includes the code you can use to set up the Sami configuration and an example of the output from the command execution. He then includes a bit about the versioning of the documentation, using themes and customizing the look and feel through custom assets and markup changes.


Link: http://www.sitepoint.com/generating-php-documentation-sami/

Symfony Blog: New in Symfony 2.7


The Symfony blog has been posted spotlights in several of the improvements in the 2.7 release of the framework over on their blog. Each of them describes the changes and includes some sample code showing the new feature in action:




Keep an eye on the Symfony blog for more of these component spotlights and improvements as they're released.


Link: http://symfony.com/blog/

Alejandro Celaya: Composer advanced concepts


Alejandro Celaya has shared some advanced concepts when using Composer that you may or may not know this popular tool could do.



Composer is The Tool in any modern PHP project. Nowadays I can't imagine to work without it. It is much more powerful than some people think, easily solving the integration of third party components in our projects, but there are some advanced features that are less known. I'm going to try to explain some of the best practices and mechanisms bundled with composer.

His list of more advanced techniques and concepts includes:



  • Globally installing composer
  • Create the composer.json file (with composer init)
  • Production environments (and flags to customize the installation)
  • Executing CLI scripts


There's several more items in his list and each includes a description of the feature/practice and commands or code where appropriate.


Link: http://blog.alejandrocelaya.com/2015/04/25/composer-advanced-concepts/

What is your website saying about your organisation?

A review of your online presence can do a lot more than identify ways to improve your website. It can also reveal underlying organisational issues.

Don’t judge people by their appearance. That is what our parents taught us. But it is rubbish. You can learn a lot about a person by how they hold themselves and what they wear. The same is true for a website. A website gives many insights into the organisation behind it.


I spend a lot of time reviewing websites and social media channels. Over all that time I have learnt something. Rarely are the failures of an organisations online presence due to shortcomings in their digital team.


You can have the best digital team in the world. But if the organisations culture is incompatible with digital there will be problems. These organisational failures are plain to see on your website.


Let me share with you some examples of what I mean.


The secrets your information architecture reveal


One of the most telling parts of your website is your information architecture. Many websites have an information architecture built around organisational thinking rather than user needs.


This shows a complete indifference to their customers. But if you look deeper it reveals something else as well. It shows an organisation trapped in departmental silos unable to collaborate. Unless this is overcome, even the best digital team will struggle to create a user centric site structure.


Reading between the lines of your content


I encounter many websites with terrible content. It is either poorly written or out of date. At times it is even contradictory.


There is almost always a single reason behind these problems; a distributed content model. In other words people across the organisation have permission to publish content to the website. In some cases this is thousands of people!


This is indicative of a decentralised organisation. An organisation lacking editorial oversight or strong digital leadership.


What your silence says on social media


It is not just your website that is revealing a lot. Your behaviour on social media is too. One of the most common failures I see on social media is a lack of engagement. Organisations update their social media channels with news stories, blog posts and press releases. But that is it. There is little in the way of conversation or more casual updates.


This screams of a marketing department stuck in the past. Trapped in a world of mass media and broadcast marketing. Unfortunately consumers now have little tolerance for this kind of traditional marketing. They want organisations that talk with them and not at them.


The story behind an unresponsive website


Having a site that works well on mobile is becoming ever more critical. This is especially true in the light of the upcoming changes that Google are introducing. But when I see an unresponsive site I am not just concerned about the impact on mobile users. I am also concerned about why the site is not responsive.


Often this is symptomatic of an even more serious issue, periodic investment in the website. If a site isn’t responsive it means nobody has worked on the technical architecture of the website for many years. It is indicative of a company stuck in an endless cycle of redesigns every few years. Instead organisations need to commit to ongoing incremental improvement.


The hidden danger of a fragmented user interface


When I review larger websites I encounter the same thing time and again. A fragmented user interface consisting of many sub-sites. Sites for departments, sites for campaigns, sites for products. Everything has its own sub-site with its own user interface.


This is an obvious concern from a user experience perspective. But it rings warning bells for another reason too. It shows a lack of digital leadership. There is nobody with the authority and control to rein in this kind of excess. If nobody can stop this, what other areas are suffering from a lack of digital leadership?


Why a lack of visual hierarchy is a cause for concern


Finally there is the lack of visual hierarchy that exists on many websites. Long lists of links, too many navigational items and pages with little structure. A related issue is a lack of strong calls to action.


All these things matter from a usability stand point. But they are also emblematic of a much more worrying problem; a lack of priorities. When there is little visual hierarchy and poor calls to action it is because there is no clear vision for the role of the site.


This in itself is a symptom of an even deeper problem; senior management aren’t engaged with digital. It is the role of senior management to set direction and decide on priorities. If a website lacks these priorities it is often a sign. A sign that management aren’t engaged with the website, don’t think its important or don’t understand it. Whatever the case, that is cause for serious concern.


Dig a little deeper


The issues listed here are just some examples of deeper problems that need addressing. There are many others. For example the existence of CAPTCHA on a site is often a sign of an overworked digital team. A team forced to ignore user needs to produce something quick and dirty. Or how unnecessary form fields are a sign of an overly powerful sales and marketing department.


My point here is that a good review should dig a little deeper. It shouldn’t just highlight the symptoms but search for underlying causes. It shouldn’t just be about listing the problems. It should be about asking why those problems exist.


Would you like a review of your website? One that digs a little deeper. If so drop me an email.








2015年4月27日星期一

Community News: Latest PEAR Releases for 04.27.2015

Latest PEAR Releases:

Luciano Mammino: Developing a web application with Lumen and MySql


Luciano Mammino has a tutorial posted to his site showing you how to create a Lumen application that ties into a MySQL database from start to finish. It's a simple "display a famous quote" application, but it shows the full process you'll need to follow to hook it all together.



Lumen is a new Php micro-framework developed by Taylor Otwell, the same author of the famous Laravel framework. I wanted to give it a try and I am here to share my experimentations. I am not an expert of Lumen (yet), but I think one of the best characteristics of this framework is that it makes really really easy to bootstrap a new project. So to prove this, we will now build a fully functional app backed by a MySql database in less than 30 minutes. Are you ready to start?


His goal is a create a simple application that displays a quote, "randomized" based on the day. He shows you how to set up a new Lumen project, configure the database and create a migration to create the table in MySQL. He also includes the code for the data seeder and the main application routing (just two routes). Finally, he includes the output template and the CSS needed to make the end result look as expected.


Link: http://loige.co/developing-a-web-application-with-lumen-and-mysql/

Marc Morera: Behat and Data-test


In a new post Marc Morera makes a suggestion for a testing practice to add to the use of the popular BDD PHP testing framework Behat - a "data-test" option to help with decoupling the tests from implementation.



Tests should be as robust as possible. I think you will agree with me with that phrase. If your tests are too coupled with your implementation, a simple modification of your code will need the modification of your tests, and that's so annoying, right? [...] My question is… should the frontend of your website be aware of the how your Behat tests are built? In my opinion, nope. Your tests should live in a simple layout on top of your application, emulating some cases and ensuring that your users will be able to do what they should be able to.


He points out the main problem with the current testing methods, mainly that the real issue is in the hard-wiring of the test functionality to the name/id/type of the interface elements. He also brings up the aspect of translations and ensuring that your tests take into account that the text may not always be in English. He also mentions Symfony forms and how they define their own structure and naming, not necessarily what you manually generate. He instead proposes a "data-test" property that could be added to elements both indicating that they're used by the testing process and can help in locating the elements during the testing process.


Link: http://mmoreram.com/blog/2015/04/25/behat-and-data-test/

NetTuts.com: Creating a Dating Application with Sinch: RESTful API


NetTuts.com has kicked off a new tutorial series today about building a dating application with a combination of Laravel, MongoDB and the Sinch service allowing for messaging between users. The Sinch service has several features including voice/messaging/SMS communication methods and device verification.



In this tutorial, we're going to create a dating application for iOS similar to Tinder. For voice and messaging, we will leverage the Sinch platform, making use of its powerful SDK. In the first part, we will focus on the development of a RESTful API to store and retrieve user information. In the second part, the iOS client will hook into this API to find nearby users based on the user's current location. We will use Laravel 5.0 for the RESTful service and will be covering basic concepts, such as routes and controllers. We are also going to define custom models to support MongoDB integration in an ActiveRecord-like manner.


This first part of the series is mostly about just getting things set up so they walk you through:



  • Basic setup of the Laravel application
  • Creation of the Base model (for MongoDB connection)
  • Creating helper methods
  • Building out CRUD functionality for the database layer
  • Making a User model
  • Creating the BaseController class
  • Making a SessionController class (and working with sessions)
  • Building a UserController


They end this part of the series by hooking all of this functionality together with some simple RESTful routing for GET, POST, PUT and DELETE request handling for the various endpoints.


Link: http://code.tutsplus.com/tutorials/creating-a-dating-application-with-sinch-restful-api--cms-23709

PHP Roundtable: 018: F8 Afterglow & The PHP SDK


The PHP Roundtable Podcast has posted their latest episode today, hosted by Sammy Powers and featuring guests Fosco Marotto and Nathan Stokes. In this new episode they talk about their experiences at the Facebook F8 conference and their PHP SDK.



A short afterglow discussion about the 2015 F8 Facebook Developer Conference in San Francisco, CA & a look at the new Facebook PHP SDK and where it's headed.


You can catch this latest episode through the in-page video player. If you enjoy the episode, be sure to subscribe to their feed to get the latest as they're released.


Link: https://www.phproundtable.com/episode/f8-2015-facebook-developer-conference-and-the-new-php-sdk

SitePoint PHP Blog: Sending Emails in PHP with PHPMailer


The SitePoint PHP blog has a tutorial from Narayan Prusty showing you how to effectively use PHPMailer to send emails from your PHP application. PHPMailer provides a simplified interface to send both simple and complex emails.



PHPMailer is one of the most popular open source PHP libraries to send emails with. It was first released way back in 2001 and since then it has become a PHP developer's favorite way of sending emails programmatically, aside from a few other fan favorites like Swiftmailer. In this article we'll talk about why you should use PHPMailer instead of PHP's mail() function and we'll show some code samples on how to use this library.


He starts by answering the obvious question - is it an alternative to PHP's own mail function? He describes the differences, mostly in the way of enhanced functionality PHPMailer offers. He then helps you get it installed via Composer and how to send a first simple email. Next up he shows how to send an email with attachments and connecting the library to an external SMTP server for sending. The tutorial finishes with a quick mention of using POP3 to read emails and how to show local error messages when something goes wrong.


Link: http://www.sitepoint.com/sending-emails-php-phpmailer/

Toad the Wet Sprocket’s New Album is Free on Amazon Prime

TOAD_Cover8


This morning I saw Justin’s tweet about Toad the Wet Sprocket which led me to their Wikipedia to confirm that they took their name from a Monty Python sketch. Along the way, I saw that they just released a new album. California Wasted stands out to me on my initial listen through.


I went to Amazon to buy the MP3 album and was quite surprised to find that it was available free as part of Amazon Prime Music. You’ve all got Prime, right? Go grab your free copy.


They are touring too. I saw them perform at Chautauqua a few years ago and they did a great show.

Submit a Form on Command + Enter from Textarea with jQuery

I’m a big fan of keyboard control in productivity applications. I love being able to type my changes/additions and submit them without needing to tab around too much, or gasp grab the mouse. I’m not the only one who feels this way. David Walsh has a great post explaining how to submit web forms with Command+Enter. However, for my needs I needed to tweak this a little:



  1. I only want Command+Enter to submit the form if I’m in a textarea.

  2. I need the form submission to play nicely with AJAX requests, specifically when using jQuery delegates to catch the form submission. In David’s example code, the submit() was firing before the delegate could catch the event and preventDefault() on it.


Luckily it was quite simple to adapt his code for my needs.


View the code on Gist.

2015年4月26日星期日

Product shearing layers and the "double-diamond" approach to design

The organising principles of agile are based around the needs of developers. So processes and systems are broken down into units of functionality and fed to development teams along a pipeline of delivery.



We all know that estimating big tech projects is a crap shoot, so the focus with agile is on just in time decision making, problem solving and optimising through-put. With so many unknowns this is a much more rational and realistic approach than trying to plan and estimate everything up front.



Unfortunately, while this organising principle performs well for developers, it can be problematic for designers who need to tackle things as part of a coherent system, rather than a series of functional chunks.



Agile allows for iteration, so one way of tackling this problem is to give in to the inherent uncertainty and allow the design to emerge over time. So you slowly end up aquiering design debt, with the hope that you’ll have time at the end of the project to bring all the disparate pieces together. Sometimes this happens, but often this gets relegated in favor of more functionality.



I believe this is one of the reasons why so many established tech companies struggle to produce a holistic user experience and end up creating a disjointed UI instead. Lots of small pieces loosely joined rather than a coherent and considered system.



Lean ux has attempted to add a layer of design thinking to the process. However the minimal shippable unit is still based around features rather than systems and stories rather than journeys or experiences.



With this method experiments are run in the wild on real users rather than on paper. This has the benefit of giving you real rather than aproximated feedback. However it can also lead to significant amounts of technical debt and a poorly considerd product in the hands of your users for longer than is absolutely necessary. This probably doesn’t matter in a new start-up with just a few users, but can be much more damaging for an establish company with millions of customers expecting you to deliver of your brand promis. How often have we seen the MVP end up being the final product?



By comparison, the traditional UX approach sees problems iterated on with paper and prototypes rather than live users and working code, allowing you to iterate in a faster and more cost effective way. The trick is for these sketches to remain as recommendations rather than specifications, which is often not the case.



Of course these two approaches aren’t mutually exclusive, but I’d like to see Lean companies do more of their learning with prototypes and less at the expense of real users. Not everything has to be deduced from first principles, and there is a huge canon of design knowledge to draw upon here.



The tension between design and development reminds me of the famous shearing layer diagram which Stuart Brand used to explain the different speeds at which buildings evolve - the interior moving faster than the shell.



While developers find it easier to break off pieces of functionality, encapsulate them and then tie everything together as they go, designers require a higher vantage point in order to map out the entire system to do their jobs well. The business often appreciates this vantage point as well.



In typical, highly functionality agile environments, a single product will be broken down into multiple product teams with their own product manager, design lead and team of developers which they are tasked with servicing. These smaller “products” will usually focus on “slices” of a user journey rather than the whole experience - another reason why many products feel somewhat disjointed.



The speed of progress is dictated by the speed at which the developrs can ship products, forcing designers to operate at a pace which they’re often uncomfortable with. This also forces them to focus their talents on production and delivery rather than strategic thinking, which may be fine for junior designers but can be both isolating and demoralising for more experienced practitioners.



Ironically, a small group of designers are usually better able to service the needs of a large number of developers by working as a team across the whole proudct, rather than being separated out into individual product teams. However this approach is often branded as “waterfall” and dismissed by many agile proponents.



Now if you have a fairly unreconstructed design team who are more comfortable dictating rather than collaborating, they may have a point. The goal here isn’t to hand a spec document to the Dev team in the form of a set of wireframes or working prototype and simply get them to build what you’ve specified without question.



However I do believe we’re entering into a post agile world where prouduct can adopt the best parts of waterfall and agile, without having to pick one or the other and stick to them dogmatically. Instead, let’s be aware of the differing shearing layers and adopt and approach that works for all parties.



In his recent IA Summit talk, Peter Merholz spoke about the “double diamond” approach, which is the method I personally favour.



At Clearleft we typically undertake an initial definition phase where we talk to the business, interview potential users, develop a product strategy, sketch out the key user journeys and create the basics of a design system. This system isn’t set in stone, but provides just enough of an overview to set the general direction and avoid us aquiering too much design debt.



During this initial phase of the project, the team can be fairly small and efficient. Maybe just one UX designer, one UI designer and one creative technologist. We can test ideas quickly on paper or with low fidelity prototypes and discard work that proves ineffective. We’re iterating, but at a pace dictated by the needs to the product, rather than the artificial tempo of a “sprint”. We’re not looking for perfection, but hope to get the main design problems finished to a level of fidelity all parties (business and tech) are happy with.



Once the plan is fleshed out, we’re more than happy for the tech team to work in whatever way best suites them, be that Scrum, Kanban or some other variant of agile. With a better understanding of the whole, it becomes easier to break things down into chunks and iterate on the individual stories. Designs will change, and the language will evolve, but at a pace that works better for both parties.



This “double diamond” approach places the needs of designers at the forefront of the first “diamond” and sees them leading the initial strategic enguagement. The second “diamond” flips this on its head and sees design servicing the needs of development and production.



I’m sure some people will claim that this to be part of the agile canon already, be that “iteration zero”, “dual track agile” or some other methodological variation. For me I really don’t care, just as long as design gets to dictate the process during the formative phases while development drives production.

2015年4月25日星期六

coding style – Naming “class” and “id” HTML attributes – dashes vs. underlines

Some very good arguments here in favor of dashes, which was already my preference.


#

Just received detailed instructions for caring for…


Just received detailed instructions for caring for a pink seahorse stuffed animal. Including what to do if she gets hungry or starts whining.


2015年4月24日星期五

Site News: Popular Posts for the Week of 04.24.2015

Popular posts from PHPDeveloper.org for the past week:

Graze.com Tech Blog: Sharing Controller Logic with Traits in PHP


On the Graze.com Tech blog there's a recent post about sharing logic between controllers with the help of traits. He makes use of the traits functionality in PHP to abstract out functionality common to multiple controllers (in his case, common user functionality).



There have been a few times I have come across a situation where I need to share some logic between controllers but it hasn't been as clear cut as abstracting that logic out into a library. I've been pondering the best way to tackle this problem and would like to share my thoughts.


In his example he shows how two different controllers, the Account and Signup controllers, both need to be able to look up an address and perform some simple checks on the results. The logic is duplicated so he first tries to move it out to an abstract controller but notes that it's not the most ideal solution. Next he tries moving the code out into a library but finds issues with separating out the necessary concerns. Finally he moves the logic into a trait (AddAddressTrait) that contains it and allows the direct integration of his "lookupPostalCode" method into the controller without inheritance or other design issues.


Link: http://tech.graze.com/2015/04/14/sharing-controller-logic-with-traits-in-php/

Sameer Borate: Adding WordPress like shortcodes to your web applications


Sameer Borate has posted a new tutorial showing you how to add shortcode-like handling to your application. Shortcodes are a feature that's common in tools like WordPress to make adding custom markup easier (like "[tag][/tag]").



One of the cool features of WordPress is its shortcode feature. There may be times one wished to add this capability to your PHP web applications. Recently I found one such library which allows you to add shortcode features to your web apps. The library discussed here implements WordPress style shortcode syntax as a standalone package. Its a small package and so can be easily integrated into you existing applications. Content from editors, databases, etc. can be scanned by the Shortcode Manager and the contents replaced by a custom callback.


He makes use of the maiorano84/shortcodes library (installable through Composer) that makes it simple to add the functionality to your existing application. He includes a few examples of tag formats that the library can parse and the code needed to parse and handle the formatting. The custom tags are processed via callbacks and can modify the incoming value easily. He also shows how to access any attributes that may be set on the codes and grouping all of his functionality into one self-contained class.


Link: http://www.codediesel.com/php/adding-wordpress-like-shortcodes-to-your-web-applications/

Pádraic Brady: TLS/SSL Security In PHP: Avoiding The Lowest Common Insecure Denominator Trap


In his latest post Pádraic Brady shares his thoughts about the state of TLS/SSL functionality in PHP and how he thinks developers should avoid the trap of "lowest common denominator" and opt for insecurity.




A few weeks back I wrote a piece about updating PHARs in-situ, what we've taken to calling "self-updating". In that article, I touched on making Transport Layer Security (TLS, formerly SSL) enforcement one of the central objectives of a self-updating process. In several other discussions, I started using the phrase "Lowest Common Insecure Denominator" as a label for when a process, which should be subject to TLS verification, has that verification omitted or disabled to serve a category of user with poorly configured PHP installations.



This is not a novel or even TLS-only concept. All that the phrase means is that, to maximise users and minimise friction, programmers will be forever motivated to do away with security features that a significant minority cannot support by default.




He goes on to talk about how, in some places, targeting the lowest common denominator is okay, security isn't one of them. He also includes four basic concepts developers can adhere to to prevent this targeting:



  • You should never knowingly distribute insecure code.
  • You should accept responsibility for reported vulnerabilities.
  • You should make every effort to fix vulnerabilities within a reasonable time.
  • You should responsibly disclose vulnerabilities and fixes to the public.


He follows these up with three steps you can follow to migrate an insecure architecture into something much more robust. This includes identifying the consequences of the update and documenting the solutions you've chosen, be those configuration updates or library changes.


Link: http://blog.astrumfutura.com/2015/04/tlsssl-security-in-php-avoiding-the-lowest-common-insecure-denominator-trap/

ServerGrove Blog: Useful Linux command-line tools to work with PHP projects


The ServerGrove blog has posted a new tutorial with a selection of useful command line tools to help you in working with your PHP applications. None of them are PHP specific but are Unix-based commands that can help in every day development.



Linux provides a lot of interesting command-line tools that we can use when working with PHP projects. In this post we give you some useful commands.

They include examples of commands that can help with:



  • Find all PHP files in the current directory
  • Check the syntax of all PHP files in the current directory
  • Get the size of each Composer dependency
  • Find suspicious PHP files
  • Find files with abstract classes
  • List PHP settings for the xdebug extension
  • Find empty files and/or directories
  • List files currently open by a PHP process


As mentioned, most of the tools themselves are not PHP specific but these example commands do relate to things that are more in a PHP context.


Link: http://blog.servergrove.com/2015/04/23/useful-linux-command-line-tools-work-php-projects/

Christoph Rumpel: Hello world, I am Laravel (5)


With Laravel 5 out in the wild, you may be wondering what this new version has to offer either as someone already using the framework or brand new. In this recent post from Christoph Rumpel you can find out some of the highlights of this new release along with some code samples to illustrate.



So there is this thing called Laravel. You may have heard of it already, but you're not sure what it is actually about? Or you do, but want to know more about it and its great new features in version 5? Great, this post is especially for you! Laravel is at the same time one of the youngest and most popular PHP frameworks out there. So how does this work together? Let us take a closer look at why it is that popular and how it could be of use for you too. We will go through the main functionalities and talk about brand new features in version 5.


He touches on several different topics including: routing, use of the Eloquent ORM, the "artisan" command line tool, controllers, migrations and form request handling. Each section has some example code and a brief description of the feature. Obviously the Laravel documentation is a much more complete resource for each of these topics, but at least this gives you a feel for the framework and what it can do.


Link: http://christoph-rumpel.com/2015/04/hello-world-i-am-laravel/

DigitalOcean Community Blog: Horizontally Scaling PHP Applications: A Practical Overview


On the Digital Ocean blog there's a new post with a "practical overview" of how to effectively scale PHP applications, specifically as it relates to horizontal scaling not vertical.



Shipping a website or application to production has its own challenges, but when it gets the right traction, it's a great accomplishment. It always feels good to see the visitor numbers going up, doesn't it? Except, of course, when your traffic increases so much that it crashes your little LAMP stack. [...] But fear not! There are ways to make your PHP application much more reliable and consistent. If the term scalability crossed your mind, you've got the right idea.


The article starts with a brief overview of what scalability is and the main difference between horizontal and vertical scaling (scaling out vs scaling up). They then get into a bit more detail about what horizontal scaling is and how it commonly works in relation to the average PHP application (complete with diagrams). They also talk about some things you can do inside your code to help make things flow a bit more smoothly including decoupling between services and user session/file consistency measures. There's also a bit at the end about load balancing but as that depends a good bit on what technology you're using and the actual load, they just provide an overview and some links to other articles and tutorials with more information.


Link: https://www.digitalocean.com/company/blog/horizontally-scaling-php-applications/

Setting the wp_remote_get() User Agent

I was recently trying to make some API requests from within WordPress using `wp_remote_get()`, but the site I was asking for data from was rejecting requests from the default WordPress User Agent. I tried to set the user agent to something different, but it still wasn’t working:


$response = wp_remote_get($url, array(

  'timeout' => 20,

  'User-Agent' => 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:20.0) Gecko/20100101 Firefox/20.0'

));


Thankfully, Otto spotted my problem. The `user-agent` key needs to be lowercase so that it is picked up properly by the WordPress core code. This works:


$response = wp_remote_get($url, array(

  'timeout' => 20,

  'user-agent' => 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:20.0) Gecko/20100101 Firefox/20.0'

));


And there you have it. It’s always nice to have an extra set of eyes on some code.

Waiting for Apple Watch

I know it only seems like everyone I know got an Apple Watch today, but my Twitter feed is full of photos of white boxes.


My watch order confirmation shows a 12:06am US/Pacific timestamp, but my order hasn’t even moved into “preparing for shipment” status yet. I saw one note on Twitter that indicated the cutoff for this first batch was likely 12:03am. I couldn’t even get the Apple Store app to load until around that time. I wonder how many orders were placed in those first few minutes.


Or perhaps the delay in delivery has to do with shortages for specific models. I ordered the Steel + Milanese Loop band, where most of the deliveries I’ve seen so far are for the Sport model. My order still shows a 4/24-5/8 delivery window, so I guess I’ll be seeing it sometime in the next two weeks.

2015年4月23日星期四

Site News: Blast from the Past - One Year Ago in PHP

Here's what was popular in the PHP community one year ago today:

ServerGrove Blog: Symfony2 components overview: OptionsResolver


The ServerGrove blog has posted another in their spotlights on specific Symfony2 components. In this latest post they look at the OptionsResolver component.



In the 13th post of the Symfony2 components series we will be talking about one little but extremely useful component: OptionsResolver. This component helps us to reduce the boilerplate code required to create an options system with default parameters. As stated in the official docs, is array_replace on steroids.


They start with a common situation, wanting to use options from user input, but only if they exist, and otherwise provide a default. This includes the use of the array_replace function but with the OptionsResolver there's an even easier way. A simple example is included showing how to use it to define options (and throw an exception when an undefined one is set). They show how to use a closure to set defaults on a specific option with more complex logic and how to use the validation and normalization handling.


Link: http://blog.servergrove.com/2015/04/13/symfony2-components-overview-optionsresolver/

PHP Town Hall Podcast: Episode 40: Return of the Ferrara


The PHP Town Hall podcast has posted a new episode today with the Return of the Ferrara. Hosts Ben Edmunds and Phil Sturgeon are joined once again by guest Anthony Ferrara to talk about, among other things, scalar type hints.



Regular guest Anthony Ferrara joins us "in the studio" to talk about the new version of his scalar type hints, which since recording - a f**king month ago - has been accepted for PHP 7. We thought it would be good to have a bit of a chat about the feature, the nonsense that surrounded it and a bunch of other random internals and PHP 7 related blathering.


You can catch this latest episode in a few different ways, either through the in-page audio player, by downloading the mp3 or through the video recording of the live session. If you enjoy the show, be sure to subscribe to their feed too.


Link: http://phptownhall.com/blog/2015/03/20/episode-40-ferrara-scalar-type-hints/

Stephan Hochdörfer: Processing CSV files in a memory efficient way


In his latest post Stephan Hochdörfer shares some of his experience in using the PHPExcel tool to parse CSV files and the performance issues he ran into. Fortunately, he found a solution...in the form of another library.




A little while ago I had to dive deeper into the performance optimized usage of PHPExcel. Our users are uploading files like Excel or CSV with a lot data to process. Initially we used the PHPEXcel instance without any tuning of the default configuration which lead to heavy memory issues on relativly small files. So I had to avoid reading all file content at ones to the buffer (like file_get_contents does).



In my research mainly optimizing the usage of PHPExcel I came across a tiny library I am grown really fond of. It is called Goodby/CSV. Both tools have a very well grounded documentation to read in and understand the basics and the usage.




He describes some of the main differences between the two tools and includes some basic benchmark results comparing memory consumption and overall speed.


Link: https://blog.bitexpert.de/blog/processing-csv-files-in-a-memory-efficient-way/

SitePoint PHP Blog: StackPHP Explained


The SitePoint PHP blog has a tutorial posted today that wants to help you understand StackPHP, the project centered around middleware, specifically related to the Symfony2 HttpKernelInterface.



Today we are going to look at StackPHP and try to understand what this thing is all about. Although this post will have some code, this article will be rather theoretical as we are interested in learning what StackPHP actually is, where it comes from and why it is useful. As the front page of the StackPHP project says, Stack is a convention for composing HttpKernelInterface middlewares. But, in order to actually understand this definition, we will have to cover a few concepts first. At the end, we will also illustrate the concepts we learned in the context of StackPHP with some example code.


They start with a brief look at the HttpKernelInterface and how it works with the overall request and response flow of a typical application request. From there they describe the Decorator design pattern that will be used to augment the request/response objects as they're going through the middleware process. Following this they look at how StackPHP fits into this picture and provides a few code examples showing both basic and a bit more complex middleware handling (including the use of StackBuilder).


Link: http://www.sitepoint.com/stackphp-explained/

David Lundgren: When does Dependency Injection become an anti-pattern?


In a new post to his site David Lundgren wonders when dependency injection becomes an anti-pattern when used in PHP applications. The idea of dependency injection is to provide objects with instances of other objects representing things they'll need to get the job done (goes along with separation of concerns). Unfortunately, if used incorrectly, DICs - dependency injection containers - can become less useful and more of a hinderance than a positive part of the application.



During my tenure as a seasoned, and tenderized, PHP developer I have used many design patterns: adapters, factories, data mappers, facades, etc. The most recent one that I have been working with is Dependency Injection. Inversion of Control is not a new idea, at least not in the programming world, but in the PHP world it seems to have taken us by storm in recent years. Every framework will often have a Dependency Injector built in, or offer it as a component for use. It is the hip thing to do in PHP, but I believe we need to take a step back and evaluate it for what we are really trying to achieve. That is reducing the tight coupling that our objects may have. I view it as removing the new-able's from our objects code, and handing the object creation over to something else to deal with.


He talks about how dependency injection containers and service locators relate to each other. He also suggests that, at the heart of every dependency injection container, there's a service locator. He gives an example of a project where a large number of dependencies are being injected and how, despite the assumption of flexibility, his dependencies don't change that often, making the DIC and its functionality a bit less important.


Link: http://davidscode.com/blog/2015/04/17/when-does-dependency-injection-become-an-anti-pattern/

Share Icon on Google Homepage

share-icon-google


It was very cool to see the Share Icon on Google’s homepage today. Thanks to Mark for making sure I saw it.


This post is part of the project: Share Icon. View the project timeline for more context on this post.

2015年4月22日星期三

Community News: Recent posts from PHP Quickfix

Recent posts from the PHP Quickfix site:

Full Stack Radio: 15: Everzet - Classicist and Mockist TDD


The latest episode of the Full Stack Radio podcast, episode #15, features a focus on Behat (the PHP BDD testing tool) and an interview with its creator Konstantin Kudryashov, aka everzet.



In this episode, Adam talks to Konstantin Kudryashov, creator of Behat and BDD Practice Manager at Inviqa. Konstantin and Adam talk about the schools of TDD, how to use test doubles effectively, and common challenges people face when trying to learn TDD.


They talk about several other subjects besides just BDD too including the book "Test Driven Development: By Example" and Ian Cooper's talk "TDD: Where did it all go wrong?". You can listen to this latest episode either through the in-page audio player or by grabbing the mp3. If you like the episode and want to hear more, be sure to subscribe to their feed too!


Link: http://fullstackradio.com/episodes/15/

Scotch.io: Build a Time Tracker with Laravel 5 and AngularJS - Part 2


Scotch.io has posted the second part of their series today showing you how to build a simple time tracking application with Laravel and AngularJS. In this latest part of the series he finishes the application and connect the two pieces.



This is the second of a two-part series on using Laravel 5 and AngularJS together to build a simple time tracking application. If you've gone through part 1, you'll have seen that we put together the front-end first and used a simple JSON file with some mocked-up data to test with. We left off with the ability to add new time entries and have the total time from all of them display on the side. We didn't include any way to edit or delete the time entries, and of course there was no persistence to a database. In this part we will complete the application so that the time entries get stored in a database and our Angular front-end and Laravel backend work together to create, read, update and delete from it.


He starts by helping you get a Laravel application up and running (time-tracker-2), set up the database and modify the configuration to point to the database location. He helps you run the migrations to set up the database tables and generate the related model code. Next up he shows how to inject the seed data, setting up the main index view and adding in routes for the Angular code to access. The rest of the article is just about as detailed and covers steps to:



  • View all the Available Routes
  • Return all Time Entries
  • Return All Users
  • Updating the front-end
  • Setting up the users list
  • Creating time entries
  • Updating time entries
  • Deleting time entires


Finally he wraps it all up with a few possible things that could be done to improve the application, both simple and a bit more complex. He challenges you the developer to implement those features.


Link: https://scotch.io/tutorials/build-a-time-tracker-with-laravel-5-and-angularjs-part-2

ServerGrove Blog: Symfony2 components overview: Filesystem


The ServerGrove blog has posted another in their series of Symfony2 component spotlights with a look at the Filesystem component.



The 15th post of the Symfony2 components series is focused on the Filesystem component, which provides some basic utilities to work with the filesystem. It extends PHP built-in functions such as mkdir() or copy() to make them more portable and easier to use and test.


They start by stating the common problems with working in the file system from PHP and the warnings/errors that can come with them. They show how this kind of thing can be prevented with the Filesystem component and the functionality it provides. They also list some of the other useful functions (besides mkdir and touch previous mentioned) including: chmod, rename, makePathRelative and mirror. They also briefly mention the file locking ability the component has to prevent issues with multiple services interacting with the same files.


Link: http://blog.servergrove.com/2015/04/22/symfony2-components-overview-filesystem/

TechEmpower.com: Web Framework Benchmarks - Round 10


The TechEmpower.com site has posted round 10 of their PHP framework benchmarks that includes several test types and hardware configurations.



Round 10 of the Framework Benchmarks project is now available! It has been a little less than a year since the previous round and in that time, approximately 133 contributors have made 2,835 git commits. View Round 10 resultsThese contributions have improved the project's toolset and added many new framework test implementations.


Frameworks tested include Phalcon, Slim, Yii2, Fuel, Symfony2, Laravel and CodeIgniter. They've run tests on:



  • JSON serialization
  • Single queries (requests)
  • Multiple queries (requests)
  • Fortunes
  • Data updates
  • Plaintext output


If you click on each item in the tab list above the results, you'll also get a description of what each test entails. They also provide the results in multiple formats, not just in graphical form that include both latency and framework overhead. You can also read more commentary about the results in this related blog post.


Link: https://www.techempower.com/benchmarks/#section=data-r10

An Engineering Design Process

Our recent explorations into the world of connected hardware have taught us a lot about the engineering design process. Namely, engineering design is not a linear path, but a highly creative and dynamic process characterized by problem definition, rapid iterations, and working solutions. I’d like to take some time to touch on this process by illustrating its nuances within the context of a novel internal project: The Whiteboard Cleaner Bot.





Whiteboard cleaning prototype: An internal propeller pushes a rotating cleaning head into the whiteboard.


I’ve broken down our engineering design process into five steps:




  1. Identify the problem

  2. Research the problem

  3. Brainstorm and choose a promising solution

  4. Prototype the solution

  5. Evaluate and improve the prototype.



Let’s explore each step in greater detail, using the Whiteboard Cleaner Bot as our example.



Step 1 - Identify the Problem



As obvious as it may sound, every solution begins by clearly defining the problem/challenge.  To flesh this out, we ask questions such as: What problem needs solving? Who is it for? Is there a budget? How about a timeline? Will it need to operate underwater or in space?



Example: We realized we had an itch -- dirty whiteboards. We wanted an automatic solution that would be as simple as a light switch. Cost was a constraint. It needed to be cheap. For us, a successful win would look something like a clean whiteboard.



Step 2 - Research the Problem



The second step involves relevant self-education. Do off-the-shelf solutions already exist? Can aspects of existing solutions be improved upon? Do similar solutions or useful technologies exist in adjacent markets? How much pain does the problem cause, and how strongly is a solution needed?



Example: Our research uncovered a number of autonomous cleaning solutions. There are window cleaning robots that climb skyscrapers with suction cups. There are robots that clean massive solar arrays in the solar photovoltaics industry. But, in the automatic whiteboard cleaning space, there are very few players. Maybe this is because the pain is too minimal, or the cost is too high.



Step 3 - Brainstorm and Choose a Promising Solution



The third step involves everyone. Gather a team around a whiteboard, use post-it notes, throw caution to the wind, and brainstorm potential solutions. Temper ideas against design constraints. Compare the best ideas. Finally, select which idea you will prototype.



Example: We gravitated towards a solution that was fairly out of the box but which also felt promising. We’re constantly on the lookout for interesting engineering challenges and this met the bill. Our design involved a cleaning vehicle suspended by fishing line. Stepper motors at the end of the fishing line coordinated the movement of the cleaning vehicle.





Step 4 - Prototype the Solution



Prototypes are functioning versions of the solution. The early versions are rough and unpolished; but, they help to quickly verify a design by identifying its strengths and weaknesses. Often, they are built to test critical functions. But, not every prototype will test every aspect of a solution. In some cases, prototypes require incremental progress, a small change with each iteration. In this way, they continually evolve.



Examples: Our first prototype of the Whiteboard Cleaner was built from low-cost RC components and cardboard. Our intention was to quickly validate our design approach for the cleaning mechanism.





In our second iteration we leveraged RC components and a 3D printed chassis. This enabled the first complete test of our solution.





Step 5 - Evaluate and Improve the Prototype



Thinking of the prototype as part of the working solution is valuable because you leave room for critique and improvement in future iterations. Be open to complications that challenge your idea and make it better. Once the initial prototype is tested, get everyone together to think critically. Did it solve the problem you originally identified? What worked well? What didn’t work at all? Perhaps there are many areas for improvement.



Examples: We noticed that our design would wobble uncontrollably without additional points of contact. During one test, the entire prototype dropped to the ground and broke -- only the strongest parts of the cleaning vehicle survived. Though the drop test was unexpected, it led us to reinforce and reorient the cleaning vehicle. The result was a stronger and more stable prototype.





Supports added during testing pictured above (in black).





Reinforced/reoriented design pictured left. Original design pictured right.



Conclusion



We were excited with the progress we had made on the Whiteboard Cleaning Bot. And, while it worked, it was not the lean mean cleaning machine we had hoped for. However, it was a wonderful engineering challenge and we thoroughly appreciated the process that guided us along the way.



Please feel free to ask any questions about the Whiteboard Cleaning Bot, or our process, in the comments below.





The completed Whiteboard Cleaning Bot. A microcontroller and IR detector receive instructions and control the rotating cleaning element.

2015年4月21日星期二

Community News: Latest PECL Releases for 04.21.2015

Latest PECL Releases:
  • lzf 1.6.3
    - PHP 7 compatibility
    - move liblzf sources to /lib directory
    - add --with-liblzf option to use system liblzf
    - add LICENSE file in documentation
    - adapt Windows build (Anatol)
    - add arginfo for reflection


  • hprose 1.4.2
    Fixed segmentation fault when serialize/unserialize custom PHP class object on Non Thread Safe (NTS) PHP.


  • xattr 1.2.1
    - PHP 7 compatibility (Remi)
    - add LICENSE to documentation
    - add arginfo for reflection (Remi)
    - add a test for set/get/list/remove functions (Remi)


  • amqp 1.6.0beta3
    1.6.0beta3 Release:
    * Add basic.recover AMQP method support (see AMQPChannel::basicRecover() method) (Bogdan Padalko)
    * Fix building on OS X (Bogdan Padalko)

    For a complete list of changes see:
    https://github.com/pdezwart/php-amqp/compare/v1.6.0beta2...v1.6.0beta3

    1.6.0beta2 Release:
    * Pulled 1.6.0beta1, as it had the stable tag

    For a complete list of changes see:
    https://github.com/pdezwart/php-amqp/compare/v1.6.0beta1...v1.6.0beta2

    1.6.0beta1 Release:
    * Add support for nested arguments values (Bogdan Padalko)
    * Add auto_delete and internal flags support for AMQPExchange::declare (librabbitmq version > 0.5.2 required) (Bogdan Padalko)
    * Fix persistence support (Bogdan Padalko)
    * Add AMQPExchange::unbind method and fix AMQPExchange::bind method. WARNING: this can potentially break BC (Bogdan Padalko)
    * Add support to consume messages from multiple queues (Bogdan Padalko)
    * Add AMQP_DURABLE flag support to AMQPExchange::setFlags (librabbitmq version > 0.5.2 required) (Bogdan Padalko)
    * Fix inconsistent INI values comparison which leads to deprecation warnings (Bogdan Padalko)
    * Various segfault and memory leak fixes (Bogdan Padalko)

    For a complete list of changes see:
    https://github.com/pdezwart/php-amqp/compare/v1.4.0...v1.6.0beta1

    1.4.0 Release:
    * Fix #72: Publishing to an exchange with an empty name is valid and should not throw an exception (lstrojny)
    * Fix #77: AMQPQueue::delete() now no longer returns a boolean, but an integer of how many messages were deleted. WARNING: this can potentially break BC (Bogdan Padalko)
    * Fix #75: adhering to the AMQP spec by closing channel and sometimes even the connection in case of certain errors (Bogdan Padalko)
    * Fix #81: Add optional arguments parameter to bind()/unbind() (Michael Squires)
    * Fix #82: additional getters (getChannel(), getConnection()) (Bogdan Padalko)
    * Fix #92: fix various memory leaks in the AMQPConnection class (Lars Strojny)
    * Using amqp_error_string2() instead of deprecated amqp_error_string() (Lars Strojny)
    * Fix memory leaks in setHost, setLogin, setPassword, setVhost (Lars Strojny, Bogdan Padalko)
    * Fixed a memleak in php_amqp_connect (Julien Pauli)
    * Use rabbitmq-c defaults for max channels and default frame size (Bogdan Padalko)
    * Fix socket timeout error when connecting over high-latency network (Bogdan Padalko)

    For a complete list of changes see:
    https://github.com/pdezwart/php-amqp/compare/v1.3.0...v1.4.0

    1.3.0 Release:
    * Allow retrieving auto-delete exchanges (Guilherme Blanco)
    * Add connection timeout support. This requires bumping the version requirement for librabbitmq to >= 0.4.1 (Bogdan Padalko)

    For a complete list of changes see:
    https://github.com/pdezwart/php-amqp/compare/v1.2.0...v1.3.0

    1.2.0 Release:
    * New methods AMQPChannel::getPrefetchCount() and AMQPChannel::getPrefetchSize()
    * Deprecate AMQPQueue::declare() in favor of AMQPQueue::declareQueue()
    * Deprecate AMQPExchange::declare() in favor of AMQPExchange::declareExchange()
    * Smaller fixes to our stubs

    For a complete list of changes see:
    https://github.com/pdezwart/php-amqp/compare/v1.0.10...v1.2.0

    1.0.10 Release:
    * report correct version in module info (Lars Strojny)
    * fix class interface definitions (Vladimir Kartaviy)
    * add ability to bind a queue with an empty routing key (Vladimir Kartaviy)
    * fix constant AMQP_IFUNUSED (Florin Patan, Bernhard Weisshuhn)
    * added stubs for ide use (Vladimir Kartaviy, Bernhard Weisshuhn)
    * Fixed memory leak in queue->declareQueue (Ilya a.k.a. coodix)
    * support for php 5.5 (Lars Strojny)
    * add support for read and write timeouts (Bogdan Padalko)
    * fix memory leak in queue->consume (Dmitry Vinogradov)
    * add support for custom exchange types (empi89)
    * support for nested custom headers (Bernhard Weisshuhn)
    * fix memory (Bernhard Weisshuhn)

    For a complete list of changes see:
    https://github.com/pdezwart/php-amqp/compare/v1.0.9...v1.0.10

    1.0.9 Release:
    * Fix pecl relase

    1.0.8 Release:
    * Skip var_dump test on PHP 5.2
    * Initialize consumer tag string length to zero
    * Support connection time outs
    * Adding consumer_tag parameter to AMQPQueue::cancel
    * Clean up error code handling

    1.0.6 Release:
    * 62354: Segmentation fault when printing or dumping an object that contains an AMQP object
    * Adding in missing tests
    * Fixing release number in PHP information
    * Adding .gitignore info for Git users
    * Cleaning up debug handling

    1.0.5 Release:
    * 62696: Incorrect exchange type
    * Handles server connections being closed during consume and publish correctly
    * 62628: Exception thrown in consume will lock PHP
    * 61533: Segmentation fault when instantiating channel, queue or exchange with wrong object, then using it

    1.0.4 Release:
    * 62549: Fixing broken persistent connection
    * 62412: Fixing segfault due to destruction order
    * 62411: Fixing declaration overload bug
    * 62410: Fixing declaration overload for 5.4
    * 61337: Adding License file
    * 61749: Fixing handling for binary content in envelope
    * 62087: Adding appropriate version information
    * 62354: Enabling debugging dumping of objects
    * 61351: Updating min PHP version requirements to 5.2.0

    1.0.3 Release:
    * Fixing compilation issue with PHP 5.4

    1.0.2 Release:
    Fixed bug:
    * Memory leak when using AMQPQueue::get from a queue with no messages

    1.0.1 Release:
    Fixed bug:
    * 61247: Allow queue creation with empty queue name, and return auto generated name
    * 61127: Segmentation fault when cleaning up an AMQPChannel without calling AMQPConnection::connect first

    1.0.0 Release:
    Changed/finalized API signature:
    * Exposing AMQPChannel
    * Exposing AMQPEnvelope
    * Exposing more queue and exchange arguments and flags
    * Exposing basic.qos
    Added persistent connections
    Cleaned up codebase
    Fixed memory leaks and segmentation faults

    0.3.1 Release:
    Fixed bug:
    * 24323: Cannot get the name for auto-named reply-to queues

    0.3.0 Release:
    Fixed memory leaks in many functions (courtesy Jonathan Tansavatdi and Andy Wick)
    Fixed consume method to return proper values
    Cleaned up variable usage
    Fixed bugs:
    * 22638: Unexpected exit code 1 with AMQPQueue::consume()
    * 22698: AMQPQueue::consume

    0.2.2 Release:
    Made extension compatible with PHP lt 5.3 (courtesy John Skopis)
    Fixed wrong typing of message properties (courtesy John Skopis)

    0.2.1 Release:
    Fixed refcount decrementing bug causing segfaults.

    0.2.0 Release:
    Works with AMQP 0-8 and 0-9-1 (used by RabbitMQ 2.*)
    Modified AMQPConnection object:
    * Requires call to 'connect' method to connect (no longer connects on instantiation)
    * Added support for disconnect and reconnect
    * Added helper setters for port, host, vhost, login and password
    Improved consume method to block for MIN messages, and try to get MAX messages if available
    Fixed zval descoping bugs
    Fixed bugs:
    * 17809: Couldn't compile pecl extension under PHP 5.3
    * 17831: Segmentation fault when the exchange doesn't exists
    * 19707: AMQPQueue::get() doesn't return the message
    * 19840: Connection Exception


  • zip 1.12.5
    - add OPSYS_Z_CPM missing constant
    - Fixed bug #69253 (ZIP Integer Overflow leads to writing past heap boundary). (CVE-2015-2331) (Stas)


  • libsodium 0.1.3
    crypto_scalarmult() has been added.


  • timezonedb 2015.3
    Updated to version 2015.3 (2015c)


  • swoole 1.7.15
    - Fixed swoole_client waitall parameters failures
    - Fixed swoole_table dead loop BUG
    - Disable swoole_websocket_server->send method
    - Added swoole_table->incr/decr methods
    - Added http server gzip compression supports
    - Added swoole_server open_eof_split configuration


  • ZendOpcache 7.0.5
    - Fixed bug #69281 (opcache_is_script_cached no longer works)
    - Fixed bug #68677 (Use After Free in OPcache)
    - Make killing a locker an ERROR event
    - Fixed bug #69125 (Array numeric string as key)
    - Fixed bug #69038 (switch(SOMECONSTANT) misbehaves)
    - Fixed segfault while running with moodle