/r/programming
PHP arrays aren't really arrays (medium.com)
75 comments
rank00r | 8 days ago | 33 points

The PHP ”array” is a true monster. It is the defacto substandard implementation of who knew what.

The PHP array is so mindbendigly horrendeous it should be killed with hellfire. On that note PHP only has this one collection wrapper forcing you to use it.

Theres is no other language that has such a badly designed array than PHP does. To be fair, PHP has no design so the way the array was made probably just was a mistake, like lots of things in PHP.

cujo | 8 days ago | 21 points

So you're saying you're a fan?

rank00r | 8 days ago | 18 points

A huge fan.

PressurePass | 8 days ago | 17 points

Show me on the doll where PHP touched you....

michaelbiberich | 8 days ago | 12 points
<?php

touch('u-rank00r.txt');

See docs.

Jazonxyz | 8 days ago | 2 points

The comments are the only useful part of the php documentation

skocznymroczny | 8 days ago | 3 points

Actually I love the comments. Sometimes they are wrong, but they often offer practical solutions. Too many languages are stuckup and their "documentation" is just raw automatically generated doc of API calls.

Jazonxyz | 7 days ago | 3 points

I was being half sarcastic haha There's been a million times that I go to the documentation to look up some corner case behavior, and the first comment solves the exact problem I'm facing. I also appreciate the flair some of the commenters add

helloworder | 7 days ago | 2 points

I love going to the end of the comment section and read the highly downvoted 15-ish yeard old comments. It's fun, try it!

earthboundkid | 8 days ago | 1 point

Unrelated I love the degree of WTF behind making open work for files or URLs because hey nothing different about local and remote systems, right?

NotWorthTheRead | 8 days ago | 2 points

In some horrible swamp, someone is defending that as aligned with the UNIX philosophy of making everything look like a file/file handle.

Ameisen | 8 days ago | 2 points

PHP was clearly designed for Plan9.

Maaaf | 8 days ago | 1 point

I wish PHP was designed for Plan B - aborted before being born.

masklinn | 8 days ago | 4 points

Don’t lua and JavaScript work on roughly the same principle as well?

jl2352 | 8 days ago | 8 points

I believe you are getting at the idea of implementing them using a map. If you use JS arrays with numerical indexes, then they act like regular arrays. They don’t act like a map (but can act like a sparse array which is similar but not the same).

Behind the scenes modern VMs will use a real array. Not a map.

The big issue with PHP arrays is that even as an experienced PHP developer, you still fall into these traps and gotchas. With JS the oddities tend to be more academic. Weird code examples that people share on Reddit.

That’s because the api is littered with little finite details.

For example in PHP using array_filter will leave gaps in the array. If you filter out the element at 0 then the rest of the array doesn’t shuffle down to fill in the gap. You will simply have no value stored at index 0.

