Blog

WTF is a Late Static Binding in PHP?

One of the features in “advanced” PHP you come across is Late Static Binding. There are two things that make this feature very interesting:

  1. It is remarkably useful
  2. It is extremely poorly explained in the official docs

So if you’ve heard of this term the first-time, or like me, have lost a few hair over what exactly does it mean, you’ve come to the right place.

First, let’s get a few facts in order:

  • Late Static Binding applies only when there is inheritance involved. No inheritance, no Late Static Binding.
  • The “static” in “Late Static Binding” means that this idea crops up only when static class members are involved.

So, only inheritance, and only static members. Some people even call it “static inheritance”, but I think that term gives the concept an unnecessary aura of erudition, and thus, intimidation.

Anyway, generally we don’t work in inheritance hierarchies where a lot of static members are involved in base and derived classes. But if there’s ever a need, a nasty surprise awaits us. Let’s learn this through an example.

Suppose you are designing a game where Minions are an important NPC entity (yes, you can’t exactly do that because of copyright issues and all that, but for a moment let’s assume you can). Classically, the Minions are all yellow, so this is a property that should be at the class-level; in other words, a static property. So you might define the class as follows:

class ClassicMinion {
    public static $color = "yellow";

    public static function introduceYourself() {
        echo "I'm a " . self::$color . "-colored Minion!";
    }
}

Nice!

Now imagine that our game also has Minions that can talk clearly; we decide that these will be of blue color. But since they are primarily Minions, we don’t need to redefine the introduceYourself() method.

The new class might look like this:

class Minion2K extends ClassicMinion {
    public static $color = "blue";
}

And finally, it’s time to give this a spin:

Minion2K::introduceYourself();

And the output is: I’m a yellow-colored Minion.

WTF just happened?!!

Well, this is inheritance of static stuff in action. When the program runs, the call to `self::$color` resolves the base class, because `self` is always supposed to resolve to the class that contains the function. In this case the function comes from the `ClassicMinion` class, which is why we see a “yellow”.

The fix is startlingly simple, and equally startlingly reminiscent of bad naming conventions in PHP: static. The idea is to just replace the call `self::` with `static::`, and PHP will calculate which class we’re actually talking about, like this:


public static function introduceYourself() {
    echo "I'm a " . static::$color . "-colored Minion!";
}

The binding of `self`, so to speak, will be figured out later when there is inheritance of static stuff. Hence the name:Late Static Binding.

And now we get the correct output: I’m a blue-colored Minion!

The choice of the keyword static is unfortunate, in my opinion; it adds confusion to an already too-messed-up language. But I digress. 🙂

The pointless PHP vs. Node debate

Imagine a million transactions a  month. Okay, 10 million. Assuming it’s a company that sells products, and the typical order size is $50, we’re talking of $500 million in monthly revenue. Or $6 billion annual. That’s big deal. Very few businesses reach that level.

Now, also asuume that the order flow is evenly distributed during the day; that is, there’s no radical spike in traffic (for instance, traffic doesn’t shoot up 200 times without warning).

Question: How many PHP servers would you need for this setup?

Now, 10 million transactions a month sounds mind-boggling. Let’s break it down. Per hour, this comes down to 10,000,000 / (30 * 24) ~= 13,800 transactions. Per second, it’s about 13,800 / 3,600 = 4 transactions.

4 transactions a second. That’s the typical load for a business making half a billion in revenue. Let’s double it: 8-10 transactions per second takes us to a monthly revenue of 1 billion!

Let’s compute the memory involved: 300 MB for the OS + 300 MB for PHP-FPM and Nginx + let’s say, 50 MB of memory per transaction (which is unlikely). So, we’re looking at around 1.1 GB of memory. Let’s also factor in unforeseen circumstances and jack that up to around 4 GB.

Now, what kind of server do you need to handle 10 transactions a second?  Yes, a trivial one. A simple VPS costing around $20 a month can easily handle this traffic alone. If you want to be on the safe side, a  $50/month VPS is all you need to run this setup.

Even if you have a load balanced setup, it’s hard to imagine how the monthly expense can exceed $150, inclusive of taxes (for servers alone, that is; we’re not taking account the cost of sending email, because it’s going to be the same on every backend).

I may be incorrect in my assumptions, but look at the big picture: $100 spent on infrastructure gives you $1 billion revenue’s worth of traffic-handling!

