Update Array Items

La Lakshmi Priya Updated 19 Oct 2026
8 min read ·Lesson 126 of 143

How Updating Works

In simple terms: To change a value in an array, assign a new value to its key: $product['price'] = 1199;. The old value is replaced.

Technically: Assigning to $array[$key] writes a value into the array's hash table. If the key exists, its value is replaced and its position is kept; if it does not exist, a new element is created at the end. Because arrays are values in PHP, updates affect only the variable being modified — not copies of the array held elsewhere.


Updating a Single Element

Example

<?php
$product = ['name' => 'Desk Lamp', 'price' => 1299, 'stock' => 10];

$product['price'] = 1199;     // replace a value
$product['stock'] -= 2;       // update based on the current value
$product['name'] .= ' (LED)'; // append to a string value

print_r($product);

Output

Array
(
    [name] => Desk Lamp (LED)
    [price] => 1199
    [stock] => 8
)

How It Works

  • = 1199 replaces the price.
  • -= 2 reads the current stock, subtracts 2, and writes the result back. All compound assignment operators (+=, -=, *=, .=, ??=) work on array elements (see Assignment Operators).
  • The keys keep their original positions; updating never moves an element.

Indexed Arrays

<?php
$tasks = ['Write outline', 'Record video', 'Publish'];

$tasks[1] = 'Record and edit video';

print_r($tasks);

Output

Array
(
    [0] => Write outline
    [1] => Record and edit video
    [2] => Publish
)

Update vs Accidental Creation

Assignment does not check whether a key exists. A typo silently creates a new key instead of updating the intended one:

<?php
$product = ['name' => 'Desk Lamp', 'price' => 1299];

$product['prise'] = 999;   // typo

print_r($product);

Output

Array
(
    [name] => Desk Lamp
    [price] => 1299
    [prise] => 999
)

The price is unchanged, and an extra key appears. When only existing keys should be changed, check first:

<?php
function updateExisting(array $data, string $key, mixed $value): array
{
    if (!array_key_exists($key, $data)) {
        throw new InvalidArgumentException("Unknown field: $key");
    }

    $data[$key] = $value;

    return $data;
}

$product = ['name' => 'Desk Lamp', 'price' => 1299];

$product = updateExisting($product, 'price', 999);
echo $product['price'] . "\n";

try {
    updateExisting($product, 'prise', 999);
} catch (InvalidArgumentException $e) {
    echo $e->getMessage() . "\n";
}

Output

999
Unknown field: prise

For data with a fixed structure used throughout an application, classes with typed properties prevent this problem at the language level (see PHP Classes and Objects).


Updating Nested Arrays

Use one pair of brackets per level:

<?php
$order = [
    'id' => 501,
    'customer' => ['name' => 'Asha', 'address' => ['city' => 'Madurai']],
    'items' => [
        ['name' => 'Gel Pen', 'qty' => 10],
        ['name' => 'Notebook', 'qty' => 3],
    ],
];

$order['customer']['address']['city'] = 'Chennai';
$order['items'][1]['qty'] += 2;
$order['customer']['address']['pin'] = '600042';   // creates a new nested key

echo $order['customer']['address']['city'] . " " . $order['customer']['address']['pin'] . "\n";
echo $order['items'][1]['name'] . ": " . $order['items'][1]['qty'] . "\n";

Output

Chennai 600042
Notebook: 5

Nested assignment also creates missing intermediate levels: $config['mail']['smtp']['port'] = 587; creates the mail and smtp arrays automatically if they do not exist.


Updating Every Element

Option 1: foreach With the Key

<?php
$prices = ['Pen' => 20, 'Notebook' => 60, 'Bag' => 1299];

foreach ($prices as $item => $price) {
    $prices[$item] = round($price * 1.10, 2);
}

print_r($prices);

Output

Array
(
    [Pen] => 22
    [Notebook] => 66
    [Bag] => 1428.9
)

Writing back through $prices[$item] updates the original array. Assigning to $price alone would only change a temporary copy.

Option 2: foreach by Reference

<?php
$prices = ['Pen' => 20, 'Notebook' => 60, 'Bag' => 1299];

foreach ($prices as &$price) {
    $price = round($price * 1.10, 2);
}
unset($price);

echo implode(', ', $prices) . "\n";

Output

22, 66, 1428.9

&$price makes the loop variable an alias of each element. The unset($price) afterwards is essential to avoid the reference bug described in Foreach Loop.

Option 3: array_map() — Create an Updated Copy

<?php
$prices = ['Pen' => 20, 'Notebook' => 60, 'Bag' => 1299];

