in Back to PHP

My Way to PHP: Day 8 of 75

Day 8. Today, it will be one week since I started! I’m rather pleased with my progress and satisfied. My goal today is to finish PHP: The Right Way and watch at least one conference video.


I’m reading up on traits again. I still don’t have a good use case in mind. However, one interesting thing I learned is that use in namespaces resolves in the global namespace whereas use in traits is local.

After reading the original RFC and the wiki article on traits I stumbled on this question on SO: Traits in php – any real world examples?

Ok, so the main opinions are either a) you don’t need traits and b) you can use it for isolated cross cutting concerns, e.g. logging.


Something new, you can import functions via namespaces since PHP 5.6:

use function My\Namespace\functionName;

Composer! Here’s what I need to know

  • composer require package:~version to update the composer.json
  • composer install to install packages
  • require 'vendor/autoload.php' injects composer’s autoloader
  • You can add your own files to the autoloader in the compoer.json (supports PSR-4)

You basically map your vendor on a directory:

"autoload": {
    "psr-4": { "Foobar\\": "mysrc/"}
}

Now you can use a namespace like Foobar\Baz\Foo and it will include mysrc/Baz/Foo.php. And if you leave the key in the json (in this case Foobar\\) empty it will search your directory for any namespace!

Sweet!


Here’s a nice cheat sheet on using PHP and UTF8

  • Set your DB to utf8
  • Use mb_string and mb_* functions
  • Set headers

I’ve looked into Behat – a storyBDD tool – a few days ago. It’s basically like Ruby’s Cucumber. Neat tool, especially nice for the final testing. I think I have a video about that in my queue. So it will come up some time.


Regarding caching, there’s APCu which seems to have the same API as APC had. Also important to note, it will cache inside a PHP process. That is, if you’re using (F)CGI, they cache won’t be shared between these processes. Here memchached could be a solution. I also want to look into Redis in the future.


And done! Good read, I knew most of the stuff so far – which is what I aimed to. This was probably one of my first exposures since I started and I modeled my goals a bit after that!


Before starting the next book I want to read a few articles from PlanetPHP.


New terminology from the article Fault tolerant programming in PHP: Circuit breaker. That is a wrapper around a class which can fail (mostly I/O). It will handle the errors through either

  • Fallback
  • Retry
  • Monitors
  • Or just fast failing

And a new pattern: Repository Design Pattern pack the data to a central place which can be accessed by a public API.


Good. Let’s start a new book: Mastering the SPL Library. It’s 182 pages about obviously about SPL. My first critique is that the title is Mastering the Standard PHP Library Library.

Let’s start! The SPL reminds my of C++’s STD on the first sight. The intro is a short essay about complexity.

It also covers the PHP internal hash table. This is the stuff I wanted to know about! So the implementation is pretty standard. They use double linked lists in case of hash collision. That also explains why for large N the look up time of the associate array converges from O(1) to O(n).

The hash table grows automatically – it doubles in size. And every time it does that it has to recalculate hashes!


An other talk – in German – I will summarize the most interesting facts:

The title is “Vor BDD und TDD war PDD” which means “Before BDD and TDD there was PDD”.

  • PDD is Pain-Driven Development
  • They show an actual – and still developed – source file which is just one class, with about 400 methods, and around 25k LoC. Insane!
  • Sebastian (the creator of PHPUnit) actually build it because his professor mocked him that he didn’t want to do real software development in Java but in PHP. Sebastian then created the first rudimentary version of PHPUnit in one week which was a clone of JUnit at the time.
  • About 6 months after the initial bet he expanded PHPUnit and published it. But for at least 2-3 years nobody really cared.
  • A lot of QA tools are made by German developers
  • They talked about Code Rank and Manuel’s project PHP Depend has a great overview over different software metrics.
  • Code Rank (CR) is basically PR applied on Packages / Classes. The higher the CR the more this entity should be tested
  • Use the complexity metric (Cyclomatic Complexity Number) for starters – the goal is between 12 and 14 for a method!

I normally subscribe to the idea that a method / function shouldn’t be longer than your head (or fit on your screen).

  • The problem with CCN is that it doesn’t count the number of paths. It just counts the number of branches

