in Back to PHP

My Way to PHP: Day 3 of 75

And again I woke up early! I just spend about half an hour editing todays post (that is yesterday when you read this). Now I’m looking for more resources especially about PHP in detail. I added one yesterday which I will probably read after the current one. I also added the top stackoverflow questions on PHP which I will selectivly read – probably the top 20-30 pages.

In Learning PHP Design Patterns I’m currently on page 41. My goal is 50 pages, that is page 91. That will be around the fifth chapter which is about the factory method design pattern.


In the meantime I’ve searched for some more interesting resources which support my goals.

While looking for books I found this video about legacy code in PHP:

The speaker also wrote a book which I will probably read in the future.

  1. Most PHP software starts out as one script file
  2. Afterwards it gets put into different files but it won’t be designed in a modular way

Jesus, the code he shows in the video.

Incremental goals

  • Keep the application running
  • Consolidate classes for autoloading
  • Convert globals to injected dependencies

Interesting talk! I learned about the autoloading ability of PHP and know what dependency injection means. And I finally understood why there’s code like:

$foo = new Foo(new Bar());

 


Now back to Learning PHP Design Patterns.

First principle: program to an interface, not an implementation.

Ok, the idea is that you use interface as your main type while writing code. Let’s say you have an interface called DatabaseInterface. You write implementation for it, e.g. one for MySQL, one for SQLite, etc.

Now, if you want to use a database as a parameter you don’t use the SQLite type but rather DatabaseInterface. That’s allows you to switch out implementations. And most important you can write mock implementations for testing.


Here’s also something new. Each object is instance of its class (obviously) but also instance of the interface the class implements:

interface I {
    public function foo();
}

class A implements I {
    public function foo() {
        echo "I'm A";
    }
}


$a = new A;

var_dump($a instanceof A); // true
var_dump($a instanceof I); // true

Second principle: favor object composition over class inheritance.


One thing to consider in choosing a design pattern is what will vary in a design. […] what you want to be able to change without redesign.


Factory Method Design Pattern

Ok, the idea about creational design patterns is that the object initiating a new object shouldn’t need to know how to create the object.

Which is also basically the idea behind the factory method DP. Just with multiple subclasses which implemented one interface.


While thinking about the usage of the factory DP I looked around and found one blogpost about GoF. The author talks a bit about the misunderstandings of Design Patterns which helped me understand the usage of them.

The main misunderstandings are:

  • The authors of the book thought they invented the patterns
  • The book says that you have to use the patterns from the book to write good software.
  • The book says that the patterns in the book are the only and most important design patterns

All this is totally, absolutely, completely, outright and utterly wrong. The intent of the book was totally different than many people seem to think today.

This was pretty useful! I actually wondered why something like the Factory became so popular and I can see the usage of it in SOME cases. And that’s it. It isn’t the right way to do it generally but in the cases you need to solve that problem.


Now all this hype around GoF and OOP makes a lot more sense…

Ok, back to the book. Yeah. So I’m through the chapter about Factory Method DF. The most important things I learned – so far – were a) dependency injection (from the video) b) the first principle of DF and c) the idea that you might want to generalize the object creation.


Prototype Design Pattern Ok, the idea is that you create a prototype object which then can be cloned.

Here’s what I would do without looking at the pattern:

  • Either just write a function which creates the object, does all the defaulting and returns the object
  • Or inherit the object and do the same thing

I would probably do the first thing.

Now, I looked at the pattern and it uses inheritance. Ok, I forgot to code against the interface. But otherwise pretty good.


Structural Design Patterns: The idea is to combine stuff to make up new stuff.

Adapter Pattern: The idea is that you want to use A and B together but they don’t fit. Therefore you intercept an adapter.

I’m seriously wondering why GoF became so popular.


Decorator Design Pattern: Add stuff to an existing object without changing it.


Behavioral Design Patterns: How do objects work together / communicate?

Template Method Pattern: When you want apply different functions but the functions vary.

You might know what I was thinking.

function foo($a, $b) {
    if(call_user_func($a) > 10) {
        echo call_user_func($b, 25);
    }
}

foo(function() {return 100;}, function($x) { return $x * $x; });

I just leave this uncommented.


State Design Pattern: Change behavior when state changes


Okay, dokey. The next part is called MySQL and PHP Design Patterns

Proxy Pattern: Stay in place for the real deal.


Strategy Pattern: Use different algorithms


Chain of Responsibility Pattern: Put something through a lot of things.

The basic idea is that you make a linked list with processing in it.


Observer pattern: Hey look. Something was updated.

Actually php offers SPL functions for that: SplObserver, SplSubject and SplObjectStorage. Otherwise you had to poll an object all day or attach something to the setters.


Freaking amazon reviewers were right again. The first 4 chapters (basic OOP) were alright. The following chapters not so much. I skimmed most of the later chapters but I wasn’t impressed (which led to the skimming btw).


So, I have another book lying around which also has patterns in its name. But the ToC looks great. But after reading through the last book I want to read some Stackoverflow question on PHP!

When to use self vs $this?

I didn’t even know self existed. self refers to the class in which it was mentioned, that is not at run-time. If you want to use a static method use static::foo instead of self::foo. Why? Because if you use self and you inherit the self will still relate to the parent class.


How should I ethically approach user password storage for later plaintext retrieve?

What I found most interesting was a link to Diceware. If you have used Electrum you may have seen Diceware in action. The idea is that you present a password as a list of words. The name Diceware comes from the idea that you roll the dice X times and the resulting number is mapped to a word.

