Hacker News new | past | comments | ask | show | jobs | submit login

I've been using PHP since 5.x. Often had to work on older 4.x web apps. I find it interesting when I read people saying "PHP has come a long way. It's a proper language now, etc."

If you work long enough with a language and figure out most its quirks, it's a breeze. It's nice that they are adding all these new features, but they are hardly what makes it or break it for me.

Here is the one features that is taken for granted in "modern stacks":

Edit file -> Alt+tab ctrl+R. Oops, Alt+tab fix -> Alt+tab ctrl+R.

When debugging I can do that 50 times a minute. With my react app, I can do it maybe 5 times a minute. With my golang app I'm lucky if I can do it twice a minute.

I worked with PHP solely for years and always thought the language was good for me but that it made it easy for codebases to go to shit. I’ve worked with half a dozen other languages now and have realized all codebases just suck for the individual because like all things people are heavily opinionated about how the code should be organized.

As for react, I work with a medium sized code base in the hundreds of thousands of lines and all I have to do is alt tab since it hot reloads for me. Don’t see how PHP is any better since it isn’t even hot reloading. Also with react I can update css and it doesn’t lose the state which is nice for debugging style changes.

I wonder how much of the shitty code bases have more to do with the popularity of PHP (for web based applications) than anything else. I've seen plenty of shitty code bases fin just about any language. If there's more of something, there will be more of it that's of low quality.

Not denying your point though. There is some real awful stuff out there that could make a grown man cry.

You can use a live reload tool, e.g. BrowserSync, to automatically refresh webpage after source file change. Put your browser on half of screen if you have big enough monitor, or even better - use dual screen setup. And if your IDE supports automatic saving, you are down to single step: "Edit file".

That's still much slower with JavaScript. We use both in php land.

In Javascript I don't compile or transpile Javascript during development so my src chagens are loadeded in chrome really fast. I suggest you to try snowpack or create your dev code test stream in fashion that do not require src code transformations.

What monsterous golang app are you running that takes 30 seconds to compile?

More interested in what meaningful fixes can be done in some fraction of the 1.2s RTT of this rapid-fire style PHP development.

Output to html, meta refresh page every second. Pretty much real-time results.

> Pretty much real-time results.

This to me feels really underrated nowadays - at best, you shouldn't always have to reason about your code inside of your head and try to figure out how it'll work in detail, or read API docs for all of the obscure frameworks that you're using.

Test things in real time at first and in the cases where they don't, continue doing so, but with a debugger and stepping through everything bit by bit, or read the docs, or whatever the non-trivial cases will demand.

In my eyes, that's the exact same thing as autocomplete in IDEs - instant feedback, to free you from having to think about yet another mundane level of abstraction or API details, instead letting you solve the actual problems that you're faced with.

I think the problem is they haven't set up tools to make it really quick. Even if the compilation only takes a few seconds, they are probably switching to a shell, firing of a make command, maybe restarting the server etc. All stuff that could (and should) be automated and available at the press of a keyboard button. In my emacs setup, any language that requires compilation I bind the key C-c C-c to "build the app now". So then compilation literally takes a few seconds not a few second plus ten seconds of overhead.

With a proper type system you don’t need to run your code 50 times a minute.

Code that passes type checks can also fail to solve the user's problem, make 10,000 database calls, or render a page that is completely unreadable.

The human in the loop is a good thing. All things being equal, the type system is also a good thing, but what usually happens is that you end up checking your page once a minute or once every 10 minutes, not 50 times in a minute. That difference can make or break a project.

It depends a lot on what you're working on. If you are building a front end with PHP as your templating language, then yes, the ability to instantly see your changes is huge. In my experience, when working on back end, the difference isn't that significant because you really want to be using unit tests anyway, not constantly interacting with the front end to test your work. In those back end cases, having a strong type system makes a huge difference.

I'm working on a project that has a legacy PHP code base and a new JVM code base. What kind of naturally happened is that we end up doing most of our front end work in PHP and all of our new backend work on the JVM.

I've rewritten a ton of legacy PHP services / page generation code into NodeJS over the last couple years. I know PHP inside-out and love it the way you love... um, something fugly like an old futon. It's really nice to be working in Typescript on both ends now, to have share modules and data models between server and client codebases. But one thing I do miss about PHP is not needing to make sure the server restarts on every backend code change. Nodemon and PM2 are both pretty good about this, but it's that one out of ten times they don't restart and I spend a minute or two wondering what I missed before realizing they didn't restart; happens a few times a week and drives me up the wall.

Yeah I definitely agree that it's domain specific, and I was really talking about front ends (hence "checking your page").

User interfaces, data science, and security/reverse engineering work are three domains that really require tight feedback loops. The work I did on parsing shell [1] is basically a kind of blackbox reverse engineering, and was done with < 100 ms feedback loops.

[1] https://www.oilshell.org/blog/tags.html?tag=parsing-shell#pa...

And for those cases you should use tests, not a manual procedure.

