Skip to content
beginner Phase 4 · PHP Fundamentals

PHP Functions: Declaration, Arguments, and Return Types

Master PHP functions including declaration, arguments, return types, variadic functions, and named arguments in PHP 8.

45m
0 problems
Topic Progress 0%

Function Declaration and Arguments

Basic Function Declaration

<?php
// Simple function
function greet(string $name): string
{
    return "Hello, $name!";
}

echo greet('John'); // 'Hello, John!'

// Function with no return value
function logMessage(string $message): void
{
    error_log(date('Y-m-d H:i:s') . ': ' . $message);
}

// Function with multiple parameters
function calculateTotal(float $price, int $quantity, float $taxRate = 0.08): float
{
    $subtotal = $price * $quantity;
    $tax = $subtotal * $taxRate;
    return $subtotal + $tax;
}

// Using default parameter
echo calculateTotal(29.99, 3);        // Uses default tax rate 0.08
echo calculateTotal(29.99, 3, 0.1);   // Custom tax rate 0.1

Parameter Types

<?php
// Required parameters
function createUser(string $email, string $password): int
{
    // $email and $password are required
    return insertUser($email, $password);
}

// Default parameters (must come after required)
function formatPrice(float $price, string $currency = 'USD', int $decimals = 2): string
{
    return number_format($price, $decimals, '.', '', $currency);
}

// Nullable parameters
function findProduct(int $id, bool $includeDeleted = false): ?Product
{
    $product = $this->productRepository->getById($id);

    if (!$product && !$includeDeleted) {
        return null;  // Can return null
    }

    return $product;
}

// Type declarations
function processData(
    string $input,
    int $maxRetries = 3,
    float $timeout = 30.0,
    bool $strict = false
): array {
    // All parameters are type-checked
    return ['processed' => true];
}

Parameter Ordering Rules

<?php
// CORRECT: Required -> Default -> Variadic
function correct(
    string $required,           // 1. Required first
    string $withDefault = 'x', // 2. Then defaults
    string ...$variadic        // 3. Variadic last
): void {
    // ...
}

// WRONG: Default before required
// function wrong(string $withDefault = 'x', string $required): void {}
// Fatal error!

// Named parameters (PHP 8.0+)
function createUser(
    string $email,
    string $name,
    string $role = 'customer',
    bool $active = true
): User {
    // ...
}

// Can skip defaults and pass in any order
createUser(
    email: 'user@example.com',
    name: 'John Doe',
    active: false  // Skip $role, use default
);

Variable Scope in Functions

<?php
$globalConfig = ['tax_rate' => 0.08];

function getTaxRate(): float
{
    global $globalConfig;
    return $globalConfig['tax_rate'];
}

// Better: pass as parameter
function getTaxRate(array $config): float
{
    return $config['tax_rate'] ?? 0.08;
}

// Best: use a class
class TaxCalculator
{
    public function __construct(
        private float $taxRate
    ) {}

    public function calculate(float $price): float
    {
        return $price * (1 + $this->taxRate);
    }
}

Key Takeaway

Always type-declare function parameters and return types. Default parameters must come after required ones. PHP 8 named arguments allow skipping defaults and passing arguments in any order.

Return Types and Variadic Functions

Return Types

<?php
// Explicit return types (recommended)
function getProductName(int $id): string
{
    return 'Widget';
}

function calculateTax(float $price): float
{
    return $price * 0.08;
}

function findById(int $id): ?Product  // Nullable return type
{
    return $this->repository->getById($id);
}

function getProductIds(): array
{
    return [1, 2, 3, 4, 5];
}

// Return type declarations
function getData(): array
{
    return [
        'name' => 'Widget',
        'price' => 29.99
    ];
}

// Never return type (PHP 8.1+)
function throwError(string $message): never
{
    throw new \Exception($message);
}

// Union return types (PHP 8.0+)
function getValue(string $key): int|string|bool
{
    return match($key) {
        'id' => 1,
        'name' => 'Widget',
        'active' => true
    };
}

Variadic Functions (...)

<?php
// Accept variable number of arguments
function sum(int ...$numbers): int
{
    return array_sum($numbers);
}