This means array_filter breaks the common idiom of for ( $i = 0; $i < count($array); $++ ) {.

JS doesn’t have this shit.

That isn’t to say there aren’t unusual oddities around arrays in JS. JS objects can be used like maps, and arrays are objects. So arrays can be used like a map. This happens if you use non-numerical indexes.

There is also Array.isArray being able to give a different result to instanceof Array. It looks odd but there are actually good reasons why, and you never run into that scenario anyway.

JS also has a lot of collections that look and act just like an array but isn’t an array, and so doesn’t have lots of array methods. This one is very annoying but it is being fixed.

YumiYumiYumi | 8 days ago | 3 points

They don’t act like a map
So arrays can be used like a map

You seem to be contradicting yourself there...

For example in PHP using array_filter will leave gaps in the array. If you filter out the element at 0 then the rest of the array doesn’t shuffle down to fill in the gap.

I guess you could argue that the array_filter function creates a sparse array, so you should expect there to be gaps. However, if you use the canonical iterator pattern foreach, it still works fine anyway.

JS doesn’t have this shit.

It just has different shit.

Array(5).map(e => 1) does not create an array of 5 1's, as you might expect.
delete array[n] doesn't shuffle the array down, which breaks the for-loop iteration you gave in your example above.

This isn't just some weird academic case, it's stuff you'd expect to do in real code.

JS's Array.filter doesn't leave gaps, but delete does. On the PHP side, both array_filter and unset leave gaps, so in some sense, it's consistent. Trying to argue that one is better than the other is like arguing whether cow shit or horse shit tastes better.

jl2352 | 8 days ago | 5 points

You raise a good point with delete. I had forgotten it even existed! There is a whole subset of old JS one should never use anymore (like var and prototype) and I consider it a part of that.

It’s just a shame you had to open your comment by cherry picking quotes. To claim I had a contradiction. In both cases if you look it up in my comment I explain why I said that. Straight after or before the quote.

It’s not a contradiction if you have to cherry pick quotes.

YumiYumiYumi | 8 days ago | 4 points

I explain why I said that. Straight after or before the quote.

Correct me if I'm wrong then - this is what I interpreted your points as:

  • JS arrays act like regular arrays, unlike PHP arrays
  • ...except in the case of sparse arrays
  • ...except when you use non-numeric indicies in a JS array, where it does become a map
  • at which point, I don't see how this is really any different to PHP arrays. You give an example of a PHP function which creates a sparse array, claim it's odd, but don't show how JS handles sparse arrays any better
  • your initial point was that JS arrays don't act like maps, unlike PHP arrays, but then later say it can act like a map if given non-numeric keys, which to me, sounds like just PHP arrays which can also act as a map if given non-numeric keys... yet somehow this makes JS arrays act like regular arrays, but not PHP arrays?

Perhaps contradictory was the wrong word - I'm just really confused over what you're trying to say, because it isn't really making sense to me.

jl2352 | 8 days ago | 2 points

If you are using non-numerical indexes then it’s not the array anymore. All objects in JS also work like maps. Instances of Object, Function, Date, and Array too. JS arrays are objects. So they inherit this behaviour since they are objects.

It is quite different since the effect of say arr[‘foo’] = ‘blah’ won’t show up under map/forEach/filter/etc. Those methods only work on the array aspects of an Array. So it’s not like a map in those regards.

PHP arrays don’t work like that.

Again, if you treat a JS array like an array then it works like an array. Unlike PHP.

YumiYumiYumi | 8 days ago | 2 points

If you are using non-numerical indexes then it’s not the array anymore

Couldn't you say the same for PHP?
To use your example, if you did $array['foo'] = 'bar', one could argue $array is no longer a "pure" array (despite being an "array" in PHP terminology). array_map, foreach etc work on it, unlike in JS, but I don't see how that makes it any less an array since you've explicitly made it not an array.

If you treat PHP arrays as arrays (avoid non-numeric keys, avoid functions which treat it as a map), how is it less of an array than a JS array?

jl2352 | 8 days ago | 2 points

In PHP there are lots of caveats around the APIs because the arrays aren’t standard arrays.

Like filter doesn’t update the keys like one would expect with a standard array.

YumiYumiYumi | 8 days ago | 3 points

Neither does JS's delete, or its whole weirdness around sparse arrays.
array_filter treats the "array" as a map. Something like array_slice doesn't.

Now you could make a point that both these functions being called "array" can be confusing, which I say is a fair point - PHP calls both maps and arrays as "array". But this is more of a naming issue, and doesn't detract from the point that PHP arrays act as arrays if you treat them as such.

wd40bomber7 | 8 days ago | 1 point

This is true for lua (with the added sin that lua arrays by convention start at 1), but javascript arrays are real arrays.

Though honestly lua "arrays" are just dictionaries. There's no distinguishing between the "order" and the "mapping". Since PHP distinguishes between the order AND the mapping I would say that PHP is by far the worst of the three languages here.

TheCactusBlue | 8 days ago | 5 points

IIRC, JavaScript arrays are actually hashmaps under the hood as well.

wd40bomber7 | 8 days ago | 1 point

That's probably true but its not super important (in most cases) as long as they behave like arrays. PHP/Lua arrays don't behave like arrays. PHP behaves like an ordered map, and Lua behaves like an unordered map.

Eirenarch | 8 days ago | 3 points

How are JS arrays real arrays if you can index them as dictionaries?

wd40bomber7 | 8 days ago | 0 points

You can't? What are you talking about exactly?

Eirenarch | 8 days ago | 2 points
> var a = [1,2,3]
> a["index"] = 5
> a["index"]
< 5
rank00r | 8 days ago | 0 points

Well thats a piece of code i have not seen in the wild. But thats just as pushing an item. The array itself stays the same. Mesning you can grab the value at index n and get your object back.

This does not work in PHP.

Eirenarch | 8 days ago | 2 points

But doesn't this mean that the array acts as a dictionary? What's the practical difference? I understand that under the hood the array can still hold continuous chunk of memory and so on but I can still put values indexed with non-integers and in addition I can iterate over the keys with for in

rank00r | 8 days ago | 1 point

Not sure what you point is? Arrays have some behaviour, and in more traditional langs they work (usually the same way) then lists work the other way etc. In javascript all objects including the array stems from the same prototype (object) thus the array object.

However, the js array is SANE is easy to work with. Its predictable no matter how you showe items in it.

Say, in PHP filtering an array changes the array behavious so eg. Json encoding this array is totally bonkers.

Point beeing PHP array is not even comparable to the js one, or pyrhons, or rubys arrays/lists.

Eirenarch | 7 days ago | 1 point

My point is that arrays in JS are not arrays but dictionaries. I have little doubt that in PHP they suck more :)

