Seems really cool - I’d love to know more about how this works. Are there some c bindings
or something that lets us call a rust program from php?
It sounds like the actual async features come from Revolt so I’m not 100% sure where Rust fits in. Because the rust lib used is async as well, they’re compatible?
php-tokio's integrates the https://revolt.run event loop with the https://tokio.rs event loop; async functionality is provided by the two event loops, in combination with PHP fibers through revolt's suspension API (I could've directly used the PHP Fiber API to provide coroutine suspension, but it was a tad easier with revolt's suspension API (https://revolt.run/fibers), since it also handles the base case of suspension in the main fiber).
I’m one of the few contributors to ext-php-rs. I’d be interested in contributing to your fork if you are planning to support your fork too. I think there’s a lot of QOL improvements to be made still and also adopting newer php features etc
Yes, I'm planning to support my fork of ext-php-rs, given that it will be heavily used by our mongodb driver.
I've actually sent an email to David Cole, asking him to make a maintainer of the original repo, but he hasn't replied yet, feel free to send your MRs to our fork in the meantime!
I was playing with something like this a long time ago back when I was excited about NodeJS. I hooked up libuv to PHP and got https://github.com/dtjm/php-async which seemed to work in simple experiments.
https://revolt.run / https://amphp.org does basically what you did, except with also a bunch of nicely designed async libraries for HTTP/MySQL/Postgres/etc, stackful coroutines (like goroutines) with fibers and integration not only with libuv, but also with libev, or with plain stream_select.
php-tokio plugs into revolt, which in turn allows it to coexist with any async library based on or compatible with revolt (i.e. the entire amp ecosystem, PSL, reactphp, etc...).
The example isn't very good at showing what it does properly. An improvement would be to show the results for different delays, not 5 seconds for all 3 functions calls
I used the same delay because this way when running via CLI it's clearer that the requests are made asynchronously, because the "Got response" lines are printed at the same time after 5 seconds, not 5 seconds apart each; using varying delays removes this neat simultaneous effect.
Every time I read "PHP" in a thread I think "Here we go again with the useless hate/love comments".
Can we just agree on "PHP used to suck but it was very easy to work with, reason why it got traction. Things got better over the years and those that only saw the early years, rightfully only remember how much it sucked, while those that use modern versions see how much it has changed"?
I've been working with PHP since the early 2000s, and it has undergone massive changes. I made a video recently called "PHP doesn't suck (anymore)"[0] to try to cover some of the changes from 2012 to now. If you read through the comments you see a lot of people surprised at how much the language has evolved. And a lot of people saying "PHP sucks lol," but it is YouTube afterall.
> Can we just agree on "PHP used to suck but it was very easy to work with, reason why it got traction. Things got better over the years and those that only saw the early years, rightfully only remember how much it sucked, while those that use modern versions see how much it has changed"?
This comment is super interesting to me, not because it contains anything I haven't heard before, but because the phrasing managed to break through my "bubble" of being the type of PHP naysayer you're talking about by making me realize just how similar this trend is to some other tech products that I'm not nearly as down on (I use btrfs on my personal machines, and I worked for several years at MongoDB, both of which seem to suffer from similar views of "fool me once and I'll refuse to ever give you another chance, no matter how much changes"). I still probably won't end up using PHP myself, given that I don't really do much web development anymore, but you've at least gotten one person to reconsider their opinion on PHP, so thank you for that!
ok, maybe i'm falling into what you're talking about here, but i saw those as 2 separate things.
BTRFS had bugs that could be fixed, so when they're fixed you can use it. While with mongo, it's still fundamentally a schemaless datastore. If you have a fundamental problem with that, then there's no bugs that can be fixed to make it ok.
I think in these cases you need to separate out the core criticism over simply temporary issues.
The criticism of mongodb that I'm referring to is from the early days when there were some questionable defaults (e.g. writes not being required to be fully written to the database before returning success to the user, which can lead to data loss if something happens that prevents the write from completing afterwards). I agree that's a separate concern than not having the schema enforced by the database. It's possible that my experience is skewed by being more involved when I worked there, but I used to hear and see a lot more criticism of mongodb around things like data durability and ACID compliance than about the lack of an enforced schema. Maybe things have moved on enough that this isn't a common complaint anymore, which would be a pleasant surprise, and hopefully we can get to that point on PHP too.
Been working with PHP since the late '90s, still do with some legacy Zend Framework clients.
Lot's of people people who hate on PHP's "design" (not the code bases created from it), didn't understand what was going on. PHP allows taking any C program and writing a wrapper around it, and they would often just use the C program's API, which would then become part of the PHP API for that extension .
There was amazing inconsistency there, yes, when looking through a formal lens. But it was not "designed" so much as "grown" - it was an organic thing made for delivering. It was quickly able to have huge amounts of functionality added that didn't happen as fast with ASP or Cold Fusion, and I didn't find it nearly as gnarly as Perl.
I understood that a lot of API inconsistencies come from the underlying C libraries. For me, the biggest annoyance was in that the language itself was inconsistent with itself (not talking about libraries), array usage in particular was iirc really weird in terms of the usage functions. From what I understand it's better today and Laravel and other options can make it nice to work with.
I was rather partial to Classic ASP with JScript myself... Although the biggest issue in that whole space was a lot of the addons were commercial and expensive COM libraries. VB6 added a lot of value and made it more useful. It was a much different time in the mid-late 90's though.
These days, I'm still more inclined to fave JS environments such as Deno or node, that have vast and rich options for everything. Though the language itself still has a lot of detractors, even for TS. I've also been enjoying the bit I've played with Rust.
Kinda. I can agree that for example Laravel is better than what we had in the past, but it's still worse than lots of non-php alternatives we had available for years. It's still playing catch-up, and that's assuming you get to work with new frameworks rather than writing a WP plugin or something similar. And it's hard to talk about modern php when probably most of the code out therei s still written like it's year 2000.
"Modern PHP" basically boils down to "backporting features from the languages/ecosystems that have since replaced PHP".
Which is a great and smart way to improve PHP for the people who still have to work in PHP. But none of it is original to PHP, or provides a compelling reason to use PHP instead of the options where all these things originally were copied from.
So should I use lang X for one feature, then shuttle that over to lang Y for another language feature, then marshall those results to a third language for its one original feature, then keep going?
Or would it be OK to recognize that most ecosystems adapt good ideas from each other?
I think the point of GP is more that, if you're starting something new, you're probably better off with something that isn't PHP, despite the improvements that have been brought into PHP.
And yeah, many different ecosystems adopt ideas from one another. And it's often a good thing, though it can be hard for people with a lot of experience in something to see new syntax/ideas sometimes. It's also sometimes hard for people to invert/twist their thinking in different ways. I see this a lot when OO devs try to work with FP concepts. Another example is getting used to Rust's pattern matching and enum values.
Not that I agree with the person you're replying to, but while PHP is faster than almost everything else, that rarely actually matters in any application you'd be using PHP for.
Can you give examples of how Laravel is playing catch-up in these regards? Backend/front-end integration is very well done with Livewire/Inertia. Simplicity while providing batteries is a given, but even more so with some of the starter kits. And honestly, I’ve been quite impressed with all the high quality, Laravel-specific packages out there (looking at you, Spatie).
I’ll definitely give you non-web usage and most of language features (even though PHP nowadays has first class type support, which can’t be said of Rails, unfortunately). And yes, concurrency is all but absent.
Apart from RoR, I haven’t used much else in the full stack framework space, so I’d love to hear!
You might want to look into the JS/Node ecosystem sometime... there are a LOT of powerful frameworks with everything to highly flexible mix/match to batteries included (next/nuxt) options. Not to mention modules for anything and everything under the sun you might want to do, with adaptors for module development bringing in about every option under the sun.
This is just an example, not a strict advocation... I've been more fond of batteries not included options myself, and in particular been admiring rust options a lot.
As someone who used to champion PHP when PHP7 was new: if you're most productive with PHP, or if there is a PHP-only tool/library that does something specific that you want, or if you're maintaining a large PHP codebase and need to modernize it while keeping breakage to a minimum, by all means use it! But otherwise, choose something else for new projects (Node/Go).
EDIT: Also forgot to mention, PHP is great for cheap hosting, and still provides one of the simplest ways of building a server-side webapp (everything can live in an index.php file) so that is another benefit if you're looking for that.
We routinely upgrade Node versions (e.g. 12-to-18 or -20) on many-years-old projects with legitimately no code changes required. Node and JS just doesn't really break things like that.
I've always had issues with newer versions of node not running projects written with older node without upgrading the project and hoping all dependencies can be updated.
Fortunately, a lot of the earlier struggles came down to binary libraries. At this point, a lot of externalized libraries are now using webassembly targets or built-ins. SQLite being one of the more popular exceptions.
For the most part, I haven't had too much trouble the past couple years taking an existing project and running on a newer runtime. I have seen a lot of incompatible library breaks trying to update dependencies though.
Many node packages will have incompatible api breaks across years of development. More so if your TS types have changed in incompatible ways and you're stuck re-jiggering your code. Can usually resolve in a few days. My advice is to, in general plan on one day a month to upgrade all dependencies to their latest version, which reduces the exposure a lot and makes it easier to deal with than years later. It's worse on front end projects that use node for build tooling.
Ironically, I think the worst libraries for breaking changes are actually the testing libraries themselves. Having to jump 2-3 major versions to update to latest is an exercise in extreme frustration.
I appreciate a lot of what Deno is doing in their direction, though I've felt a few breaking changes along the way there too.
I think that ship has sailed for the time being. Too many of the older cohort have been traumatized back in the day, and those that came after will only know PHP from horrible ancient codebase fossils no one wants to touch with a long stick
There are also a lot of companies and people working with modern PHP frameworks. I’ve never had the displeasure to work with code bases older than a couple of years.
My experience with PHP/Laravel has been that Laravel is an awesome framework on what is nowadays a ‘decent enough’ language.
For comparison, at least PHP has first party type support nowadays, whereas Rails does not.
More like "PHP used to suck but it was installed in very cheap hosting, reason why it got traction. Things got better over the years and while those that use modern versions see how much it has changed, those that only saw the early years don't even care because they all use better tools".
Counterpoint: PHP used to be a very simple tool, the best for simple projects and to learn stuff about the how to build a website. But now it grew into one of the biggest language ever in terms of different features and syntaxes, and people have been building monstrous framework to try a build “serious” stuff with it.
PHP of the past didn't “suck”, but people who grew PHP in it current state, because they wanted a “professional” language definitely made it suck.
Come on now, it is Linux, Apache, MySQL, and PHP === LAMP...
it was more than just easy of getting a server going, it over all ease of development, PHP was MUCH easier to work with as a developer than ASP or Perl, or any of the other early web lang's
ASP was about on a par with PHP 3 tbh. PHP probably had the edge because of the array and string handling, but an IIS/ASP web server was easier to set up, and a lot of people could write visual basic.
It is the same set. Personally I used to install it in LMAP order, because Apache and PHP share configuration settings and you want to validate everything end-to-end at the end.
> "PHP used to suck but it was very easy to work with, reason why it got traction. Things got better over the years and those that only saw the early years, rightfully only remember how much it sucked, while those that use modern versions see how much it has changed"?
+1
I fall into the latter and will always defend it. PHP had a very similar development arc to JS.
Like JavaScript they've never fixed any of the fundamental issues, like implicit type coercion, and the standard library is full of completely mad methods with extra "behave_in_a_sane_way = false" parameters.
I mean, probably the sensible choice - backwards compatibility is very important. But it does mean that a lot of the things that made PHP awful still make it awful.
There's this fallacy that just because something is popular, it must have some valid niche use case. That just because it endures, it must have improved somehow over the years, rather than just been taken over by an ever-proceeding chain of fools.
You can usually recognize it because people refuse to explain why something is "good" or "better now", instead just blanket-asserting that it is.
It introduced such drastic breaking changes, that probably a lot of systems which were previously perfectly serving their users will be abandoned. Projects that could have stayed on the internet and served their users just fine.
It broke the order of parameters in join statements.
It broke calling static functions without the need to declare them as static.
It broke adding properties dynamicly to objects.
It broke easy string handling for many functions where Null was rendered as an empty string.
And these changes make PHP code more bloated. There is now no way around adding more declarations to your codebase than before.
Some of these breakages had 30% votes against them, including the original author of PHP:
The bar for breaking changes should be much higher.
Python's update from version 2 to version 3 caused a lot of pain. But at least it made the code leaner. Allowing users to go from "a=float(b)/c" to "a=b/c" is a good thing. Forcing users to go from "function f()" to "static function f()" is a bad thing.
PHP 8 is the best version of PHP yet, and the main reason why it's so good is precisely because it got rid of a huge amount of ugly, legacy behavior.
Upgrading a codebase to PHP 8 is not an insurmountable task, I've upgraded our 1 million SLOC codebase at work in just a few weeks, with the help of tools like https://psalm.dev and our own strict coding standard.
Yeah I'm aware of Rector, there's a funny story here, I actually created https://github.com/phabelio/phabel which does the same thing as Rector, but @ installation time (fully integrated with Composer!): I created because I simply did not know about its existence, or else I would've just used it, instead :)
Rector is a very nice project, but I still haven't gotten around to integrating it into our codebase at work, because it uses phpstan instead of Psalm, and apart from being slower than Psalm, phpstan kept having various issues and crashes while scanning our codebase, unlike Psalm which mostly worked out of the box (I even became maintainer of Psalm, due to the large amount of additional performance improvements I added due to our needs @ work).
At work, we're currently using Psalm with a few extensions that make some autofixes as needed, a bit like Rector.
It introduced such drastic breaking changes, that probably a lot of systems which were previously serving unsafe and error-prone code to their users will be abandoned. Projects that should have been updated ages ago and served their users dangerous code.
It fixed the order of parameters in join statements.
It fixed calling static functions without declaring them as static.
It fixed adding properties dynamicly to objects.
It fixed string handling for many functions where Null was rendered as an empty string.
And these changes make PHP code more secure. There is now no way around adding more declarations to your codebase than before.
I still remember PHP3... PHP5 was not "horrible in almost any metric", and it was much easier to write secure code with PHP5, which is why "websites running old PHP code are so seldom hacked".
PHP expects programmers not to do stupid things... I guess that is too much to ask in the modern era where "programmers" do not want to have to actually program anything, they instead want make a function statement, then have AI fill in the rest for them, or use a Low Code or "RAD" framework to abstract away all the actual programming so they can do the "fun design stuff" ...
I use PHP for my day job, but the one thing I miss most is compile-time (type) errors. PHP just goes until it can’t go any more. I prefer languages that tell me that I forgot something somewhere, or that a name or signature change broke something somewhere I hadn’t thought about.
How does this statement relate to the comment you replied to? You suppose only juniors appreciate newer versions of PHP? Or seniors don’t know how to port code bases?
Most of the stuff you talked about only causes warnings, unless (and it’s a good practice btw) you’re converting them into exceptions by setting up an error handler.
In my case, I used a combination of Rector, integration tests, and sending exceptions to Sentry to successfully upgrade a PHP code base from version 7 to 8.
I don't think it broke any of that, I think it fixed all of that.
And PHP 5,7 will continue to work just fine for a while. There still supported backports and images of PHP 5 to this day on any major operating system.
We migrated the codebase of our most ancient system (started in 2008) to PHP8 this May. Millions of lines of code. It mostly consists of PHP5-era code, and there's also newer code which is compatible with PHP7. It took 4 weeks of work of 1 dev and 1 QA (including bugfixing). The engineer responsible for the conversion downloaded all existing linters he could find, ran them and fixed code until they stopped complaining. He also he used Rector - software which can semi-automatically update PHP code to newer versions. We had a few non-critical regressions after the release due to the breaking changes, but otherwise I was surprised how smooth the release was. My favorite feature is "constructor property promotion", a lot of classes now take 2 times less code.
Javascript is a client-side language, you don't have control of the software stack, thus (ideally, if you want to) you have to write code to support every version, even a prehistoric chrome build from 2015 (be it directly or indirectly via transpiling and polyfills).
PHP is not like that, like in every other language where you can control the entire environment, it evolves and things break, and that's the way it should be, that's why we have semantic versioning.
It sounds like the actual async features come from Revolt so I’m not 100% sure where Rust fits in. Because the rust lib used is async as well, they’re compatible?