🔧 Programmierung 🕛 vor 2 Monaten 5 Min Lesezeit
0

The Array Bug That Looks Different in PHP, Python, and JavaScript (But Is Really the Same Bug)

↗ Quelle (dev.to)
🗣️ Stimme:
📑 Inhaltsübersicht




💡 TL;DR



PHP copies arrays by default. Python and JavaScript share references by default. If you switch between these languages and don't switch your mental model with them, you'll spend hours debugging an array that "shouldn't" have changed. Here's the breakdown, with code, for all three.









The Bug Nobody Warns You About



You pass an array into a function, mutate it, then check the original — and it's changed too. Or the reverse: you expected a shared reference and got a clean copy instead.



It's not really one bug. It's three different language models wearing the same disguise.




PHP arrays are value types (copied by default). Python lists are reference types (shared by default). JavaScript arrays are objects passed by reference — with a const twist that catches even seniors off guard.




If you work across a PHP backend, Python scripts, and a JS frontend (and let's be honest, a lot of us do), this is the bug that gets you when you least expect it — usually three function calls deep into a real request, long after the original array is gone.






PHP: Copy First, Reference on Request



PHP arrays use copy-on-write semantics. Assign one to a new variable, or pass it into a function, and you get an independent copy by default.




CODE
function addDiscount(array $cart): array {
$cart[] = 'discount_code_applied'; // local copy only
return $cart;
}

$userCart = ['apple', 'banana'];
addDiscount($userCart);

print_r($userCart);
// ['apple', 'banana'] — unchanged






Want to mutate the original instead? You have to ask for it explicitly with &:




CODE
function applyDiscount(array &$cart): void {
$cart[] = 'discount_code_applied'; // this IS the original
}






No & means copy. & means reference. PHP makes you say what you mean — which honestly isn't a bad design choice once you internalize it.






Python: Reference First, Copy on Request



This is where most people coming from PHP get burned. Assigning a Python list doesn't copy it — it just creates a second name pointing at the same object.




CODE
original_cart = ['apple', 'banana']
temp_cart = original_cart
temp_cart.append('cherry')

print(original_cart)
# ['apple', 'banana', 'cherry'] — yep, it changed
print(temp_cart is original_cart)
# True — literally the same object






Same story inside functions:




CODE
def add_to_cart(cart):
cart.append('discount_applied') # mutates caller's list

user_cart = ['apple', 'banana']
add_to_cart(user_cart)
print(user_cart)
# ['apple', 'banana', 'discount_applied']






To actually get a copy, be explicit:




CODE
temp = original_cart[:]        # shallow copy
temp = list(original_cart) # also shallow
import copy
temp = copy.deepcopy(original_cart) # deep copy






Watch out for nested lists — a shallow copy still shares inner lists:




CODE
original = ['apple', ['mango', 'grape']]
shallow = original[:]
shallow[1].append('kiwi')
print(original) # ['apple', ['mango', 'grape', 'kiwi']] — leaked!






deepcopy is the only thing that fully isolates nested structures.






The classic Python trap nobody escapes the first time






CODE
def add_item(item, cart=[]):  # created ONCE, reused forever
cart.append(item)
return cart

print(add_item('apple')) # ['apple']
print(add_item('banana')) # ['apple', 'banana'] — wait what






Mutable default arguments are evaluated once, at function definition time. Fix it with None:




CODE
def add_item(item, cart=None):
if cart is None:
cart = []
cart.append(item)
return cart









JavaScript: Reference, Plus a const Curveball



JS arrays are objects, so they behave like Python at first glance — shared by reference.




CODE
const originalCart = ['apple', 'banana'];
const tempCart = originalCart;
tempCart.push('cherry');

console.log(originalCart);
// ['apple', 'banana', 'cherry']






Here's the part that confuses people: const does not make the array immutable. It only blocks reassigning the variable.




CODE
const userCart = ['apple', 'banana'];
userCart.push('cherry'); // totally fine
// userCart = ['new']; // TypeError — this is what const actually blocks






So a function like this will silently mutate your caller's data:




CODE
function applyDiscount(cart) {
cart.push('discount_applied'); // mutates the original
return cart;
}






Fix it by copying first:




CODE
function applyDiscount(cart) {
const cartCopy = [...cart]; // shallow copy
cartCopy.push('discount_applied');
return cartCopy;
}






For arrays of objects, [...cart] isn't enough — go deeper:




CODE
const deepCart = structuredClone(originalCart); // modern, reliable









Array.sort() is a mutation trap too






CODE
const scores = [50, 20, 80, 10];
const sorted = scores.sort((a, b) => a - b);

console.log(scores); // [10, 20, 50, 80] — original got sorted!
console.log(scores === sorted); // true, same array






sort(), reverse(), and splice() mutate in place. map(), filter(), and slice() don't. Memorize that split — it'll save you a debugging session eventually.






The Comparison Table You'll Bookmark
























































Behavior PHP Python JavaScript
Assignment Copy Reference Reference
Function param Copy Reference Reference
Force reference &$arr N/A N/A
Shallow copy default
arr[:] / list(arr)
[...arr]
Deep copy unserialize(serialize($arr)) copy.deepcopy() structuredClone()
In-place sort sort() .sort() .sort()
Sorted copy $c = $arr; sort($c); sorted(arr) [...arr].sort()





How to Actually Debug This When It Happens




  1. Print the array right after creation — confirm it's correct at the source.

  2. Check every assignment — copy or reference? Default assumption: PHP copies, Python/JS share.

  3. Audit functions that touch the array for in-place mutators (.push(), .append(), .sort(), direct index writes).

  4. Add explicit copy semantics where intent was "don't touch the original."

  5. If nested data is involved and a shallow copy didn't fix it, go deep.






The One-Line Takeaway



PHP makes you opt into sharing. Python and JavaScript make you opt into copying. Once that flips in your head, this entire category of bug stops being mysterious.



Found this helpful? Check out more at codepractice.in

Vollständiger Original-Artikel
Den kompletten Beitrag mit allen Details direkt auf dev.to lesen.
↗ Original-Artikel auf dev.to lesen
Wie bewertest du diesen Beitrag?
1 Klick Feedback
Teilen mit Netzwerk & Team:

Community-Analysen & Experten-Meinungen 0

Verfasse deine eigene Analyse, teile Workarounds oder diskutiere diesen Vorfall im Blog.
Noch keine Community-Analyse verfasst. Markiere einen Textabschnitt oder klicke oben auf Eigene Analyse verfassen“!
Community Pulse: Relevanz-Einschätzung
1 Klick Experten-Votum
🔴 Akute Relevanz 0%
🟡 In Evaluierung 0%
🟢 Keine Auswirkung 0%
Spannende Innovation 0%
Verwandte Story-Cluster & Quellen (Vektor-KI)
Port 8095 Engine
1 Quelle
Staatliche Hacker treiben laut Chainalysis einen Anstieg von 420 % bei Onchain-Malware voran
1 Quelle
Chinesische KI-Modelle verursachen Anstieg der auf der Blockchain platzierten Malware ...
1 Quelle
Millionen-Lösegeld nach Hacker-Angriff auf Revolut: Was Kunden jetzt wissen müssen
Ähnliche Beiträge
🔍 Verwandte News

Auch interessante Nachrichten The Array Bug That Looks Different in PHP, Python, and JavaScript (But Is Really the Same Bug)

Thematisch verwandte Begriffe: Array, That, Looks, Different · 6 Treffer

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...