in Back to PHP

My Way to PHP: Day 6 of 75

Day 6! Still a bit hyped :). I just published yesterday’s article. In the PHP Cookbook I’m on page 93 which is just at the beginning of the chapter about arrays. The goal is 50 page, that is page 143 which is at the end in the chapter about variables.


However, before I start with the book I want to get done with the pitfalls. I found several sites which cover problems.

My first source is PHP quirks and pitfalls

The first pitfalls is about operator precedence and implicit casting. The operators + - . have the same precedence. That is every statement is evaluated left to right.

And implicit casting happens if you try to add to a string. If PHP can’t convert the string into a number it uses the value 0. The result is this:

echo "foo" . $a + 1 . "bar"; // 1bar

echo "foo" . $a; // foo1
echo "foo" . $a + 1; // 1

The next pitfall which I saw mentioned quite a lot is the old header already send error. It mostly happens because there’s some whitespace before the opening or closing php tag. Because of that the file already sends out content and with that a header.


The next source is PHP Pitfalls.

They offer a nice table of falsey values in PHP. That is values which are considered as false by if().

null      // null
0         // integer
0.0       // float
"0"       // string
""        // empty string
false     // boolean
array()   // empty array

So I read a few more sites on the topic but most behaviors were pretty clear if you knew a bit about the internals. I think that there will be a few more pitfalls which I will find on my way. But for now that’s good enough!


I learned a new term again Microservices. Yesterday, I wrote about the CL tool with a web interface. The idea looks very similar.

In short, the microservice architectural style is an approach to developing a single application as a suite of small services, each running in its own process and communicating with lightweight mechanisms, often an HTTP resource API. These services are built around business capabilities and independently deployable by fully automated deployment machinery. There is a bare minimum of centralized management of these services, which may be written in different programming languages and use different data storage technologies.

In my opinion that’s a good idea – the biggest problem can be speed, though!

We do not claim that the microservice style is novel or innovative, its roots go back at least to the design principles of Unix.

Yep. I’ve written about that, from Day 2:

I think I’ve written about this before but I love the UNIX philosophy of everything is a file. A database is kind of a file but it’s decoupled from the language or tool. That is, you can write your frontend in PHP, your scheduling algorithm in Python, your optimizations in C and it’s no problem because there’s this beautiful thing called a file or database which connects without problem to any of them. Or even better, you don’t have to write much code because you can use existing software!


Fowler talks about the problem of multiple databases. I still think that you should use one database which collects all the data you need. Of course, if one of your application needs a database to – let’s say store the newest data from a web crawler – that’s ok. But it should be a read-only interface. Every change you want to do to that data can only come from the application – not from the ‘end-user’.


One last great point Fowler makes:

Finally, there is the factor of team skill. New techniques tend to be adopted by more skillful teams. But a technique that is more effective for a more skillful team isn’t necessarily going to work for less skillful teams.

I can’t remember who said it but it was a critique on extreme programming. The author of that piece basically said.

Sure XP worked for people like Kent Beck but I think every other method would have worked with people as experienced as them.

It also comes down to what Beck said in XP explained.

Do you play to win or not to lose?


New terminology: Gateway a class which wraps a API so that you can access an object instead of the API directly.


EventSourcing. The basic concept is easy: You want to redo something or be able to look at past events. However, two of the biggest problems are a) external interface and b) internal changes.

While it works quite simple for a Web UI it’s incredible hard for a backend system.

You can see that quite easily. Let’s say that you have some transactions with transaction fees. You calculate these fees when an event happens (a transaction). Over time you can look at the account of an individual because you saved all events.

Now you find that you had an error in your transaction fee method. When you fix it however then all past transactions are different. Are they wrong or not?

Technically they are wrong but they were accepted by the end user. That is you need to retain the old data. However, maybe you haven’t sent out the invoice yet, then they could be wrong!

It’s incredible finicky. There are numerous other examples. For example, you hardcoded the fee and now it changes. You had to rewrite the events including a fee variable which can then be correctly recalculated.


More terminology incoming: Polyglot Persistence. Comes from Polyglot Programming which means use the right language for the right job. Polyglot Persistence means use the right data storage for the right job.


Reporting Database is a database which is used for reporting. It’s read only, you can duplicate data, don’t have to admit to the normal forms. Mostly, doesn’t need up to date all the time. Pretty good idea!