Of course you will need some manual procedure, and e2e tests, but not “50 times a minute”. That is just frustrating.

Well php has strong typing built in now and they have been iterating on it every release. It's well ahead of native js. I can't imagine having any real complaints on using 8.x php for a back end these days.

I still dislike the constant $ and ->, today it just feels like extra typing. Otherwise I agree with you.

I'm with you. This is the only complaint I have about the language itself.

Trying to imagine php without $ and all I can think is... :o

I never seen any practical proof of that often repeated claim. Unless you define "proper" in an absurd way that has absence of bugs as the part of its definition, I've seen roughly as many bugs and as much time spent debugging in strongly typed languages as I have in weakly typed ones. Sure, some kinds of bugs go away, but they're replaced with different ones.

Just try it out.

I am not saying that a type system will find all bugs. It will stop you from running incorrect code “50 times a minute”. Then you should have tests. Lastly you must also do some manual procedure (or run slower e2e tests).

Doing all this yourself constantly is just frustrating.

I did. I've been doing it for over 3 decades, and worked with all kinds of languages. Of course, it's only my own anecdotal data set, but no, "once you try strongly typed language you'll see how magnificent it is" doesn't work anymore. I tried, and it's not that it's bad - it has its advantages - but it's not the bugless paradise that fanboys promise. And also I learned that running incorrect code 50 times a minute is not bad at all - actually, it's a pretty good rapid prototyping technique. Some people never launch their code until they are sure it's 100% perfect, I am not one of those people.

As someone who isn't perfect, it's nice to be able to quickly iterate on ideas.

You still can. It’ll just stop you before you get to a running web application that may be doing something wrong with the data that goes through it.

Iterating on ideas is much quicker when the compiler tells you when you made a mistake or failed to change your code after changing your mind.

Honestly, I don't see much difference. You learn either way. People may have preferences, that's fine. A compiler isn't a magical tool that creates bug free code.

A compiler with a good type system catches a mistake instantly instead of at runtime.

The difference in time it saves the dev can be anywhere from a few seconds to minutes per mistake.

Multiplied by hundreds of mistakes, it makes a huge difference. And that's not even getting into the advantages of better autocomplete for external libraries.

As someone who has written many thousands of lines of PHP, JS, TS, C#, Java, and Python, I now find it baffling that someone would start a project in 2021 without a great type system as a safety net.

The difference is massive. Computers are many orders of magnitude better at this kind of thing than humans, especially in a large application where changing the shape of a single data structure can have cascading effects throughout the entire code base; you simply will not catch things a typechecker will.

An IDE does provide some help. Certainly, I'm not arguing against compilers. I was merely commenting on the "iterating on ideas is much quicker".

Hello me! Nice to meet me!

Show me a practical type system that rejects all programs with logical bugs.

When working on PHP only I didn’t care at all for the quirks or missing features. When going back and forth with other languages, PHP getting better becomes a huge quality of life improvement, the mental load we need to keep gets much lower.

PHP has always been a powerful language where the burden of making it work properly 250% relies on the dev. Stuff like enums should significantly reduce that ratio, it’s a big deal I think.

On the debugging part, I found something like ruby’s pry to be the easiest and fastest option. I wish PHP had something similar.

Tight feedback loops are a very good thing.

It's probably part of the reason for the success of PHP and similar.

However, being able to have a "compile" step that does a lot of work to make things faster is also very useful. The key is being able to switch between them easily.

In PHP for example there is the code cache (added later but basically standard now), and assuming it's a web app you probably want to crunch the images and CSS in production.

Tight feedback loops are great, but even as an experienced dev, I still make minor mistakes that the ide doesn't pick up, and even with tools like psalm, you will still encounter type error.

One of the reasons I use golang where possible, I feel more productive in golang because any mistakes you are make are almost always logical issues with the code, rather than language error and usually works first time.

> When debugging I can do that 50 times a minute.

In interviewing, I've seen a few candidates re-run their application after making single statement changes. They'll rename a variable, re-run. Change a conditional, re-run. Introduce whitespace, re-run.

These people aren't even confident in renaming variables!

PHP enables this type of underestimation in your own abilities. You don't need to distrust yourself so much.

Don't think you have to do this.

>PHP enables this type of underestimation in your own abilities. You don't need to distrust yourself so much.

That might be true, but sometimes it happens that you overestimated and introduced a breaking change 20 changes ago and now you have to rewind your steps back to find the exact place. If an iteration can be done in less than a second, it's probably cheaper (and less stressing) to just check every single change like this. This is what many coding editor integrations actually do for you.

> PHP enables this type of underestimation in your own abilities. You don't need to distrust yourself so much.

I've even had IDE refactoring tools fail on me whilst doing this, in type checked Java codebases, with reflection in place and annotations, which predictably caused problems down the road. At this point, i'll take any and every method that can help me in development, especially in the face of meaningless cruft and unreasonable complexity.

I'm actually writing this in my 5 minute break after being stuck at work 1 hour past my official work hours, due to some stupid bug where one service ignores a client certificate from service A, but not from service B on the server in containers.

