Skip to content
beginner Phase 4 · PHP Fundamentals

PHP Variables: Syntax, Scoping, and Superglobals

Master PHP variable syntax, scoping rules, superglobals, type juggling, null coalescing operator, and practical examples.

45m
0 problems
Topic Progress 0%

PHP Variable Syntax and Naming

Declaring Variables

PHP variables start with $ and don't need explicit type declaration.

<?php
// Variable declaration
$name = 'John Doe';           // String
$price = 29.99;              // Float
$quantity = 5;               // Integer
$isAvailable = true;         // Boolean
$products = ['Widget', 'Gadget']; // Array
$nothing = null;             // Null

// Multiple assignment
$a = $b = $c = 0;  // $a, $b, $c all equal 0

// Variable variables (dynamic variable names)
$varName = 'greeting';
$$varName = 'Hello!';  // Same as $greeting = 'Hello!';
echo $greeting;  // 'Hello!'

Naming Rules

<?php
// VALID variable names
$firstName = 'John';        // camelCase (recommended)
$first_name = 'John';       // snake_case (also common)
$productName = 'Widget';    // camelCase
$MAX_SIZE = 100;            // UPPER_CASE (constants)
$_private = 'hidden';       // Underscore prefix
$item2 = 'second item';     // Numbers allowed (not first char)

// INVALID variable names
$2name = 'Bad';     // Can't start with number
$first-name = 'Bad'; // Hyphens not allowed
$my var = 'Bad';    // Spaces not allowed
$@name = 'Bad';     // Special chars not allowed

// Magento naming conventions
$productId = 123;          // camelCase for variables
$productRepository = null; // camelCase for objects
$_redirect = '/';          // Underscore for private-like

Variable Types (Dynamic)

<?php
// PHP is dynamically typed
$variable = 'string';      // Now a string
$variable = 42;            // Now an integer
$variable = 3.14;          // Now a float
$variable = true;          // Now a boolean
$variable = null;          // Now null

// Check type at runtime
$price = 29.99;
echo gettype($price);    // 'double' (float)
echo is_float($price);   // 1 (true)
echo is_int($price);     // (empty - false)
echo is_string($price);  // (empty - false)

// var_dump for debugging
var_dump($price);  // float(29.99)

// print_r for arrays
print_r(['name' => 'Widget', 'price' => 29.99]);

String Variables

<?php
$productName = 'Widget Pro';
$price = 29.99;

// Single quotes - no interpolation
echo 'Price: $price';         // Output: Price: $price

// Double quotes - interpolation works
echo "Price: $price";         // Output: Price: 29.99
echo "Price: {$price}";       // Output: Price: 29.99 (explicit)
echo "Total: " . $price * 2;  // Must use concatenation for expressions

// Heredoc - multi-line strings with interpolation
$html = <<<HTML
<div class="product">
    <h2>$productName</h2>
    <p>Price: \$$price</p>
</div>
HTML;

// Nowdoc - multi-line without interpolation
$sql = <<<'SQL'
SELECT * FROM catalog_product
WHERE price > 0
SQL;

// Concatenation with .=
$message = 'Hello';
$message .= ' World';  // $message is now 'Hello World'

Key Takeaway

PHP variables are dynamically typed and start with $. Use camelCase for variable names. Single quotes don't interpolate, double quotes do. Always use $this-> for object properties.

Variable Scoping

Three Types of Scope

<?php
// 1. LOCAL SCOPE - Only accessible inside the function
function calculateTotal($price, $quantity) {
    $total = $price * $quantity;  // $total is local
    return $total;
}

// echo $total;  // ERROR: Undefined variable

// 2. GLOBAL SCOPE - Accessible everywhere outside functions
$globalVar = 'I am global';

function accessGlobal() {
    global $globalVar;  // Must use 'global' keyword
echo $globalVar;  // Works
}

// Alternative: $GLOBALS superglobal
function accessGlobalAlt() {
    echo $GLOBALS['globalVar'];  // Also works
}

// 3. STATIC SCOPE - Persists between function calls
function counter() {
    static $count = 0;  // Initialized once, persists
    $count++;
    echo $count . '\n';
}

counter();  // 1
counter();  // 2
counter();  // 3

Scope in Practice

<?php
$taxRate = 0.08;  // Global variable

// WRONG: Can't access global directly
function calculateWithTax($price) {
    // echo $taxRate;  // ERROR: Undefined variable
    return $price * 1.08;  // Hardcoded - BAD
}

// CORRECT: Use global keyword
function calculateWithTax($price) {
    global $taxRate;
    return $price * (1 + $taxRate);
}

// BETTER: Pass as parameter
function calculateWithTax($price, $taxRate) {
    return $price * (1 + $taxRate);
}

