Bird
Raised Fist0
PHPprogramming~15 mins

Declare strict_types directive in PHP - Deep Dive

Choose your learning style10 modes available
Overview - Declare strict_types directive
What is it?
The declare strict_types directive in PHP is a special instruction placed at the top of a PHP file that tells the interpreter to enforce strict type checking for function calls and return values. When enabled, PHP will not automatically convert types for function arguments or return values, requiring exact matches. This helps catch type errors early and makes code behavior more predictable.
Why it matters
Without strict_types, PHP automatically converts types in many situations, which can hide bugs and cause unexpected behavior. Strict typing forces developers to be explicit about data types, improving code quality and reducing runtime errors. This is especially important in large projects or when working with APIs where type safety matters.
Where it fits
Before learning strict_types, you should understand PHP's basic type system and how functions work. After mastering strict_types, you can explore advanced type declarations, type hinting, and PHP 8's union and mixed types for even stronger type safety.
Mental Model
Core Idea
Declare strict_types tells PHP to stop guessing and require exact data types for function inputs and outputs.
Think of it like...
It's like setting a rule in a kitchen that only exact ingredients can be used in a recipe, no substitutions allowed, so the dish always turns out as expected.
┌─────────────────────────────┐
│ PHP File with declare(strict_types=1); │
├─────────────────────────────┤
│ Function expects int         │
│ Caller passes '5' (string)  │
│ ─────────────────────────── │
│ Without strict_types: PHP converts '5' to 5 (int) silently
│ With strict_types: PHP throws a TypeError
└─────────────────────────────┘
Build-Up - 7 Steps
1
FoundationUnderstanding PHP's default type behavior
🤔
Concept: PHP automatically converts types when calling functions unless strict_types is declared.
In PHP, if a function expects an integer but you pass a string like '5', PHP will convert it to an integer automatically. For example: function addOne(int $num) { return $num + 1; } echo addOne('5'); // outputs 6 Here, PHP converts the string '5' to integer 5 without error.
Result
The function runs successfully and outputs 6, even though the input was a string.
Understanding PHP's default behavior helps you see why silent type conversions can hide bugs.
2
FoundationWhat declare(strict_types=1) does
🤔
Concept: The declare(strict_types=1) directive enforces exact type matching for function calls and returns.
At the very top of a PHP file, you can write: declare(strict_types=1); This tells PHP to stop automatic type conversion for that file. Now, if a function expects an int and you pass a string, PHP will throw a TypeError instead of converting it.
Result
Passing '5' (string) to a function expecting int causes a TypeError.
Knowing this directive exists lets you control how strict PHP is about types, improving code safety.
3
IntermediatePlacement and scope of strict_types directive
🤔
Concept: strict_types applies per file and must be declared at the top before any code.
The declare(strict_types=1); line must be the very first statement in a PHP file, before any whitespace or code. It affects only that file's function calls and return values. If you include or require other files without strict_types, those files use PHP's default behavior. Example: // file1.php
Result
strict_types controls type checking only in the file where it is declared.
Understanding scope prevents confusion about why some files enforce strict types and others don't.
4
IntermediateEffect on return types and function arguments
🤔
Concept: strict_types enforces exact types on both function arguments and return values.
With strict_types enabled, PHP checks: - That arguments passed to functions exactly match declared types. - That functions return values exactly matching their declared return types. Example: declare(strict_types=1); function getNumber(): int { return '5'; // TypeError because return is string, not int } getNumber(); This throws an error because the return type is string, not int.
Result
TypeErrors occur if return types do not match exactly under strict_types.
Knowing strict_types affects both inputs and outputs helps write fully type-safe functions.
5
IntermediateInterplay with type declarations and coercion
🤔Before reading on: Do you think strict_types affects type coercion inside function bodies or only at call boundaries? Commit to your answer.
Concept: strict_types only affects type checking at function call and return boundaries, not inside function bodies.
Inside a function, PHP still allows normal operations and conversions. strict_types does not change how PHP handles types internally, only how it checks types when calling or returning. Example: declare(strict_types=1); function add(int $a, int $b): int { return $a + $b; // addition works normally } add(2, 3); // works fine But add('2', 3); // TypeError because argument '2' is string Inside the function, $a and $b are guaranteed ints, so operations are safe.
Result
strict_types enforces type safety at boundaries but does not restrict internal operations.
Understanding this boundary focus clarifies where strict_types applies and where PHP remains flexible.
6
AdvancedCommon pitfalls with strict_types and mixed files
🤔Before reading on: If you call a strict_types file function from a non-strict file, do you think strict_types applies? Commit to your answer.
Concept: strict_types applies only to the caller file, not the callee file, which can cause unexpected behavior when mixing strict and non-strict files.
If a file with strict_types calls a function defined in a non-strict file, the call is checked strictly. But if a non-strict file calls a function in a strict_types file, the call is not checked strictly. Example: // strict.php
Result
strict_types enforcement depends on the caller file, not the function definition file.
Knowing this caller-based enforcement prevents subtle bugs in mixed codebases.
7
ExpertWhy strict_types is a directive, not a global setting
🤔Before reading on: Why do you think PHP made strict_types a per-file directive instead of a global setting? Commit to your answer.
Concept: strict_types is per-file to maintain backward compatibility and allow gradual adoption in large projects.
PHP was originally loosely typed, so changing to strict typing globally would break existing code. By making strict_types a per-file directive, developers can enable strict typing gradually, file by file. This design balances safety with flexibility, letting projects migrate at their own pace. However, this also means developers must be careful about mixing strict and non-strict files.
Result
strict_types as a directive allows gradual adoption but requires awareness of scope.
Understanding the design tradeoff explains why strict_types behaves the way it does and guides best practices.
Under the Hood
When PHP parses a file with declare(strict_types=1), it sets an internal flag for that file's execution context. During function calls and returns, PHP checks this flag in the caller's context to decide whether to enforce strict type checks. If strict_types is enabled, PHP compares the actual argument types exactly to the declared types and throws TypeErrors on mismatch. Otherwise, PHP performs type coercion silently. This flag does not affect code inside the function body, only the call and return boundaries.
Why designed this way?
PHP was designed as a loosely typed language for ease of use and rapid development. Introducing strict typing globally would break millions of existing scripts. The per-file declare(strict_types=1) directive was introduced in PHP 7 to allow developers to opt-in to strict typing gradually. This design preserves backward compatibility while enabling safer, more predictable code where desired.
┌─────────────────────────────┐
│ PHP File Execution Context   │
│ ┌─────────────────────────┐ │
│ │ strict_types flag = 1   │ │
│ └─────────────────────────┘ │
│                             │
│ Caller function call         │
│ ┌─────────────────────────┐ │
│ │ Check strict_types flag  │─┼─> If 1, enforce exact types
│ └─────────────────────────┘ │
│                             │
│ Function execution (body)    │
│ ┌─────────────────────────┐ │
│ │ No strict enforcement    │ │
│ └─────────────────────────┘ │
│                             │
│ Return from function        │
│ ┌─────────────────────────┐ │
│ │ Check strict_types flag  │─┼─> If 1, enforce exact return type
│ └─────────────────────────┘ │
└─────────────────────────────┘
Myth Busters - 4 Common Misconceptions
Quick: Does declare(strict_types=1) affect all files in a project automatically? Commit to yes or no.
Common Belief:Many believe that declaring strict_types in one file makes the whole project strict.
Tap to reveal reality
Reality:strict_types applies only to the file where it is declared, affecting calls made from that file only.
Why it matters:Assuming global effect leads to unexpected type errors or silent bugs when mixing strict and non-strict files.
Quick: Does strict_types prevent all type coercion in PHP? Commit to yes or no.
Common Belief:Some think strict_types disables all type conversions everywhere in PHP.
Tap to reveal reality
Reality:strict_types only enforces type checks at function call and return boundaries, not inside function bodies or other operations.
Why it matters:Expecting full strictness can cause confusion about why some type coercions still happen.
Quick: If a function is defined in a strict_types file, is it always called with strict checking? Commit to yes or no.
Common Belief:People often believe that functions defined in strict_types files always enforce strict typing regardless of caller.
Tap to reveal reality
Reality:strict_types enforcement depends on the caller file, not the function definition file.
Why it matters:This misconception can cause bugs when calling strict functions from non-strict files without errors.
Quick: Does declare(strict_types=1) affect type declarations like class properties? Commit to yes or no.
Common Belief:Some think strict_types affects all type declarations including class properties and internal operations.
Tap to reveal reality
Reality:strict_types only affects function calls and returns, not property type declarations or internal PHP behavior.
Why it matters:Misunderstanding this leads to incorrect assumptions about type safety in object properties.
Expert Zone
1
strict_types enforcement is determined by the caller's file context, which can cause subtle bugs in mixed strict and non-strict codebases.
2
The directive must be the very first statement in a file, immediately after the opening
3
strict_types does not affect internal PHP functions or extensions, only user-defined functions in PHP code.
When NOT to use
Avoid using strict_types in legacy projects with many loosely typed functions unless you can refactor all related code. Instead, use gradual typing tools or static analyzers like PHPStan or Psalm to improve type safety without runtime strictness.
Production Patterns
In production, strict_types is often enabled on new modules or APIs to ensure type safety, while legacy code remains non-strict. Developers use strict_types combined with typed properties and union types to build robust, maintainable systems. Continuous integration pipelines run static analysis to catch type issues before runtime.
Connections
Static Type Checking
strict_types complements static type checking by enforcing types at runtime, while static analysis checks types before running code.
Understanding strict_types helps appreciate the balance between compile-time and runtime type safety.
Type Systems in Programming Languages
strict_types is PHP's way to add optional strong typing, similar to how languages like TypeScript add types to JavaScript.
Knowing strict_types connects PHP's dynamic typing with broader type system concepts across languages.
Quality Control in Manufacturing
strict_types acts like a quality control checkpoint ensuring only exact parts (types) fit into a machine (function), preventing defects.
This cross-domain link shows how enforcing exact matches prevents errors both in code and physical production.
Common Pitfalls
#1Expecting strict_types to apply globally across all files.
Wrong approach:
Correct approach:
Root cause:Misunderstanding that strict_types applies per file, not globally.
#2Placing declare(strict_types=1) after code or whitespace.
Wrong approach:
Correct approach:
Root cause:Not knowing strict_types must be the very first statement in the file.
#3Assuming strict_types affects internal PHP functions.
Wrong approach:
Correct approach:Use explicit casts or wrapper functions to ensure correct types when calling internal functions.
Root cause:Believing strict_types enforces types on all PHP functions, including built-ins.
Key Takeaways
The declare(strict_types=1) directive enforces exact type matching for function calls and returns in the file where it is declared.
strict_types applies only at the boundaries of function calls and returns, not inside function bodies or on class properties.
The directive must be the very first statement in a PHP file to take effect.
strict_types enforcement depends on the caller file, which can cause subtle bugs when mixing strict and non-strict files.
Using strict_types improves code safety and predictability but requires careful adoption in existing projects.

Practice

(1/5)
1. What does the declare(strict_types=1); directive do in a PHP file?
easy
A. It enables automatic type conversion for function arguments.
B. It disables all error reporting in the PHP script.
C. It sets the default timezone for the script.
D. It forces PHP to check that function arguments match their declared types exactly.

Solution

  1. Step 1: Understand the purpose of strict_types

    The directive declare(strict_types=1); tells PHP to enforce exact type matching for function arguments and return values.
  2. Step 2: Compare with other options

    Options B, C, and D describe unrelated PHP features: error reporting, timezone setting, and type conversion, which are not controlled by this directive.
  3. Final Answer:

    It forces PHP to check that function arguments match their declared types exactly. -> Option D
  4. Quick Check:

    strict_types enforces exact type checks = A [OK]
Hint: Strict types means exact argument types only [OK]
Common Mistakes:
  • Thinking it disables errors
  • Confusing with timezone settings
  • Assuming it enables type coercion
2. Which of the following is the correct way to enable strict types in a PHP file?
easy
A.
B.
C.
D.

Solution

  1. Step 1: Check correct syntax for declare directive

    The correct syntax is declare(strict_types=1); placed at the top of the PHP file.
  2. Step 2: Analyze each option

    <?php declare(strict_types=1); ?> uses the exact correct syntax. Options A and B use invalid PHP syntax. <?php declare(strict_types = true); ?> uses true instead of 1, which is invalid for this directive.
  3. Final Answer:

    <?php declare(strict_types=1); ?> -> Option C
  4. Quick Check:

    declare(strict_types=1) is correct syntax = C [OK]
Hint: Use declare(strict_types=1); at file top [OK]
Common Mistakes:
  • Using true instead of 1
  • Trying to assign strict_types as a variable
  • Calling a non-existent function
3. Given this PHP code with strict types enabled:
<?php
declare(strict_types=1);
function add(int $a, int $b): int {
    return $a + $b;
}
echo add(5, '3');
?>

What will be the output?
medium
A. TypeError: Argument 2 passed must be of the type int, string given
B. 8
C. 53
D. Warning: Implicit conversion from string to int

Solution

  1. Step 1: Understand strict_types effect on function calls

    With declare(strict_types=1);, PHP requires exact types. Passing a string '3' to a parameter typed as int causes an error.
  2. Step 2: Predict the runtime behavior

    PHP throws a TypeError because the second argument is a string, not an int, and no automatic conversion happens.
  3. Final Answer:

    TypeError: Argument 2 passed must be of the type int, string given -> Option A
  4. Quick Check:

    strict_types=1 + wrong argument type = TypeError [OK]
Hint: Strict types cause TypeError on wrong argument types [OK]
Common Mistakes:
  • Assuming PHP converts string '3' to int automatically
  • Expecting output 8 or 53
  • Confusing warning with error
4. Identify the error in this PHP code snippet:
<?php
function multiply(int $x, int $y): int {
    return $x * $y;
}

declare(strict_types=1);
echo multiply(4, 5);
?>
medium
A. The declare(strict_types=1); must be at the top before any code.
B. The function multiply must return a string, not int.
C. The function parameters should not have types declared.
D. There is no error; the code runs fine.

Solution

  1. Step 1: Check position of declare(strict_types=1);

    The strict_types directive must be declared at the very top of the PHP file, before any code or whitespace.
  2. Step 2: Analyze the code order

    Here, the function is declared before the strict_types directive, which is invalid and causes the directive to be ignored or cause an error.
  3. Final Answer:

    The declare(strict_types=1); must be at the top before any code. -> Option A
  4. Quick Check:

    declare(strict_types=1) must be first line = B [OK]
Hint: Put declare(strict_types=1); at file very top [OK]
Common Mistakes:
  • Placing declare after code or functions
  • Thinking return type must be string
  • Removing type declarations from parameters
5. You want to write a PHP function that accepts only integers and returns their sum. You also want to ensure no accidental type coercion happens anywhere in the file. How should you set up your PHP file?
hard
A. Use no type declarations and rely on PHP's automatic type conversion.
B. Place declare(strict_types=1); at the top, then define the function with int types.
C. Use declare(strict_types=0); and define the function with int types.
D. Define the function with int types but do not use declare(strict_types=1);

Solution

  1. Step 1: Enable strict types at the file start

    To prevent type coercion, add declare(strict_types=1); at the very top of the PHP file.
  2. Step 2: Define the function with int type hints

    Declare the function parameters and return type as int to enforce integer-only usage.
  3. Final Answer:

    Place declare(strict_types=1); at the top, then define the function with int types. -> Option B
  4. Quick Check:

    strict_types=1 + int types = strict integer enforcement [OK]
Hint: Use declare(strict_types=1); plus int type hints [OK]
Common Mistakes:
  • Skipping declare(strict_types=1);
  • Using declare(strict_types=0); which allows coercion
  • Not adding type hints in function
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard