When building tools that inspect PHP code, ReflectionFunctionAbstract::getTentativeReturnType() helps answer a focused question: reads the tentative return type of certain internal functions.
Reflection is useful in framework tooling, dependency injection, testing, code inspection and debugging.
What Is ReflectionFunctionAbstract::getTentativeReturnType()?
Reads the tentative return type of certain internal functions.
Its method signature is:
public function getTentativeReturnType(): ?ReflectionType
This method has no required arguments.
Return value: ?ReflectionType
Example 1: Inspect a function or callable
Start with a self-contained PHP declaration and inspect the method result.
<?php
declare(strict_types=1);
#[Attribute(Attribute::TARGET_FUNCTION | Attribute::TARGET_METHOD | Attribute::TARGET_PARAMETER)]
class FunctionMarker { public function __construct(public string $label) {} }
/** Formats one price for a product listing. */
#[FunctionMarker('currency')]
function formatPrice(float $amount, string $currency = 'USD'): string {
return $currency . ' ' . number_format($amount, 2);
}
function logMessages(string ...$messages): string { return implode(', ', $messages); }
function &returnReference(array &$values): array { return $values; }
function valuesFromGenerator(): Generator { yield 10; yield 20; }
class FormatterService {
public function label(int $id): string { return '#' . $id; }
public static function uppercase(string $message): string { return strtoupper($message); }
}
$functionReflection = new ReflectionFunction("strlen");
$result = $functionReflection->getTentativeReturnType();
echo $result === null ? "none" : (string)$result;
Output:
none
Explanation: Reads the tentative return type of certain internal functions.
Example 2: Compare a different callable
Next, change the reflected declaration or parameter to observe a related situation.
<?php
declare(strict_types=1);
#[Attribute(Attribute::TARGET_FUNCTION | Attribute::TARGET_METHOD | Attribute::TARGET_PARAMETER)]
class FunctionMarker { public function __construct(public string $label) {} }
/** Formats one price for a product listing. */
#[FunctionMarker('currency')]
function formatPrice(float $amount, string $currency = 'USD'): string {
return $currency . ' ' . number_format($amount, 2);
}
function logMessages(string ...$messages): string { return implode(', ', $messages); }
function &returnReference(array &$values): array { return $values; }
function valuesFromGenerator(): Generator { yield 10; yield 20; }
class FormatterService {
public function label(int $id): string { return '#' . $id; }
public static function uppercase(string $message): string { return strtoupper($message); }
}
$functionReflection = new ReflectionFunction("array_keys");
$result = $functionReflection->getTentativeReturnType();
echo $result === null ? "none" : (string)$result;
// Check the returned value type before using the result.
echo "\nResult type: " . get_debug_type($result);
Output:
none
Result type: null
Explanation: Tentative internal types are distinct from enforced declared return types.
Practical Example: Use reflection in validation or tooling
This final case shows how the same API can be used when inspecting application definitions.
<?php
declare(strict_types=1);
#[Attribute(Attribute::TARGET_FUNCTION | Attribute::TARGET_METHOD | Attribute::TARGET_PARAMETER)]
class FunctionMarker { public function __construct(public string $label) {} }
/** Formats one price for a product listing. */
#[FunctionMarker('currency')]
function formatPrice(float $amount, string $currency = 'USD'): string {
return $currency . ' ' . number_format($amount, 2);
}
function logMessages(string ...$messages): string { return implode(', ', $messages); }
function &returnReference(array &$values): array { return $values; }
function valuesFromGenerator(): Generator { yield 10; yield 20; }
class FormatterService {
public function label(int $id): string { return '#' . $id; }
public static function uppercase(string $message): string { return strtoupper($message); }
}
$functionReflection = new ReflectionFunction("strtolower");
$result = $functionReflection->getTentativeReturnType();
echo $result === null ? "none" : (string)$result;
// Use the reflection result in a simple decision.
if (is_bool($result)) {
echo "\nStatus: " . ($result ? "yes" : "no");
} elseif (is_array($result)) {
echo "\nEntries: " . count($result);
} elseif ($result === null) {
echo "\nNo value returned";
} else {
echo "\nReflection result available";
}
Output:
none
No value returned
Explanation: getReturnType reads the declared enforced return type.
Important Behavior and Edge Cases
- Tentative internal types are distinct from enforced declared return types.
- getReturnType reads the declared enforced return type.
- Reflection describes declarations and runtime state; requesting metadata does not automatically validate or sanitize application input.
Comparison With Related Approaches
| Approach | When to Use It |
|---|---|
ReflectionFunctionAbstract::getTentativeReturnType() | Reads the tentative return type of certain internal functions. |
Related API | getReturnType reads the declared enforced return type. |
Common Beginner Mistakes
| Mistake | Correct Approach |
|---|---|
| Ignoring this condition: Tentative internal types are distinct from enforced declared return types. | Handle the specific limitation: Tentative internal types are distinct from enforced declared return types. |
| Confusing this method with Related API | getReturnType reads the declared enforced return type. |
Key Takeaways
- Reads the tentative return type of certain internal functions.
- Tentative internal types are distinct from enforced declared return types.
- getReturnType reads the declared enforced return type.
Use ReflectionFunctionAbstract::getTentativeReturnType() when you need the precise metadata or behavior demonstrated above. Keep the target declaration and relevant PHP version in mind when adapting the examples.