echo sum(1, 2, 3);        // 6
echo sum(1, 2, 3, 4, 5);  // 15

// Variadic with other parameters
function createProduct(string $name, float $price, string ...$tags): array
{
    return [
        'name' => $name,
        'price' => $price,
        'tags' => $tags
    ];
}

$product = createProduct('Widget', 29.99, 'sale', 'new', 'featured');
// ['name' => 'Widget', 'price' => 29.99, 'tags' => ['sale', 'new', 'featured']]

// Spread operator (unpacking arrays)
$prices = [10, 20, 30];
echo sum(...$prices);  // Same as sum(10, 20, 30)

// Practical example: logging
function logMessages(string $level, string ...$messages): void
{
    foreach ($messages as $message) {
        error_log("[$level] $message");
    }
}

logMessages('ERROR', 'Failed to save', 'Database timeout', 'Connection lost');

Named Arguments (PHP 8.0+)

<?php
// Traditional positional arguments
function createUser(
    string $email,
    string $name,
    string $role = 'customer',
    bool $active = true,
    ?string $phone = null
): User {
    // ...
}

// Must pass all arguments in order, even defaults
createUser('user@example.com', 'John', 'admin', true, null);

// Named arguments (PHP 8.0+):
// Can skip defaults, pass in any order
createUser(
    email: 'user@example.com',
    name: 'John',
    phone: '555-1234',
    role: 'admin'
    // $active skipped, uses default true
);

// Useful with functions that have many optional params
html_entity_decode(
    $encoded,
    flags: ENT_QUOTES | ENT_HTML5,
    encoding: 'UTF-8'
);

// Array unpacking with named arguments
$config = [
    'email' => 'user@example.com',
    'name' => 'John',
    'role' => 'admin'
];
createUser(...$config);

Closures and Anonymous Functions

<?php
// Anonymous function assigned to variable
$double = function (int $x): int {
    return $x * 2;
};
echo $double(5); // 10

// Arrow functions (PHP 7.4+)
$triple = fn(int $x): int => $x * 3;
echo $triple(5); // 15

// Closures with use keyword
function createMultiplier(float $factor): Closure
{
    return fn(float $number): float => $number * $factor;
}

$double = createMultiplier(2);
$triple = createMultiplier(3);
echo $double(10); // 20
echo $triple(10); // 30

// Callback functions
$prices = [10, 20, 30, 40, 50];
$filtered = array_filter($prices, fn($p) => $p > 25);
// [30, 40, 50]

$mapped = array_map(fn($p) => $p * 1.1, $prices);
// [11, 22, 33, 44, 55]

Key Takeaway

Always declare return types. Use ?Type for nullable returns. Variadic functions accept unlimited arguments. PHP 8 named arguments make functions with many optional parameters much cleaner.

Functions in Magento Context

Magento Function Patterns

<?php
namespace Vendor\Module\Helper;

class ProductHelper
{
    // Constructor with typed parameters
    public function __construct(
        private \Magento\Catalog\Model\ProductFactory $productFactory,
        private \Magento\Catalog\Api\ProductRepositoryInterface $productRepo,
        private \Magento\Framework\Logger\Monolog $logger
    ) {}

    // Method with strict types
    public function formatPrice(float $price, string $currency = 'USD'): string
    {
        return number_format($price, 2) . ' ' . $currency;
    }

    // Nullable return type
    public function findProductBySku(string $sku): ?\Magento\Catalog\Api\Data\ProductInterface
    {
        try {
            return $this->productRepo->get($sku);
        } catch (\Magento\Framework\Exception\NoSuchEntityException $e) {
            $this->logger->warning("Product not found: $sku");
            return null;
        }
    }

    // Array return type
    public function getProductList(int $categoryId, int $page = 1, int $pageSize = 20): array
    {
        // Returns array of products
        return [
            'items' => [],
            'total' => 0,
            'page' => $page,
            'page_size' => $pageSize
        ];
    }

    // Variadic for bulk operations
    public function updateProductStatus(int $status, int ...$productIds): int
    {
        $updated = 0;
        foreach ($productIds as $id) {
            $product = $this->productRepo->getById($id);
            $product->setStatus($status);
            $this->productRepo->save($product);
            $updated++;
        }
        return $updated;
    }

