Skip to content
Muhammet Şafak
tr
Languages 3 min read

Type Conversion and Type Coercion in PHP

A practical look at PHP type conversion and coercion: gettype, settype, var_dump, and why strict_types belongs in every file.


I have a long history with PHP’s type system. For years I treated PHP’s “thinking about types for you” as a convenience — then I learned it was also a trap, through hours lost debugging. This post approaches PHP type conversion and type coercion not as a feature list, but as a decision point.

PHP infers the type for you

When you declare a variable in PHP you don’t specify its type; PHP looks at the value and decides. You can see that decision with gettype():

$veri = "Muhammet Şafak";
echo gettype($veri); // string

gettype() returns one of: boolean, integer, double (including float), string, array, object, resource, NULL. In practice I rarely call it — but understanding how PHP sees a value is the foundation for every decision that follows.

Conversion: be explicit

There are a few ways to change a value’s type. settype() mutates the variable in place; cast operators ((int), (string), (bool)…) produce a new value; functions like intval() and strval() return the converted equivalent without touching the original.

$veri = "10";
$sayi = (int) $veri;        // 10 — $veri is untouched
settype($veri, "integer");  // $veri is now an integer

All three work. My preference is cast operators: I want to see the intent while reading the code. Because settype() silently transforms a variable into something else, anyone reading the code later — usually me — can mistakenly assume the variable is still a string. Explicit conversion is explicit intent.

The real issue: type enforcement

PHP 7 introduced the ability to declare type hints for function parameters and return values. It’s one of the most valuable additions in the language’s history:

function topla(int $x, int $y): int
{
    return $x + $y;
}

A type declaration is not just a constraint — it’s documentation. Anyone looking at a function signature sees exactly what it expects and what it returns, without guessing. When my own codebase grew to tens of thousands of lines, I felt the value of this concretely.

But there is a trap. By default PHP behaves “loosely”:

function topla(int $x, int $y): int { return $x + $y; }
echo topla("3", "4"); // 7 — strings were silently converted to int

"3" was a string; PHP accepted it as an int. It usually looks harmless — until something like "3 apples" silently becomes 3.

strict_types: non-negotiable

That’s why, for years, the first line of every PHP file I write is this:

declare(strict_types=1);

With that line, PHP no longer silently corrects a type mismatch — it throws a TypeError. You see the error the moment you call the function, not in production. The behaviour marketed as “flexibility” is really just debt that defers bugs to a later date — strict_types settles that debt.

The type is correct; the value still needs validation

A type hint says int; it does not say “int greater than zero”. My fastest tool for inspecting both a variable’s type and its value is still var_dump():

var_dump(3.14); // float(3.14)

The type system guarantees the type; it does not guarantee that the value satisfies a business rule. It’s important to keep type enforcement and value validation separate: one answers “is this a number?”, the other answers “is this number a valid age?”.

Summary

PHP’s loose type system is marketed as a convenience — but left unchecked, it is a source of ambiguity. My approach is clear: declare(strict_types=1) in every file, type declarations on every function, explicit casts for every conversion. The language gives you the freedom not to think about types — I prefer to hand that freedom back and make types visible again. In a long-lived codebase, the returns from this small discipline compound over time.

Tags: #PHP
Share:

Comments

Sign in with your GitHub account to join the discussion. Comments are stored in GitHub Discussions.

Related Posts

Search the site

Start typing to search posts, projects and pages.

Esc to close Powered by Pagefind