$newPrices = array_map(fn(float $price): float => round($price * 1.10, 2), $prices);

foreach ($newPrices as $item => $price) {
    echo "$item: ₹" . number_format($price, 2) . "\n";
}

Output

Pen: ₹22.00
Notebook: ₹66.00
Bag: ₹1,428.90

array_map() returns a new array and leaves the original unchanged. With a single array argument, it preserves string keys. This is often the clearest option: the old and new prices both remain available, for example to show a "price changed" message.

Option 4: array_walk()

<?php
$prices = ['Pen' => 20, 'Notebook' => 60];

array_walk($prices, function (float &$price, string $item): void {
    $price = round($price * 1.10, 2);
});

print_r($prices);

array_walk() calls a function for each element, passing the value (by reference, if declared with &) and the key. It modifies the array in place.

ApproachModifies Original?Best For
foreach with keyYesClear, explicit updates
foreach by referenceYesShort in-place updates (remember unset())
array_map()No — returns a new arrayTransformations, keeping the original
array_walk()YesCallback-based in-place updates

Bulk Updates With array_replace()

<?php
$product = ['name' => 'Desk Lamp', 'price' => 1299, 'stock' => 10, 'active' => true];
$changes = ['price' => 999, 'stock' => 25];

$updated = array_replace($product, $changes);

print_r($updated);

Output

Array
(
    [name] => Desk Lamp
    [price] => 999
    [stock] => 25
    [active] => 1
)

array_replace() returns a new array in which values from the second array replace values with the same keys. Keys that exist only in $changes would be added, so filter incoming changes against allowed keys when they come from user input:

$allowed = ['price', 'stock'];
$safeChanges = array_intersect_key($changes, array_flip($allowed));

array_flip() turns the list of allowed names into keys, and array_intersect_key() keeps only matching keys. This prevents a request from changing fields such as id or is_admin.


Replacing a Range: array_splice()

<?php
$playlist = ['Intro', 'Song A', 'Song B', 'Outro'];

$removed = array_splice($playlist, 1, 2, ['Song X', 'Song Y', 'Song Z']);

echo implode(', ', $playlist) . "\n";
echo 'Replaced: ' . implode(', ', $removed) . "\n";

Output

Intro, Song X, Song Y, Song Z, Outro
Replaced: Song A, Song B

array_splice($array, $offset, $length, $replacement) removes $length elements starting at $offset, inserts the replacement elements, re-indexes the list, and returns the removed elements.


Updates Do Not Affect Copies

<?php
function applyDiscount(array $cart, int $percent): array
{
    foreach ($cart as $sku => $price) {
        $cart[$sku] = $price - $price * $percent / 100;
    }

    return $cart;
}

$cart = ['PEN-01' => 100, 'NB-A5' => 200];
$discounted = applyDiscount($cart, 10);

echo implode(', ', $cart) . "\n";
echo implode(', ', $discounted) . "\n";

Output

100, 200
90, 180

The function received a copy of $cart, updated it, and returned it. The caller's $cart is unchanged. This makes functions safe to call: they cannot modify your data unless you assign the result (or pass by reference deliberately).


Practical Example: Updating Inventory After an Order

<?php
function reserveStock(array $inventory, array $orderItems): array
{
    $messages = [];

    foreach ($orderItems as $sku => $quantity) {
        if (!isset($inventory[$sku])) {
            $messages[] = "$sku: unknown product";
            continue;
        }

        $available = $inventory[$sku]['stock'];

        if ($available < $quantity) {
            $messages[] = "$sku: only $available in stock, requested $quantity";
            continue;
        }

        $inventory[$sku]['stock'] -= $quantity;
        $messages[] = "$sku: $quantity reserved, {$inventory[$sku]['stock']} left";
    }

    return [$inventory, $messages];
}

$inventory = [
    'PEN-01' => ['name' => 'Gel Pen', 'stock' => 120],
    'NB-A5' => ['name' => 'Notebook', 'stock' => 8],
    'BAG-02' => ['name' => 'Backpack', 'stock' => 2],
];

$orderItems = ['NB-A5' => 3, 'BAG-02' => 5, 'PEN-01' => 20, 'MUG-01' => 1];

[$inventory, $messages] = reserveStock($inventory, $orderItems);

echo implode("\n", $messages) . "\n\n";

foreach ($inventory as $item) {
    echo "{$item['name']}: {$item['stock']}\n";
}

Output

NB-A5: 3 reserved, 5 left
BAG-02: only 2 in stock, requested 5
PEN-01: 20 reserved, 100 left
MUG-01: unknown product