    // Named arguments in practice
    public function createProduct(array $data): \Magento\Catalog\Api\Data\ProductInterface
    {
        $product = $this->productFactory->create();
        $product->setName($data['name'] ?? '');
        $product->setSku($data['sku'] ?? '');
        $product->setPrice($data['price'] ?? 0.0);
        $product->setStatus($data['status'] ?? 1);
        $this->productRepo->save($product);
        return $product;
    }
}

Using Functions in Magento Templates

<?php
/** @var \Vendor\Module\Helper\Data $helper */
$helper = $this->helper('Vendor\Module\Helper\Data');

// Call helper methods
$formattedPrice = $helper->formatPrice($product->getPrice());
$productUrl = $helper->getProductUrl($product->getId());

// Use closures with Magento collections
$products = $collection->filterByCallback(function ($product) {
    return $product->getPrice() > 50 && $product->getStatus() === 1;
});

// Named arguments for clarity
$formattedPrice = $helper->formatPrice(
    price: $product->getPrice(),
    currency: $storeManager->getStore()->getCurrentCurrencyCode()
);

Key Takeaway

Magento functions should always have type declarations, use nullable types for optional returns, and follow PSR-12 coding standards. Named arguments improve readability when calling functions with many optional parameters.

Quiz

1. What is the correct order for function parameters?

Question 1 options

2. What does the ? (nullable) return type mean?

Question 2 options

3. What does the ... (spread) operator do in a function call?

Question 3 options

4. What is a named argument in PHP 8?

Question 4 options

5. What does the void return type mean?

Question 5 options

Flashcards

Question

What is the correct parameter order in PHP functions?

Answer

Required parameters first, then parameters with defaults, then variadic (...$args) last.

Question

What does ?string return type mean?

Answer

The function can return either a string or null. Equivalent to string|null union type.

Question

What are named arguments in PHP 8?

Answer

Ability to pass arguments by parameter name: createUser(email: 'a@b.com', name: 'John'). Allows skipping defaults and passing in any order.

Question

What does the ... operator do in function parameters?

Answer

Makes the function accept a variable number of arguments as an array. Example: function sum(int ...$numbers) accepts any number of int arguments.

Question

What is the void return type?

Answer

Indicates the function doesn't return any value. Used for side-effect functions like logging or database operations.

Question

What is the difference between arrow functions and closures?

Answer

Arrow functions (fn() =>) are one-line functions that automatically capture variables from parent scope. Closures require explicit 'use' keyword to import variables.

Question

How do you type-declare a function that returns an array?

Answer

Use array return type: function getProducts(): array { return [...]; }. For specific structures, use PHPDoc comments.

Question

What is the never return type (PHP 8.1)?

Answer

Indicates the function never returns normally - it always throws an exception or terminates. Example: function throwError(): never { throw new Exception(); }

Revision Notes

Key Takeaways

  • 1. Always declare parameter types and return types for functions
  • 2. Required parameters must come before default parameters
  • 3. Variadic parameters (...$args) accept unlimited arguments
  • 4. PHP 8 named arguments allow skipping defaults and passing in any order
  • 5. Use ?Type for nullable return types
  • 6. void return type means no value is returned
  • 7. Arrow functions (fn() =>) automatically capture parent scope variables

Interview Tips

  • Explain parameter ordering rules (required, default, variadic)
  • Describe named arguments and their benefits
  • Know the difference between arrow functions and closures
  • Understand when to use nullable return types
  • Be able to write functions following Magento coding standards

Cheat Sheet

PHP Functions Cheat Sheet

Basic Syntax:

function name(Type $param): ReturnType {
    // body
}

Parameter Types:

function example(
    string $required,           // Required
    string $default = 'x',     // Default
    int ...$variadic           // Variable args
): ?string { /* ... */ }

Return Types:
: string, : int, : float, : bool, : array, : void, : ?Type, : never

Named Arguments (PHP 8):

createUser(email: 'a@b.com', name: 'John', active: false);

Arrow Functions:

$double = fn($x) => $x * 2;

Closures:

$fn = function($x) use ($factor) { return $x * $factor; };