This is the reality of 99.9% of the projects out there. They’re going to grow, but they are rarely going to touch levels of more than a few transactions per second. Now imagine what a server with 32 GB of RAM can do! What about 64 GB RAM? I think you get the idea. 🙂

In other words, the debate of what is more “scalable” falls flat on its face in the real world. That’s why PHP is still going strong, and that’s why experienced PHP developers yawn when they hear “scalability”.

Node.is is a great choice, mind you. If you have a team comfortable with Node.js, by all means use that. I would even say that because of it’s real-time capabilities, Node is an overall better choice than PHP. However, discarding PHP just because you think you’ll run into scalability problems soon is like worrying about your pile of bricks reaching the moon: it’s not going to happen.

Biases and improvement

The biggest hurdle to your improvement as a software developer are your biases.

The idea that React/Angular/Vue/Backbone are somehow superior to other alternatives; the idea that Python is a much more robust web development language than PHP; the idea that PostgreSQL is the only sensible relational database out there; the idea that nothing matches the capabilities of Node.js (or Go, or Java, or Erlang, or something else); the idea that a particular stack was ordained by the gods; the idea that AWS is the one true hosting solution; the idea that everything other than machine learning, blockchain, chatbots, AR/VR and 3D printing is garbage; the idea that you know enough already . . .

Stop forming conclusions.

There will never be a point in your life when you’ll have all the answers and 100% surety.

Things you rely on today and break their characters any time.

Your own abilities may nosedive, for all you know.

It’s much better to keep an open mind, a smile on your face, and realize that you’re in a rabbit hole. The best you can do is keep going deeper and enjoying the sense of directionlessness. 🙂

Laravel: How many controller are too many?

Recently, in a phone interview for a remote positions, this post of mine was called out by the interviewer. His comment was, more or less, that it was stupid to worry about the number of controller in an MVC application. He said that putting logic in controller is a very bad practice, and that I should have clear separation of concerns via the Repository pattern.

I agreed with him that day, but when I later thought about it, I realized there’s still a lot of value in having multiple controllers for a single entity. This may not be obvious in small applications, but consider a large system where one entity can do multiple actions, and each action has a sub-action. For instance, a Customer can buy, review, return, reject, a product, and so on.

Now also suppose that there are three ways of buying something, three of returning, two of rejecting, and so on. If you put all these functions inside a single controller, the controller becomes harder to reason about. I, for one, would definitely recoil if I saw 50 functions in a single class, even if everything is still being done by a repository.

In these cases, I don’t think dividing your controllers into, say, CustomerPurchaseController, CustomerReviewContoller ,etc., is a bad idea. The work is still being done by the Repository, but now I have a much easier time analyzing the code base.

Lesson? Don’t be quick to dismiss something that doesn’t agree with your experience. It might be useful in some cases.

When not to work for a startup [for developers]

These days, startups have a charm that only Paris can rival. They are painted as the far-off, blessed lands where creativity, money, and benefits are flowing freely, and no conformity exists. If you’re a developer, you have dreamed of working for a startup at least once already.

Well, sometimes it’s not a good idea. Please understand: almost all the startups around us are surviving on borrowed money and trying to find a market-fit. “Trying” is the operative word here. Everyone, from the guy who lent them money, to the guys running the show, knows that there’s a very high chance of failure, but this picture is never presented to you.

Given how fast money can get burned in a startup, you might be staring at joblessness within a few months (or even weeks). Yes, you gain a lot in exchange, but ultimately, you have to be honest with yourself: do you like that idea? If not, then it’s most likely the culture you’re attracted to. If so, try to find some small but established business that has a friendly culture. It will have a few disadvantages, sure, but financial insecurity won’t be one of them.

Personally, I decided to avoid all these high and lows for some time, as they give me sleepless nights. Once I have a stable position in life and ample money, I’ll take the risky route and hope for my ESOPs to explode.

And in case you do decide to ditch the startup route, don’t badger yourself  with the thoughts that you’re a loser. The only loser is the person who is not true to himself and hasn’t been able to structure his life accordingly.

Correctly setting up October CMS through Composer on Ubuntu 16.04

(Sorry I’m in a real hurry as I write this. I’ll expand on this later, but today I figured out how to correctly set up October CMS through composer. Hope this helps somebody.)

(To-do: A post on why care about October CMS)

$ composer create-project october/october myapp
$ cd myapp
$ php artisan october:env
$ php artisan key:generate
$ php artisan october:up
$ php artisan serve

Choosing the right tech stack for development [for developers]