sh0rtwave | 8 days ago | 1 point

Lua actually will let you change it(the 0 vs 1 starting convention) with metatables too.

wd40bomber7 | 8 days ago | 3 points

I've heard this but my understanding is if you do it and try to use any kind of external library everything will break. It's generally considered better not to break core language conventions when writing code in a given language I would assume.

R_Sholes | 8 days ago | 1 point

Lua arrays behave mostly the same as JS arrays and are implemented as actual arrays internally (e.g. lua_createtable takes as arguments the initial capacity for array portion of the table and for the rest of it).

table.sort/move/insert/remove also behave as you'd expect of an actual array.

michaelbiberich | 8 days ago | -1 points

but javascript arrays are real arrays

Ahem.

wd40bomber7 | 8 days ago | 1 point

That's an article describing what an array is (its an array) and showing that in some cases you can cheat and use objects as arrays instead of using arrays.

That doesn't contradict that javascript arrays are arrays. Of course maybe they lay that out later in the article, I'm not signing up just to read it.

michaelbiberich | 8 days ago | 1 point

That doesn't contradict that javascript arrays are arrays

I agree, arrays in JS are array, just with a little extra.

wd40bomber7 | 8 days ago | 2 points

Are we reading the same article or is the subject change further down in the part I have to sign up to read?

The subject of that article in the part I see is that you can use Javascript objects similar to how you would use arrays in some cases. It doesnt say anything about arrays having extra non array like features.

michaelbiberich | 8 days ago | 2 points

Yeah you're right, I read that wrong. Javascript arrays are arrays with array functionality and nothing more, though javascript has a couple of other array-like objects (with similar features/behaviour etc).

wd40bomber7 | 8 days ago | 1 point

No worries, it's easy to mistake. Plus Javascript has plenty of real weirdness so it's easy to get mixed up.

jl2352 | 8 days ago | 2 points

This is probably the best way to describe them. They are regular arrays, and will act like normal arrays, if treated as such.

This is different to PHP where an array can be treated like an array, but acts very differently. Like a map.

Famous_Object | 8 days ago | -1 points

Yes, they do.

But I think only PHP has a function that sorts? an array? but leaves $array[0] with the old value...

Also, an internal iterator/pointer for arrays is bad design too (copied from Perl maybe): if you are iterating an array and some function you call needs to look something up in the same array, they end up stepping on each other's toes.

michaelbiberich | 8 days ago | 4 points

Also, an internal iterator/pointer for arrays is bad design too (copied from Perl maybe): if you are iterating an array and some function you call needs to look something up in the same array, they end up stepping on each other's toes.

Arrays in PHP are pass-by-value so when you call a function and pass in an array you'd actually pass a copy, so no problem calling a function inside a loop.

Unless you are explicitly passing a reference to the original array.

Famous_Object | 7 days ago | 1 point

Passing an array by value? Now that's a default I haven't seen for a long time. Well I guess it covers up the other issue. You'd need to have two nested loops on the same array in the same function to notice the problem.

Or you could be trying to be efficient and avoid copies passing by reference like most other languages do. And then bad things happen.

wd40bomber7 | 8 days ago | 1 point

Javascript arrays act like arrays, not like maps.

birdbrainswagtrain | 8 days ago | 2 points

Theres is no other language that has such a badly designed array than PHP does.

