PHP Casting

sa sahaya jerish Updated 17 Oct 2026
11 min read ·Lesson 23 of 52
In this post

What Is Casting? In simple terms: Casting means converting a value from one type to another on purpose — for example, turning the text "42" into the number 42 . Technically: Type casting is an explici

What Is Casting?

In simple terms: Casting means converting a value from one type to another on purpose — for example, turning the text "42" into the number 42.

Technically: Type casting is an explicit type conversion. You write the target type in parentheses before a value, such as (int) $value, and PHP returns a new value of that type. The original variable is not changed.

PHP also converts types automatically in many situations (for example, when you add a string to a number). That automatic behavior is called type juggling and has its own lesson. Casting is the explicit counterpart: you decide when and how a conversion happens.

Why Casting Is Needed

Data often arrives with the wrong type for what you want to do with it:

  • Form fields, URL parameters, cookies, and CSV values are always strings.
  • Some database drivers return numbers as strings.
  • JSON may contain numbers where your code needs strings (or the reverse).
  • Functions with strict type declarations require exact types.

Casting makes the conversion visible in the code, so a reader knows that a type change is intentional.


Cast Operators

Syntax

\$result \= (type) \$value;

 

CastConverts ToExampleResult
(int)Integer(int) "42"42
(float)Float(float) "3.5"3.5
(string)String(string) 42"42"
(bool)Boolean(bool) "hello"true
(array)Array(array) "PHP"["PHP"]
(object)Object (stdClass)(object) ['a' => 1]object with property a

 

Version Notes

  • Long aliases are deprecated. (integer), (double), (boolean), and (binary) are older spellings of (int), (float), (bool), and (string). Since PHP 8.5 they produce a deprecation notice, and PHP 9 is expected to stop recognizing them. Always use the short forms.
  • Removed casts. (real) and (unset) were removed in PHP 8.0 and cause a parse error. Use (float) and assign null instead.

Example

<?php

\$input \= "42";

 

\$number \= (int) \$input;

 

var_dump(\$input);

var_dump(\$number);

 

Output

string(2) "42"

int(42)

 

The cast returns a new integer. $input still holds the string "42".


Casting to Integer: (int)

Rules

<?php

var_dump((int) "123");

var_dump((int) " 123");

var_dump((int) "123abc");

var_dump((int) "abc123");

var_dump((int) "");

var_dump((int) 12.99);

var_dump((int) -12.99);

var_dump((int) "1e3");

var_dump((int) true);

var_dump((int) false);

var_dump((int) null);

 

Output

int(123)

int(123)

int(123)

int(0)

int(0)

int(12)

int(-12)

int(1000)

int(1)

int(0)

int(0)

 

What These Results Mean

InputBehavior
Numeric stringConverted to the number; leading whitespace is ignored
String starting with digits ("123abc")Uses the leading number, ignores the rest
String not starting with a number ("abc123", "")Becomes 0
FloatTruncated toward zero — 12.99 becomes 12, not 13
Numeric string in exponent form ("1e3")Interpreted as the number 1000
true / false / null1 / 0 / 0

 

Casting Never Fails — and That Is a Risk

(int) always returns an integer, even for meaningless input. (int) "abc" silently becomes 0, and (int) "12abc" silently becomes 12. This is convenient for trusted data, but dangerous for validation:

<?php

\$quantity \= (int) "five"; // 0 — no error, no warning

 

For user input, validate first and convert second:

<?php

\$quantity \= filter_var("five", FILTER_VALIDATE_INT);

 

if (\$quantity \=== false) {

    echo "Please enter a whole number.";

}

 

Output

Please enter a whole number.

 

filter_var() both validates and converts: it returns an int for valid input and false otherwise. See PHP Numbers for more validation options.

Rounding Before Casting

Because (int) truncates, round first when you need the nearest whole number:

<?php

var_dump((int) 7.8);

var_dump((int) round(7.8));

 

Output

int(7)

int(8)

 


Casting to Float: (float)

<?php

var_dump((float) "3.75");

var_dump((float) "10");

var_dump((float) "2.5e2");

var_dump((float) "12.5kg");

var_dump((float) "1,250.50");

var_dump((float) 7);

 

Output

float(3.75)

float(10)

float(250)

float(12.5)

float(1)

float(7)

 

The same "leading number" rule applies. Note the fifth result: "1,250.50" becomes 1.0 because conversion stops at the comma. Formatted numbers must be cleaned before conversion, for example with str_replace(',', '', $value) or filter_var($value, FILTER_VALIDATE_FLOAT, FILTER_FLAG_ALLOW_THOUSAND).


Casting to String: (string)

<?php

var_dump((string) 42);

var_dump((string) 3.0);

var_dump((string) 0.1);

var_dump((string) true);

var_dump((string) false);

var_dump((string) null);

 

Output

string(2) "42"

string(1) "3"

string(3) "0.1"

string(1) "1"

string(0) ""

string(0) ""

 

Details

  • Floats with no fractional part lose the .0: (string) 3.0 is "3".
  • true becomes "1"; false and null become an empty string.
  • Since PHP 8.0, float-to-string conversion always uses . as the decimal separator, regardless of the locale.