If you’re a progressive software developer and do not spend a few hours worrying about which tech stack to choose next, you’re lying. We all do it. In fact, combined with the famous Impostor Syndrome, this constant anxiety is enough to break anyone’s back.

Laravel or Symfony? Node or Go? React or Angular? Ember or Vue? Java or Scala? Java or Kotlin? Django or Rails? Python or PHP? Go or Elixir? C++ or Rust? These and countless other similar comparisons possibly run in your mind over and over and drive you insane (well, they drive me insane).

I was recently struck by an idea that could help resolve this confusion for most of the developers. Here’s how it goes:

Are you a junior to intermediate developer?

If not, do whatever you want.

If yes, stick to the stack that has most jobs in your language ecosystem.

In other words, if you’re into PHP framework-based development, pick Laravel over everything else. Not because it’s the most amazing framework (it isn’t) but because it will bring you more jobs, more projects, more growth.

And that’s it, really. Do not, I repeat, do not crave for the greener grass on the other side. There’s no written rule that Node developers are paid better than PHP developer always. Code monkeys are always paid peanuts no matter what tool they pick up; don’t be one of them.

Are you a JavaScript developer confused between Angular and React? The decision is simple: React. More popularity (thanks to React Native), larger community, more jobs, and so on.

As a junior to intermediate developer, your goal is to master (I repeat, master) one stack that is quite popular. This will ensure a healthy income and self-esteem. Once you’ve started architecting complex system in your language, it won’t that much. Your first responsibility is to be useful to your employer and be able to provide for your family.

Adventure comes second. And so, your language is not dying or going to be replaced. Relax.

Stop wasting time thinking about it.

How many Controllers should you have? [Laravel]

Controllers are the life and blood of a Laravel application. It’s impossible to imagine a framework without them (well, it is, but technically something has to receive the route action, and whether it’s a class or function, it becomes a controller, so to speak).

In the last 3-4 years of my development experience, I went through a minor transformation when it comes to the number of controllers in my application. Earlier, my reasoning was like this: “Controllers, well, control stuff; what they control are the business entities — customers, orders, sellers, etc.”.

So, it was natural to have one “controller” per entity, and the directory structure would look like this:

Controllers
 - UserController.php
 - CustomerController.php
 - SellerController.php
 - [ . . . ] 

Looks very pristine to the eye: all the controllers live inside an aptly-named directory, and all clearly demarcate their territory. Just like the number of figureheads in a system, the fewer the better, right?

The approach worked, but only as far as trivial projects like To-Do List were concerned. In any real-life system, an entity is involved in so many transactions that its controller ends up having a few dozen functions and hundreds of lines of code. Not pretty at all.

I then came across the approach that increases the number of controllers. Now my applications have 20, 30 or more controllers, depending on how many types of transactions every entity is involved in. And they’re into their separate directories. As a result, code organization becomes more sane, and the controllers becomes smaller and more DRY.

Here’s what my new structure looks like:

Controllers
- User
  - UserLoginController
  - UserProfileController
  - UserPurchaseController
- Admin
  - AdminAccountController
  - AdminTransactionController
[. . .]

There’s no limit to how deep you can go, but so far for me, one level deep is good enough.

Agree? Disagree? Do you have a better scheme? I’d love to hear your side. 🙂

The curious relationship between Laravel and Node.js

Even a cursory survey of skills (try LinkedIn) will tell you that a huge percentage of Laravel developers end up learning Node.js. The skills list goes something like this: “LAMP, Laravel, Ionic, Node, Full Stack Developer”. And it’s not just beginners bragging about their skill-set, mind you; I’ve met serious architects who passionately love Laravel and use Node.js.

Why? I can think of a few reasons:

  • The Socket.io library has disgustingly good support for web sockets. When it comes to stuff like chatting and notifications, PHP has no answers while Node.js shines brighter than a thousand suns.
  • Node.js is JavaScript. Everyone learns JavaScript for the browser, and the transition to Node.js becomes easy.
  • It allows you to sprinkle words like “real-time”, “scalable” on to your profile.

Interestingly, you won’t see this skill combination with other, “lesser” PHP frameworks. CodeIgniter, CakePHP, or even WordPress, these developers tag themselves as “LAMP” and get it over with. They are bounded by the four walls of shared hosting, cPanel, GoDaddy and FileZilla, and they’re pretty happy in their wonderland. Node.js? What is that, a new plugin?

