The Demise of the Mildly Dynamic Website
devever.net
devever.net
And set up a webserver. Perhaps compile mod_php for Apache and configure it, taking care to do it securely. Then configure php too, again taking care to do it securely. Only then you can drop a bunch of files in a docroot and have PHP process them. And put some .htaccess files in so that things that aren't supposed to be directly executed can't be. I think it all just appeared simple, but it wasn't. It was dumb luck and lowest common denominator configurations on shared hosting that made it appear easy.
You don't need to do any of this if you use a hosted service, which most people did. In that case you just needed to setup an FTP client. Of course these days hosted services for other stacks like Heroku are about as simple. Just push to a git repository and you're done.
And then you find the software doesn't work because it relied on imagemagick to resize avatars to display the index page and your web host skimped out on the imagemagick module in their PHP deployment to minify resource use or it was just too much effort for them to deploy because it was the 2000s and they were using Slackware on their production servers.
Oh and the web host disabled .htaccess support so you need to turn off the pretty URL support in the config files. Oh and their default config (which you can't override - see .htaccess) is insecure as it means people can execute PHP files from the upload directory. So then you got owned because of that.
Oh and the MySQL configuration or old version used had some weird ideas about character encoding, so good luck with those € signs.
And then you wanted to install a plugin for phpbb or something and the instructions were basically a diff in textual form on a forum post.
I wouldn't necessarily presume that. I mean I would want that now. But for my first forays into web development, I didn't have that. Precisely because it was hard to setup. I would just FTP stuff onto the "live" server (it wasn't exactly a critical site anyway, so if it broke for a while then that didn't matter so much). There were editors which could edit files directly on an FTP which made the dev workflow pretty seamless.
Stuff like imagemagick could indeed be a pain. But you could at least get started without that. In general there were lots of problems, but the on-ramp to some dynamic behaviour was really minimal.
Or you did it like mentioned on another comment here (https://news.ycombinator.com/item?id=31247426): "copying homepage.php to homepagenew.php, hacking on it until it works, and then renaming homepagenew.php to homepage.php".
You may even have a script gathering urls for .php files starting with "homepage-" and echo a link for each chronologically (sorted alphabetically)
No need to self host a git server.
This is a quote from Jeff Atwood (founder of Stackflow) about PHP (he's not a fan):
Despite the serious problems with PHP, I was forced to consider it. If you want to produce free-as-in-whatever code that runs on virtually every server in the world with zero friction or configuration hassles, PHP is damn near your only option. [1]
When did Atwood say this? 2012.
A decade has passed and hardly anything has changed. Server installation remains needlessly complicated. Current solutions like Docker, Sandstorm, Cloudron, command line scripts etc. are "easy" for developers but not for ordinary users. What is easy for ordinary users? Installing a web app by uploading files to a folder on a server using a GUI FTP app is one example for PHP. (And for some non-technical users, even that might be too complicated).
> Current solutions like Docker, Sandstorm, Cloudron, command line scripts etc. are "easy" for developers but not for ordinary users.
It sucks that Sandstorm didn't "win". But the implication here is that PHP is easy for "ordinary users". It's not, though. It's easy for a slice of the somewhat technical population at the low end of the technical spectrum. Ordinary people are still left out—and not to mention: susceptible/vulnerable to being lured by the false promises about the "easiness" of the PHP model. Unpatched installs of shoddily written PHP apps (or plugin-laden installs of WordPress) are an undeniable vector for potential security compromises of personal data, spam, and nodes use to coordinate the spread/execution of malware.
I agree. I've often wondered: why can't web server apps be installed with the same ease-of-use as desktop apps? Simply click through simple screens and installation is complete. All desktop users know how to install desktop apps. Unfortunately, Sandstorm and Cloudron - trying to provide easy app installs - are not widely supported by hosting providers.
Eh? Installing an app on Sandstorm or Cloudron is basically the same UX as installing an app on your phone. Certainly much easier than uploading files to an FTP server.
I agree with your comment with regards to Docker and CLI.
I'm also happy to agree that Sandstorm and Cloudron hosts are much less ubiquitous than PHP hosts, and that's a real blocker to ordinary users... but it seems weird to classify them as developer-oriented on that basis?
(Disclosure: I co-founded Sandstorm.)
That's a very fair point. It was unfair of me to lump Sandstorm and Cloudron togther. Sandstorm and Cloudron setup is carried out by the hosting provider. The trouble is that not many Sandstroms hosts exist, as you acknowledge.
Sandstorm's aim is very commendable and thank you for tackling this important problem of deployment and web app installation.
Of course it had tons of issues (GET and POST variables turning into globals, SQL injection etc.) but the barrier to entry was very low.
WSK didn't support PHP, of course.
Nowadays it's not that difficult; you can just run nginx or Apache with Docker, and a few command-line options later you have a server running. If you have IPv6 or can reconfigure your home firewall (and aren't afflicted with CGNAT), it's a globally accessible server. Hosted options are a little trickier but not much.
It is work but I mean you’re writing a website then knowing these things is a prerequisite and the docs are good and there’s tutorial after tutorial all over the place.
Now it's far more likely to find a hosting provider that already has PHP set up over NodeJS, but as the main article observed, those are in decline. That seems to me as simply a lack of demand. If people want static sites, theres no need for PHP. If people want even a bit of dynamicism, then it's not hard to use a framework, and you get far more scalability. The barrier to entry for these frameworks is so low that it's not worth using barebones PHP and then having to rewrite everything if you start wanting more.
node.js also implements a deployment model, but it's a different one. (node.js rather than JS is maybe a closer analogue to PHP.) nodemon gets you partway to the PHP model (by restarting your server when something changes) but not all the way; it doesn't start running random files it finds lying around. And people never run it in production.
So, in summary, it is comprehensively not true that if you're already running node.js on the server, you can just drop files in. If you just drop files in, node.js will ignore them.
There's an enormous difference between claiming that "you can also just drop files on your server" and have a running application, which is what you said in https://news.ycombinator.com/item?id=31246963, and claiming that "[some] people don't need nor want" to just drop files on their server and have a running application, which is what you're saying now.
Now you're bringing up "drag and drop functionality", which is a GUI gesture, totally irrelevant to the things PHP's deployment model enables, which you are correct are things that some people don't want. Here are some examples:
1. You can unzip a zipfile of PHP on your server and have a running app. This is super helpful when you're a novice who doesn't know much about processes and sockets.
2. You can add a new URL by sshing into the server and typing "cp homepage.php homepagenew.php", even using a slow or low-bandwidth connection. Then you can incrementally change the new URL's behavior by editing that new file, while the main site hums along unaffected—at least until you hose the production database. If you want to change the old version, you can type "mv homepagenew.php homepage.php".
3. If you have two PHP apps, like MediaWiki and WordPress, you can unzip them in two different directories on your server and have two apps running on the same server. If one of them is broken, even contains parse errors, it doesn't affect the other one. You can add links in one of them that link to the other.
4. You can temporarily disable a page by typing "chmod 0 upload.php", without breaking any other pages and without slowing down the server.
5. You can host apps belonging to hundreds of mutually untrusting users in the same Apache process, running on different virtual hosts, without the different users being able to screw up each other's "sites".
6. You can break into somebody's website by uploading a file to it with a .php extension in a directory that the webserver is (mis)configured to execute PHP files in.
7. You can make a usable backup of an old version of a page by typing "cp homepage.php homepage.old.4.php". Which you can later restore in a similar way, without affecting other pages, by doing the reverse. Without learning how to use Git.
8. You can load a page in your browser and not have to think about whether possibly the running server has an old version of the page in its memory and that's why your attempted fix has no effect.
Now, PHP has never been my tool of choice; it's optimized by, and written by, people who don't know how to program, and I'd already been making web pages for years when it came out. It has its share of embarrassing bonehead design errors that can now never be fixed, though it did fix a lot of them. I like getting error messages instead of wrong results when I try to run broken code; it's one of the major reasons I switched from Perl to Python for soft stuff, near the turn of the millennium. I already know how to use version control systems, so I don't find it reassuring to have a directory full of "homepage.old.4.php". I want to be able to run the whole site on my laptop, not using the production database, and I want to be able to use a staging server. I don't want to have to worry about whether someone else has edited the files in production and that's why this page, that never should have worked, has always worked, until today. And I especially don't want my site getting popped because the uploads directory treated .php files as plain text but .php4 files as executable PHP. (Oops!)
But the fact is that PHP's deployment model enables beginning programmers to manage a website by putting files in directories, copying files around, making backup copies of files, and so on, without ever taking their entire site down with a parse error at startup, and, as far as I know, there is nothing even vaguely similar for node.js. Nodemon isn't it. Express isn't either.
You're definitely right, but the entire lament seems like a lot of special catering for the convenience of an audience that is technical enough to write PHP, but isn't particularly accommodating to, like, the actual masses of people out in the world who are not and will not ever be inclined to wade through the issues inherent to setting up a shared hosting plan with a PHP provider and hashing out their craving to publish by fiddling with templating code.
The author of this piece has a lot to say about SPAs and other client-side fads, which is fair. Lots of what makes up current trends in the "modern" Web is an abomination. But the PHP application/deployment model they advocate for is nothing special wrt the affordances it makes for non-technical folks, nor is it a particularly good implementation of TBL's original vision for the Web—despite the implicit ("explicit"?) claims in the article to the contrary. On both of those fronts, stuff like Zonelets <https://zonelets.net/> has moral superiority (despite its being basically a toy). The essence of Zonelets is also, at a fundamental level, much closer to what we see with SPAs than the "mildly dynamic websites" of yore.
These people may drift out of doing any programming as and when it becomes unnecessary. It's similar to the sentiments expressed with GeoCities, where you had web design being done by amateurs who weren't very good at it. Nowadays they probably use some kind of site generator and aren't exposed to HTML at all.
Of course one can say that these these things are better left to professionals, but it's clear I'm not the only one with a clear sense that we've lost something here. Neocities, for example, is a clear reaction to that.
It's similar to how home computers used to boot to a command prompt and now they don't. They essentially invited you to learn how they worked, whereas the modern desktop computing experience tries to seem as magic as possible. Many people of a certain generation probably learnt to program as kids on these old 8-bits because the machines themselves basically invited to. As a professional programmer now I'm genuinely unsure what I would recommend to a child of the same age today.
The KBFS-backed keybase.pub and the never-officially-launched Keybase Pages also had such huge potential.
0. Arduino. You can make colors and sounds that aren't locked in a box and that communicate over infrared. You can drive motors. In some cases, you can repurpose parts from existing consumer electronics. I had the privilege one weekend of helping out with a beginner programming class for artists; in about four hours they went from not knowing what a variable was to being able to program the robots they'd been given to follow a line around a racetrack. (Adults, but evidence suggests Arduino is good enough for kids too.)
1. Minetest. If they like Minecraft, Minetest is a Minecraft clone where they can write mods in Lua. This requires juggling a lot of files, and it can be difficult to figure out why existing mods are doing one thing or another, but you can add new mobs and blocks to the world that affect existing ones in a wide variety of ways. You can play it on your phone, even hosting a server, but there isn't a reasonable way to edit mods on your phone. And if you've spent a few hours playing Minetest the things in the simulated Minetest world can seem very real to you, which makes programming them more appealing.
2. Scratch or, on Squeak, EToys. A lot of kids seem to find Scratch easy to start out with but then want to switch to a textual programming language because they see it as more "grown up". And to be fair Scratch does have some real intrinsic limitations. EToys has maybe a smoother path to full Smalltalk but kids may not be impressed by full Smalltalk if they don't see adults using it.
3. Browser JS. The applicability and deployability is super high, and the barrier to entry here is pretty low if you have a desktop browser: type data:text/html,<a href="javascript:alert('hi')">x into the address bar. Graphics, sound, and multitouch APIs are available. You can easily load in images, including animated GIFs, composite them with alpha, and move them around and stretch them.
For more elaborate graphics there's both a pixel-based <canvas> API and a vector-based SVG API. You can draw SVGs with Inkscape. You can render a fractal in <canvas> in an OG Tweet, though color costs a few more bytes:
<canvas onclick="c=this.getContext('2d');function d(x,y,k){
c.fillRect(x,y,1,1);(k/=2)>1&&(d(x,y,k),d(x,y+=k,k),d(x+k,y,k))
}d(0,0,150)">
By putting your JS into a bookmarklet you can use it on pages you didn't write, including things like Fecebutt. The developer tools in the modern clones of Firebug (browser console, element inspection, CSS editing) are absolutely first class. Unfortunately a lot of this is limited to desktop browsers because vendors have deliberately crippled the browsers on hand computers; those are for consumers, not creators.Video games are very doable in browser JS, and the situation has improved significantly in the last five, ten, and twenty years. Beginners, especially kids, would probably benefit from a game engine library here because they don't know how to combine constructs to solve problems yet. I wrote http://canonical.org/~kragen/sw/dev3/invaders one day last March, but that's four pages of code full of arcane constructs like row.push((x / barricades.dx / 2 + 12) % 16 < 8). I refactored a game engine ("qj2d") out of it and got http://canonical.org/~kragen/sw/dev3/qvaders, but I haven't tried to teach anyone else to use the game engine, and it has some stumbling blocks and boilerplate.
Chris DeLeon demonstrates coding Pong in Notepad with <canvas> in 5½ minutes in https://youtu.be/KoWqdEACyLI as a teaser for a longer course.
JSFiddle and similar services make it easy to anonymously share your work without signing up for a hosting plan.
4. Micropython, or Adafruit's fork, Circuitpython, as an alternative to the Arduino environment. Circuitpython is focused on getting beginners, especially kids, up and running with a smooth UX. What we were saying above about dropping PHP files in a directory on a server to run them? Well, with Circuitpython you drop Python files in a directory on a USB device to run them. AFAIK they don't run on the AVR that's in the traditional Arduino boards but they do run on another half-dozen types of microcontrollers, mostly ARM.
5. Proce55ing. The Arduino IDE is a fork of the Proce55ing IDE, which is optimized for making mouse-interactive graphics on the CPU, but it can also straightforwardly do sound, integrate with additional sensors and actuators, load GPU shaders, and so on. It's been demonstrated to be very accessible to adult beginners, and I think it works for kids too. You can export the results as Android apps. It normally uses its own Java-like language but there are also JS and Python versions.
6. Shadertoy. There are a lot of graphical effects that are straightforward to achieve on in a shader on the GPU but difficult or impossible to achieve on the CPU, and the Shadertoy website makes it easy to get started with that; you can edit the shader live and see the results in your browser, and save it to a URL. Also maybe check out Patricio Gonzalez Vivo's The Book of Shaders.
7. PyGame, the Python binding for SDL. You can write games in PyGame (solarwolf is in apt, and you can find others with apt-cache rdepends python-pygame) but also it's good for the kind of interactive graphical art Proce55ing is great at. You can get a blue rectangle on the screen as simply as this:
#!/usr/bin/python
from pygame import *
pantalla = display.set_mode((0, 0), FULLSCREEN)
draw.rect(pantalla, 128, (50, 100, 200, 400))
display.flip()
time.delay(2000)
And work up from there. That's https://github.com/kragen/pyconar-talk/blob/master/helloneg1..., which is one of a series of examples I wrote for a talk on this 11 years ago.8. Godot.
The commitment to this claim is the source of contention.
On "technical enough to write PHP" vs "technical enough to drive a car": there's a much lower barrier to entry for the latter than the former. The latter is about the same as merely operating a computer. Derping around in PHP is def a level above that.
Regardless of theoretical considerations, it's clearly the case that at least hundreds of thousands of people have used PHP without previous programming experience, and from talking to them (and maintaining their code, eugh, and worse, tweaking their servers—via TeamViewer on one occasion) I think the dirt-simple deployment model is a major enabler of that. They don't have to learn about decentralized version control and build processes to get something running.
As I said elsewhere I think a lot of beginners are programming instead in Roblox and hosting their sites on Wordpress or something.
Not saying they are good, but someone starting out wouldn’t ever start installing things like that.
I grew up on PHP, it was the first thing beyond BASIC I ever wrote, and I wrote a lot and enjoyed it so much. It really was this magic thing, that you just modified whatever file you needed to modify, throw it on the server, and hit f5 to see your changes reflected.. No processes to restart, no state to be lost, you jammed, and it was a very gentle way to learn.
Back then the "LAMP" stack was common enough that there were turnkey packages for Windows that setup "LAMP" for you. Was one called Wampp, or something? I forget. At first I liked using a particular proprietary web server for Windows called 'Sambar Server' which made learning easy due to its PHP support and web GUI config editor. Later setting up Apache, PHP and MySQL on a new Windows install became a common habit for me, once I learnt how to do it. I would make PHP websites and host them locally, then show them to people by giving them the IP (and this was over dialup!)
I really wish y'all would stop making me feel old by reminding me that there are now grown-ups who were children when PHP existed.
My current iteration looks something like this, and it is only a few functions to do it (I do use a router library, no point of reinventing that)
return
#[Route(method: 'GET', route: '/projects/{project_uid}/edit')]
#[Template(path: __DIR__ . '/template/template.php)]
function (Request $request, ProjectRepository $projectRepository) {
$projectUid = ProjectUid::of($request->vars['project_uid'] ?? '');
if ($projectUid === null) {
return [__DIR__ . '/../errorView.php', [400, 'Missing project_uid']];
}
$project = $projectRepository->getProjectByProjectUid($projectUid);
if ($project === null) {
return __DIR__ . '/../notFoundView.php';
}
?>
<div class="container">
<h1><?= escape($project->title) ?></h1>
</div>
<?php
};
Attributes is huge imporovemt to writing a small framework, attributes can not only be used for help setting up routing, HTML templating but other things as middlewares, output buffering, dependency injection.I think we should resist the takeover of large frameworks, and the thing is if you are architecting your application properly, it should be framework independent anyway. Unfortunately many ideas in large frameworks makes it harder or at least invites the developer to make the framework takeover the application.
SSI still works, and you can turn it on with Nginx. It's still quite limiting and fragile.
PHP still works, but as your project grows, unless you have equally experienced PHP developers, you'll see things get out of hand quickly with scope issues.
CGI will still work, but similar to PHP, it's a headache to setup the sandbox so a malicious or naive committer doesn't clobber the environment. At least PHP's defaults were pretty sane until someone does something cute and bypasses magic quotes and introduces some SQL injection.
Let's give AWS Lambda some credit though, it's virtualized and containerized CGI and can scale to handle loads that you'd think your backend was written in Elixir.
I think the issue is more cultural than technical to be honest. If you want to learn how to make a website the first thing you're told to do is install node and spin up npm, it's nonsensical. You can't even buy an HTML template anymore, I wanted some nice looking CSS for my website, I searched all over, even bought a few and they all came with 20 scripts out of the box. Even the supposedly pure CSS libraries that advertise themselves as JS-free come with Javascript (just try to make a responsive header in Bulma). It is an insane culture that seems to have forgotten that HTML and CSS are sufficient to implement 99% of what's online today.
With PHP (and other things like classic ASP) the model was the exact same - it's just that instead of an HTML file, you would request a PHP file and then that would be what was run. The output of that file is what the user would see.
With modern-day backend frameworks, that relationship is severed. Your user makes a request, it goes through a bunch of "stuff", and ends up executing a function. How that happens isn't nearly as obvious. It's learnable for sure, but it takes what is a 5 second explanation to something that most brand new developers chalk up to magic for a while.
I think Next.js does this very well, although I'll admit that their "getting started for total beginners" documentation spends way too much time explaining the magic. If I were to throw someone into the deep end to make their own mistakes, as I assume we all did with PHP, I would tell them to git clone https://github.com/vercel/next-learn/tree/master/basics/lear..., and then experiment with "pages/index.js".
Hot reloading that you get out-of-the-box with most JS frameworks is a massive improvement over static HTML, or PHP.
Borrowing liberally from the CSS Zen Garden (still online), or taking a look at the rise of "classless CSS" "frameworks" might be of some benefit to you.
It is a badge of pride to have blue underlined hyperlinks that turn purple if you've been to them before.
The moment your site gets a little bigger you need some kind of routing. This means you start redirecting all requests to one PHP file.
Then you start using forms and you need a database, a little framework for responses, and so on.
So you very quickly need a framework. This can of course be a very small framework.
The point is, small frameworks are so easy to setup you start skipping the 'mildly dynamic website' part because it doesn't scale at all.
Tell that to a non-developer who has a $1 a month shared hosting account who would like to spruce up their website a little bit with (let's say) a visitor counter.
It's pretty basic right now, but can already handle a number of use cases for injecting dynamic content into a mostly static site. (Essentially SSI using css selectors and DOM changes on the server side).
Alas I haven't had much time to work on it lately, but I plan to use it for something at $DAYJOB so it will get some attention at some point.
I want to understand this statement however I only use Lua with haproxy to achieve "mildly dynamic" pages. It is difficult for me to understand what exactly the author wants to do without an example.
Are there any good examples showing that the author is correct, i.e., that it is impossible to "dip in and out" of Lua inside HTML.
Certainly I recall projects that purported to offer Lua as a CGI-like interpreter, "Lua Server Pages", or something similar. Have they not delivered on their promises.
For example, see
http://keplerproject.github.io/cgilua/manual.html
https://fuguhub.com/LuaServerPages.lsp
If there's a distinction to be made, it's that things like mod_php provided this embedded script functionality out of the box, whereas it looks like these things are separate modules that need to be stacked on top of something like mod_lua. That's not necessarily even a bad thing, as it means more of the stack is readily customised, but it does mean people aren't given an obvious, bright path to get started with in the way LAMP was. You have to seek it out for yourself.
I guess the common criticism is "it doesn't scale" but it seemed perfectly fine for me and my needs, and countless others, right up until every major rails project on github was "last updated: 2014". Feels like the rug was pulled out from under our feet. An exodus without cause, an ark without a flood.
I wouldn't use them for most things but I built an email mailing list manager that uses Lambda for several things such as bounce handling, subscribes, verification, unsubscribes, etc.
Sometimes I go (more than a few) months without looking at the system. Then I write a blog post that hits it big and get a few hundred sign ups in a few hours.
If I were trying to deploy the manager as part of a web site the calculations would be different, but as a stand-alone application I dread the thought of running the manager as a cloud instance or VPS. If I ran the system on a really adequate instance it would cost way too much to run. If I ran the machine on an instance I could afford, every six months or so the system would get a burst of traffic, go swap crazy (quit running AND possibly running up an extra $200 a month in EBS I/O charges) and need maintenance to get it back up.
The API gateway for the Lambda function is almost Salesforce.com expensive on a per-request basis but it cheap when you consider the value of an email subscription and that I never have to think about the thing.
We had a tool for this called frames!
Essentially, on those boards, HTML wouldn't be rendered for each request but instead regenerated and stored on each update (POST request etc). The update script would generate a plain html file and store it in the www directory of a static web server, overwriting the previous version of that file. For GET requests, the server simply returned the current version of whatever file was requested.
This allowed the server to employ the full range of optimizations for static files (caching, partial content headers, etc) while still essentially serving dynamic content.
Of course, this kind of architecture makes only sense if updates are rare compared to GETs and if very little of the content depends on individual user identity. However e.g. for blogs or news sites, both conditions are usually given.
If there are small amounts of individualized content, this content could be pulled in via scripts.
I've sometimes pondered generating "static" sites which comprise PHP files, where PHP is only used for the actually dynamic parts. So common headers/footers are regenerated only when changed, but things that change constantly are still dynamic. But this would probably be pointless optimization; if one is using PHP, one may as well use it.
It's been great: I have all the flexibility of a dynamic template engine and a turing complete language running before that. But equally if I want to hardcode HTML then I can. And because it's Rust its still wicked fast (I'm getting 50ms page loads including all assets) and resource usage is almost non-existent (it's running on a VM with 256mb ram).
I run a small laser cutting service for the rocketry hobby. That stack works pretty well for me.
Edit: payments are handled by stripe
Basically if you want an "authentic" experience:
- Install Apache with mod_php and a MySQL (/MariaDB) server. Your distro will probably make this fairly easy (with Debian it's just apt install libapache2-mod-php7, etc., for example). You might need some PHP extensions as well, like for MySQL.
- For more information read about the "LAMP" stack, though keep in mind modern materials will probably encourage you to use some PHP framework.
- Create a file named info.php and put in it "<?php phpinfo();".
- Visit the file on the web server. Congratulations, you've done the classic PHP hello world.
- Have fun doing random stuff. If you want to do anything serious you will probably want to use (or craft your own) framework, but try seeing what you can do with just 'bare' PHP. PHP also has a built in sessions facility which comes in handy in a pinch.
- Remember that going to php.net/FOO does a search of PHP documentation for FOO - they have a 404 handler which does a search for functions. This has been a feature of the PHP website from the very beginning and it's very neat.
- Challenge yourself not to use JavaScript. I'm not even saying don't use it (but definitely do use progressive enhancement), but it's a good exercise to give an impression of when people would have done things on the server side instead.
You might also look at some older PHP web software - for example things like old-style web forums like phpBB, SMF, etc. to get an idea of how things were done.
If you're willing to spend (very few) dollars, you could sign up with a cheapo PHP shared host (they still exist, even if VPSes are big now) and see what you can do with it. (I've used nearlyfreespeech.net in the past, and they're particularly cheap. I have no affiliation with them.) I guess most people probably install WordPress, but back in the day people would craft their own sites in PHP, each with their own character.
And suggesting that there's anything wrong with this is "gatekeeping".