Saturday, May 24, 2014

Leaving PHPTek


As I'm waiting for my flight at Chicago O'Hare airport, I decided it was a good time to write up my experiences I had at PHPTek in Chicago. I can describe the event as AWESOME as I met a ton of new people and learned quite a bit during the sessions and in hallway tracks.

If you're not familiar with PHPTek, let me enlighten you a bit. PHPTek is an annual PHP conference organised by php[architect], the company that publishes books and a monthly magazine. Each year PHPTek is being held in Chicago (USA). Even though this conference is a commercial conference by nature, once you attend it you don't feel that commercial pressure at all. The talks are all technical or soft-skill related without service or product sales pitches which makes PHPTek a great conference to attend if you're a developer. For business owners, managers and other non-technical folks it's also a great conference as you get in touch with an international community of PHP developers and businesses that allow you to establish long-lasting relationships and first class support on products or services you might use from the sponsors of the event.

This edition of PHPTek the crew behind the conference really raised the bar compared to last year. The food was incredibly good, the sessions were divided better with enough time between sessions to talk to speakers, get a drink or have a smoke. The crew created a schedule where more than once I had to decide between sessions and not once I regretted making a tough choice.

In2it sponsoring the PHPTek Open Spaces
It was also the first year that the conference offered "open spaces" besides the presentations which my company in2it sponsored. The concept of open spaces is simple: you have a round table discussion about a subject for the length of a regular talk, and the topic can be anything: keysigning, community discussions or business/customer discussions to improve the products or services. Each slot the open spaces was taken and it was great to see lots of people had great discussions there. So on behalf of in2it: thank you all for participating and we hope to be able to sponsor this opportunity again next year.

Ben Marks discussing Magento with users
The evening socials were inspiring, educative and above all: a lot of fun. From boardgames to hackathon, all was possible.

So all in all, I had a blast learning a ton of new things I need to try out at home and I'm really happy to have seen so many new faces. I hope to keep seeing them in the future at any other conference on this planet. And I would like to express my gratitude to the organisers of PHPTek, because they pulled of a great event and I'm already looking forward to next year's edition of PHPTek!

Wednesday, April 30, 2014

LoneStarPHP 2014 in review

Last week I returned from LoneStarPHP conference in Addison, Texas. The first thing I noticed flying over the area that all is flat and very extend. Later I heard from Omni Adams, who came to pick me up at the airport, that this was as a protection measure for storms and tornadoes that appear from time to time.

The hotel was Marriott SpringHill Suites Dallas Addison/Quorum Drive which was a very nice hotel. The hotel staff was very friendly, common to the area I was told and had the best feature: non-stop supply of coffee! Already scoring good in my book.

As tradition dictates, all the speakers were invited to a dinner the evening before the conference kicked off. The LoneStarPHP crew arranged something at a traditional BBQ & Grill called "Hard Eight BBQ" which was about an half hour drive away from the hotel.
The meat at Hard Eight BBQ
This was the first time I was at such a place, but I enjoyed the delicious meats they served. Surprising to see that just a bit of meat could fill one up so quickly.

The conference lineup was incredibly well orchestrated and it was sometimes difficult to choose which session to attend. I was able to sit in sessions of Adam Culp, Keith Casey and a small part of Eryn O'Neil before I had to go on stage and present my talk "Your code are my tests". I received good feedback on joindin to improve this talk even further and got compliments on Twitter and in the hallway from people that needed this type of talk to see that you can get started with unit testing on any given project at any given time, even though writing tests close to writing the code it covers is still better (and TDD is still ruler in this field).


The closing keynote was given by Alison "Snipe" Gianotto about security. Even though we all know how important security is, Alison showed us with some statistics how bad we all are at security and gave us tips to improve. If you care about security (and you should), go grab her slides now!

That evening the crew had activities in store but I had the pleasure to sit outside and talk with Alison. Soon our conversation took a full 180ยบ turn and draw out a decent amount of people joining our conversation. It was awesome!

The second conference day was again challenging to choose between all the great talks. I had chosen for the talks of Eli WhiteJeremy Lindblom and Jeff Carouth. Again, it was tough to choose but my chosen talks were exactly what I needed and picked up a couple of things.
Eli White talking about his time working for the NSA
I closed the sessions track with my "Community works for business too" presentation, talking about how businesses and their employees could do little things to give back to the (PHP) community.