Even more interestingly, pure Node.js never give a shit about learning PHP. In fact, they adamantly stick to Node.js. Developers from other languages like Go, Elixir, Java, Scala, etc., never learn PHP. They also don’t learn Node.js. Why? Probably because their language ecosystems already have great support for web sockets and soft real-time communication (I hear the Netty server kicks some serious ass, and Elixir . . . well, that’s on a whole new level).

But more importantly, why do Laravel developers don’t get attracted to other alternatives? Why don’t Laravel developers get tired of the fact that Node is a disaster on multi-core CPUs? Or that it has hideous memory leak problems? Or that npm run build alone takes 1.6 GB of peak RAM? Or that the npm ecosystem is eccentric, to say the least? Or that Golang is much smaller, neater, easier to learn, and absolutely rock-solid?

We can never know the real reason, but I’ll attribute it to laziness. The bulk of PHP developers are not passionate (just dive into the Ruby and Python communities and you’ll know what I mean). Laravel has turned a bland language into something more enjoyable, but that’s about as far as the average developer is willing to explore. The more serious ones end up embracing Symfony, or go the framework-less way, but the other ones remain stuck with the language they know. Why make the massive effort of learning something new? Why not just rinse and repeat?

Any developer who learns these other languages seriously will drop PHP like a rotten banana. I say that as a PHP developer myself. Maybe I’m lazy, too?

Rust Tutorial – Part 6 – Functions

Functions in Rust are much like functions in conventional languages – simple entities that accept an input and produce an output (but not always). Here’s a very simple example of a function in Rust:

fn main() {
    simple_function(32);
}

fn simple_function(x: i8) {
    println!("The value received was {}", x);
}

So, we see that functions are defined using the keyword fn. You might have noticed that main() is also a function defined with fn. The value 32 is passed to the function, and it gets printed to the console. The only catch here is the type of the variable: Rust needs to know in advance the type of value that’ll be arriving in the function. I chose i8 because our example carries a really small integer. Generally, you’d want to use i32 unless memory is at a premium.

But what if we want our function to return a value? It can, as long as we tell Rust in advance what the return value’s type will be. Let’s see another example:

fn main() {
    let x = simple_function(10);
    println!("Got {} from function", x);
}

fn simple_function(x: i8) -> i8 {
    return x * 2;
}

The output, unsurprisingly, is Got 20 from function. We need to be careful when defining functions. If the outcoming value is larger than what the declared type can hold, things will blow up:

fn main() {
    let x = simple_function(10);
    println!("Got {} from function", x);
}

fn simple_function(x: i8) -> i8 {
    return x * 20000;
}

Now are multiplying x by 20000, and there’s no way the result can be contained in an 8-bit integer (i8). Let’s see what we get when we compile it:

warning: literal out of range for i8
  --> 01_variables_and_mutation.rs:14:16
   |
14 |     return x * 2000000;
   |                ^^^^^^^
   |
   = note: #[warn(overflowing_literals)] on by default

We’ve been warned; there’s going to be integer overflow. If we go ahead and run the program anyway, the sky falls down:

thread 'main' panicked at 'attempt to multiply with overflow', 01_variables_and_mutation.rs:14:12
note: Run with `RUST_BACKTRACE=1` for a backtrace.

There’s another trickery related to returning values, instead of saying return x * 2;, you can simply write x * 2 (note, no semi-colon):

fn simple_function(x: i8) -> i8 {
    x * 2
}

This works as intended. Why? Well, the details are a bit technical, but basically it’s the different between statements and expressions in a programming language. Statements do things, expressions return values. But the catch is that what’s expression in one programming language isn’t in another. So, something like this doesn’t work in Rust:

let y = (let x = 6);

This is an error, because let x = 6; doesn’t return a value (this will come as a major surprise to folks from C, Python, Java, Ruby, etc.). And that is so because x = 6; is considered a statement in Rust. It does something (Assigns 6 to x), but doesn’t return it. without the semi-colon, x * 2 is an expression and returns the value of x plus 2.

Is all this hair-splitting any practical use? Yes, if you ever want the value of one let to be returned to another variable:

fn main() {
    let y = {
        let z = 10;
        z + 2
    };

    println!("y is {}", y);
}

Looks odd, I’ll be honest, but it does what we need. We get y is 12 when we run the program.

A word of caution before we finish: using something like return z + 2; won’t work in the last example as the return statement marks the end of the code. I encourage you to try that and see what happens. 🙂