The biggest issue that I have seen among freshers and students is that they are hardwired to imagine arrays as sequential list. Most coaching institutes in India doesn't explain students about the under the hood concepts. All they are taught is that all PHP arrays are associative.
Also, PHP as a language itself, has evolved a lot from 4 -> 5 -> 7. PHP that I code today is not the same that I learned back in college. When I was in college, PHP wasn't an Object-Oriented language. The OO features added in PHP-5 were mostly a syntactic sugar over functional php. This is the reason why all the memes about PHP being dead originate from, people still imagine it as its older incarnation.
PHP Arrays are ordered hashmaps under the hood, thats why it is more powerful than conventional arrays found in Java or C, at the same time it is more frustrating for those who still visualize it as common list type array. But that doesn't mean they are slow. array type might feel like too wide, but it isn't.
An array in PHP is actually an ordered map. A map is a type that associates values to keys. This type is optimized for several different uses; it can be treated as an array, list (vector), hash table (an implementation of a map), dictionary, collection, stack, queue, and probably more. As array values can be other arrays, trees and multidimensional arrays are also possible.
Fair points about the evolution, and about outdated thinging. However, I never claimed that arrays are slow; just that expecting or passing an array is probably much more than what one wants, which creates the kind of problems I describe here, and hence this type is too wide.
You are stating that it is not too wide. What would you like to back that up with, given the detailed explanation of my reasoning given in this article? Which, by the way, has nothing to do with what they teach you at school, or with how PHP arrays are implemented under the hood.
When you say array type is wide, I am assuming you are talking about all the features, functions, etc it have on it. If that is what you were going for, then php arrays are not too wide, because it has all the functions that is expected from a map collections. Infact, look at the functions related to maps and collection in any language, Java, C, D-lang, Go-lang etc, they are all similar to whats in php. The only thing that is different, is that those languages have have both sequential list (traditional simple array) and collections (maps) whereas php doesn't have any traditional sequential array, only maps that fulfills both roles. Only reason why it feels too wide, is because of the perception of traditional arrays in other languages.
Long ago, when I read the following blogpost, I tried to be cautious around php arrays, But looking back, in past 10 years, there may have been maybe 2 niche scenarios where I even had to think about it. Infact, I have worked on some java projects where people have made complex array-utils library to implement some handy features which are basically available in php for free.
Your example in the Data representation section, is basically a proper, secure, OO way to do that, irrespective of language. That approach is very similar to design pattern used in JavaBeans or kotlin data class, albeit a bit more smaller pieces ( it may be generalization pattern? or specialization pattern? ) .
From what I read, this post covers design pattern, not php arrays.
Just re-read your summary section, you have made amazing points on design patterns, but it had nothing to do with merits and demerits of php arrays. Specifically in your last point about only providing minimal interface under ISP, That is true for all languages. For example, using JavaBean, we don't expose entire java array of a data, we create interface which implements minimum functions needed downstream, abstracting the array ( or collection ) itself. This technique is basically enforced on most OO languages I have worked with.
I think we're just looking at it differently. I am referring to the array type as an interface, a collection of known common attributes of all arrays. I feel that you may be referring to the implementation.
The point I am making is that the interface of the array is comprized of multiple different smaller interfaces, which as you have correctly pointed out would be hidden behind an abstraction in an OO scenario. Depending on array - i.e. read, write, and enumerate interfaces of it, as they are inseparable from the array type - is making too many assumptions that are not useful anywhere.
For example, I have nothing against sumNumbers([1, 1, 2, 3, 5]), because an array is an easy way to create something that passes the iterable typecheck.
What I believe is wrong is requiring an array there. If array values would pass the ArrayAccess check, I would have nothing against declaring function getGreeting(ArrayAccess $user): string, and then invoking getGreeting(['first_name' => 'Santa', 'last_name' => 'Claus']). But unfortunately, it does not work, which IMHO goes a long way to reinforce my point.
Another perhaps more pragmatic way of explaining this.
By depending on array in my signature, it's the same ISP issue as with depending on ArrayAccess&Countable&iterable - why would you do that? Except that a real concrete array won't pass that typehint in PHP, which is even worse, because it necessitates a userland interface for something so extremely simple.
And I'm not saying that there's really never a reason to depend on ArrayAccess&Countable&iterable. But if you are depending on 3 interfaces by depending on array, you should know well what your reason is. And that I'd be curious to know it.
This point of view makes sense. You are right, while arrays are one of the way to work on data, in practical real world usage, it is safer to limit exposure.
Comment hidden by post author - thread only visible in this permalink
Now this do make sense. PHP arrays does expose the three interfaces. Although like we know, this is by design, a side-effect of emulating an array using ordered maps. Maybe this is why some frameworks prefer to abstract these. Maybe they will rewrite the internals someday, but it would be tough to do that without breaking the internet.
In a talk by Rasmus Lerdorf, he mentioned how he never intended PHP as a language that we know today, that is why all these inconsistencies in internal apis, the language quirks, etc, are all there because he created PHP to be something else. It was after the fact of PHP's popularity, that he decided to rewrite the language internals from the scratch, in a way that it doesn't break internet, yet become a proper backend language.
Now this do make sense. PHP arrays does expose the three interfaces. Although like we know, this is by design, a side-effect of emulating an array using ordered maps. Maybe this is why some frameworks prefer to abstract these. Maybe they will rewrite the internals someday, but it would be tough to do that without breaking the internet.
In a talk by Rasmus Lerdorf, he mentioned how he never intended PHP as a language that we know today, that is why all these inconsistencies in internal apis, the language quirks, etc, are all there because he created PHP to be something else. It was after the fact of PHP's popularity, that he decided to rewrite the language internals from the scratch, in a way that it doesn't break internet, yet become a proper backend language.
The biggest issue that I have seen among freshers and students is that they are hardwired to imagine arrays as sequential list. Most coaching institutes in India doesn't explain students about the under the hood concepts. All they are taught is that all PHP arrays are associative.
Also, PHP as a language itself, has evolved a lot from 4 -> 5 -> 7. PHP that I code today is not the same that I learned back in college. When I was in college, PHP wasn't an Object-Oriented language. The OO features added in PHP-5 were mostly a syntactic sugar over functional php. This is the reason why all the memes about PHP being dead originate from, people still imagine it as its older incarnation.
PHP Arrays are ordered hashmaps under the hood, thats why it is more powerful than conventional arrays found in Java or C, at the same time it is more frustrating for those who still visualize it as common list type array. But that doesn't mean they are slow.
array
type might feel like too wide, but it isn't.from the docs
Hi!
Fair points about the evolution, and about outdated thinging. However, I never claimed that arrays are slow; just that expecting or passing an array is probably much more than what one wants, which creates the kind of problems I describe here, and hence this type is too wide.
You are stating that it is not too wide. What would you like to back that up with, given the detailed explanation of my reasoning given in this article? Which, by the way, has nothing to do with what they teach you at school, or with how PHP arrays are implemented under the hood.
When you say
array
type is wide, I am assuming you are talking about all the features, functions, etc it have on it. If that is what you were going for, then php arrays are not too wide, because it has all the functions that is expected from a map collections. Infact, look at the functions related to maps and collection in any language, Java, C, D-lang, Go-lang etc, they are all similar to whats in php. The only thing that is different, is that those languages have have both sequential list (traditional simple array) and collections (maps) whereas php doesn't have any traditional sequential array, only maps that fulfills both roles. Only reason why it feels too wide, is because of the perception of traditional arrays in other languages.Long ago, when I read the following blogpost, I tried to be cautious around php arrays, But looking back, in past 10 years, there may have been maybe 2 niche scenarios where I even had to think about it. Infact, I have worked on some java projects where people have made complex array-utils library to implement some handy features which are basically available in php for free.
Your example in the Data representation section, is basically a proper, secure, OO way to do that, irrespective of language. That approach is very similar to design pattern used in JavaBeans or kotlin data class, albeit a bit more smaller pieces ( it may be generalization pattern? or specialization pattern? ) .
From what I read, this post covers design pattern, not php arrays.
Just re-read your summary section, you have made amazing points on design patterns, but it had nothing to do with merits and demerits of php arrays. Specifically in your last point about only providing minimal interface under ISP, That is true for all languages. For example, using JavaBean, we don't expose entire java array of a data, we create interface which implements minimum functions needed downstream, abstracting the array ( or collection ) itself. This technique is basically enforced on most OO languages I have worked with.
Oh wow, thank you for such an extensive reply!
I think we're just looking at it differently. I am referring to the
array
type as an interface, a collection of known common attributes of all arrays. I feel that you may be referring to the implementation.The point I am making is that the interface of the array is comprized of multiple different smaller interfaces, which as you have correctly pointed out would be hidden behind an abstraction in an OO scenario. Depending on
array
- i.e. read, write, and enumerate interfaces of it, as they are inseparable from thearray
type - is making too many assumptions that are not useful anywhere.For example, I have nothing against
sumNumbers([1, 1, 2, 3, 5])
, because an array is an easy way to create something that passes theiterable
typecheck.What I believe is wrong is requiring an array there. If
array
values would pass theArrayAccess
check, I would have nothing against declaringfunction getGreeting(ArrayAccess $user): string
, and then invokinggetGreeting(['first_name' => 'Santa', 'last_name' => 'Claus'])
. But unfortunately, it does not work, which IMHO goes a long way to reinforce my point.What do you think?
Another perhaps more pragmatic way of explaining this.
By depending on
array
in my signature, it's the same ISP issue as with depending onArrayAccess&Countable&iterable
- why would you do that? Except that a real concrete array won't pass that typehint in PHP, which is even worse, because it necessitates a userland interface for something so extremely simple.And I'm not saying that there's really never a reason to depend on
ArrayAccess&Countable&iterable
. But if you are depending on 3 interfaces by depending onarray
, you should know well what your reason is. And that I'd be curious to know it.This point of view makes sense. You are right, while arrays are one of the way to work on data, in practical real world usage, it is safer to limit exposure.
Now this do make sense. PHP arrays does expose the three interfaces. Although like we know, this is by design, a side-effect of emulating an array using ordered maps. Maybe this is why some frameworks prefer to abstract these. Maybe they will rewrite the internals someday, but it would be tough to do that without breaking the internet.
In a talk by Rasmus Lerdorf, he mentioned how he never intended PHP as a language that we know today, that is why all these inconsistencies in internal apis, the language quirks, etc, are all there because he created PHP to be something else. It was after the fact of PHP's popularity, that he decided to rewrite the language internals from the scratch, in a way that it doesn't break internet, yet become a proper backend language.
Now this do make sense. PHP arrays does expose the three interfaces. Although like we know, this is by design, a side-effect of emulating an array using ordered maps. Maybe this is why some frameworks prefer to abstract these. Maybe they will rewrite the internals someday, but it would be tough to do that without breaking the internet.
In a talk by Rasmus Lerdorf, he mentioned how he never intended PHP as a language that we know today, that is why all these inconsistencies in internal apis, the language quirks, etc, are all there because he created PHP to be something else. It was after the fact of PHP's popularity, that he decided to rewrite the language internals from the scratch, in a way that it doesn't break internet, yet become a proper backend language.
Exactly. Because it is just more predictable this way.
I'm glad we have come to an agreement.
Thanks for the amusing conversation :)