If you want to have 100% branch coverage, you need at least one test for each path you can take. You can calculate that number with NPath Complexity.

  • A huge amount of duplicated code is often a sign for communication problems in the dev team
  • People starting with PHPUnit (or other QA tools) often feel pain and project it onto the tool itself

Incredible good talk! Sadly, only in German.


The next talk is titled: Recognising smelly code

  • Methods should do a specific task

Code smells:

  • High level of nesting (see CCN and NPath!) => decouple
  • Bad naming
  • Too many parameters => use a Object instead if possible
  • Class should be a noun and should have a responsibility

Code smells:

  • God object => decouple
  • Tight coupling / typing new => DI
  • Using arrays instead of objects => check if it makes sense

General code smells:

  • Copy & paste
  • Speculative Generality => YAGNI

This talk is titled: FAIL: The Best Ways to Bring Down Your Website.

So, far interesting war stories! Also failure normally means that your are out of something (CPU, Bandwith, Money, whatever).

The best way to fail is to be inordinately successful!

  • Statelessness works great for scaling

Most of the talk is the admin / infrastructure side so far which I didn’t cover.

Even if you don’t care about the infrastructure watch the first 8 and the last 8 minutes for war stories.


This talk is titled: The 7 Deadly Sins of Dependency Injection

The first new terminology was Service Locator. I looked it up and it looked similar to a DI container. Here’s an article about the difference: Service Locator vs. DI container

The main difference is in the usage not in the implementation. The idea is that instead of injection all your dependencies you are going to write a class which returns you each dependency.

It also gets covered in the talk (around 33:00). For SL you explicitly call get and anyone could set them. For DIC however, you explicitly set the dependencies!

The problem is that you’re hiding the ‘mess’ with ServiceLocators most of the time.


The next terminology is ContainerAware. Here’s my source: ContainerAware considered harmful.

It’s like a DIC (DI Container) but not in the constructor but with one special setContainer() method. And this will be called implicitly at construction time!

They are even worse than ServiceLocators.


If there are two many dependencies injected feel free to split the class up into multiple ones.

Use constructor DI. If there’s an optional injection you can use setter injection.


The whole talked reminded me of a part of The Zen of Python

Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.


Another talked PHP Under the Hood, however a bit newer from 2014:

  • Profiling: looks for bottle necks in the call graph, memory usage, etc.
  • Benchmarking: actual performance

Jesus, I feel sorry for that guy. He has such a hard time breathing :/


Ok, now it goes a bit in depth. All data is stored in zvals (Zend values). The zval saves 4 things (the value, refcount, type and reference). Here’s the struct:

typedef struct _zval_struct {
    zvalue_value value;
    zend_uint refcount__gc;
    zend_uchar type;
    zend_uchar is_ref__gc;
} zval;

An interesting bit is the type zvalue_value which is a union:

typedef union _zvalue_value {
    long lval; // stores ints, bools and resources
    double dval; // float
    struct {
        char *val;
        int len;
    } str;
    HashTable *ht;
    zend_object_value obj;
} zvalue_value;

What’s interesting is that PHP never changes the zvals actual type but rather creates a new zval.

The rest of the talk looks at Opcode from a few simple examples. It’s very understandable!

Generally, pretty approachable talk. However, I would say that you probably need a bit of background. I make this assumption given a note in the description:

Note: This is an advanced talk, you should be extremely familiar with PHP and have some experience with profiling if you are to get the most from this talk.

What helped me is to understand how a VM works, some C, some Assembly and a bit of knowledge about operating systems.


Talk: Caching Best Practices

Caching everything that is expensive – either getting it once or once ever so often

I like the generality of that statement. Memorization can also be seen as caching.


Cache things that don’t change often

He presents several methodologies with variable flexibility. I quite like the idea of caching widgets and it made me aware about cache invalidation. There are cases when cache invalidation is clear and easy. One example is that, you have a push system. You can cache forever and then invalidate if you push out a change. That’s called update invalidation.

Alternatively, you can directly update the cache. However, it gets problematic if the database changes and the cache and DB get out of sync.


Pre-generation strategy: You proactively generate the cache. Facebook used that for new clusters.


The ideal form is the biggest-smallest re-usable object. Basically cache everything which doesn’t change often enough but has a big influence on the performance.


