PHP’s Type System, part II: The Internet is Made of String

By | 2020-11-05

Part of a series on why PHP’s type system is the best in the world. This post explores why web languages need to be dynamically typed: because the internet is made of string.

A tangled ball of string

The internet is made of string. Everything that enters your application is a string. Query string? String. Cookie data? String. POST data? String. That integer ID number in your URL? Came over the wire as a string of ASCII characters which happened to be numerical digits. Everything coming in is a string. And a lot of it needs to be treated as something else.

Here are three ideas as to how you can do maths with something that came into your application as a string:

  1. Use a language with dynamic typing features
  2. Use a language without dynamic typing features, and add boilerplate code
  3. Use a language without dynamic typing features, along with a framework that does typecasting magic

Here are how these methods might work, in more detail:

Implicit Typecasting and Coercive Typehinting

The main benefits of PHP’s dynamic typing features are implicit typecasting, and coercive typehinting. Implicit typecasting might look like this:

$stringFromPostData = $_POST['price-in-cents']; // "500 "
$priceIncPostage = $stringFromPostData + 199;

var_dump($priceIncPostage); // outputs int(699)

This shows a string of numerical characters coming into the application, then being treated as numbers using implicit typecasting. Whitespace has been trimmed automatically. Note that this implicit typecasting example works only in PHP. There is a class of bug present in other dynamically typed languages, including Python and Javascript, which could cause problems here. See another blog post in this series, Dynamic Typing Causes Bugs.

Here is an example of how coercive typehinting works:

function addPostage(int $priceWithoutPostage) : int
    return $priceWithoutPostage + 199;

$stringFromPostData = $_POST['price-in-cents']; // "500 "
$priceIncPostage = addPostage($stringFromPostData);

var_dump($priceIncPostage); // outputs int(699)

In this example, a coercive typehint forces the parameter of our function to be an integer, even if the data passed in is a string.

This dynamic typing feature can be switched off using declare(strict_types=1); but it would be quite rare for a PHP project to take this approach. It may seem to developers that there is little point in suffering through all of PHP’s other features, if you can’t use its powerful type system.

Working with Languages With No Dyamic Typing

If you use a language without dynamic typing features, such as Java or C#, you still have options. You can add extra boilerplate code in a Java application, to do what implicit typecasting would do, like this:

String stringFromPostData =
int intFromPostData = Integer.parseInt(stringFromPostData(;
int priceIncPostage = intFromPostData + 199;

Here the typecasting has been made explicit, with an additional line of code. Not as clean as PHP, but it’s not the end of the world.

The other major option for writing a web application in a language with no dynamic typing features is to use a framework that works around this for you. It is possible for an MVC framework to simulate the effects of coercive typehinting, if the routing configuration allows it. For example, C#’s ASP.NET Core allows this approach:

app.UseEndpoints(endpoints =>
        name: "default",
        pattern: "{controller=Product}/{action=SetPrice}/{price}");

public IActionResult SetPrice(int price)
    // etc.

Here we see ASP.NET Core essentially using reflection work out that an integer is required, then pulling a string out of the URL slug, and sorting out the type conversion behind the scenes. This approach allows an application in a language without dynamic typing features to be more like PHP – providing the same developer ergonomics, at the cost of some slightly clunky magic under the bonnet of the MVC framework.


Overall, the internet is made of string. Your query string, POST data, cookies, and any incoming JSON etc. from databases all enter your web application as a string. Dynamic typing features provide the most convenient solution to this problem. Whether features like coercive typehinting are provided by your language, simulated by your framework, or absent entirely, there will be a way of typing your variables as you need. But PHP is a language built for the web, and its type system is very well suited for the task at hand.