Arrays and Objects

<?php

\$tags \= ['php', 'mysql'];

echo (string) \$tags;

 

Output

PHP Warning: Array to string conversion in /path/script.php on line 3

Array

 

An array cannot be meaningfully converted to a string, so PHP produces the text Array and a warning. Use implode() or json_encode() instead.

An object can be cast to a string only if its class defines a __toString() method; otherwise PHP throws an Error:

<?php

class Money

{

    public function __construct(private int \$paise) {}

 

    public function __toString(): string

    {

        return '₹' . number_format(\$this->paise / 100, 2);

    }

}

 

\$price \= new Money(149900);

 

echo (string) \$price . "\n";

echo "Price: \$price\n";

 

Output

₹1,499.00

Price: ₹1,499.00

 

__toString() is called whenever the object is used as a string — in casts, echo, interpolation, and concatenation. Magic methods are covered in Magic Methods.


Casting to Boolean: (bool)

(bool) converts any value to true or false using PHP's truthiness rules: false, 0, 0.0, "", "0", [], and null become false; everything else becomes true.

<?php

var_dump((bool) "0");

var_dump((bool) "0.0");

var_dump((bool) "false");

var_dump((bool) []);

var_dump((bool) [0]);

 

Output

bool(false)

bool(true)

bool(true)

bool(false)

bool(true)

 

(bool) "false" is true, because the string is not empty. To interpret text such as "yes", "no", "on", or "false", use filter_var($value, FILTER_VALIDATE_BOOLEAN). All rules are covered in PHP Booleans.


Casting to Array: (array)

Scalars and Null

<?php

var_dump((array) "PHP");

var_dump((array) 42);

var_dump((array) null);

var_dump((array) ['already', 'an', 'array']);

 

Output

array(1) {

  [0]=>

  string(3) "PHP"

}

array(1) {

  [0]=>

  int(42)

}

array(0) {

}

array(3) {

  [0]=>

  string(7) "already"

  [1]=>

  string(2) "an"

  [2]=>

  string(5) "array"

}

 

  • A scalar value becomes a one-element array.
  • null becomes an empty array.
  • An array stays unchanged.

Practical Use: Accepting One Value or Many

<?php

function addTags(string|array \$tags): array

{

    \$tags \= (array) \$tags;

 

    return array_map('strtolower', \$tags);

}

 

print_r(addTags('PHP'));

print_r(addTags(['PHP', 'MySQL']));

 

Output

Array

(

    [0] \=> php

)

Array

(

    [0] \=> php

    [1] \=> mysql

)

 

(array) normalizes both inputs into an array, so the rest of the function handles a single case. This pattern is common for options that accept either one value or a list.

Objects to Arrays

Casting an object to an array produces an array of its properties:

<?php

class User

{

    public string \$name \= 'Asha';

    protected string \$role \= 'editor';

    private string \$password \= 'secret';

}

 

\$data \= (array) new User();

 

foreach (array_keys(\$data) as \$key) {

    echo str_replace("\0", '\0', \$key) . "\n";

}

 

Output

name

\0*\0role

\0User\0password

 

Public properties keep their names. Protected properties are prefixed with \0*\0, and private properties with \0ClassName\0, where \0 is an invisible null byte (made visible here with str_replace()). These prefixes make the result awkward to use, and the cast exposes private data such as passwords.

To export object data, use public methods or get_object_vars() inside the class, and never pass objects containing secrets to output or logs via a cast.


Casting to Object: (object)

<?php

\$config \= (object) [

    'host' \=> 'localhost',

    'port' \=> 3306,

];

 

echo \$config->host . ":" . \$config->port . "\n";

var_dump(\$config instanceof stdClass);

 

Output

localhost:3306

bool(true)

 

An associative array becomes a stdClass object whose properties match the array keys. Scalars become an object with a single property named scalar:

<?php

var_dump((object) "hello");

 

Output

object(stdClass)#1 (1) {

  ["scalar"]=>

  string(5) "hello"

}

 

