My Way to PHP: Day 13 of 75

Day 13 and I want to work a bit on my goals. Today, I start reading Modernizing Legacy Applications in PHP. My goal is 50 pages which means up to Chapter 7 about writing tests.


I really like the different approaches to why rewriting is dangerous. I’ve seen some rewrites myself which miserably failed or took extremely long. I know about one rewrite which took around 14 months and by the time the rewrite was complete is was already dated. But at least the code base was better. On top of that I took around a year to re-fix the bugs that were reintroduced, add business rules, etc.


Prerequisites

  • A VCS
  • Modern PHP version
  • Style guide (PSR-2)
  • Test suite (Characterization test: output doesn’t change) – Selenium/Codeception

After implementing an autoloader the next step is to consolidate all class files into a central directory and remove the includes for these class files, one by one.

For all functions without classes create a class with (static) methods and do the same again.


The next step is to eradicate global. First, we put the global stuff into the constructor and assign it to a field. After that works fine we are going to use DI and create factories.

The general guide line is: Don’t use new outside of factory classes (exception: SPL and Exceptions).

I looked at my code again and found several instances where a factory would be useful and implemented it!


Now it’s time to write tests. If we’re done with that we can go to the embedded database stuff. Every database access, csvs, etc. should be in its own class called a gateway.

You could either organize by implementation layers (MySQL, CSV, etc. classes) or by domain entities (recommended).


Next, we’re going to extract the domain-logic into transaction classes. This will probably take the longest.

After that we can extract the view. One tip I liked is to use the output buffer and save the generated view into a var for testing!

The same with the action logic.


He then creates a public directory and leaves stuff like includes non-public. Then a front controller can be added and finally DIC.

Wow, lots of things to do! I can only imagine doing this on a 500k+ legacy project. It’s a short book without fluff. Really good book in my opinion!


Playing with Neo4j ­-[:USING]­- PHP

I heard about graph databases – especially Neo4j – but never really took a look into it. Let’s see!

As a friend of graphs I quite like the idea. You basically have nodes which can store some information. And you also describe some relation between them. And that’s it!

Also pretty cool. There’s an event system which allows you to execute code on some predefined events!

Graph databases really seem to shine for complex relationships. Something to keep in mind.


How You Can Architect and Develop Enterprise Mission-Critical Applications with Domain-Driven Design

  • Bounded context: constraint the model (what belongs and doesn’t belong?)
  • Ubiquitous language: Terminology within a specific meaning
  • Main goal: Unify the mental model (domain expert = developer)

  • Language isn’t just nouns.

  • Who?
  • When?
  • What?

  • Context mapping: Maps relationships between bounded contexts

  • Ports & Adapters: Architecture; Domain Model takes Adapters to connect to outside ports (DB, I/O, etc.)
  • Domain Event – Event within a domain

I watched most of the talk at 1.5 to 2x speed and I still felt that it was slow. The content is good though, however it’s probably better to read something to save time.


Being grumpy for fun and profit

So far I can only agree on his points. His points on scalability are interesting. Definitely a good watch!


Workflows of Refactoring

A Fowler talk which means lots of new terminology.

  • Litter-Pickup Refactoring aka. Boy scout rule: Always leave something cleaner as before
  • Comprehension Refactoring You don’t understand the code and spent time figuring it out.
  • Preparatory We should have done it this way.

It’s funny that he’s making such a science out of it. However, if nobody wouldn’t think that it is a science he wouldn’t tell it. Somehow I’m quite happy that I never followed the dogma.

Also interesting that the IT world is rediscovering Kaizen. That’s how I saw refactoring all the time. Probably thanks to my ignorance of the exact definition.

One good advice about refactoring is: Refactoring is about economics.

We’re doing this do deliver more functionality easier.


The software journeyman’s guide to being homeless and jobless

The first 10 minutes are pretty light-hearted but there’s some insight in this talk:

We got nothing done because we were afraid of failure.

n.c.

I can get over that, that’s alright!

He said that about VisualStudio but that’s with a lot of things in life. I’m notorious for that. I don’t like something – mostly because I never really looked into it. I get over it. I actually learn about it. I start to understand it. And I actually can form a valid opinion. Sometimes I even start to love it.

We’re developers and we can get it done with enough time.

Yep!


So, I’ve made some progress on my project. The example files are working and the server is working. I want to refactor some method which does the routing. And then write an interface for the comments.


Updates Goals:

  • Learn a bit more about legacy systems and how to handle them
  • Learn a bit more about MySQL
  • Learn Symfony2
  • Write at least one web app using Symfony2 and its core components (templating, testing, forms, validation, security, caching, i18n)
  • Get a bit more exposure to OOP and OOD
  • Watch one video per day on average

Progress status

Done

  • Reading Modernizing Legacy Applications in PHP [done]
  • Learn a bit more about legacy systems and how to handle them

In Progress

  • Watch one video per day on average [38 of 75]

My Way to PHP: Day 12 of 75

Day 12! I just published yesterday’s post. Yesterday, was pretty good. It was great to finally write some  code again. Before continuing with a book I want to watch a few talks first. I also want to refactor my current code a bit and write some example frontend code. However, the focus will be on talks. I just want to get some more from my list.


Don’t be STUPID, Grasp SOLID

I liked the intro! He talks about the typical OOP example of a taxonomy of animals and then you generate some lion, who roars, and hunts, etc. But do we write code like that? Nope.

Instead:

An object is a collection of behaviors.

This is a really good talk so far. Definitely, some I would have like to see around 2 weeks ago :D

STUPID:

  • S Singletons
  • T Tight coupling
  • U Untestable code
  • P Premature Optimization
  • I Indescriptive Naming
  • D Duplication

Once you do understand the code base written in OOP it’s easier to understand but it takes time

Principle of Good enough

There’s probably a better way but what matters is that it delivers business value.


Great! I spent the last 3 hours working on my project. Guzzle is integrated and it works pretty fine. The next step is to write an example frontend for the RESTful service. I’m considering AngularJS for it but on the other hand it’s not really necessary – though cool.


Your (coding) standards matter

A pretty good remark:

You should control your tools and not the other way around.

The talk covers PHPMD and PHPCS. He recommends to use all the standards in PHPMD and use PSR2 for PHPCS and configure like you want.

I use both in PHPStorm and just did an inspection.  It really helps to get those standards correct!

I like his idea for legacy systems. Start with the most essential rules. Run the test. Fix those violations. Then add more rules and repeat.


Scrum Tuning: Lessons learned from Scrum implementation at Google

The sound is bad at the beginning but gets better at around 4mins.

Most of Agile is taken from Toyota but they didn’t talk about that up front. The content is very similar to the stuff I read about Quality management. I know that Scrum takes a lot of these ‘old’ methods like Kanban.

A product owner with a product backlog is pretty important.

Scrum Process

  • Team pulls from product backlog
  • This is the sprint backlog
  • Daily meeting
  • 2-4 weeks sprints
  • deliver working software
  • Burndown chart

Scrum Master

  • Between team and customer
  • Improves productivity / practices
  • Shows customers how to maximize ROI

Practices

  • Minimize WIP: Complete features as quickly as possible
  • Change the scope of done (Programming -> Testing -> Performance -> User Acceptance -> Roll-out)
  • Daily Scrum Board (Userstory + Tasks)

Scrum is based on the same concepts as Lean Manufacturing is.


The Driven Developer

From the Mercury Project at NASA (early 60’s):

Project Mercury ran with very short (half-day) iterations that were time boxed. The development team conducted a technical review of all changes, and, interestingly, applied the XP practice of test-first development, planning and writing tests before each micro-increment.

My theory of ‘basically everything is there we just have to rediscover it’ shows – again – some support!


