php language basics

Operators and Expressions

An expression is any piece of PHP code that produces a value. A literal such as 10 is an expression. A variable such as $priceCents is an expression. A calculation such as $priceCents * $quantity is also an expression.

Operators are the symbols and keywords that combine expressions. They are how PHP adds numbers, joins strings, compares values, chooses defaults, and builds conditions for if, while, and other control-flow code.

This matters because most everyday PHP code is built from expressions. A junior developer is often asked to change a price calculation, fix a condition, add a validation rule, or explain why a comparison behaved unexpectedly. To do that safely, you need to know what value each expression produces.

Arithmetic Expressions

Arithmetic operators work with numbers. The common ones are +, -, *, /, %, and **.

PHP example
<?php

$priceCents = 1299;
$quantity = 3;
$discountCents = 500;

$subtotalCents = $priceCents * $quantity;
$totalCents = $subtotalCents - $discountCents;

echo "Subtotal: {$subtotalCents} cents\n";
echo "Total: {$totalCents} cents\n";

// Prints:
// Subtotal: 3897 cents
// Total: 3397 cents

The expression $priceCents * $quantity produces 3897. That value is then assigned to $subtotalCents. The next expression subtracts the discount and stores the result in $totalCents.

In real applications, money is often stored as integer cents to avoid floating-point rounding surprises. A later lesson can cover money modelling in more depth; for now, the important point is that the arithmetic expression should use values with a clear unit.

String Concatenation

PHP uses . to join strings. This is different from JavaScript, where + can join strings. In PHP, use . when the job is text.

PHP example
<?php

$firstName = 'Ada';
$lastName = 'Lovelace';

$fullName = $firstName . ' ' . $lastName;

echo $fullName . "\n";

// Prints:
// Ada Lovelace

PHP also supports variable interpolation inside double-quoted strings, such as "Hello, $firstName". Concatenation is still useful when you are joining several pieces conditionally or building a value in steps.

Assignment And Comparison

The assignment operator = stores a value in a variable. It is not the same as comparison. This is one of the most common beginner mistakes.

PHP example
<?php

$status = 'paid';

if ($status === 'paid') {
    echo "Ship the order\n";
}

// Prints:
// Ship the order

Use === when you want to compare both value and type. Use = only when you want to assign.

Some compound assignment operators update a variable in place:

PHP example
<?php

$stock = 10;

$stock -= 2;
$stock += 5;

echo "Stock: {$stock}\n";

// Prints:
// Stock: 13

$stock -= 2 means "take the current stock, subtract two, and store the result back in $stock." You will see this style in counters, totals, stock levels, retry counts, and pagination offsets.

Comparisons And Strict Equality

Comparison expressions produce booleans: true or false.

PHP example
<?php

$submittedQuantity = '3';
$availableStock = 3;

var_dump($submittedQuantity == $availableStock);
var_dump($submittedQuantity === $availableStock);

// Prints:
// bool(true)
// bool(false)

== checks loose equality, so PHP may convert types before comparing. === checks strict equality, so both value and type must match. In application code, prefer strict comparisons unless you have a specific reason to allow conversion.

This becomes important at boundaries. Form data, query strings, and JSON payloads often arrive as strings. If your code expects an integer, validate and convert deliberately instead of relying on loose comparison.

Logical Operators

Logical operators combine boolean expressions. The most common are && for "and", || for "or", and ! for "not".

PHP example
<?php

$isPaid = true;
$hasStock = true;
$isFraudCheckPassed = false;

$canShip = $isPaid && $hasStock && $isFraudCheckPassed;

var_dump($canShip);

// Prints:
// bool(false)

The order matters for readability. Put each named condition in a variable when it helps the next developer understand the rule. A long if condition with several comparisons can be correct but hard to review.

PHP example
<?php

$quantity = 2;
$stock = 5;
$accountIsActive = true;

$quantityIsValid = $quantity > 0;
$stockIsAvailable = $quantity <= $stock;

if ($accountIsActive && $quantityIsValid && $stockIsAvailable) {
    echo "Order accepted\n";
}

// Prints:
// Order accepted

This version is longer, but it gives each business rule a name. That is often worth it in validation, checkout, permissions, and status transitions.

Defaults With ??

The null coalescing operator ?? gives a default when a value is missing or null.

PHP example
<?php

$settings = [
    'currency' => 'GBP',
];

$currency = $settings['currency'] ?? 'USD';
$locale = $settings['locale'] ?? 'en_GB';

echo "{$currency} / {$locale}\n";

// Prints:
// GBP / en_GB

This is common when reading optional array keys, configuration, decoded JSON, and request data. It is not a replacement for validation. It only chooses a fallback when the value is absent or null.

Choosing Between Two Values

The ternary operator condition ? value_if_true : value_if_false is useful for short choices.

PHP example
<?php

$totalCents = 7_500;

$shippingLabel = $totalCents >= 5_000 ? 'free shipping' : 'standard shipping';

echo $shippingLabel . "\n";

// Prints:
// free shipping

Use ternaries for simple choices. If the condition or either branch needs explanation, use a normal if block instead.

Precedence And Parentheses

Operator precedence decides which part of an expression PHP evaluates first. Multiplication happens before addition, so this expression may not mean what a beginner expects:

PHP example
<?php

$result = 10 + 5 * 2;

echo $result . "\n";

// Prints:
// 20

Use parentheses when they make the rule clearer:

PHP example
<?php

$result = (10 + 5) * 2;

echo $result . "\n";

// Prints:
// 30

Do not rely on another developer remembering every precedence rule. Parentheses are cheap and often make business logic safer to review.

Common Mistakes

The biggest mistake is confusing assignment with comparison: = stores a value, while === compares a value and type.

The second mistake is trusting loose comparisons at application boundaries. If user input arrives as a string, convert it deliberately before comparing it with an integer.

The third mistake is writing clever expressions that hide the business rule. A compact one-liner can be harder to maintain than a few named variables.

What You Should Be Able To Do

After this lesson, you should be able to:

  • identify the value produced by a PHP expression;
  • use arithmetic operators for simple totals and counters;
  • join strings with .;
  • compare values with strict equality;
  • combine conditions with &&, ||, and !;
  • use ?? for simple defaults;
  • use parentheses to make evaluation order clear;
  • explain why a condition is true or false before running the code.

Practice

Task: Total Calculator

Task

Write a small PHP script that calculates an order total in cents.

Start with these values:

PHP example
<?php

$priceCents = 1499;
$quantity = 2;
$discountCents = 300;

Calculate:

  • $subtotalCents as price multiplied by quantity;
  • $totalCents as subtotal minus discount;
  • print both values.

Expected Behaviour

Your script should print this output from the runnable PHP block:

PHP example
<?php

echo "Subtotal: 2998 cents\n";
echo "Total: 2698 cents\n";

// Prints:
// Subtotal: 2998 cents
// Total: 2698 cents

Hints

  • Use * for multiplication.
  • Use - for subtraction.
  • Keep the values as integer cents.
Show solution

Solution

PHP example
<?php

$priceCents = 1499;
$quantity = 2;
$discountCents = 300;

$subtotalCents = $priceCents * $quantity;
$totalCents = $subtotalCents - $discountCents;

echo "Subtotal: {$subtotalCents} cents\n";
echo "Total: {$totalCents} cents\n";

// Prints:
// Subtotal: 2998 cents
// Total: 2698 cents

Explanation

$priceCents * $quantity produces the subtotal. $subtotalCents - $discountCents produces the final total. The variables are named with Cents so the unit is visible during review.

Task: Predict Comparisons

Task

Before running the code, predict what each var_dump() will print.

PHP example
<?php

$submittedQuantity = '3';
$availableStock = 3;
$minimumQuantity = 1;

var_dump($submittedQuantity == $availableStock);
var_dump($submittedQuantity === $availableStock);
var_dump((int) $submittedQuantity >= $minimumQuantity);
var_dump((int) $submittedQuantity <= $availableStock);

Then run the code and compare your prediction with the real output.

Hints

  • == allows type conversion.
  • === requires the same value and the same type.
  • (int) $submittedQuantity converts the string before comparison.
Show solution

Solution

PHP example
<?php

$submittedQuantity = '3';
$availableStock = 3;
$minimumQuantity = 1;

var_dump($submittedQuantity == $availableStock);
var_dump($submittedQuantity === $availableStock);
var_dump((int) $submittedQuantity >= $minimumQuantity);
var_dump((int) $submittedQuantity <= $availableStock);

// Prints:
// bool(true)
// bool(false)
// bool(true)
// bool(true)

Explanation

The loose comparison is true because PHP can compare the string '3' with the integer 3. The strict comparison is false because the values have different types.

The last two comparisons convert the submitted value to an integer before checking it. That makes the boundary decision visible instead of relying on loose comparison.

Task: Build Price Expression

Task

Write a PHP script that decides whether an order gets free shipping.

Use these starting values:

PHP example
<?php

$order = [
    'total_cents' => 6400,
    'country' => 'GB',
];

$freeShippingThresholdCents = 5000;

Your script should:

  • read the order total;
  • read the country, defaulting to 'GB' if it is missing;
  • create a $qualifiesForFreeShipping boolean;
  • print either Free shipping or Standard shipping.

Hints

  • Use ?? for the country default.
  • Use >= for the threshold comparison.
  • Use && to require both the total and country rule.
  • A ternary is fine for the final label.
Show solution

Solution

PHP example
<?php

$order = [
    'total_cents' => 6400,
    'country' => 'GB',
];

$freeShippingThresholdCents = 5000;

$totalCents = $order['total_cents'];
$country = $order['country'] ?? 'GB';

$meetsTotalThreshold = $totalCents >= $freeShippingThresholdCents;
$shipsInsideFreeShippingRegion = $country === 'GB';

$qualifiesForFreeShipping = $meetsTotalThreshold && $shipsInsideFreeShippingRegion;

$shippingLabel = $qualifiesForFreeShipping ? 'Free shipping' : 'Standard shipping';

echo $shippingLabel . "\n";

// Prints:
// Free shipping

Explanation

The solution separates the expression into named conditions. $meetsTotalThreshold explains the price rule. $shipsInsideFreeShippingRegion explains the country rule. The final && expression is easier to review because each side has a name.

The ?? operator gives a default country only when the key is missing or null. In a real checkout flow, you would still validate the country before accepting the order.