Solutions:

  • APC for one machine, is incredible fast (runs in memory), native PHP interface
  • Memcached / Redis for multiple servers

Multi-Layer Cache: Store data given access time and staleness.

  • PHP instance = immediately
  • APC = Quick expiration
  • Memcached = longer expiration
  • DB = worst case

Never store something in cache that you can’t recreate

Also use a DB.

Have external configuration for caching

E.g. in case of a traffic spike you can increase the caching.

Prefix your keys with a version no.

Saves flushing, no problem when rolling out a new version, and no old stale data which might be accessed.


The next talk is called PHP Opcache Explained.

That’s interesting: include, require and eval() in source files, are included, then executed and as soon one of these statements appears, these files get compiled again and executed!


So a OPcode consists out of an uint (internal numeric representation), an handler (actual function), two operators, a result, an extended value (e.g. a carry), the line no and the type information.


OpCache optimizes calculates at compile time which is great. For example, if you’re dealing with time you often write something like:

60 * 60 * 3 // 3 hours

This gets optimized!


OPCache just keeps old (wasted) files in the memory. If a threshold is reached it will recompile all the files.


Okay, back to the book!

Chapter 3 which presents all data structures.

SplDoublyLinkedList They actually implemented count() as O(1) by saving meta data. Otherwise, the complexity is like expected. What’s pretty cool is that you can set the iterator mode to LIFO and FIFO and so traverse the list backwards.

SplStack This shares the same codebase with the Double Linked List (inherits it) and could be implemented with LIFO mode.

SplQueue Nothing special about that. Also inherits from `SplDoublyLinkedList but uses FIFO mode.


SplHeap This is an abstract class and you need to implement a function called compare(). That’s pretty cool. Otherwise it implements a binary tree internally.

However, there’s a special case in the case something in compare() goes wrong. Then the heap is corrupted and throws an RuntimeException.

SplMaxHeap Like SplHeap but the maximum element is at the top (i.e. compare() is already implemented).

SplMinHeap The opposite of SplMaxHeap.

SplPriorityQueue Similar to the heaps but an other internal implementation. It still compares however, you add a priority when using insert(). It will then push out the most important (highest priority) item at first.


SplFixedArray Sweet. Traditional arrays implemented in PHP. You set the size at construction. You can however, also set a new size with setSize(). That’s pretty great.

SplObjectStorage Interesting. A hash map in which objects can be keys.

At the end of the chapter there’s a neat table listing all data structures and their complexities for different operations. Neat!


The next chapter is about iterators. There are a lot of iterators which I will talk about later. But how you can work with them is neat.

An example from the book:

$it = new DirectoryIterator("."); // lists all files in the current directory
$it = new RegexIterator($it, "/.mp3$/i"); // extracts only files with matched regex
$it = new LimitIterator($it, 0, 3); // returns only the first 3 

foreach($it as $file) {
    // 
}

That’s super cool!

To create your own iterator you just have to implement Iterator. And for filter iterators (like RegexIterator) implement FilterIterator – which has just one function called accept().

Man, that’s beautiful. I really love those iterators. Let’s see which ones are available in the SPL.


  • AppendIterator = appends several iterators (key isn’t changed!)
  • CachingIterator = caches all ‘old’ elements, can look ahead one and you can specify the __toString() behaviour
  • CallbackFilterIterator = apply a callback to filter the elements
  • FilterIterator = abstract class which allows to implement a filter
  • InfiniteIterator = repeats the given iterator over and over again
  • LimitIterator = returns the Xth to Yth elements
  • MultipleIterator = returns the elements of several iterators simultaneously
  • NoRewindIterator = the iterator can only be used once
  • RecursiveIteratorIterator = iterates through all the children
  • There are also several recursive iterators and one

Okay, enough for today :)


Updates Goals:

  • Learn about composer
  • Learn about caching
  • Get an overview of the standard library (SPL)
  • Learn the intricacies: how does the interpreter work, the OOP system, etc.
  • Learn about PHPUnit
  • 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 PHP: The Right Way [done]
  • Learn about composer
  • Learn about caching

In Progress

  • Mastering the sPL [155 of 186 pages]
  • Watch one video per day on average [13 of 75]

Write a Comment

Comment

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