Gel Pen: 100
Notebook: 5
Backpack: 2

Step-by-Step Explanation

  1. The function receives copies of both arrays, so the caller's inventory changes only when the returned array is assigned.
  2. Unknown products and insufficient stock are reported and skipped with continue.
  3. $inventory[$sku]['stock'] -= $quantity updates one nested value in place.
  4. The function returns two values — the updated inventory and the messages — as an array that is destructured by the caller.

In a real application, stock updates happen in the database inside a transaction, so that two customers cannot reserve the same last item at the same time (see MySQL Transactions with PHP).


Common Mistakes

Modifying the Loop Variable Instead of the Array

Effect: foreach ($items as $item) { $item['qty'] = 0; } changes nothing.

Fix: Write back with $items[$key], or loop by reference.

Typos Creating New Keys

Effect: The intended value is unchanged, and an extra key appears.

Fix: Validate keys before updating, or use classes for structured data.

Expecting a Function to Update the Caller's Array

Effect: Changes are lost because the function worked on a copy.

Fix: Return the updated array and assign it, or use pass by reference deliberately.

Applying Unfiltered User Changes

Effect: Requests can modify fields that should be protected.

Fix: Filter with array_intersect_key() against an allow-list.


Best Practices

  • Update single values with direct assignment or compound operators.
  • Prefer returning updated copies (array_map(), functions that return arrays) for clarity.
  • When modifying in place in a loop, write back by key, or use references and unset() afterwards.
  • Validate keys and filter incoming changes against an allow-list.
  • Keep updates to shared data (inventory, balances) in the database inside transactions.

Official reference: https://www.php.net/manual/en/language.types.array.php#language.types.array.syntax.modifying

0 Comments

Reviewed before they appear

No comments yet.

PHP
PHP Home PHP Switch PHP Match Alternative Syntax PHP Loops While Loop Do While Loop For Loop Foreach Loop Nested Loops Break Statement PHP Home PHP Intro PHP Install PHP Built-in Web Server PHP Syntax PHP Tags PHP and HTML PHP Comments PHP Multiline Comments PHP Variables Variables Scope PHP Casting Logical Operators Null Coalescing Operator Spaceship Operator Operator Precedence Continue Statement Modify Strings PHP If...Else...Elseif PHP If Modify Strings PHP If Operators PHP Functions Concatenate Strings PHP If...Else Slicing Strings User-defined Functions Slicing Strings PHP Shorthand if Escape Characters Default Argument Values PHP Nested if Pass by Reference String Interpolation Named Arguments PHP File Upload Variadic Functions Return Values Search in Strings Multibyte Strings Type Declarations in Functions PHP Numbers PHP Math PHP Floats PHP Random Numbers PHP Constants PHP Properties PHP Methods PHP Constructor Constructor Property Promotion PHP Cookies PHP Destructor PHP Access Modifiers Readonly Properties PHP Sessions PHP Inheritance Method Overriding PHP Filters The final Keyword CSRF Protection PHP Filters Advanced Session Security Secure Cookies PHP Magic Constants File Upload Security PHP Callback Functions PHP Operators Filesystem Security PHP JSON Arithmetic Operators Error Reporting in Production Hiding PHP Assignment Operators PHP Configuration (php.ini) Comparison Operators PHP Command Line (CLI) PHP Exceptions Increment / Decrement Operators Migrating to PHP 8 PHP Form Validation PHP Form Required PHP Form URL/E-mail Error Handling Form Input Sanitizing Escaping Output (htmlspecialchars) Custom Error Handler Checkbox, Radio and Select Inputs Sticky Forms PHP Form Complete PHP Date and Time Date Formatting Error Logging HTTP Headers and Redirects Output Buffering Sending Email PHP cURL Consuming REST APIs PHP Generators AJAX PHP AJAX Database AJAX XML AJAX Live Search AJAX Poll AJAX with JSON Security Introduction Password Hashing SQL Injection Prevention XSS Prevention Garbage Collection Project: Simple Blog PHP What is OOP PHP Classes/Objects The $this Keyword Access Array Items Update Array Items Add Array Items Remove Array Items Sorting Arrays Multidimensional Arrays Array Destructuring Array Spread Operator Search in Arrays Merge Arrays PHP Abstract Classes PHP Interfaces Polymorphism PHP Traits PHP Static Methods PHP Static Properties Late Static Binding Magic Methods Object Cloning
Ask about this post
AI Ask about this post

Ask questions about Update Array Items and get answers drawn from it.

Signed-in readers only.