# 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.

- Published: 2021-09-22
- Category: Languages
- Tags: PHP
- Reading time: 3 min read
- Source: https://www.muhammetsafak.com.tr/en/blog/php-type-conversion-and-type-coercion/
- Language: en-US
- Author: Muhammet Şafak

---
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()`:

```php
$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.

```php
$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](/en/blog/scalar-type-declarations-and-return-types-in-php-7/). It's one of the most valuable additions in the language's history:

```php
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":

```php
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"` throws a `TypeError`.

## strict_types: non-negotiable

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

```php
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()`:

```php
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.