Larry Garfield closed the conference with a keynote on refactoring explaining the challenges they faced on their road towards Drupal 8. An excellent keynote!

This was a superb conference I enjoyed so much, I want to book my ticket for next year already. I want to thank the whole LoneStarPHP crew who made this possible and I hope to see you all next year.

Saturday, March 08, 2014

Bootstrapping ZF1 application in Apigilty

Apigility
Apigility is a Zend Framework 2 tool that provides a REST API management interface, which is very useful if you want to build an API.
Apigility can directly connect with your database and offer a full REST API for your application, but in most cases you already have an application build with Zend Framework 1.x (ZF1). Let's assume you have incorporated a lot of business logic in this application so it would be a waste not to use it building a rich REST API.
This article describes what needs to be done to incorporate your ZF1 application into a vanilla installation of Apigility. It will not describe the installation of Apigility as this is fully documented on the Apigility website.
NOTE: We use our demo ZF1 application as example.

Including your ZF1 app into Apigility

The easiest way is to use Gitmodules if you have your ZF1 project in GIT. If you have your ZF1 project in SVN, you need to do a manual checkout of the project.
Since Apigility uses Composer for installation and updates, we decide that our ZF1 application should be installed in the vendordirectory.

Using Gitmodules

As said, the easiest way would be to use Gitmodules.
$ git submodule add https://github.com/in2it/zfdemo.git vendor/zfdemo

Using Subversion

Alternatively we can use Subversion
$ svn co https://github.com/in2it/zfdemo/trunk vendor/zfdemo
NOTE: This requires often manual updates if the source of your ZF1 changes!

Zend Framework 1

If you're application does not come pre-installed with Zend Framework, the easiest way to include it in your project is to add it to your composer.json of Apigility.
Add the following to your Apigility composer.json:
"zendframework/zendframework1": "1.12.5"
This should be added within the require segment, as displayed below.
"require": {
    ...
    "zendframework/zendframework1": "1.12.5"
}
Now add a symlink in your Zend Framework 1 library pointing to this repository.
$ cd vendor/zfdemo/library
$ ln -s ../../zendframework/zendframework1/library/Zend Zend
$ cd ../../.. (application root)
With this setup, you now have the ZF1 library autoloaded

Custom libraries

If your application uses 3rd-party libraries or custom libraries, you need to see if they exists as Composer packages or if they are available through SCM (GIT or Subversion).
For our zfdemo, we depend on In2it library which is on GitHub, but not available as a Composer package. So for our own convenience we add them as a Gitmodule.
We need to make the exception in our .gitignore file to allow adding our library in, so we add the following line into our .gitignore file.
!vendor/In2it
Now we can safely add the library as Gitmodule.
 $ git submodule add https://github.com/in2it/In2it.git vendor/In2it
Lastly we add a symlink in our vendor/zfdemo/library to point to our In2it library.
$ cd vendor/zfdemo/library
$ ln -s ../../In2it/library/In2it In2it
$ cd ../../.. (application root)

Changing APPLICATION_PATH in index

The entry point for Apigility's web interface, sets up the include paths, environments and loads the ZF2 application. But it also uses constants that are used in ZF1 which conflict when using both applications at the same time.
We therefor change the Apigility public/index.php file and replace APPLICATION_PATH into ZF2APP_PATH. So the public/index.php file looks like this:
<?php
/**
 * @license   http://opensource.org/licenses/BSD-3-Clause BSD-3-Clause
 * @copyright Copyright (c) 2014 Zend Technologies USA Inc. (http://www.zend.com)
 */

/**
 * This makes our life easier when dealing with paths. Everything is relative
 * to the application root now.
 */
chdir(dirname(__DIR__));

// Decline static file requests back to the PHP built-in webserver
if (php_sapi_name() === 'cli-server' && is_file(__DIR__ . parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH))) {
    return false;
}

if (!file_exists('vendor/autoload.php')) {
    throw new RuntimeException(
        'Unable to load ZF2. Run `php composer.phar install` or define a ZF2_PATH environment variable.'
    );
}

// Setup autoloading
include 'vendor/autoload.php';