You know what I like about the PHP community? It’s diverse. Most other language communities seem to exist out of people from California. The blog posts / books I read from the PHP community comes from Germany, England, Texas, North Carolina, France, etc.


Here’s a super solid piece of getting the state of a company’s codebase / dev process: Learning a new codebase

TL;DR:

Ask about coding standards, package managements, tests and the deployment process.


I just saw that PHP 5.6 started to support an alternative to func_get_args() with nice syntactic sugar. I complained about that a few days ago and here it is.

function foo(...$args) {
    foreach($args as $arg) {
        echo $arg, "\n";
    }
}

foo(1, 23, 42, 0); 

/*
1
23
42
0 */

Nice!


Ok, back to the book. The chapter about arrays was pretty standard and nothing new – which makes sense because I read about that in the past.

However, in the chapter about variables they mention apc. Let’s take a deeper look into that.

So APC is a opcode cache, that is it saves the opcode / byte code of PHP. However, you can also use apc to store and fetch variables!

You can basically work with apc_store() and apc_fetch().

Example:

$someGiantObject = ...;

apc_store('mygiantobject', $someGiantObject);

// do something

apc_fetch('mygiantobject'); // to read

Since PHP 5.4 – if I understand that correctly – OPcache is the preferred package to apc.

But it only does bytecode caching and doesn’t support memory caching. However, there’s support for memcache and memcached. This is probably confusing, the simplest explanation is that memcache is a daemon based cache and memcached is a library. So for smaller things memchached is probably the easier approach.


Reading about default parameters also brings the static defaults in Python in mind. PHP handles them a bit differently:

function foo($a = array()) {
    $a[] = "1";
    var_dump($a);
    echo "\n";
}

foo();
foo();
foo(); // stays 1

in the case of Python, the output would have been an array("1", "1", "1").


There are sadly no named parameters in PHP. One idea suggested by the book is using arrays:

function foo(array $params) {
    echo "Foo is {$params['foo']} and bar is {$params['bar']}";
}

foo(["foo" => "hello", "bar" => "bye"]);

// Foo is hello and bar is bye

Thanks to the compact array notation it’s quite readable. But your missing type hinting for single parameters which sadly don’t work with this approach quite so simple. Also default values are more complicated, etc.


filter_input() is quite interesting. There’s also filter_var() which works on variables instead of external input. There are several build-in filters.

Here’s a short summary of the most extravagant ones:

Validate filters

  • FILTER_VALIDATE_EMAIL – no more regexs!
  • FILTER_VALIDATE_URL

Sanitize filters

  • FILTER_SANITIZE_EMAIL
  • FILTER_SANITIZE_FULL_SPECIAL_CHARS = htmlspecialchars()
  • FILTER_SANITIZE_URL

Pretty neat!

Example:

$email = filter_input(INPUT_POST, 'email', FILTER_VALIDATE_EMAIL); // returns false if not validation

Oh Jesus, the list a recipe to valid CC numbers.

Protip: Never deal with payment if you don’t have to.


Learned something new again. There’s DBA which supports embedded key/value databases aka Berkeley DB style. Several different databases are supported (DBM, NDBM, GDBM, DB2, DB3, DB4, CDB, …). You can store, fetch and delete keys and values and that’s all you need!

Really cool didn’t know that there’s a lightweight key/value DB available.


Most of the other chapters either present ‘special’ functions like graphics or emails – which is something I look up when I need it. Or present stuff I’ve already learned!

Therefore it was rather quick to go through the last few chapters.


Ok, I wanted to reread The Pragmatic Programmer. The last time I read it in 2008 I think and just want to update my knowledge. I remember there were a few gems in there. Let’s see how good the book holds after 6 years.

The second chapter mentions the broken window theory. In case you’re not familiar with the topic. It basically means that the threshold to break a second window is a lot lower than breaking the first.

I’ve seen this theory applied in different contexts and also in projects. Because the authors don’t go into the implementation, here’s how I reached the point of immediately fixing broken windows.

  1. Start small. Don’t try to get everything perfect. You’ll probably either won’t start or stop because it is too much
  2. Make a commitment
  3. Realize that it is hard but don’t back out. It’s like working out. It’s hard, and you may not want to do it, but if you do, you’ll feel great.

The next tip is about change: Show something!

Let’s say you want to introduce a new framework. There’s a lot of discussion. Instead trying to convince people by words do it by action. Build a small product or part of the product you want to build. Show it. Show how easy it was, how much faster it is, how the code quality is higher, etc.