The opposite end of this spectrum (my current circumstances) is completely unreasonable IMO - a change in code needs an app recompilation and a push to the container registry before it's deployed on the server (cannot reproduce locally, possibly proxy configuration is to blame, but it's so simple it should not be possible), whereas configuration changes need the Ansible playbook to run to the end, which also takes time.

Thus, my feedback loop is ~10 minutes for seeing a new way in which the app will fail to do something supposedly simple. Even in normal circumstances, local app reboots still take at least a minute or so, since JRebel and code hotswapping just doesn't work a lot of the time with the frameworks we're using. I'd take being able to see the changes in my code every X seconds over every X minutes any day of the week.

Even if i trust myself, i still want that freedom and speed of development and checking why everything breaks.

>Here is the one features that is taken for granted in "modern stacks":

>Edit file -> Alt+tab ctrl+R. Oops, Alt+tab fix -> Alt+tab ctrl+R.

Yeah, this is pretty much what the Common Lisp and Smalltalk people have been doing since mid 1980s. Except that they're not limited to web applications. And also python people to some extent, with ipython. And Haskell people with ghci.

The value of less friction cannot be overstated in coding work.

> Except that they're not limited to web applications

With PHP, you're not limited to web apps as well. The same rapid-fire style development can be applied when building CLI applications.

That's news to me. Does PHP have a REPL now with module reloading with lingering state?

> Edit file -> Alt+tab ctrl+R. Oops, Alt+tab fix -> Alt+tab ctrl+R.

> When debugging I can do that 50 times a minute. With my react app, I can do it maybe 5 times a minute. With my golang app I'm lucky if I can do it twice a minute.

Hmm... when working on React stuff I don't even have to do the ctrl+R stuff. Hot reloading in the browser is a thing and works quite well. When working with Django it's very close to being the same as the PHP experience thanks to automatic server reloading. I worked with PHP extensively back in the day but I never miss the tight feedback loop (although maybe this experience is why I always make sure I have such a tight feedback loop in whatever I do, I guess you don't always get it by default).

You can do this in Golang as well. Just put all of your business logic inside template/html.

Yeah, you could, but should you? ¯\_(ツ)_/¯

It really depends what you call a language. I find it interesting how developers can be to 3 different things with the word language : the actual language, the language + standard library or even the language + standard + ecosystem. So a sentence like "PHP has come a long way. It's a proper language now, etc." will mean very different things to different people.

The heart of PHP (not the standard library binding C libraries part) do have come a very long way. Even the things that look the same to you on surface have change under the hood and are way more performant thanks to it.

The idea that development in golang is slow is funny.

Same folks say Perl is unreadable because the syntax for certain aspects of the language is unfamiliar to them.

There might be more to it than that...


Going from PHP to jinja templates in python is also pretty terrible. But I guess that's more of a hobbyist problem, than large commercial web-app problem.

Good point. One can read it as "making 50 mistakes per minute", I read it as "wait only 1.2 seconds to see the effect".

Is oopsing 50 times per minute a good thing?

No, not just oops. I get to see the state of the entire application with different values.

If you're doing iterative development, why not.

Less oops and more "let me try this out"

Of course not, it is just a way to show how fast things can go with PHP.

I just run go test. No need for alt+tab. Why reloading anything when testing the backend code?

Perhaps it's not a SPA but has traditional backend-side templates for pages.

What's the problem having a HTTP client running in tests?

Nothing but not really a substitute for looking at the page.

You don’t need to recompile for template updates.

Once you throw that stuff in K8s, you’re back to 10seconds.

If I throw my dinner in K8s, will I get back filet mignon?

Nope, you get Vienna sausage


Do you debug your apps in a K8s environment? Why?

To be clear, I’m not saying this is a good reason, but I’ve been doing it lately because otherwise the browser security features prevent a local auth service from passing tokens to the backend app via the browser. I need to figure out a way around this because the iteration loop sucks; probably I’ll add a flag to disable auth on the backend app so I can test non-auth-things locally.

Sometimes in that scenario my approach is to ssh into the app container and make the changes in there, moving the fix to version control when it is in a shipable state.

Yeah, that’s not a bad idea. I considered that but it seemed like a lot of work to set up the container to run an SSH daemon and work out the forwarding, but maybe I’m overestimating the work involved?

Usually a docker exec will do the trick. I do a lot of that when exploring an application that's new to me - where it keeps logs that don't trickle up to monitoring and stuff like that.

If you find Emacs in a container, it's probably me ;-)

I don’t think that would work because you would need to drop in the new binary and restart the program and as soon as you kill the program it will kill the container and bounce the pod. Moreover, my app is just a static binary with some certs on a scratch image, so I can’t even `kubectl cp` the binary because that depends on a tar binary on your container.

I think I would need to run some sshd program on the binary and use a reverse SSH tunnel from my laptop, but that requires me to expose an SSH port on the pod which isn’t a big concern, but it’s just a grind to get it all working end to end.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact