emGee Software Solutions Custom Database Applications

Share this

Planet PHP

People blogging about PHP
Updated: 44 min 29 sec ago

PHP 7.1.18 Released - PHP: Hypertext Preprocessor

Thu, 05/24/2018 - 17:00
The PHP development team announces the immediate availability of PHP 7.1.18. All PHP 7.1 users are encouraged to upgrade to this version. For source downloads of PHP 7.1.18 please visit our downloads page, Windows source and binaries can be found on windows.php.net/download/. The list of changes is recorded in the ChangeLog.
Categories: Web Technologies

Interview with Karen Baker - Voices of the ElePHPant

Wed, 05/23/2018 - 04:30

@wsakaren Audio Show Notes


This episode is sponsored by Nexcess.

The post Interview with Karen Baker appeared first on Voices of the ElePHPant.

Categories: Web Technologies

Interview with Karen Baker - Voices of the ElePHPant

Wed, 05/23/2018 - 04:30

@wsakaren Audio Show Notes


This episode is sponsored by Nexcess.

The post Interview with Karen Baker appeared first on Voices of the ElePHPant.

Categories: Web Technologies

Atlas.Query: Simple. Sensible. SQL. - Paul M. Jones

Tue, 05/22/2018 - 05:00

I am happy to announce that Atlas.Query is now stable and ready for production
use! Installaton is as easy as composer require atlas/query ~1.0.

With Atlas.Query and any PDO instance, you can build and execute your queries in a single fluent series of method calls:

use Atlas\Query\Select; $rows = Select::new($pdo) ->columns('*') ->from('posts') ->where('id IN ', $ids) ->fetchAll(); foreach ($rows as $row) { // ... }

If you prefer, you can exercise fine control over your PDO connection, use a query factory, or build your queries in smaller steps:

use Atlas\Pdo\Connection; use Atlas\Query\QueryFactory; $connection = Connection::new( 'mysql:host=localhost;dbname=testdb', 'username', 'password' ); $queryFactory = new QueryFactory(); $select = $queryFactory->newSelect($connection); $select->columns('*'); $select->from('posts'); $select->where('id = ', $id); $row = $select->fetchOne();

Atlas.Query provides the full power of SQL at your fingertips …

$select ->columns(...) ->from(...) ->join(...) ->where(...) ->groupBy(...) ->having(...) ->orderBy(...) ->limit(...) ->offset(...);

… along with UNIONs, paging, sub-selects, inline value binding, and all sorts of fetch and yield styles.

Atlas.Query comes with INSERT, UPDATE, and DELETE builders as well:

use Atlas\Query\Insert; $insert = Insert::new($pdo); // insert a row ... $insert->into('posts') ->columns([ 'title' => $title, 'body' => $body, ]) ->raw('created_at', 'NOW()') ->perform(); // ... and get back the autoincrement value: $post_id = $insert->getLastInsertId();

Do you work on different project with different datbase backends? Atlas.Query lets you use the same interface for them all, while not restricting you to a common subset of functionality. MySQL, PostgreSQL, SQLite, and SQL Server are all supported explicitly.

And if you discover you need more than just a query system, you’ll have a clear refactoring path towards Atlas.Orm. If you are looking for a modern, stable, easy-to-use query system, try Atlas.Query in your project!

Categories: Web Technologies

Book review: Fifty quick ideas to improve your tests - Part 2 - Matthias Noback

Mon, 05/21/2018 - 23:05

This article is part 2 of my review of the book "Fifty quick ideas to improve your tests". I'll continue to share some of my personal highlights with you.

Replace multiple steps with a higher-level step

If a test executes multiple tasks in sequence that form a higher-level action, often the language and the concepts used in the test explain the mechanics of test execution rather than the purpose of the test, and in this case the entire block can often be replaced with a single higher-level concept.

When writing a unit test for some complicated object, you may be collecting some data first, then putting that data into value objects, maybe wrapping them in other value objects, before you can finally pass them to the constructor of the value object. At that point you may have to call several methods on the object before it's in the right state. The same goes for acceptance tests. You may need quite a number of steps before you get to the point where you can finally write a 'When' clause.

I find that often the steps leading up to the 'When' clause (or to the 'Act' part of a unit test), can be summarized as one thing. This is meant by the "single higher-level concept". So instead of enumerating everything that has happened to the system, you look for a single step that described what your starting point is. For instance, instead of:

Given the user logged in And they have created a purchase order And they added product A to it, with a quantity of 10 And they placed the purchase order When the user cancels the purchase order Then ...

You could summarize the 'Given' steps as follows:

Given a placed purchase order for product A, with a quantity of 10 When the user cancels the purchase order Then ...

Once you start looking for ways to make things smaller and simpler, easier to follow and read, you'll find that many of the details you previously added to the smaller steps are completely irrelevant for the higher-level step. In our case, the product and the quantity may be completely irrelevant for the scenario that deals with cancelling the purchase order. So the final version may well be:

Given a placed purchase order When the user cancels the purchase order Then ...

When implementing the step definition for this single, simplified step, you still need to provide sensible default data. But it happens behind the scenes. This technique hides the details that are irrelevant, and only shows the relevant ones to the person reading the scenario. It will be a lot easier to understand what's being tested with this particular scenario.

I find that this approach works really well with unit tests too. One test case may show how a complicated object can be constructed, another test case won't just repeat all those steps, but will summarize it properly (like we did for the above scenario). This often requires the introduction of a private method in the test class, which wraps the individual steps. The method is the abstraction, its name the higher-level concept.

Specification, acceptance tests, living documentation

When creating your artifacts, remember the three roles they must serve at different times: now as a specification, soon as acceptance tests, and later as living documentation. Critique the artifact from each perspective. How well does it serve each distinct role? Is it over-optimised for one role to the detriment of others?

In workshops I often point out that testing is a crucial part of the development workflow. You need it to verify that the unit of code you've been working works as expected. To improve this perspective on writing tests, you could aim for not just verifying correctness of a unit, but specifying it. This implies some kind of test-first approach, where you specify expected behavior. The next level would be to consider the future. What happens when you're done writing this code? Could someone else still understand what's going on? Do you only have technical specifications, or also domain-level specifications?

For unit tests, the danger is that you'll be doing only technical verifications. You may be testing methods, arguments and return values instead of higher-level behaviors. It happens when you're just repeating the logic of the class inside its unit test. You find yourself looking into the box (white box testing), instead of treating the box as an object with proper boundaries.

The best thing you can do is to think hard about

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

Categories: Web Technologies

How to Fix Magento Login Issues with Cookies and Sessions - SitePoint PHP

Sun, 05/20/2018 - 23:00

This article was created in partnership with Ktree. Thank you for supporting the partners who make SitePoint possible.

In this article are looking at how Magento cookies can create issues with the login functionality of both the customer-facing front-end and admin back-end, the reason it occurs and how it should be resolved.

This is also known as the looping issue, as the screen redirects itself to the same screen, even though the username and password is correct.

A script is provided at the end of the article which can help detect a few of the issues. Feel free to use and modify as per your needs.

What is a Cookie?

A cookie is a piece of text that a web server can store on a user's hard drive, and can also later retrieve it. Magento uses cookies in Cart & Backend Admin functionalities, and they may be the source of a few problems when unable to login to Magento.

What is a Session?

A session is an array variable on the server side, which stores information to be used across multiple pages. For example, items added to the cart are typically saved in sessions, and when the user browses the checkout page they are read from the session.

Sessions are identified by a unique ID. Its name changes depemnding on the programming language — in PHP it is called a 'PHP Session ID'. As you might have guessed, the same PHP Session ID needs to be stored as a cookie in the client browser to relate.

Magento's storage of Sessions

Magento can store sessions via multiple session providers and this can be configured in the Magento config file at app/etc/local.xml. These session providers can be chosen here.


<session_save><![CDATA[files</session_save> <session_save_path> <![CDATA[/tmp/session </session_save_path>


Allowing sessions to store themselves in the database is done in /app/etc/local.xml by adding <session_save><![CDATA[db</session_save>.

Magento applications store sessions in the Core\_session table.


<session_save>db</session_save> <redis_session> <host></host> <port>6379</port> </redis_session>


session_save><![CDATA[memcache</session_save> <session_save_path> <![CDATA[tcp://localhost:11211?persistent=1&weight=2&timeout=10&retry_interval=10 </session_save_path> Magento Usage

Magento uses two different cookies named 'frontend' and 'adminhtml'. The first one is created when any page is browsed. The same cookie is also updated whenever the customer logs in, and the next one is created when a backend user is logged in. You can check whether the cookies have been created by clicking Inspect Element > Application, as in the below picture (from Chrome):

Cookies are configured in Magento via the Configuration admin menu - System > Configuration > General > Web.

Problem: Login Fails & Redirects to Login Page

If you haven't experienced this problem, then you haven't worked with Magento long enough!

This is how it typically happens: when you login by entering your username and password, you will be redirected to the same login page and URL, and your browser is appended with nonce id. This happens for both the customer front-end and the Magento back-end login.

Let's look at a few reasons why this happens, and how we should resolve those issues.

Reason #1: Cookie domain does not match server domain

Let's say your Magento site is example.com and the cookie domain in Magento is configured as xyz.com.

In this scenario both Magento cookies will set Domain Value as xyz.com, but for validating the session Magento will consider the domain through which the site was accessed — in this case example.com. Since it won't be able to find an active ses

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

Categories: Web Technologies

PHP-1701-A - Nomad PHP

Fri, 05/18/2018 - 10:55

August - US
Presented By
Adam Culp
August 23, 2018
20:00 CDT

The post PHP-1701-A appeared first on Nomad PHP.

Categories: Web Technologies

Building Lego Robots with PHP - Nomad PHP

Thu, 05/17/2018 - 21:02

August - EU
Presented By
Christopher Pitt
August 23, 2018
20:00 CEST

The post Building Lego Robots with PHP appeared first on Nomad PHP.

Categories: Web Technologies

PHP Versions Stats - 2018.1 Edition - Jordi Boggiano

Tue, 05/15/2018 - 01:00

It's stats o'clock! See 2014, 2015, 2016.1, 2016.2, 2017.1 and 2017.2 for previous similar posts.

A quick note on methodology, because all these stats are imperfect as they just sample some subset of the PHP user base. I look in the packagist.org logs of the last month for Composer installs done by someone. Composer sends the PHP version it is running with in its User-Agent header, so I can use that to see which PHP versions people are using Composer with.

PHP usage statistics May 2018 (+/- diff from November 2017)

All versions Grouped PHP 7.2.4 7.54% PHP 7.1 35.02% (-1.61) PHP 7.1.16 7.41% PHP 7.0 23.02% (-7.74) PHP 7.0.28 5.54% PHP 7.2 20.18% (+20.18) PHP 7.1.15 4.11% PHP 5.6 16.48% (-6.8) PHP 7.2.3 3.85% PHP 5.5 3.50% (-2.61) PHP 7.1.14 3.79% PHP 5.4 1.04% (-0.47)

A few observations: PHP 7.1 is still on top but 7.2 is closing real quick with already 1/5th of users having upgraded. That's the biggest growth rate for a newly released version since I have started collecting those stats. Ubuntu 18.04 LTS ships with 7.2 so this number will likely grow even more in the coming months. 78% of people used PHP 7+ and almost 95% were using a PHP version that is still maintained, it sounds too good to be true. PHP 5.6 and 7.0 will reach end of life by late 2018 though so that's 40% of users who are in need of an upgrade if we want to keep these numbers up!

Here is the aggregate chart covering all my blog posts and the last five years.

PHP requirements in Packages

The second dataset is which versions are required by the PHP packages present on packagist. I only check the require statement in their current master version to see what the latest requirement is, and the dataset only includes packages that had commits in the last year to exclude all EOL'd projects as they don't update their requirements.

PHP Requirements - Recent Master - May 2018 (+/- diff from Recent Master November 2017)

5.21.16% (-0.12) 5.315.9% (-2.85) 5.416.59% (-3.7) 5.515.52% (-3.55) 5.619.57% (-0.83) 7.019.47% (4.62) 7.111.15% (5.83) 7.20.64% (0.61)

This is as usual lagging behind a little but PHP 7 is finally seeing some real adoption in the OSS world which is nice.

Categories: Web Technologies

Book review: Fifty quick ideas to improve your tests - Part 1 - Matthias Noback

Tue, 05/15/2018 - 00:11

After reading "Discovery - Explore behaviour using examples" by Gáspár Nagy and Seb Rose, I picked up another book, which I bought a long time ago: "Fifty Quick Ideas to Improve Your Tests" by Gojko Adzic, David Evans, Tom Roden and Nikola Korac. Like with so many books, I find there's often a "right" time for them. When I tried to read this book for the first time, I was totally not interested and soon stopped trying to read it. But ever since Julien Janvier asked me if I knew any good resources on how to write good acceptance test scenarios, I kept looking around for more valuable pointers, and so I revisited this book too. After all, one of the author's of this book - Gojko Adzic - also wrote "Bridging the communication gap - Specification by example and agile acceptance testing", which made a lasting impression on me. If I remember correctly, the latter doesn't have too much practical advice on writing goods tests (or scenarios), and it was my hope that "Fifty quick ideas" would.

First, a few comments on the book, before I'll highlight some parts. I thought it was quite an interesting book, covering several underrepresented areas of testing (including finding out what to test, and how to write good scenarios). The book has relevant suggestions for acceptance testing which are equally applicable to unit testing. I find this quite surprising, since testing books in general offer only suggestions for a specific type of test, leaving a developer/reader (including myself) with the idea that acceptance testing is very different from unit testing, and that it requires both a different approach and a different testing tool. This isn't true at all, and I like how the authors make a point of not making a distinction in this book.

The need to describe why

As a test author you may often feel like you're in a hurry. You've written some code, and now you need to quickly verify that the code you've written actually works. So you create a test file which exercises the production code. Green light proves that everything is okay. Most likely you've tested some methods, verified return values or calls to collaborating objects. Writing tests like that verifies that your code is executable, that it does what you expect from it, but it doesn't describe why the outcomes are the way they are.

In line with our habit of testing things by verifying outputs based on inputs, the PhpStorm IDE offers to generate test methods for selected methods of the Subject-Under-Test (SUT).

I always cry a bit when I see this, because it implies two things:

  1. I've determined the API (and probably wrote most of the code already) before worrying about testing.
  2. I'm supposed to test my code method-by-method.
  3. A generated name following the template test{NameOfMethodOnSUT}() is fine.

At the risk of shaming you into adopting a test-first approach, please consider how you'll test the code before writing it. Also, aim for the lowest possible number of methods on a class. Make sure the remaining methods are conceptually related. The SOLID principles will give you plenty of advice on this topic.

Anyway, if we're talking about writing tests using some XUnit framework (e.g. JUnit, PHPUnit), don't auto-generate test methods. Instead:

Name the test class {NameOfConcept}Test, and add public methods which, combined, completely describe or specify the concept or thing. I find it very helpful to start these method names with "it", to refer to the thing I'm testing. But this is by no means a strict rule. What's important is that you'll end up with methods you can read out loud to anyone interested (not just other developers, but product owners, domain experts, etc.). You can easily check if you've been successful at it by running PHPUnit with the --testdox flag, which produces this human-readable description of your unit.

Rules and examples

There's much more to it than following this simple recipe though. As the book proposes, every scenario (or unit test case), should first describe some rule, or acceptance criterion. The steps of the test itself should then provide a clear example of the consequences of this rule.

Rules are generic, abstract. The examples are specific, concrete. For instance, a rule could be: "You can't schedule

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

Categories: Web Technologies

PHP-GTK.eu End of Life and GDPR - PHP-GTK Community

Mon, 05/14/2018 - 02:08

If you're reading the PHP-GTK.eu community site these days, you certainly noticed that not a single piece of significant content was created since 2015, and not much since 2013.

Whatever this may mean for PHP-GTK itself is another issue, but for the site itself, it means it ceased to be relevant about 5 years ago, and it's time to move on for the site members. Since the site contains non-anonymous user, it will fall under the new EU GDPR regulations entering into force on 2018-05-25, and there is no point for me to spend time on evolving the site towards compliance when no one is actually using it.

So here is the EOL announcement: the site will be shutting down on 2018-05-24 and its data will taken offline.

A static version of the articles may be published again at some point here or elsewhere, but I wouldn't hold my breath on it. So if you have even some interest in the site content, be sure to copy/paste the pages of interest before it goes dark on 2018-05-24. Or contact me if you want a copy of the files and content, or check my blog for newer content.

Thanks all for participating, it's been a pleasure while it lasted.

read more

Categories: Web Technologies

Atlas 3.x (“Cassini”) and PHPStorm Completion - Paul M. Jones

Wed, 05/09/2018 - 08:13

I’m proud to announce the release of Atlas.Orm 3.0.0-beta1, along with releases of the supporting Mapper, Table, Query, Cli, and Pdo packages. (Atlas is a data-mapper for your persistence model, not your domain model, in PHP.)

The goal for this release round was “better IDE return typehinting support” and I am happy to say that it has been a great success, though it did take some substantial renaming of classes. Unfortunately, this results in a big break from the prior alpha release; if you already have alpha-based data source skeleton classes, you will need to regenerate them with the new class names. Barring the unforeseen, this marks the first, last, and only time that regeneration will be necessary.


I am not a heavy user of IDEs; I lean more toward text editors like Sublime. However, I work with people who use the PHPStorm IDE extensively, and I have come to appreciate some of its features.

One of those features is code autocompletion. For example, if you type $foo = new Foo(), and then refer to $foo later, the IDE will pop up a list of methods and properties on that object.

This is very convenient, except that the IDE has to know what class is being referenced, in order to figure out what the hinting should be. If you are using a non- or loosely-return-typed factory/locator/container, which is what everything in PHP land does, the IDE cannot know by default how to map the requested name to an actual class. In this example …

class Factory { public static function new($class) { return new $class(); } } $foo = Factory::new(Foo::CLASS);

… the IDE has no idea what the return from the new() method is, or ought to be, so it cannot give you autocompletion hints on $foo.

That idiom is exactly what Atlas MapperLocator::get() and TableLocator::get() use: the get() param is a class name, and the locator then retains and returns an instance of that class. Likewise, the overarching Atlas class methods all take a mapper class name as their first param, which Atlas uses to figure out which mapper to use for that method call.

You can typehint those methods to abstract classes or interfaces, but then the IDE will not recognize any custom extensions or overrides on the returned concrete classes. What is needed is a way to determine the return type from the get() param, rather than from the method’s return typehint.


Lucky for us, the PHPStorm IDE allows for a .phpstorm.meta.php file (or a collection of files under a .phpstorm.meta.php/ directory) where you can map the factory method inputs to their return types. (See here for the documentation.)

On working with it, though, I found it to be a little inflexible. I expected to be able to map a string directly to a literal class name, but that didn’t really work. The IDE never seemed to pick up the return typehinting. Further, with class names the way they are in the 1.x, 2.x, and 3.x-alpha releases, I would need to add a series of param-to-type mappings for every single data source class (i.e., about 10 entries for each data source type). I imagined that would become cumbersome.

To adapt to this, I decided to modify the Atlas class naming with PHPStorm’s ‘@’ metadata token in mind. The ‘@’ token, per the above documentation, gets replaced with the factory method parameter value, making it perfect as a class name prefix. However, you can’t do any string manipulations on it; you cannot, say, call substr('@', 0, -6) . 'Record' and give it “FooMapper” to get back “FooRecord”. It would have to be ‘@Record’ or nothing.

This leads to the biggest change in Atlas since its inception: the data source mapper classes are no longer suffixed with “Mapper”. Previously, if you had a

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

Categories: Web Technologies

Book review: Discovery - Explore behaviour using examples - Matthias Noback

Tue, 05/08/2018 - 01:00

I've just finished reading "Discovery - Explore behaviour using examples" by Gáspár Nagy and Seb Rose. It's the first in a series of books about BDD (Behavior-Driven Development). The next parts are yet to be written/published. Part of the reason to pick up this book was that I'd seen it on Twitter (that alone would not be a sufficient reason of course). The biggest reason was that after delivering a testing and aggregate design workshop, I noticed that my acceptance test skills aren't what they should be. After several years of not working as a developer on a project for a client, I realized again that (a quote from the book):

You can write good software only for problems that you understand.

BDD book 1 - "Discovery" - revolves around this fact of the developer's life. How often did you produce a piece of code based on some vague issue in Jira, only to realize after showing it to stakeholders that almost everything about it was wrong? Often you don't know enough, so you'll mix in some of your own assumptions. And very often, you don't know how the thing you wrote is actually going to be used. In short, you don't know if what you created is adequate. You can write any amount of clean code, with lots of automated tests, and no observable bugs; if the software doesn't fit the intended use, it's useless.

You have to get out of the code, move away from your desk, and talk to the people who want you to build the software. Don't let them give you a requirements document and leave you alone afterwards. Don't lock yourself up with your project manager for a day-long sprint planning. Make sure you get together more often for a quick session to come up with good examples, of what kind of information will go into the system, what rules there are about processing the information, and what the expected outcomes are. Make sure you talk about realistic scenarios, and document all of the decisions you make.

Seems easy, but this, for many of us including myself, is far out of the comfort zone. I'm happy if I can do some coding alone. But eventually, you want clients and users to be happy about what you produce, and this only happens when what you build is useful to them. It should match their way of living, their business processes, their domain expertise.

BDD: not about tools, not about testing

It's my habit to mock development subcultures, like DDD, but also BDD. Even though what they bring to the table is very useful, there are always blanket statements that people will start using, to identify themselves with that subculture.

The process of learning a culture— enculturation— is partly explicit but mostly implicit. The explicit part can be put into books and taught in seminars or classrooms. Most of culture is acquired by a process of absorption— by living and practicing the culture with those who already share it.
West, David. Object Thinking (Developer Reference) (Kindle Locations 244-246). Pearson Education. Kindle Edition.

The same is actually true for myself, quoting David West and all.

#DDDesign blanket statement; can be inserted anywhere in the conversation: "Maybe there's a concept that's missing."

— Matthias Noback (@matthiasnoback) April 6, 2018

I was actually anticipating to read BDD subculture's favorite thing to say: "BDD is not about the tools". So I was happy to see it here too:

One typical mistake is to see BDD as a tool-thing. BDD is primarily about collaboration and domain discovery; any “BDD tool” can be only useful in supporting this process. You have to start by investing in collaborative discussions and the creation of a shared vocabulary. Just going after automation (using Cucumber or SpecFlow) does not work.

No hard feelings of course, because this is simply true. I've seen it happen too. PHP's Cucumber is called Behat. Many projects that use Behat end up having many, many scenarios. That may sound like a good thing. Although these scenarios are all written in plain English, which may give the illusion that they are business-oriented, they don't do anything a simple PHPUnit test case couldn't do.

The power of Gherkin (the syntax for these scenarios) lies in being able to capture usage examples, together with business rules. The only way to come up with good examples

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

Categories: Web Technologies

Remote working - Matthias Noback

Tue, 05/01/2018 - 01:30

Recently I read Ouarzy's review of Jason Fried and David Heinemeier Hansson's "Remote - Office Not Required". I'd read their previous books, "Getting Real" and "Rework". They're all a joy to read. Short chapters, nice little cartoons. Just a lot of fun, and inspiring too. Not many authors make as much of an effort as they do to condense their message and reward the reader for taking the time to read an actual book. It's insulting how much work some authors expect you to put in before they will reveal their secrets!

Since I've been working remotely since last October, I was curious to read more about it in a book by people who have a thriving business with lots of remote workers. At least there should be some useful suggestions in it, and some reassurance that some of my own remote working troubles were nothing special. I found both in this book. Together with some powerful quotes from the book, I wanted to share some of my own discoveries about remote working with you in this post.


A big part of the book is about countering some common arguments against letting people work remotely. There's a lot of resistance to it, which ultimately boils down to trust issues. Managers all too often seem to be "managing chairs" as Fried and Hansson call it. Employees should be behind their desks, hands on the keyboard, from 9 to 5 every weekday. Preferably longer, or you'll be marked as "unmotivated".

There are many flavors of management-level trust issues, and letting people do remote work would be many a manager's nightmare. I think it's safe to conclude that Fried and Hansson mainly see advantages in it though. The starting point should be to realize that "Most people want to work, as long as it's stimulating and fulfilling". If an employee is slacking at home, unmotivated to do work, they will be unmotivated at the office too. The effort should not be in keeping the employee behind their desk for 40 hours a week, but to re-motivate them for their job.

As a contractor I've been demotivated several times, but this was a long time ago, when I was paid much less, and the tasks I had to do were quite boring (often because they were never-ending exercises in pointlessness). And with being demotivated came procrastination, lack of communication, and severely decreased effectiveness.

Distractions, focus

For the project I'm currently working on, I don't need any more motivation. This quote from the book really hit home: "In reality, it's overwork, not underwork, that's the real enemy in a successful remote-working environment. [...] The fact is, it's easy to turn work into your predominant hobby." Remote working has me working very hard. I think the main issue is focus: since my working environment at home is quiet, and away from other family member's activities in the house, I can really concentrate on something and "fix it".

In a regular office working environment with some kind of "open floor" plan (the managers can watch you sit behind your desk...), there are so many things that disturb me. No matter if a phone call is interesting or not, I will consciously or unconsciously follow it and get the gist of it. Same for conversations between co-workers. Any discussion that developers will start, runs in my own mind in the background, and when I get invited to join the conversation, I already know what it's about. This may seem nice, but the cost is high: I can only focus with half my brain capacity on the problem I'm currently working on.

All of these pretty standard "office life" distractions are not to be found in my personal office. But highly focused working comes with a cost. I can't do 40 hours a week of it. Which is why I often have to remind myself to take things a bit easier.

Private and professional life

Even though I work hard, I rarely make more than 40 hours, more often it's between 32 and 36. But I sneak in some hours for open source coding, or blogging. Sometimes my son voices his concerns about that. And last week he said: finally! You're chilling! (I had taken off my shoes and socks and was watching TV on the couch...) I think these are good signals; they're telling me that I'm not pulling the plug hard enough.

The other way around never happens by the way. "If you don’t have to be anywhere at a certain time, you can easily end up lying in bed until close to noon, just casually working away on the laptop. Or you can let work drift into that evening you’re supposed to share with your spouse and kids." Routine comes easily with a family. The youngest will be awake well before 7:00, and I'm usually the one who gets up with her, so it's only natural to open my laptop at around 8:30.

Still, it will always be hard to close the laptop

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

Categories: Web Technologies