What I like is the idea of small, medium and large tests which is presented in ‘How Google test software’. The idea is that you write small Unit tests, then maybe combine two units, do integration tests, acceptance tests, etc.


What I think about all these movements is that you should use your own brain instead following something. Pick the stuff that works for you and leave the rest behind.


ISP’s Unauthenticated SOAP Service = Find (Almost) All The Things!

A security talk for good measure! Really good talk and quite funny. :D


Updates Goals:

  • Learn a bit more about MySQL
  • Learn a bit more about legacy systems and how to handle them
  • Learn Symfony2
  • Write at least one web app using Symfony2 and its core components (templating, testing, forms, validation, security, caching, i18n)
  • Get a bit more exposure to OOP and OOD
  • Watch one video per day on average

Progress status

In Progress

  • Watch one video per day on average [33 of 75]

My Way to PHP: Day 11 of 75

Day 11! Yesterday evening was a bit unsatisfying. I think it was just a lot of general stuff I learned. I want to do something concrete. I suspect that my dissatisfaction led to me refactoring.


So, I spent the last 90 minutes looking for a dead simple feedback widget. Didn’t find anything. I decided to write one myself. I’m not going to use a framework. I want it really dead simple. My initial idea for the architecture is actually just a SQLite DB with a form and a simple output page. That’s all.

Because I want to embed the form I’m writing a super simple REST API.

POST /feedback
GET /feedback

You send to POST using JSON and you get the data in JSON when requesting GET. If the POST was successful I will return a 201. If the POST was unsuccessful I will return a 4XX with a message.

The internal architecture will be inspired by the Action-Domain-Responder.

Here’s a good and short video on ACR:

Here;s my super short version:

  • Action gets the request and gives it to the Domain.
  • Domain does what is does and returns it to Action
  • Action gives it to the Responder which handles all the output

Great, in the meantime I installed PHPStorm and finally set everything up. Composer, PHPMD, PHPUnit, PHP Documentor and PHP CodeSniffer. This took quite a while but now it works!

The integration with these tools is pretty good.


Oh fuck. I spent the last 2 hours debugging my tests because a function couldn’t get the mock object. After 2 hours I found the problem. I named the constructor __constructor instead of __construct.

What helped me was to replace the mock object with the real one. Then it didn’t work and I found the problem.


Ok, that was pretty good and long. I spent the last 7 hours writing code and learning the tools. I’m thinking about using a framework for the routing because that’s pretty messy at the moment.


phpDocumentor – your source matters

At the start he talks about line comments. This reminded me of yesterday. I think you’ll write the best comments when you try to understand something you’ve written a while ago. Because you are going to document what you found out – again – so that you don’t have to look it up in the future.

Not how, but why.

On commenting. Otherwise there wasn’t that much new stuff if you already used docblocks.