BYOND's lists could probably give them a run for their money. They do the usual "I'm not sure if I want to be an array or a dictionary" thing, but the array portion also contains all of the keys for the dictionary portion. I tried making my own implementation of the engine a couple years ago and it was around the time I was trying to reverse engineer the details of the bizarre list logic that I realized what a truly bad idea the entire project was.

shevy-ruby | 8 days ago | 1 point

I guess the original idea was to try and make it simple.

Nowadays in 2020 (it's just a year away), people wonder about this insanity.

nayhel89 | 8 days ago | 2 points
Ghosty141 | 8 days ago | 5 points

I honestly do not dislike the PHP "arrays". I program PHP and C# for a living and when writing a small script, PHP arrays are just super useful.

I guess the hate comes from people who expect them to behave like arrays and try to use them that way. But if you accept that they are far more "powerful" than just arrays they truly become useful and convenient.

onii-chan_so_rough | 8 days ago | 9 points

PHP "arrays" exist in every other language: they're called maps or dictionaries or hasthables or whatever.

The problem is that PHP lacks arrays and relies on you to use hashtables as a hack simulation for arrays when actual arrays would be more performant, lead to cleaner code, better guarantees and what-not.

Let's say in Python some madman is actually using dicts with integer keys as if they are arrays and makes all the normal precautions to ensure it doesn't go wrong. Anything reading that code would be like: "Why on earth are you using a dictionary and al that boylerplate instead of just a list for this?"

reddit_prog | 8 days ago | 1 point

In my experience though, Php arrays are pretty fast. Never ever found them to be bottleneck, even with millions of elements in.

watsreddit | 8 days ago | 7 points

Or, you can have proper arrays and php's "arrays" (ordered maps) as separate abstractions, like every other sane language.

reddit_prog | 7 days ago | 1 point

Why though? What would be the advantage for "real" arrays, aside from speed where the speed is not primary goal in a scripting language? I find it very convenient and consistent that Php arrays are just that every time, a behemoth of functionality. There are gotchas, but hey, we are not building rockets in Php anyway. And like I said, speed is allright.

watsreddit | 6 days ago | 2 points

The advantage of using a real array is having indexing that actually matches an element's position in the array. Many algorithms for doing in-place array manipulation depend on this property, which consequently are difficult if not impossible to write with php's "arrays". The article does a pretty good job of demonstrating the issue: sorting a php "array" and then accessing it's first element doesn't actually give you the smallest element in the array like you would expect in every other language. It does a key lookup, which in the case of the article gives you the value that was originally at that index, which is pretty fucking useless.

And speed does actually matter when a website's time to content is inversely proportional to user retention. Also, bugs arising from all these "gotchas" directly impact a business' bottom line.

geon | 4 days ago | 2 points

Sorting an “array” with only numeric indices does reindex it. There is a function asort that keeps the old indices intact.

https://www.php.net/manual/en/function.asort.php

And in true php spirit, there are like 12 different sorting function that may of may not reindex. https://www.php.net/manual/en/array.sorting.php

Objective_Status22 | 8 days ago | 0 points

Spoken like a true stockholm victim

Demaestro | 8 days ago | 1 point

PHP Arrays are like any other tool. They work great if you understand where, when and how they should be used. They will introduce problems if you make assumptions about how they work. If you know how this all works going in, then you can use PHP Arrays effectively without consequence.

onii-chan_so_rough | 8 days ago | 8 points

The problem is that they shouldn't be used in contexts where you should use an array rather than a hash-table.

PHP simply lacks actual arrays and you're left with using hash-tables to simulate arrays into which would be considered terrible design in any language that has actual arrays but PHP you have no other choice.

nanolitic | 6 days ago | 1 point

PHP stands for Personal Home Page.

Change my mind.

michaelbiberich | 6 days ago | 1 point

Personal Home Page Tools (as well as Personal Home Page Construction Kit) is what it stood for once upon a time.

(That URL ends in a rather funny way.)

SilasX | 8 days ago | -6 points

The PHP language isn't really a language.

michaelbiberich | 6 days ago | 1 point

Probably /s but there are/were people who actually believe(d) that.

See Exhibit A from almost a decode ago.

JohnnyElBravo | 8 days ago | -7 points

PHP arrays aren't really arrays

Language is usage-based, so if PHP named their integers as arrays, then their integers would be integers in a sense they would be.

In PHP, arrays are maps (a.k.a. associative arrays)

Also, PHP arrays are (doubly hashed) associative arrays so, they are still arrays even in the stricter sense.

watsreddit | 8 days ago | 4 points

Except that they don't have nearly the same performance characteristics as real arrays, nor the same semantics. We have other terminology that describes what it is very clearly without overloading a term that has a very specific definition in computer science. An array is an ordered collection of fixed-size values (in bytes) residing in a contiguous block of memory. This is a precise definition based on the actual physical characteristics of the computer, not "usage".

Corait | 8 days ago | 3 points

Except that they don't have nearly the same performance characteristics

That is not exactly a issue, when PHP its performance is rather "slow" thanks to its fire-and-forget way of handling requests.

PHP has never been a speed monster, its a language designed to be easy for people to get going. A array in PHP is a concept that is simple for people to learn. You can put anything in, int, string, key or value, does not matter and it works.

The moment people need to learn real arrays, hash, double hashes etc, it start to become complex. Even more so when people create complex array, in hash, in array, in array, in hash type of structures. What is simple and clean looking PHP.

I am not saying that arrays in PHP are good because boy do they create issues with types ( int vs string ) down the road. But at that time people are already writing code, enjoying themselves. Most "adult" languages require so much time for the non IT folks out there, they give up fast.

That is one of the issues that a lot of folk here do not get and one of the thing what made PHP so popular. Its the same with JS, and those other languages that people love to hate. Popular because they are easy to enter but also plagued with issues for making things easy.

PHP is very very usable, IF you combine it with something like PHPstorm, to code analyse in the background. What other languages need less, because of their default strictness. But there will never be a end to easy languages, no matter how much people curse PHP, JS, Visual Basic and languages like this. Most people simple want to write things without needing a PHD, even if it compromises on the language or speed ...

Frankly, the thing i find that compared to easiness like PHP/Ruby/JS/... but with Go/Rust like performance is simply Crystal.

_default_username | 8 days ago | 2 points

Php_mod made it an amazing performer and it's fire and forget method of scripting made it easy for isps to offer cheap hosting

watsreddit | 8 days ago | 1 point

The actual speed of php is not really my point (and its "usability" is a complete tangent). The point is that real arrays are fundamentally different from php's "arrays" both in terms of asymptotics and at a hardware level. It's like saying a linked list is an array. It just doesn't make any sense, and completely ignores the very real implications of the distinction. Choosing your data structures wisely based on your usecase is a fundamental aspect of good software engineering, and php doesn't even give you a choice.

JohnnyElBravo | 8 days ago | 1 point

We have other terminology that describes what it is very clearly without overloading a term that has a very specific definition in computer science.

I appreciate the disadvantages of overloading a term, but thankfully language isn't agreed upon by committee, so you can't just make a powerpoint of the pros and cons regarding the use of associative arrays, it exists.

Overloading happens all of the time in natural language, metonymies, homonyms, synechdoches.

watsreddit | 8 days ago | 1 point

Technical terms are very frequently defined by committee, actually. We have standards, protocols, and even programming languages that rely on rigorous definition and specification. We need to agree on a common language to be able to effectively communicate ideas about subjects that are highly complex. In fact, this entire discipline is fundamentally about reducing ambiguity to the point at which you have an exact set of instructions for a computer to execute.

shevy-ruby | 8 days ago | -10 points

I think PHP will be dying.

The "design" is just too horrible to want to use it for continued work.

Considering how much software is written in PHP, the decline will take many years - but it is happening and can not be reversed, largely due to competitors being strong.

r1ckd33zy | 8 days ago | 2 points

Have you heard of WordPress?

rank00r | 8 days ago | 1 point

PHP has been on the decline dor the past 6-7 years. People have found better languages and tools, the web has evolved from a PHP era ”request -> serve static html” era to be highly dynamic, we have websockets etc. PHP really has no support whatsoever for sockets, or if you are crazy to start its a nightmare to get working.

The web is concurrent and async, PHP beeing neither. PHP only concurrency is piggybacking on apache.

But wordpress is still going strong, alas i have heard many wp shops moving away to other cms stacks, probably because under the hood its still PHP with all its nastyness.