if (!defined('ZF2APP_PATH')) {
    define('ZF2APP_PATH', realpath(__DIR__ . '/../'));
}

$appConfig = include ZF2APP_PATH . '/config/application.config.php';

if (file_exists(ZF2APP_PATH . '/config/development.config.php')) {
    $appConfig = Zend\Stdlib\ArrayUtils::merge($appConfig, include ZF2APP_PATH . '/config/development.config.php');
}

// Run the application!
Zend\Mvc\Application::init($appConfig)->run();

Autoloading of ZF1 classes and services

Now the most challenging part of this assignment is to autoload our ZF1 classes and services, we mighte even need to make the ZF1 classes available (but we can always add them as a seperate library in vendor directory).
I had a discussion with the Aleksey (@xerkus) and Evan (@EvanDotPro) of Roave regarding the best way to bootstrap ZF1 applications in ZF2 architectures.
It seemed that Aleksey already created a ZF2for1 bootstrapper, where they allowed ZF2 resources to become available in ZF1 applications. A reverse way of what we want to achieve.
I created a zf1to2 bootstrapper in my zfdemo application, which is basically the same as a vanilla ZF1 public/index.php file, except it doesn't contain a run() call on $application->bootstrap(). It just needs to bootstrap the application without running it.

Getting started with Apigility