Here’s a list of things I discovered in PHPStorm which are pretty nifty:

  • Crtl + B: Jump to definition
  • Crtl + P: Shows the parameter signature
  • Crtl + Q: Quick doc lookup
  • Crtl + Alt + T: Surrounds code block with block construct (if, etc.)
  • Crtl + /: Comment and uncomment lines
  • Crtl + W: Select blocks of text (expands)
  • Alt  + Enter: Shows quick fixes and what’s wrong (those little symbols)
  • Crtl + Alt + I: Auto-indent block
  • Crtl + D: Duplicates current line
  • Crtl + Y: Delete line
  • Crtl + Alt + F7: Shows uses of the entity your selecting
  • Crtl + N: Goto class (you can enter the name)
  • F5: Copy file
  • F6: Move file
  • Shift + F6: Rename (I used that quite a lot!)
  • Crtl + Alt + M: Wow, that’s cool. Extract the block and create a method out of it.
  • Crtl + Alt + V: Same for variables
  • Crtl + Alt + F: Same for fields
  • Alt + `: Quick popup for version control
  • Crtl + Shift + A: Super quick function lookup for PHPStorm

The productivity guide in the help menu is awesome!


For testing my RESTful API I needed some tool and found Guzzle. Here’s a quick video about it:

The interface looks pretty good. Reminds me a lot of requests for Python. It can send requests in parallel which is great!

The video also features a great poem about Guzzle :D


Today’s post was short but I didn’t expect something else when I don’t watch a lot of videos or read a lot. I still have a few books on my reading list and a few videos on my watch later list.

I think that I’m going to write my current app to a production-ready state and also watch some more general talks. After I’m done with that and finished the legacy stuff I’m going into Symfony.


Updates Goals:

  • Learn a bit more about MySQL
  • Learn a bit more about legacy systems and how to handle them
  • Learn Symfony2
  • Write at least one web app using Symfony2 and its core components (templating, testing, forms, validation, security, caching, i18n)
  • Get a bit more exposure to OOP and OOD
  • Watch one video per day on average

Progress status

In Progress

  • Watch one video per day on average [28 of 75]

My Way to PHP: Day 10 of 75

The tenth day. I’m still reading through PHP Internals Book and I’m at the start of the last chapter which is about the OOP system. I want to finish that today. And afterwards I’m going to start reading a book about Unit testing. My goal is  to get to page 25. I think that’s about right.


Great, let’s get back to the book. Objects are saved in the zend_object_value:

typedef struct _zend_object_value {
    zend_object_handle handle;
    const zend_object_handlers *handlers;
} zend_object_value;

This consists of a handle which is an individual ID and a list of handlers which define the actual behavior of the object.

Here’s the “standard” object structure zend_object:

typedef struct _zend_object {
    zend_class_entry *ce;
    HashTable *properties;
    zval **properties_table;
    HashTable *guards; /* protects from __get/__set ... recursion */
} zend_object;

You can see that there are two tables: properties and properties_table. The latter is for dynamic objects whereas the former is for declared ones.

This is so because using a hash table has a big overhead around 100 bytes per entry!

Then there’s guards. These are for magic calls and guard them against recursing.


Next book: PHPUnit Essentials.

The more complex the code, the bigger the chance it will break (CRAP = Change Risk Analysis and Predictions).

Great name!

The first chapter was just about installing PHPUnit and Xdebug. The following chapter is about PHPUnit and IDE integration.

Most used assertions:

  • assertTrue() and assertFalse()
  • assertEquals() and assertSame()
  • assertNull() and assertEmpty()

  • Try to test all branches!

  • Test only public methods – everything else can change but the public output shouldn’t change

This talk is called Building Testable PHP Applications:

Principles:

  • Single purpose
  • Decoupled
  • Consistent architecture

One note was especially interesting:

The more complex your objects, the way more test you have to write.

He said that related to NPath complexity. And it’s interesting. Take for example polymorphism. You could write that with a trigger in each method you want to call.

However, suddenly each function would be twice as complex (you have to test each trigger).

When using polymorphism your code suddenly gets half as complex because you enclosed that complexity and gave it to the language. So it’s no longer your problem.

At run-time however, it basically has the same complexity but the code is reduce.


He talked about onion architecture

Here’s a quote from the article:

organize the layers of your application code like the layers of an onion. Every layer of the onion is only coupled (or dependent upon) any layer deeper in the onion than itself.

I wonder if it’s just the Interface segregation principle applied.


Hoare’s Law of Large Programs:

Inside every large program is a small program struggling to get out.


Your framework should be an implementation detail, not a giant killer squid, sucking the life out your application.

UNIX philosophy again. Keep as much stuff away as you can from the framework.


Your app shouldn’t care where it runs

No flags in code between production and developing. Rather .ini or similar files.


Drupal has come back to the fold, time to pay attention aka Tech is not a zero-sum game

  • There’s a lot of popular low art
  • Same in tech

It’s funny how all the successful things seems to be the things to be critiqued

but

Familiarity dispels fears

Interesting. A lot of people said that Drupal has a bad architecture but in 2000 – when it started (around PHP 4.0) it was pretty good.

It’s interesting how isolated the Drupal community was in the past. While the PHP moved forward they seem to have developed their own stuff – just like a tribe without contact to the rest of the civilization.


Back to the book! PHPUnit annotations to test exceptions:

/**
  * @expectedException FooException
  */

Test fixtures / test context: set ups and tear downs. There is also setUpBeforeClass() which persists over individual tests.

Globals backup You can use @backupGlobals disabled when working with legacy code to enable mutable globals in your tests.

Data providers You can write a function providerFOO() which returns an iterator of arrays which are then used as input to a method annotating @dataProvider providerFOO. PHPUnit then tests with all the data provided by the data provider!

phpunit.xml You can configure your runs, create suites and groups. E.g. you can only run your unit tests and only run unit tests in the staging area.


Test doubles

  • Dummy: empty shell and not used
  • Fake: imitates real object but only for tests
  • Stub: predefined values for a method call
  • Spy: Remembers returned values which can be verified later
  • Mock: Stub with expectations (when and how will it be called)

The main functions in PHPUnit are getMock() which takes parameters and getMockBuilder() which can be chained.

Here’s an example of a mock:

$mockCalculator = $this->getMock('MyCalculator');

$mockCalculator->expects($this->any())
    ->method('getZero')
    ->will($this->returnValue(0));

$this->assertEquals(0, $mockCalculator->getZero());

Building Better Developers

Cool talk that points together a lot of ideas. I heard most of them before but nonetheless a good refresher.

After my experience in the last year or so I think that the psyche of the person is a lot more important than the industry wants to believe.


Back to the book. Chapter 9: Database Testing.

The conclusion is that when you write tests, try to make your development environment as close as possible to the production system.

And also in my opinion apply the Dependency inversion principle as much as possible. It makes testing so much easier. Abstract every IO and you’re a lot better of.


Good to know: You can directly mock PDO but you can if you inherit from it and replace the constructor with an empty one.

Then, there’s also DBUnit which is specialized for testing the connection to the DB.

Also a clever idea. If you use a ORM like Doctrine you could use SQLite as your testing tool quite easily.


Testing legacy code You can start off with black-box testing!

There are several examples using the Reflection API, Patchwork, vfsStream and runkit. However, I’m going to read an other book which is more specialized on handling legacy code. So I rather let me influence more by that.

There’s also a chapter about: Selenium, CI and Behat. I skimmed those.

All in all a pretty good book. I’m surprised that there isn’t that much more to the basics of writing tests than I thought. That makes me feel pretty good.


The Power of Abstraction by Barbara Liskov

Highly interesting talk. It’s a small part of history about data abstraction in CS. Really insightful!

I remember that time. It had never rained.

Surprising, this is the first person I’ve heard that also described memories in a sense of weather. I do the same. There are times which I remember as bright or dark and I mean literally bright. No clouds, no rain, no storms.


Ok, enough for today! I spent the last hour refactoring my soundboard. The code is now a lot cleaner. I like it!


Updates Goals:

  • Learn the intricacies: how does the interpreter work, the OOP system, etc.
  • Learn about PHPUnit
  • Learn a bit more about MySQL
  • Learn a bit more about legacy systems and how to handle them
  • Learn Symfony2
  • Write at least one web app using Symfony2 and its core components (templating, testing, forms, validation, security, caching, i18n)
  • Get a bit more exposure to OOP and OOD
  • Watch one video per day on average

Progress status

Done

  • Learn the intricacies: how does the interpreter work, the OOP system, etc.
  • Learn about PHPUnit
  • Reading PHP Internals Book [done]
  • Reading PHPUnit Essentials [done]

In Progress

  • Watch one video per day on average [25 of 75]