calculateWithTax(100, $taxRate);

// BEST: Use a class
class TaxCalculator
{
    private float $taxRate;

    public function __construct(float $taxRate)
    {
        $this->taxRate = $taxRate;
    }

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

Static Variables in Functions

<?php
// Static variables persist between calls
function getRequestCount(): int {
    static $count = 0;
    $count++;
    return $count;
}

echo getRequestCount(); // 1
echo getRequestCount(); // 2
echo getRequestCount(); // 3

// Static initialization
function getDbConnection(): PDO {
    static $pdo = null;

    if ($pdo === null) {
        $pdo = new PDO(
            'mysql:host=localhost;dbname=magento',
            'root',
            '',
            [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]
        );
    }

    return $pdo;
}

Why Scoping Matters in Magento

<?php
// In Magento, avoid global variables - use dependency injection

// BAD: Global state
global $productRepository;
$product = $productRepository->getById(1);

// GOOD: Dependency injection
class ProductHelper
{
    private ProductRepository $productRepo;

    public function __construct(ProductRepository $productRepo)
    {
        $this->productRepo = $productRepo;
    }

    public function getProduct(int $id): Product
    {
        return $this->productRepo->getById($id);
    }
}

Key Takeaway

Variables have local scope inside functions. Use global keyword or $GLOBALS to access global variables. Static variables persist between function calls. In Magento, prefer dependency injection over global variables.

Superglobals and Type Juggling

PHP Superglobals

Superglobals are predefined variables accessible from any scope.

<?php
// $_GET - Query string parameters
// URL: /products?category=electronics&page=2
$category = $_GET['category'] ?? '';   // 'electronics'
$page = (int)($_GET['page'] ?? 1);     // 2

// $_POST - Form data sent via POST
// Form: <input name="email" value="user@example.com">
$email = $_POST['email'] ?? '';

// $_SERVER - Server and request information
$method = $_SERVER['REQUEST_METHOD'];  // GET, POST, etc.
$uri = $_SERVER['REQUEST_URI'];        // /products?category=electronics
$ip = $_SERVER['REMOTE_ADDR'];        // Client IP address
$userAgent = $_SERVER['HTTP_USER_AGENT']; // Browser info
$host = $_SERVER['HTTP_HOST'];        // magento-store.com
$scheme = $_SERVER['REQUEST_SCHEME']; // https
$https = $_SERVER['HTTPS'];           // on/off
$scriptName = $_SERVER['SCRIPT_FILENAME']; // /var/www/pub/index.php

// $_SESSION - Session data (requires session_start())
session_start();
$_SESSION['user_id'] = 123;
$_SESSION['cart'] = ['product_1' => 2];

// $_COOKIE - Cookie data
$sessionId = $_COOKIE['PHPSESSID'] ?? '';

// $_FILES - Uploaded files
if (!empty($_FILES['avatar'])) {
    $tmpName = $_FILES['avatar']['tmp_name'];
    $error = $_FILES['avatar']['error'];
    $size = $_FILES['avatar']['size'];
    $type = $_FILES['avatar']['type'];
    $name = $_FILES['avatar']['name'];
}

// $_REQUEST - Combined GET, POST, and COOKIE
$value = $_REQUEST['key'] ?? '';
// Avoid $_REQUEST - it's unclear where data comes from

Type Juggling

PHP automatically converts types in certain contexts.

<?php
// String to number
$price = '29.99';
echo $price + 1;      // 30.99 (string becomes float)
echo $price * 2;      // 59.98

// Boolean context
$active = 'hello';
if ($active) {
echo 'Active';  // Prints! Non-empty string is truthy
}

// Empty values are falsy
var_dump((bool) '');     // false
var_dump((bool) 0);      // false
var_dump((bool) null);   // false
var_dump((bool) []);     // false
var_dump((bool) '0');    // false (this is a gotcha!)

// Non-empty values are truthy
var_dump((bool) '00');   // true
var_dump((bool) -1);     // true
var_dump((bool) [1]);    // true

// Loose comparison (==)
echo '1' == 1;     // true (type juggling)
echo '1a' == 1;    // true (string '1a' becomes 1)
echo '' == false;   // true
echo '0' == false;  // true

// Strict comparison (===) - recommended
echo '1' === 1;    // false (different types)
echo '' === false;  // false (different types)
echo '0' === false; // false (different types)

Null Coalescing Operator (??)

<?php
// Null coalescing - returns left side if not null, otherwise right
$page = $_GET['page'] ?? 1;           // 1 if not set
$name = $user['name'] ?? 'Anonymous'; // 'Anonymous' if null
$price = $product->getPrice() ?? 0.0; // 0.0 if null

// Chaining
city = $_SESSION['user']['address']['city'] ?? 'Unknown';

// Null coalescing assignment (??=)
// Set variable only if it's not set
$page ??= 1;  // Same as: $page = $page ?? 1;

// vs empty() - different behavior
$value = 0;
echo $value ?? 'default';  // 0 (not null, so keeps 0)
echo empty($value) ? 'default' : $value;  // 'default' (0 is empty)

// Ternary operator (alternative)
$page = isset($_GET['page']) ? (int)$_GET['page'] : 1;
$page = $_GET['page'] ?? 1;  // Cleaner with null coalescing

Safe Variable Access

<?php
// DANGEROUS: Can throw warnings
$value = $array['key'];       // Warning if 'key' doesn't exist
$value = $object->property;   // Warning if property doesn't exist

// SAFE: Use null coalescing
$value = $array['key'] ?? null;
$value = $object->property ?? null;

// SAFE: Use isset()
if (isset($array['key'])) {
    $value = $array['key'];
}

// SAFE: Use null safe operator (PHP 8.0+)
$city = $order?->getShippingAddress()?->getCity();

// In Magento controllers
$productId = $this->getRequest()->getParam('id');
if ($productId === null) {
    throw new \Magento\Framework\Exception\NotFoundException(__('Product not found'));
}

Key Takeaway

Always use ?? (null coalescing) to safely access potentially undefined values. Use === (strict comparison) instead of ==. Superglobals provide access to request data, but always sanitize and validate inputs.

Quiz

1. What is the correct way to access a global variable inside a function?

Question 1 options

2. What does the ?? (null coalescing) operator do?

Question 2 options

3. What is the output of: var_dump('0' == false)?

Question 3 options

4. What superglobal contains form data sent via POST?

Question 4 options

5. What does a static variable in a function do?

Question 5 options

Flashcards

Question

What are PHP superglobals?

Answer

Predefined variables accessible from any scope: $_GET, $_POST, $_SERVER, $_SESSION, $_COOKIE, $_FILES, $_REQUEST, $GLOBALS.

Question

How do you access a global variable inside a function?

Answer

Use 'global $variableName;' at the start of the function, or access it via $GLOBALS['variableName'].

Question

What is the null coalescing operator (??)?

Answer

Returns left operand if not null, otherwise returns right. Example: $page = $_GET['page'] ?? 1; // Returns 1 if page is not set.

Question

What is type juggling in PHP?

Answer

PHP automatically converts types in certain contexts. '29.99' + 1 = 30.99. Always use === for strict comparison.

Question

What does static do in a function?

Answer

Makes a variable persist between function calls. Initialized once. Useful for counters: static $count = 0; $count++;

Question

Difference between == and ===?

Answer

== (loose) performs type juggling: '1' == 1 is true. === (strict) checks type AND value: '1' === 1 is false. Always prefer ===.

Question

What is $_SERVER used for?

Answer

Contains server and request information: REQUEST_METHOD, REQUEST_URI, HTTP_HOST, REMOTE_ADDR, HTTP_USER_AGENT, HTTPS, etc.

Question

How do you safely access potentially undefined array keys?

Answer

Use null coalescing: $value = $array['key'] ?? null; Or check isset() first. This prevents undefined index warnings.

Revision Notes

Key Takeaways