Apigility requires read/write permissions on the configuration files, so don't forget to allow write access for your application if you're using a web server (like Apache or Nginx). If you run Apigility from the buildin PHP server, you won't have any issues as the user you run the app is most likely the same that owns the configuration files.
$ chmod -R go+w config/ data/ module/
When you go the url of your Apigility project (in my case it's http://zf-apigility.local), you should see the welcome screen.
Apigility Welcome
Now it's time to add endpoints. So in "Admin" -> "API's" we create an new API for "zfdemo", our demo application. Of course you can replace this with your own application name.
New zfdemo API
Now we add REST endpoints to our application. To start we define an endpoint for "user" and we choose a "Code-Connect" endpoint.
REST user endpoint
When we look at the "resources" tab, we see three defined files there:
  • Collection Class: zfdemo\V1\Rest\User\UserCollection.php
  • Entity Class: zfdemo\V1\Rest\User\UserEntity.php
  • Resource Class: zfdemo\V1\Rest\User\UserResource.php
We only need to work with the Resource Class file as this is the one actually building the logic in a similar way we build it initially in our demo application.
To test our installation, we can make a GET call to http://zf-apigilty.local/v1/user and we should receive the following JSON string
{"type":"http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html","title":"Method Not Allowed","status":405,"detail":"The GET method has not been defined for collections"}

Modifying Resource Class

As this resource is created automatically by Apigility, it might be you need to modify permissions before you can edit and save your changes.
$ sudo chmod go+w module/zfdemo/src/zfdemo/V1/Rest/User/UserResource.php
To continue, the easiest way to start is to see if you can fetch a collection of user entities and fetch a single entity of this user by providing an ID.
So modifying fetch() and fetchAll() methods in UserResource would allow us to do this.
/**
 * Fetch a resource
 *
 * @param  mixed $id
 * @return ApiProblem|mixed
 */
public function fetch($id)
{
    $service = new \User_Service_User();
    $result = $service->findUserById($id);
    return $result->toArray();
}

/**
 * Fetch all or a subset of resources
 *
 * @param  array $params
 * @return ApiProblem|mixed
 */
public function fetchAll($params = array())
{
    $service = new \User_Service_User();
    $result = $service->getAllUsers();
    return $result->toArray();
}
So when we access http://zf-apigility.local/v1/user/922 we receive the following result.
{"id":922,"name":"Devan Armstrong","email":"destiney.parker@yahoo.com","password":"galbibtlrvp","created":"1998-04-10 23:53:31","modified":"1993-10-18 04:29:35","_links":{"self":{"href":"http:\/\/zf-apigility.local\/v1\/user\/922"}}}
NOTE: The reason we return our objects as arrays is that if we use our objects, Apigility returns our ID as \u0000*\u0000_id":922, which doesn't work well. This is because of the hydrator that tries to access protected properties of the entity classes.

Let me know if it worked for you

As Apigility is fairly new and people have a bunch of ZF1 projects to maintain, I hope this tutorial allowed you to use your existing applications while still using your older ZF1 projects.

Let me know how this worked out for you and if you have encountered any difficulties setting it up.

Sunday, February 16, 2014

I will use this password only once

Source Flickr: Lou_Lou Chan
Sad to see that people still use a single password for all their online accounts. Every day we read about accounts being compromised, major web sites being hacked and personal details stolen.

There's not a 100% secure way of securing web sites, there will always be flaws in the system that are beyond your control (like the latest Target credit card heist). But as a user, there are a lot of things you can do to ensure that whenever a site gets compromised, you don't have to worry your other accounts are in danger.

Single email address per account

First of all, if you have a Google account there's a nice trick you can do that your have only one email address assigned with an online service. A regular Google mail account looks something like <username>@gmail.com. But when you register with an online service, you can enter <username>+<servicename>@gmail.com. So, whenever this service gets compromised, you can watch suspicious emails entering on <username>+<servicename>@gmail.com and filter them out.

If you use another mail service (or have a mail service of your own) you might want to use a wildcard to accept emails, so whenever you signup for an account you can just use <servicename>@yourmail.tld.

Use one password per account

Secondly, I can only urge you to use a password tool like 1Password, LastPass or KeePass. Because you only need to remember a single password, the password for the tool itself and from that point on, you can have a different password for each account you create.

I use 1Password myself and I'm pretty happy about it. I now have for each account a different password, and I use it even for generating (and remembering) database passwords, keeping track of my loyalty programs and even store hash keys I use to connect to other servers using SSH or SSL.

1Password interface: clean, very convenient and secure
The nice thing of 1Password is it integrates with your OS and directly with your browsers. So whenever you open a website that requires authentication, you just click the plugin in your browser, enter your password and have it fill out the form. Just that easy.

But also using it for your databases, credit cards, loyalty programs and whatever thing you need to remember securely. And you save it securely with your "master" password on your computer. Just make sure this single password is the most difficult one to remember. Using a quote from a book or a movie is always a great way to secure things with a passphrase, especially when you combine 2 quotes in different languages. This ensures no one has direct access to those passwords when your computer gets stolen. I'm saying "direct access" and not "no access" as people can still try to break in once they have direct access to your computer.

Limitations on the web

Even when I'm using a password tool to generate automatic passwords, I sometimes stumble against web sites that have strict regulations on how passwords should be made. You might want to think twice using a service like that because for passwords you should be able to use any character at your disposal and as long as you want it to be.

For instance Microsoft has a limitation of 16 characters for passwords on their services.
16 Character limit on passwords by Microsoft
Other websites have even limitations on what characters you can use, which might indicate they're not even hashing passwords on their services. Another reason you want to have a password stored there that's not used anywhere else.

Your web applications

When you build a web application with authentication, be sure to allow people use whatever password they want, even if they want to paste in the whole Macbeth book.

On the backend you might want to use PHP's password_hash that's now being provided by PHP 5.5. If you haven't upgraded yet to PHP 5.5 yet, check out Anthony Ferrara's talk on password hashing, he even has made a video of it.

Conclusion

Keep your passwords safe, secure and use them only once! On the backend you need to ensure that you keep those passwords secure and difficult to break. And allow all input!

Wednesday, February 12, 2014

There's no PHP user group here!

PHP User Group PHPBenelux

When going to conferences you always hear "join a local user group, and if there's none in your area you're the person who needs to start one". But then what? Where do you get started? How do you organise a PHP user group? Basically, you're left in the dark and you're missing out of all the great stuff everyone else can enjoy.

So how do you get started?

You've attended a conference or visited a remote user group and you're completely pumped up to start a local community in your area. But how do you organise a user group meetup? How do you let people in your area know, you've started something for developers to meet each other, learn from each other and have a good time?
There's no one-size-fits-all solution to these questions though, most of it depends where you're located and what the penetration level is of PHP developers.

Meetup.com

Meetup.com
The easiest way to let everyone know you're organising a PHP meetup, is using Meetup.com where you can announce your meetups, create a user group profile and more. You can even use meetup as your user group webpage if you don't want to invest in setting up a seperate web page.
Everyone who's already a member of Meetup will receive a mail informing them there's a new meetup in their area: yours!
Meetup costs about $ 2.00 per month

Facebook.com

Facebook.com
If you don't want to invest money in setting up a user group, you can use also Facebook and create a group for your user group. It doesn't inform members there's a new user group in their area likeMeetup.com does, but via facebook sharing you might get some traction throug your peers.

Linkedin.com

Linkedin.com
As a professional, most likely you have a Linkedin profile. If not, I can highly recommend it as it is your professional network hub which you want to use anyways when networking during user group meetups.
Another benefit of Linkedin is you can search for PHP in your area and get to see companies and people currently doing "something" with PHP in your area.
I love Linkedin as it allows me to connect with local businesses and fellow PHP developers in my area. Through their social network services, I can keep in touch with my peers and follow up on their interests.
One of the nice features of Linkedin is searching people and businesses in a particular area with keywords. So if you would like to know which businesses are doing PHP in your area, you can filter on "php" in your area. This will give you a list of companies in your area who you can contact to see if they want to host a meetup or want to sponsor for drinks or pizza.
Search for PHP in Antwerp Area, Belgium

PHP.net

The PHP UG section on PHP.net
The main resource for PHP developers is still php.net and thanks to the efforts of Ben Ramsey there's a whole page dedicated to PHP user groups. Find it at php.net/ug. Here you can search for a local user group or register a new user group.

First meetup

The first meetup is going to be really exciting as you have high hopes many people will come and will congratulate you for taking the initiative.
If this is the case, you're in luck. Most of the time you get only a few people just checking out what it's all about or none at all. But don't despair, keep the faith and continue with planning meetups. As an example: our first meeting had just 2 visitors. Now we're between 50 and 80 attendees.
I think Michelle Sanver said it the best:
I knew no PHP developers in Groningen managed to get a venue and just holding my thumbs someone would turn up the first meetup. In the end the first meetup was just a "How do we do this?" meetup and I had 3 attendees, which was awesome. The next meetup we were 15 people and since then a steady stream of between 10 - 20 people depending on topic and interest, most of them have never been anywhere in the community before, so if there is no community people - Make them.

Community support

Know you're not alone out there. There's a network of PHP user group leaders available that will help you getting the word out and mentor you to grow your community.

User Group Wiki

Over on php.net there's a whole wiki created for user groups with access to the mailing list and user group handbook. Don't forget to join us on irc in channel #phpgroups where you can find further assistance in getting your community of the ground.

Cal Evans

Don't forget to inform the Godfather of the PHP Community Cal Evans that you started a PHP user group and provide the twitter handle to him, he keeps a list of user groups on his twitter account.

PHP|Architect

Did you know there's a genuine PHP magazine out there? It's PHP|Architect. Send a mail tobeth@phparch.com and notify her about the user group you created.
Whenever you have a big event or something, you can ask to have them to include it in their newsletter and if necessary have a community article or ad about it in the magazine.

Zend

Zend Technologies, Inc. is the company behind PHP and are offering professional services to businesses and governments. And they too have a newsletter. You might want to inform them about your newly created user group so they put it on their website as well and announce news reports from your community.

Closing remarks

Thanks for stepping up and start becoming a community leader. I can't say it's a simple task, but if you keep believing in it you will succeed and become the go-to community leader for your area. Remember, we've got your back on this!

Saturday, February 01, 2014

PHPBenelux Conference 2014 Review

Past weekend was the 5th anniversary of PHPBenelux Conference and people have known it! With close to 50 speakers, 400 attendees and a massive number of sponsors made this conference a true "epic" event. Not because of the numbers, but because of the social events after each conference day.

The theme of the conference was "Carnaval" and like you would expect from any big fair, there were arcade games, money slots and even a huge bumper car stand.

Speakers dinner

Speakers were invited to arrive on Thursday before 6pm because the crew of PHPBenelux had something "special" in mind: a speakers dinner in the national symbol of Belgium: Atomium. Due to a traffic jam I wasn't able to attend the dinner, but as I needed to try the location to see if it met our standards, I already experienced the good dinner in an awesome setting.

Tutorial sessions

On Friday morning we had no less than 7 tutorial tracks and it felt great to see the majority of our attendees were attending these tutorial sessions. Twitter was not lying, the content delivered by these speakers were of high quality and everyone enjoyed it a lot.

Conference day 1

Friday afternoon was the start of PHPBenelux Conference. An epic keynote presented by Elizabeth Marie Smith officially kicked of this 5th edition of the conference. After the keynote 3 simultaneous tracks with great speakers and contents was making it hard for our attendees to choose which track to attend.
Elizabeth Marie Smith keynoting on Mentoring Developers

Socials

The social events of PHPBenelux have always been "rememberable" and "epic", but since we lost the bowling alley, we needed to come up with something new: Bumper cars! And little did we know it was such a huge success. People walked away from it with bruises and pain in their backs, and still yelled "awesome".

Bumper cars ready to entertain
We haven't forgotten our signature "Belgian fries" and "Belgian beer" and even though people were waiting a long time in the cold, they all agreed it was all worth it.

Conference day 2

Saturday morning was the second conference day where everyone had time to recover from all the bruises and hangovers and again 3 tracks filled with great sessions was offered to our attendees. Of course the event was closed by our appreciation of speakers, staff, hotel and of course the attendees. In the evening we've provided again a social event for everyone left at the conference.

Behind the scenes

When you attend a conference, everything magically runs smoothly. But from an organiser point of view it's a whole other ballgame. To organise an event like this, you need to prepare everything months in advance. Sending out sponsor package details to companies, negotiating sponsor deals, open up the Call for Papers, selecting a selection of talks from all proposals, decide on the artwork, negotiate with suppliers, follow up on additional requests and so much more.

Picture taken by Brett Gaasbeek
PHPBenelux is a 7-man team with each person having a specific role: finance (Leon), logistics (Paul), communication (Jeroen), sponsorships (Thijs & Richard), website & mobile app (Martin) and last but not least suppliers (me). This team is truly awesome and we weren't able to set up an event like PHPBenelux Conference 2014 if it wasn't for these guys. And don't forget, all was done voluntarily after working hours in our free time, only using Skype, Google Drive and Asana.
Goodie bags and blankets
In preparation and during the event we also worked with volunteers to help us picking up and dropping of speakers at the airport and train station, at the registration desk, in the rooms and on the venue floor. So a big gratitude goes out to Lineke, Steffi, John, Michelle, Tobias, Peter, Tom & Stijn.

Even my five year old son Xander helped out a little.

Xander in charge of the flags
For 5 years we've been working closely with the staff of Ter Elst which allows us to be flexible in our food and drinks offerings, set up and tear down rooms as we need them and be very flexible when it comes down to people's requests. We can say that after 5 years we've grown towards each other becoming a well-oiled machine for organising a conference of this magnitude. So, a big "thank you" to the crew at Ter Elst.

Closing remarks

This event goes in the history books as "epic", "awesome" and "painful" (due to bumper cars). Yes, we've raised the bar for ourselves and it will be challenging to give you all a similar experience next year without repeating what we did this year. Knowing our team, we will come up with something crazy. Follow @PHPBenelux and keep an eye out for our announcements.

One piece of advice

Since we sold out the past 2 editions, be sure you buy your tickets early! If later you cannot make it to the conference, you can always cancel it up to 2 weeks before the conference. But don't wait until we have sold out…

Wednesday, January 08, 2014

PDO SQlite error: unable to open database file

When you're testing your PHP applications with SQLite you might bump into a problem when using PDOthat states "SQLSTATE[HY000]: General error: 14 unable to open database file".
When using Zend Framework 2, you might only get the InvalidQueryException "Statement could not be executed", for which I've made a pull request on Github to make it more clear what's going on.
The problem is about permissions. For SQLite it's not enough to make the database file writeable for the web server user, but also the directory this file is in.
I found the solution on StackOverflow, thanks to Austin Hyde for giving the answer that pointed me in the final path to the solution.
In order to fix this issue I changed the group of the directory and db file to "www-data", the group my web server (Apache) was running on, and made them writeable for the group.
$ cd /path/to/application
$ chgrp www-data data/db
$ chgrp www-data data/db/application-test.db
$ chmod g+w data/db
$ chmod g+w data/db/application-test.db
Hope to help other developers using SQLite in their development save a lot of time searching for something this trivial.
Creative Commons License
This work is licensed under a Creative Commons Attribution-Noncommercial-No Derivative Works 3.0 License.