Make Quality a Requirements Issue

Two things. Firstly, present the options: “Do you want it to work in IE5? Sure, we can do that, however it will cost you $30,000 extra? Sure, if it isn’t so important we leave that out.”

Secondly, identify the real problem you need to solve. Sometimes writing code isn’t the solution, sometimes even software isn’t the solution.


DRY is one concept I remember quite well from the book, however I forget the original context. Do you know it?

Here it is:

Every piece of knowledge must have a single, unambiguous, authoritative representation within a system.

Knowledge, not code! One example I like is the shows that you can use implicit knowledge. The example takes a class Line which has the attributes: start, end, length. Length is implicit, either take it out or let it set automatically by the setter of start and end.


Interesting observation regarding orthogonality. See how many files / classes / functions you have to change to fix bugs.


Interesting talk about HHVM:

Mostly history about HHVM and a bit of insight about the inner workings. For me, the most interesting insight were:

Facebook already optimized basically everything: Databases, the kernel, networking and then started to optimize PHP

and

I don’t think there are a lot of people who will need the HHVM

and

I don’t know how long they will support PHP in the HHVM.

The background is pretty interesting, starts around 48:00. I wouldn’t bet on it given his argument.


Another good talk. This time about the Proxy Pattern:

It’s good to learn a bit more terminology.

Lazy loading is like lazy evaluation but with the loading of something (often big or computational expensive).

Basic idea is to call this expensive operation only when it’s needed.

A pattern to implement that is the virtual proxy which just wraps around our expensive class.

class Expensive {
    public function __construct() {
        // something expensive
    }
    
    public function getSomething() {
    }
}

class ExpensiveVirtualProxy extends Expensive {
    protected $wrapped;
    public function __construct() {
    }
    
    public function getSomething() {
        $this->init();
        return $this->wrapped->getSomething();
    }
    
    public function init() {
        if(!isset($this->wrapped)) {
            $this->wrapped = new Expensive();
        }
    }
}

Super easy idea. You just wrap the expensive operation and only initialize it if needed.

Then there’s a ghost object which is empty but initializes itself if it’s accessed.

Next is a protection proxy which handles access to the real object. So it’s basically a decorator.

So, smart reference applies more logic than the real one.

Next thing I learned: Fluent interface is an interface with methods which returns the (or sometimes a) object which then can be called again.

$foo = new Foo();
$foo->setA()->setB()->read()->show();

Best Practices for Designing a Pragmatic RESTful API. I like the intro, he talks about two things. First, your API should be good enough to power your UI. Second, most of the writing on the design of RESTful APIs is academic and every writers seems to try to push his own standard – which is pretty annoying.

  1. Start with the resources (nouns)
  2. What actions can you do to them?
  3. Always version your APIs
  4. Filtering, Sorting, Searching as Parameters, e.g. /questions?sort=date
  5. Add fields to select fields in the query parameters
  6. Return the changed resource for PUT, POST and PATCH
  7. gzip your returns
  8. Use JSON for input and output
  9. Use the link header for pagination
  10. Implement rate limiting with its headers (X-Rate-Limit-*)
  11. Authentication should be stateless. Use SSL + token OR OAuth
  12. Use sensible status codes and return an error message

Great article!


Updates Goals (23th October):

  • Learn the most important pitfalls
  • Reread the Pragmatic Programmer
  • Learn about PHPUnit
  • Get an overview of the standard library (SPL)
  • Learn about functional programming in PHP
  • Learn about composer
  • Learn about coding standards
  • Learn about caching
  • Learn a bit more about legacy systems and how to handle them
  • Learn Symfony2
  • Learn a bit more about MySQL
  • Write at least one web app using Symfony2 and its core components (templating, testing, forms, validation, security, caching, i18n)
  • Learn the intricacies: how does the interpreter work, the OOP system, etc.
  • Get a bit more exposure to OOP and OOD

Progress status

Done

  • Learn the most important pitfalls
  • PHP Cookbook by David Sklar, Adam Trachtenberg [done]

In Progress

  • Reread the Pragmatic Programmer [53 of 352 pages]

Write a Comment

Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Webmentions

  • My Way to PHP: Day 7 of 75 – panictank

    […] like everyday I published yesterday’s article. In The Pragmatic Programmer I’m on page 53 which is the beginning of section 11. My goal is […]