You don’t have to roll the dice yourself of course. What’s pretty neat is that you have a pretty high entropy with just 6 words. And it’s easier to remember than some random string: major car light balloon paper radiator.


How to check if a string contains a specific word

The beauty of strpos or better of fucking implicit casting:

var_dump(strpos("a string", "a")); // 0 (okay, it is at position 0)
var_dump(strpos("a string", "string")); // 2
var_dump(strpos("a string", "banana")); // false
var_dump(strpos("a string", "a") == false); // true

How foreach actually works?

The question is actually really interesting, read it yourself. The answer is insanely detailed and interesting and explains a lot. Basically it has to do with the GC and reference count. That is behavior for foreach differs between using a variable or outputting the array directly.


After 7 pages of questions I go back. But nonetheless I tried out the use keyword which allows closures.

function foo($a) {
    return function ($b) use ($a) {
        return $a * $b;
    };
}


$multi_two = foo(2);
$multi_five = foo(5);

echo $multi_two(10); // 20
echo $multi_five(20); // 100

Works pretty nice! :D (I also just noticed that I don’t have to use call_user_func.


Great. Now that I’m far enough away from the last book I’m going to start the next one: PHP Objects, Patterns, and Practice. The ToC sounds beautiful. Let’s see if the content is as good.


Also one thing in case you’re wondering how I can plough through so much stuff. I have all day for that. I think the last two days I spend about 8 – 10 hours learning or so.


I’ve just read that there are generators in PHP and checked it out.

function incx() {
    $i = 0;
    while(1) {
        yield $i++;
    }
    
}

foreach (incx() as $i) {
    if($i > 20) {
        break;
    }
    echo $i;
}

But you can’t seem to use the iterator functions to use it:

function incx() {
    $i = 0;
    while(1) {
        yield $i++;
    }
    
}

$gen = incx();

var_dump($gen); // object#1 <0> { }
var_dump(current($gen)); // false
var_dump(next($gen)); // false
var_dump(each($gen)); // false

The third chapters – which talks about type hinting – brings up an interesting problem. What if you have a function which takes a boolean.

function foo($answer) {
    if($answer) {
        ...
    }
}

Now, because bool is a primitive you can’t use type hints. What should you do? He shows various approaches, from trying to fix it, to using comments. But the last example – and the one I think he also prefers – is using the is_ functions. He uses die() to exit the function. This would be my approach:

function foo($answer) {
    if(!is_bool($answer)) {
        throw new InvalidArgumentException("foo expects a boolean. Input was $answer");
    }
    if ($answer === true) {
        ...
    }
}

I wonder if that exception is exploitable – I sincerely hope that the input get escaped if it gets outputted to the page.

I just tested compileonline.com which doesn’t escape the expection. However, writecodeonline.com which I mainly use – so far – does escape it.


What I really like about the author (and book) is that he writes clean code in a sense of using libraries when adequate. E.g. he shows abstract classes and implementing one for an XML Writer. And he actually uses XMLWriter instead of writing one himself. Really nice!


I just pondered when I stopped writing PHP. I think it was around 2007 and my hosting provider still used PHP 4.X. It also was probably around September or October. 7 years ago – oh man. But the language developed a ton since then and I really like a lot of the changes!


I’m still thinking about traits. It’s nice that you can use its functions but on the other hand you could also just use a static method or initiate an object.

Also quite interesting, traits have full access to the class using it.

trait A {
    public function foo() {
        $this->a = 40;
        echo "a $this->a, b $this->b, c $this->c";
    }
}

class B {
    use A;
    private $a = 23;
    protected $b = 22;
    public $c = 21;
}

$b = new B;
$b->foo(); // a 40, b 22, c 21

Edit: Funny, later he wrote about exactly about that.


There’s a lengthy section about exceptions which is great. Most books neglect that!


There are quite some functions which allow to dynamically react to undefined method calls, setters, getters, etc. The author calls it interception. More at php.net

These methods are also called magic methods and like magic they introduce uncertainty.


The scope of __clone() is the new copy of the object. Also it’s a shallow copy. That is, you have to explicitly add a clone of all object variables in your class to __clone().


I have to say that so far this book is excellent!


Interesting method to handle file includes. Add your directory to the include_path. You can even do that with .htaccess:

php_value include_path value .:/path/to/lib/php-libraries


Autoloading (like described in the video above). You can use a simple autoloading which comes with PHP. It will search for a class name in lowercases as a file. And if you namespaces in the directory.

spl_autoload_register();

$foo = new Foo(); // will search foo.php or foo.inc
$bar = new baz\Foo(); // will search in baz/foo.php (or inc)

I’m done for today. But I thought about that after finishing this book I will expand my goal a bit. I was way faster that I initially estimated. And think it’s a nice idea to make the goal a bit harder.

Goals:

  • Learn more about the PHP OOP and Design Patterns
  • Learn the most important pitfalls
  • Learn the right and idiomatic way to do PHP development today
  • Read Patterns of Enterprise Application Architecture
  • Learn Symfony2
  • Learn the intricacies: how does the interpreter work, the OOP system, etc.
  • Get a overview over the standard library
  • Learn about functional programming in PHP
  • 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)

Progress status

Done

  • Learning PHP Design Patterns by William Sanders

In Progress

  • PHP Objects, Patterns, and Practice by Matt Zandstra [105 of 532 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 4 of 75 – panictank

    […] day! Like every day I edited and published yesterday’s notes. I’m currently on page 105 in PHP Objects, Patterns, and Practice – which is just at […]