(The object ID #1 may differ.)

(object) is convenient for quick data containers, but for structured data used throughout an application, a real class with typed properties is clearer and safer.


Conversion Functions

PHP also provides functions that perform the same conversions:

FunctionEquivalent CastExtra Capability
intval($v, $base)(int)Optional base, e.g. intval("ff", 16) → 255
floatval($v)(float)—
strval($v)(string)—
boolval($v)(bool)—
settype($var, $type)—Changes the variable in place

 

Why Use Functions Instead of Casts?

Functions can be passed as callbacks, which casts cannot:

<?php

\$prices \= ["499", "1299", "89"];

 

\$numbers \= array_map('intval', \$prices);

 

var_dump(\$numbers);

echo array_sum(\$numbers) . "\n";

 

Output

array(3) {

  [0]=>

  int(499)

  [1]=>

  int(1299)

  [2]=>

  int(89)

}

1887

 

array_map('intval', ...) converts every element. A cast like (int) cannot be passed by name; you would need fn($p) => (int) $p.

settype() Modifies the Variable

<?php

\$value \= "123abc";

 

settype(\$value, "integer");

 

var_dump(\$value);

 

Output

int(123)

 

Unlike a cast, settype() changes the variable itself and returns true on success. It accepts type names such as "integer", "int", "float", "string", "boolean", "bool", "array", "object", and "null". Casts are usually clearer because the conversion is visible where the value is used.


Casting and Strict Types

When a file declares declare(strict_types=1);, PHP stops converting scalar arguments automatically when calling functions with type declarations. Explicit casts are still allowed and become the standard way to convert data at the boundaries of your code:

<?php

declare(strict_types=1);

 

function calculateTotal(int \$quantity, float \$unitPrice): float

{

    return \$quantity * \$unitPrice;

}

 

\$quantityInput \= "3"; // from a form

\$priceInput \= "249.50"; // from a form

 

// calculateTotal(\$quantityInput, \$priceInput); // TypeError in strict mode

 

echo calculateTotal((int) \$quantityInput, (float) \$priceInput);

 

Output

748.5

 

The casts convert the form strings into the types the function requires. In real code, validate the inputs (with filter_var()) before casting. Strict types are covered in Strict Types.


Practical Example: Normalizing Request Parameters

A listing page receives query parameters such as ?page=3&per_page=25abc&featured=0&tags=php. Each value arrives as a string (or is missing).

<?php

function readListingOptions(array \$query): array

{

    \$page \= filter_var(\$query['page'] ?? '', FILTER_VALIDATE_INT, [

        'options' \=> ['min_range' \=> 1],

    ]);

 

    \$perPage \= filter_var(\$query['per_page'] ?? '', FILTER_VALIDATE_INT, [

        'options' \=> ['min_range' \=> 1, 'max_range' \=> 100],

    ]);

 

    return [

        'page' \=> \$page \=== false ? 1 : \$page,

        'perPage' \=> \$perPage \=== false ? 20 : \$perPage,

        'featured' \=> (bool) (int) (\$query['featured'] ?? 0),

        'tags' \=> array_map('strval', (array) (\$query['tags'] ?? [])),

    ];

}

 

\$options \= readListingOptions([

    'page' \=> '3',

    'per_page' \=> '25abc',

    'featured' \=> '0',

    'tags' \=> 'php',

]);

 

var_dump(\$options);

 

Output

array(4) {

  ["page"]=>

  int(3)

  ["perPage"]=>

  int(20)

  ["featured"]=>

  bool(false)

  ["tags"]=>

  array(1) {

    [0]=>

    string(3) "php"

  }

}

 

Step-by-Step Explanation

  1. page is validated with filter_var() and a minimum of 1. "3" is valid and becomes int(3).
  2. per_page must be between 1 and 100. "25abc" is not a valid integer, so the default 20 is used. A plain (int) cast would have silently accepted it as 25.
  3. featured is cast with (int) and then (bool). Casting to int first guarantees that values such as "0" and "1" map to false and true (and that "0.0" or "00" are treated as 0 instead of being truthy strings).
  4. tags may arrive as a single string (?tags=php) or an array (?tags[]=php&tags[]=mysql). (array) normalizes both, and array_map('strval', ...) ensures every element is a string.

The result is an array of correctly typed values that the rest of the application can trust.


Common Mistakes

Using Casts as Validation

Effect: (int) "abc" becomes 0, and (int) "12abc" becomes 12, without any error.

Fix: Validate with filter_var() before using the value.

Expecting (int) to Round

Effect: (int) 9.99 is 9.

Fix: Use (int) round($value), or floor()/ceil() deliberately.

Casting Formatted Numbers

Effect: (float) "1,250.50" is 1.0.

Fix: Remove separators or use a validating filter with FILTER_FLAG_ALLOW_THOUSAND.

Casting "false" to Bool

Effect: true, because the string is not empty.

Fix: filter_var($value, FILTER_VALIDATE_BOOLEAN).

Casting Objects With Private Data to Arrays

Effect: Private properties (including secrets) appear in the result with null-byte prefixes.

Fix: Expose data through explicit methods; never dump or log such casts.

Using Deprecated or Removed Cast Names

Effect: Deprecation notices for (integer), (double), (boolean), (binary) in PHP 8.5; parse errors for (real) and (unset).

Fix: Use (int), (float), (bool), (string), and assign null directly.


Best Practices

  • Use the short cast forms: (int), (float), (string), (bool), (array), (object).
  • Cast at the boundaries of your code — where external data enters — and work with correct types everywhere else.
  • Validate before casting untrusted input; cast only values you already know are valid.
  • Round explicitly before casting floats to integers when rounding is intended.
  • Use (array) to accept "one or many" values, and intval/strval as callbacks with array_map().
  • Prefer real classes over (object) casts for data used across the application.

Official reference: https\://www.php.net/manual/en/language.types.type-juggling.php#language.types.typecasting

0 Comments

Reviewed before they appear

No comments yet.

PHP
Ask about this post
AI Ask about this post

Ask questions about PHP Casting and get answers drawn from it.

Signed-in readers only.