  • 1. PHP variables start with $ and are dynamically typed
  • 2. Variables have local scope inside functions; use global keyword for global scope
  • 3. Static variables persist between function calls
  • 4. Superglobals ($_GET, $_POST, $_SERVER) are accessible from any scope
  • 5. Use ?? (null coalescing) for safe variable access
  • 6. Use === (strict comparison) instead of == to avoid type juggling bugs
  • 7. Always sanitize and validate superglobal data before use

Interview Tips

  • Explain the difference between local, global, and static scope
  • Know all PHP superglobals and when to use each
  • Describe type juggling and why === is preferred over ==
  • Understand the null coalescing operator and its use cases
  • Explain why global variables should be avoided in favor of DI

Cheat Sheet

PHP Variables Cheat Sheet

Variable Rules:

  • Start with $: $variableName
  • Case sensitive: $name != $Name
  • Dynamic typing: $var = 'string'; $var = 42;

Superglobals:
$_GET - URL parameters
$_POST - Form data
$_SERVER - Request/server info
$_SESSION - Session data
$_COOKIE - Cookie data
$_FILES - Uploaded files
$GLOBALS - All global variables

Scoping:
local - inside function only
global - use 'global $var' or $GLOBALS['var']
static - persists between calls

Type Juggling:
'0' == false // true (loose)
'0' === false // false (strict)

Null Coalescing:
$page = $_GET['page'] ?? 1;
$value = $array['key'] ?? null;
$city = $obj?->address?->city ?? 'Unknown';