Why do you say that? It's faster than Python and Ruby for most cases, still extremely simple to deploy, the package manager (Composer) is very predictable and easy to deal with compared to Pip or Rubygems, the documentation is good, etc.
It has clean lambda functions that you can pass around easily and has for more than a decade. Type hinting has been in place for a long time, too, as have enough OOP / reflection constructs to do just about anything you'd reasonably want to do in a language aimed primarily for web development.
The only downside of PHP that I can still point to is that it's sometimes hard to remember the function parameter order for some of the common string and array functions. Far from a dealbreaker, that.
it spawns a new php interpreter for every request, which means for example that symfony framework setup (routes, controllers, service dependencies...) have to run before every request. Sure it does that faster than python, but python only needs to do this once.
deployment is my personal nightmare. try to set the max children or whatever so concurrency is ok but memory does not run out. I mean facebook did it so it has to be possible but damn, that was hard to get `right`. Setting up logging is a mess. There is the application, the admin and the fpm error log, I gave up trying to have every log event logged exactly once. Segfaults are a common occurrence, still. I heard it mentioned just before leaving for vacation.
To be fair the last time I seriously worked with PHP was back when mod_php was still cool. I was able to serve thousands of users on a dual-core Xeon box ~15 years ago - I can only imagine the performance is better in many ways now.
The type system is weaker than Java, which is a low bar.
It has no generics, which means no real containers, no generic functions without dropping all typing, no type-hinted arrays.
Arrays are also not objects, so they don't conform to any interfaces, which is related to the "no real containers" issue.
It took until version 7.4 to actually have covariance and contravariance! Before that it didn't even implement inheritance correctly!
You can't typehint for function-as-param beyond just writing `callable`. So if you want to use those nice lambdas and still be statically typed, you're SOL.
It's definitely fast for a scripting language! So, that's fair. But it's still way slower than many other good backend languages: Java and other JVM languages: Kotlin, Scala, maybe Clojure?, Go, Rust if you're feeling frisky.
I've never used Ruby and I'm generally biased against dynamically typed languages, so that's the background for my assessment. The dynamic languages I've used in anger are Python, JavaScript, Elixir, and Clojure.
The package manager is better than the disaster that Python was the last time I used it. Agreed. It's also better than NPM, but not enough to matter most of the time. It's not better than Hex or Lein. Also, managing packages is a) not the language, which is what I criticized, and b) not where you spend most, or even a large part, of your dev time.
Looking at PHP as a dynamic language, I'd say that the built-in array is still a huge disappointment and the API sucks compared to either of Python's dict or list. It's much cleaner in JavaScript, Clojure, Elixir, and Python to define and operate on new, untyped, objects.
Also, for a dynamic language, I'd at least want SOME benefit to it being dynamic. For JS, Clojure, Elixir, and Python, the REPLs are great. The PHP REPL is... primitive.
None of the things you mentioned in PHP are actually better than any other language I've used except for the package manager. Its lambdas are not even better than any of the languages I've listed. In 2020, decent lambda syntax is table-stakes.
These things are a little advanced for the likes of me. Any chance you'd be so kind as to give me an example of something I can't easily do because of not having this?
> It's definitely fast for a scripting language! So, that's fair. But it's still way slower than many other good backend languages
But those languages require compilation and deploy cycles that are way longer than just getting files on disk, so the total cycle time of development may end up being longer in many cases. It's a tradeoff. PHP probably shouldn't be used for performance-critical things, sure, but then neither should any other dynamic language.
Well, you can do whatever you want in a dynamically typed language. I was discussing the shortcomings if you choose to use PHP's type system.
If I'm using my static types and see `function foo(): Bar` I take comfort that I will receive a `Bar`. If I see `function foo(): array` I have absolutely no idea what that array is. Is it a list of `Bar`? Is it a dictionary of some kind? Is it a heterogeneous list of bools, ints, and Maseratis?
Also, real containers are useful. A true array is a contiguous slab of memory. PHP's array is not. The performance characteristics will be very different. If you had a `Set<T>` type, you could guarantee that there are no duplicates in the set. That is sometimes very useful. No such thing in PHP. PHP arrays can't even be used as a real `Map<String, T>` because if you do `$arr["1"] = new T()`, it wont actually have "1" as a key! It'll transform the "1" into 1 and store it in the 1th slot, like an array!!! Totally flipping useless.
> But those languages require compilation and deploy cycles that are way longer than just getting files on disk, so the total cycle time of development may end up being longer in many cases.
Are you suggesting that you write PHP code and then plop in on a production server without running tests? Because running your tests is comparable to the compile cycle of Java et al. Except in those cases I don't have to write entire classes of tests, whereas you should be writing type-checking-style tests on your PHP code. You just have to be the compiler to make sure your inputs are validated correctly.
> PHP probably shouldn't be used for performance-critical things, sure, but then neither should any other dynamic language.
Then what was the point in comparing PHP's speed to Python? They're both slow and shouldn't be used for performance-critical things. That's fine, but then find me a selling point.
Hardly. PHP-FPM is a confusing mess to set up, and you're still stuck working around the massive mistake of binding routing to the file system.
And I hope you don't try to just rsync up your changes afterwards without some form of blue/green deployments.
> the documentation is good
There is.. a lot of it, for better or worse. Let's compare the functions for concatenating lists between PHP[0] and Scala[1]. The PHP version is way longer and contains several examples.. that are only needed in the first place because the PHP's array type is so messy and tries to fill so many different uses. Meanwhile, Scala's gets to the point, describes how to use it, and uses the rest of the screen estate to help me navigate to anything else that might be relevant.
> It has clean lambda functions that you can pass around easily and has for more than a decade.
Looks like they did finally clean up their baffling closure binding syntax in 7.4... unless you want to bind anything by reference.
That said, it is pretty hilarious to me that they decided to make strings and arrays of strings callable rather than add some kind of first-class function reference syntax. Surely that won't have any confusing interactions with namespaces...
> Type hinting has been in place for a long time
Not of much use without generics. `array` isn't a particularly useful type. There does seem to exist an RFC[2], but it looks dead in the water (no voting table, and the stated vote goal was years ago).
> The only downside of PHP that I can still point to is that it's sometimes hard to remember the function parameter order for some of the common string and array functions.
It's not really PHP's fault itself, but Laravel is a miserable mess of implicit magic. The fact that people often seem to hold it up as the gold standard of PHP doesn't exactly inspire confidence in the community.
[0]: https://www.php.net/manual/en/function.array-merge [1]: https://www.scala-lang.org/api/current/scala/collection/Seq....):Seq[B] [2]: https://wiki.php.net/rfc/generics
fastcgi_param SCRIPT_FILENAME /var/www/index.php;
No, but you can do function foo(SomeClass $x) {...} - doesn't that fulfill the use case for most people? Objects are basically fat types, in a sense, no? And since the OOP hierarchy is respected, I can use interfaces or abstract classes here and get basically what I want...?
Sure, it's not built-in, but I think this is the best solution for now given the size of PHP's language team.