[HN Gopher] Upcoming Hardening in PHP
___________________________________________________________________
Upcoming Hardening in PHP
Author : mmsc
Score : 304 points
Date : 2024-11-06 15:18 UTC (9 days ago)
(HTM) web link (dustri.org)
(TXT) w3m dump (dustri.org)
| ChrisMarshallNY wrote:
| _> I find it fascinating that people are putting so much efforts
| optimizing exploitation techniques, yet ~nobody bothers fixing
| them, even if it only takes a couple of lines of code and 20
| minutes._
|
| There's definite reward in having a 0-day. Either you can get a
| bounty, or sell it in the hacker-souk.
|
| That "couple of lines of code and 20 minutes" is sort of in the
| eye of the beholder. If you are a highly-experienced language
| developer, the fixes are likely to be a lot more obvious,
| simpler, more comprehensive, and robust, than if you are a
| relatively junior IC.
| maple3142 wrote:
| I think it is probably because a lot of things are deemed as
| acceptable. For example, the stream filter chain one is only
| exploitable if the input to some php IO functions like
| file_get_contents are attacker-controlled, and those things are
| already treated as LFR vulnerabilities in application, not the
| language runtime. Also some of the them (e.g. stream filter
| chain) are fun and useful enough (turning LFI into RCE), so I
| bet there definitely some people would rather those thing is
| not fixed. Given that a properly-secured application wouldn't
| be affected.
| eru wrote:
| Well, you can produce the exploit all on your own and showcase
| it.
|
| But to get your fix in, you'd have to interact with the PHP
| ecosystem.
| est wrote:
| Breaking something is easier than protecting everything from
| all fronts.
|
| Hackers write the worst code, but all the mess needs only _one_
| successful hit to become a 0day.
| blueflow wrote:
| Instead of making a website about it, you can take any step
| of your exploit chain and change the code that exploit cannot
| possibly work, and submit that as patch. You would still get
| a CVE number assigned that you can add to your resume.
|
| For example, look at the glibc/iconv CVE some other user
| posted[1]. In the section "Out-of-bound write when converting
| to ISO-2022-CN-EXT" they have mapped out the boundary checks.
| By diagnosing the problem this detailed, they already did 90%
| of the work. The other 10% are the patch and writing to the
| mailing list.
|
| [1] https://www.ambionics.io/blog/iconv-cve-2024-2961-p1
| frogsRnice wrote:
| Making a website about it benefits other people; finding
| the vulnerability helps other people; even if its 10%, why
| can't someone else do it?
|
| Surely someone doing all this would already have submitted
| a patch if they felt comfortable.
| PaulRobinson wrote:
| I think if somebody wants to describe themselves as an "ethical
| hacker", and a conference wants to let people talk about
| exploits they've found, the minimum bar for disclosure is at
| least a description of a mitigation that could be taken, and
| ideally an actual code diff if its an open source project.
|
| There's a bit of street cred for finding a 0day, a bit of
| glamour about figuring out the puzzle. There's not much for the
| person who fixes it. I think as an industry it might be worth
| trying to fix that somehow.
| calvinmorrison wrote:
| Selling hacks is ethical
| berkes wrote:
| Why? And: Always?
| PaulRobinson wrote:
| Let's suppose you are right. Why not accompany that with a
| proposed fix, too?
| frogsRnice wrote:
| Don't necessarily agree that selling hacks is ethical,
| but if I already spent time figuring out how to exploit a
| system - reporting it to the relevant place is charity.
| Ill do that, but Im definitely not spending time trying
| to fix the code if the solution isn't immediately
| obvious. ++ so if you have to fight to get the bug
| recognised in the first place
| SoftTalker wrote:
| I actually agree, in the same way that selling lock picks
| or guns is ethical. They are just tools. How they are used
| is the responsibility of the person wielding them.
| bigyikes wrote:
| I can think of benign uses for lock picks and guns. What
| is the benign use of a secret exploit?
| bratwurst3000 wrote:
| it doesnt have to be secret. for example unlocking old
| phones. There are certainly people waiting for the right
| exploits to get access to their old wallet.
| username44 wrote:
| One example I can think of is the WoW private server
| Warmane uses an RCE to extend client functionality.
|
| https://www.reddit.com/r/wowservers/comments/1eebxwf/warn
| ing...
| SoftTalker wrote:
| You've never needed to get root access on an old computer
| when nobody knows the password?
| pjmlp wrote:
| When liability and cybersecurity laws start being more hardly
| enforced, many companies will certainly bother to fix them.
|
| It like no one cares to keep a kitchen clean, or a factory in
| order, until the inspection shows up and closes doors.
|
| Naturally even for those, we are at various levels of how those
| inspections are honestly enforced across the globe.
| mgaunard wrote:
| The real question is why does PHP have so many bugs that it's so
| trivial to exploit?
| craigmcnamara wrote:
| Seems like an attitude problem.
| that_guy_iain wrote:
| Honestly, the development of the PHP core has always been
| rather amateur. From historically just adding features whenever
| to know adding hundreds of breaking changes per minor release.
| This results in a terrible codebase and a language where
| upgrading minor versions is so painful and costly for some
| firms they end up stuck on old version.
|
| The last part makes the fact their could be massive security
| holes like RCE in the core language very worrying.
| ipaddr wrote:
| Historically they have been one of the languages that added
| very few breaking changes and were criticized for that. You
| can't have it both ways.
|
| Going from php 4 to php 8 isn't even that painful and there
| are twenty years between. It's the one language where what
| you wrote 20 years ago probably still works today.
|
| Upgrading a php application is one of the least expensive and
| uneventful things you can do. Try upgrading that java swing
| application or that react app that's 15 months old. Go,
| haskell, vue, python 2 to 3 are more difficult because of
| syntax changes where in php you have some breaking changes
| like globals being removed or ereg removal or mysql_ being
| removed. The changes were small like using mysqli instead of
| mysql or using preg instead of ereg.
| JodieBenitez wrote:
| Surprised to see Go in your list though.
| that_guy_iain wrote:
| My complaint was adding lots of breaking changes to minor
| version upgrades. The fact, that historically they didn't
| do breaking changes in major version upgrades does not
| excuse going against industry standards.
|
| There are literally companies stuck on PHP 7 because going
| to 8 is too painful. And honestly with my decade of
| experience your claim that going from 4 to 8 isn't that
| painful sounds like nonsense and something you haven't
| done. And the claim that php 4 code will work on php 8 is
| 100% nonsense. The syntax for how classes were defined in 4
| is not supported in 8.
|
| I've upgraded the code to the major versions of other
| languages without hassle. But they generally had fewer
| breaking changes in their major versions when I upgraded to
| Vue3 which was super painless.
|
| And can you point to a minor upgrade where Go changed the
| syntax to the point the old one no longer works? With Go
| normally it's the tooling that changes. I can't remember
| the syntax changing on me. Especially since they have a
| Compatability Promise[1] it seems weird.
|
| [1] https://go.dev/doc/go1compat
| hparadiz wrote:
| Like everything... It depends.
|
| Just use rector
|
| https://github.com/rectorphp/rector
| that_guy_iain wrote:
| I've previously used that to do something. Fell flat on
| its face. But the fact they literally had to create a
| tool to solve this problem confirms my point.
| hparadiz wrote:
| I use it all the time and it works great. You need to
| know what you're doing.
| that_guy_iain wrote:
| So again, you seem to be confirming my point that it's
| not fool proof.
| kgeist wrote:
| Our best engineer spent 2 weeks full time updating our
| codebase from 7 to 8 using rector (the project was
| already running PHP 7 but still had a lot of deprecated
| code from the PHP 5 era which didn't work on PHP 8). That
| would be eternity without Rector.
| chx wrote:
| You are right, going from 4 to 8 is a huge challenge.
|
| Minor point: classes are using the same syntax _but_ you
| are right they typically won 't work because the
| constructor have changed, in PHP4 it was a function named
| the same as the class, in PHP5 and on it's __construct,
| the PHP4 version was deprecated in PHP 7 and removed in
| PHP 8.0.
|
| create_function is just gone. So is each(). Oh and
| HTTP_RAW_POST_DATA. The list is long.
|
| If you have used == and in PHP4 we did that, come on,
| don't be holier than holy and claim you only used === in
| PHP4 then PHP8 will have some surprises for you.
|
| In my experience rector became usable last year-ish, if
| you tried before, give it another whirl.
| arkh wrote:
| > There are literally companies stuck on PHP 7 because
| going to 8 is too painful.
|
| Usually due to frameworks. Those tend to do play fast and
| loose with language constructs so small changes can make
| them not work anymore. And as those same framework will
| also break a lot more things between version, you cannot
| easily upgrade them, so you cannot upgrade your php
| version.
|
| Currently maintaining an internal symfony 1 website so I
| know the pain. At least the documentation of old symfony
| is still available unlike many more modern frameworks.
| ChrisMarshallNY wrote:
| There's a system that I started working on, in 2008, when a
| lot of hosting outfits were still running PHP 4. It's still
| running now, but I think one of the current maintainers
| rewrote a lot of it with Laravel, recently.
|
| I know that they were still using the old code, just a year
| or so ago, on PHP 8.
| mgkimsal wrote:
| I had code I wrote for someone in 2002 (php4) still
| running in 2017 (php 5.x). It broke trying to go to 7,
| and it was a small area that broke. It was core, so broke
| everything, but it had to do with re-assigning of $this
| at runtime. I think in 5 it was complaining about it as a
| warning, but no one was looking. Had I/we been stricter
| about the use of $this back in 2002, that code might
| still be running today. Doesn't mean it _should_ or
| wouldn 't be faster if rewritten with newer language
| features, but ... it had a good run for 15 years.
|
| EDIT: Was reminded of another site started in 2000 (start
| of PHP4) that is still running. I can only see the login
| page now, but I see the login page is still displaying a
| particular URL structure that was/is slightly uncommon.
| If they kept _that_ but rewrote the entire thing
| internally... that would be odd, because it would be
| easier to rewrite the whole thing. I 've no doubt they've
| upgraded some internal parts, if only to accomodate new
| business needs over the past 20+ years (I stopped working
| with this project in 2003?) but it's still up and
| running.
| mgkimsal wrote:
| Somewhat contrary to my own comment below, migrating PHP
| upwards _can_ be painful, but some of that stems from who
| 's involved. I'm brought in on PHP upgrade projects, and
| often the code is 10+ years old, and _no one who wrote it
| is still around_. There 's typically no documentation, no
| tests, and little historical knowledge.
|
| Now... that's also a problem in other languages too, but
| I've found it less so with something like... older Java.
| Because there are some things that are completely gone from
| earlier PHP, if people relied on those bits 15 years ago,
| there's potentially a lot of code touching that needs to
| happen.
|
| My experience is there's less deprecation of language
| features in older languages (mostly thinking of Java).
| There were perhaps less 'wonky' ways of doing dynamic Java
| stuff in 2006, so 2006 Java will still work today. 2006 PHP
| _can_ work today (see comments below), but the more
| 'advanced' your PHP was the more at-risk it will be when
| trying to upgrade to, say, PHP 8.x.
|
| The other big thing, though, is frameworks. The more you
| tied your code to, say, ZF1, the bigger an upgrade effort
| will be (sometimes far bigger than expected). I've been hit
| by this a couple times in the last few years.
| esskay wrote:
| > From historically just adding features whenever to know
| adding hundreds of breaking changes per minor release.
|
| Should be noted that it stopped being the case close to a
| decade ago now. Since PHP 8 things have changed a lot and
| it's a significantly better platform, both in terms of usage
| and the people behind it.
|
| PHP spent a long time running on fumes with little backing.
| It's now got huge financial backing from Jetbrains, Wordpress
| Symfony, Laravel etc and theres now people paid to work on
| it, which has dramaticly improved the quality and quantity of
| improvements, which are mostly focused around performance and
| bug fixes.
|
| The performance gains arent just figures on paper either.
| There was a real world improvement of around 12% on PHP 8.3
| alone.
| ChrisMarshallNY wrote:
| Doesn't Facebook still run most of their backend on Hack[0]
| (compiled PHP subset)?
|
| [0] https://hacklang.org/
| Shish2k wrote:
| Hack is only PHP in a very ship-of-theseus sense - it has
| PHP _vibes_ but they replaced the language, the runtime,
| the standard library, and all of the infrastructure
|
| (and all of them much improved over PHP IMO - especially
| XHP [equivalent to JSX, where HTML is a first-class
| citizen in the language syntax])
| that_guy_iain wrote:
| I think the fact Facebook decided to just fork that
| language instead of improving it shows how bad the core
| development was. The internals newsletter was just
| brutal. I remember reading a thread from a Facebook dev
| asking who quietly just reverted his commit. No
| discussion, no nothing, the code was just reverted if
| someone didn't like it.
|
| I really think that was a major misstep by the project.
| ChrisMarshallNY wrote:
| _> I really think that was a major misstep by the
| project._
|
| Oh, yeah.
|
| As someone who has written and maintained a lot of
| "infrastructure-level" stuff, I have come to learn that
| releasing a project that serves users, or is
| infrastructure for other projects, is like having
| children.
|
| Making them is fun. Releasing them, is a pain, but, once
| they are out there, it is my Responsibility to support
| them, and accept that they have their own agency.
|
| I can't just go in and pretend that I'm Lord Farquaad,
| and treat the project as if it's my private fiefdom. It's
| now a public resource, and my decisions and actions
| affect a lot of others. I also tend to write software
| that supports folks with a rather ... _pithy_ ...
| demeanor, so screwups can result in not-pleasant
| feedback.
|
| That's a big reason why I don't mind that most of my
| public repos aren't popular.
| that_guy_iain wrote:
| > Should be noted that it stopped being the case close to a
| decade ago now. Since PHP 8 things have changed a lot and
| it's a significantly better platform, both in terms of
| usage and the people behind it.
|
| The breaking changes section of UPGRADING file for PHP 8.4
| is over 200 lines. For 8.3 it was over 100 lines.
|
| And when it went to version 8, there was only 1 full-time
| developer working on it and as far as I know 0 part-time.
| The rest were volunteers doing it as a hobby. That full-
| time developer who was paid by Jetbrains decided he wanted
| to work on another project. This resulted in the next
| release being pretty much nothing. At which point, everyone
| realised this language went from funded to not funded and
| they created the PHP foundation.
| tored wrote:
| Since PHP introduced the formal RFC process for changing the
| language things has become much less cowboy and much more
| professional.
|
| Typically it is features before that causes problems.
| phplovesong wrote:
| Historically is has been an skill issue. It seem it persists
| even today
| urban_alien wrote:
| Are these issues very particular to PHP? Honest question, this is
| all above my current programming knowledge.
| wbl wrote:
| Yes. Most languages don't have anything like the filter
| notation for arbitrary reads to escalate through.
| metadat wrote:
| The linked _CVE-2024-2961_ article is a pretty fantastic read on
| its own:
|
| https://www.ambionics.io/blog/iconv-cve-2024-2961-p1
|
| People are so creative, I can't help but feel some hope for our
| future :)
| MBCook wrote:
| That's for that. I've never seen it before. What a neat path
| they took.
| 1oooqooq wrote:
| i find it boring. because it's very obvious whoever added
| php://filter was clearly just adding exploit paths (java
| flavored ones no less). there's zero valid use for that thing.
| talkin wrote:
| Yes. Just like the Log4j issue root cause. Too powerful and
| abstract features to wield securely.
|
| Or maybe if we keep intent out of it; features were added in
| a time when we all worried less about security and internet
| implications. I would like to say 'in the security dark ages'
| but we are probably still in that era. ;)
| marcosdumay wrote:
| What a perfect shit-storm!
|
| - What people are saying about the filter protocol, and
| anything else that interprets the files.
|
| - Why do people insist on making all remote file protocols
| transparent? Fuck that, a file is a file! If you want to
| support some remote stuff, do that on the OS, where it's opt-
| in.
|
| - And PHP keeps insisting it's not a web framework while being
| a web framework. So it has no access control around local file
| reading, while clearly designing it to be used in a way where
| only a few directories should be accessible.
|
| - A buffer overflow in glibc, go figure... But yeah, C is
| perfect and the only issue is that the devs don't know the
| language well enough or there aren't enough people reviewing
| this niche library.
|
| - Didn't everybody decide to ditch the pre-unicode encodings
| from the standard tools? I remember the announcement (that was
| supposed to include glibc), it made a lot of people angry.
| Those have been an endless source of CVEs.
| justinclift wrote:
| > Suggestion to make those parts read-only was rejected as a 0.6%
| performance impact was deemed too expensive for too little gain.
|
| Big Oof. :( :( :(
| ipaddr wrote:
| I'm okay with the tradeoff. PHP prioritizing speed over
| uncommon security is the right call here.
| dev_hugepages wrote:
| missing /j
| bigtimesink wrote:
| At a large PHP shop, 0.6% can be tens of millions of dollars.
| kortilla wrote:
| Over what time period? You're implying they are spending at
| least a billion dollars on hardware costs for 0.6% to be tens
| of millions.
| Tepix wrote:
| At a large PHP shop, a successful exploit can be the end of
| the company.
| 1oooqooq wrote:
| almost everyone have all the things required for those
| exploits disabled.
|
| why would i accept performance penalty if i don't allow
| open('https://google.com') to begin with?
|
| the correct action would be to remove all the stupid
| features everyone serious disable to begin with.
| justinclift wrote:
| No doubt there. It's just that providing a secure platform
| seems a tad more important.
| pier25 wrote:
| PHP is a bad choice to begin with if your use case is _that_
| performance critical
| phplovesong wrote:
| PHP has always ben slow, its getting slightly faster, but still
| REALLY, REALLY slow for anything CPU heavy. This is why the ML
| crowd sticks with Python (numpy) thats incredibly fast.
|
| PHP is still lacking, there is no unicode support, and for a
| web language this is really bad. Also, the way PHP functions,
| makes modern web (like websockets) use impossible, there is
| hacks around this but they all kind of suck.
| chippiewill wrote:
| Actually PHP itself is very fast compared to Python,
| especially for an interpreted language.
|
| Python only seems fast because all the heavy duty number
| crunching libraries are actually written in C.
| phplovesong wrote:
| Yet, just a pip install away. In PHP this is not possible.
| johnisgood wrote:
| Just a composer require away.
| nucleardog wrote:
| http://pecl.php.net/packages.php
|
| `pecl install Tensor`?
| talkin wrote:
| This comment and all siblings fight over PHP vs Pyhton etc,
| but that just isn't the bottleneck in most apps.
|
| By far, for most apps, the biggest bottleneck is the
| database.
| larsnystrom wrote:
| I'm pretty sure this is wrong. PHP has been faster than
| Python for a long time, but numpy is not written in Python,
| it's written in C. Just like PHP, coincidentally :)
| Kwpolska wrote:
| Python is also written in C.
| phplovesong wrote:
| Its not wrong, numpy is a pyrhon package (written in c) but
| you can USE it just with an pip install.
| PaulRobinson wrote:
| Python is slower than most of the horses I bet on. That's
| pretty slow.
|
| The important - CPU intensive parts - of numpy, pandas,
| pytorch, and all the other "fast python" libraries out there,
| are actually written in C.
|
| Pure python should not be used for anything that requires
| good performance: it is programmer ergonomic, not CPU
| ergonomic. It is great that through the use of FFIs it has
| access to powerful libraries written in a language that isn't
| slow, but that does not make it as a language itself, fast.
| phplovesong wrote:
| Thats my point, pyton the is one of the slowest languages,
| and still have high quality, high perf libraries like
| numpy. PHP has no way to install deps that actually are
| written in asm/fortran or c.
| Dachande663 wrote:
| PHP still has PECL[0] which is a huge collection of C
| extensions.
|
| [0] https://pecl.php.net/
| arkh wrote:
| > PHP has no way to install deps that actually are
| written in asm/fortran or c.
|
| https://www.php.net/manual/en/book.ffi.php is not enough
| for your needs?
| ChrisMarshallNY wrote:
| I tend to use PHP for my backend work.
|
| In my experience, it's actually _very_ fast. That may be
| partly because of the way I write the code, though, and my
| backend code isn't really too massive.
| 0points wrote:
| > This is why the ML crowd sticks with Python (numpy) thats
| incredibly fast.
|
| That is not why.
|
| You stick to python because it's your common denominator. You
| all picked it up in school.
|
| Python the most popular language around, and one of the
| slowest.
| cess11 wrote:
| PHP has decent FFI, nothing is stopping you from using the
| same libraries as you would with Python. Here's someone's
| quick hack as an example: https://github.com/dstogov/php-
| tensorflow
|
| For an interpreted language PHP itself is ridiculously fast
| and the VM is rather small so you can use something else
| _cough_ Elixir _cough_ for parallellisation. I use it all the
| time for data wrangling stuff and database imports because it
| 's robust, fast and PsySh is a pretty neat environment.
|
| The array data structure is quite nice too. It's built on
| simple parts that are foundational to the VM itself, and very
| flexible, similar to lists in Lisp-like languages but without
| the seek lag when data grows due to the indexing.
| acomjean wrote:
| PsySh
|
| I'll have to check this out.
|
| Though not popular php can be a surprising decent scripting
| langauge.
| dylan604 wrote:
| There were many many times I'd start writing a bash
| script, but then switch it to a PHP script. I've done
| this so many times that now I just start writing in PHP.
| cess11 wrote:
| https://psysh.org/
|
| It's very popular, as in a lot of businesses use it, it's
| just not fashionable.
|
| I think it's a great tool to have. It had gradual typing
| before it was cool. You can type in like a page of code
| including the layout and render whatever in a PDO-
| supported database on a web page, served by the builtin
| web server, which is great for data exploration and
| things like SQL optimisation. At the moment I'm handling
| some data flows and conversions in a project with
| something like a terabyte of email and office documents
| that need to go into RDBMS, because there are some
| liberally licensed lightweight libraries (in contrast to
| the bulky stuff in Jakarta-land) and the performance is
| good enough to not be a bottleneck.
|
| Edit: And when a library isn't good enough, I can usually
| trivially fix or extend it because it's in a familiar
| language and written by a simple minded person like
| myself.
|
| There's a degree of clunkiness and incoherence in built-
| in API:s that might be off-putting at first but the
| included batteries and PsySH make for a quite decent tool
| anyway.
| EZ-E wrote:
| > I find it fascinating that people are putting so much efforts
| optimizing exploitation techniques, yet ~nobody bothers fixing
| them, even if it only takes a couple of lines of code and 20
| minutes.
|
| Like it or not, exploiting seems just more fun and rewarding. A
| lot of people will be interested to learn on your blog how you
| came to find and exploit a vulnerability. The 10 line of code
| patch gets little attention. Not even taking into consideration
| bug bounties...
| Tepix wrote:
| Exploiting is mainly much, much _harder_. Programmers are
| pretty good at preventing the obvious exploits so the gaps left
| to exploit are the tricky ones.
| p4bl0 wrote:
| Something I'd really like is for PHP to somehow be stricter on
| the number of arguments passed to a function.
|
| As of now, PHP emits an error if arguments are missing but not if
| there are too many.
|
| A way to bake that in without breaking old code would be to allow
| function definition to put an explicit stop to the argument list,
| for example using the void type keyword:
| function foo (int $a, string $b, void) : bool { ... }
|
| A few month ago I discussed this on the development mailing list
| and people seemed to agree and even suggested that this would be
| a good idea by default without the keyword thing I suggested. But
| I never got the time to properly write an RFC. There is already
| an old one from years ago that was voted against but In was told
| it was from before anything strict and typing related was
| considered important in PHP. If anyone's up to it, please write
| this RFC :) !
| MH15 wrote:
| I'd be curious to read about what percentage of active PHP devs
| use the recent features. The last time I worked in a PHP
| codebase (2020?) was half PHP 5 (bad) and half PHP 7 (much
| nicer). Curious if there's any real info out there on this
| zuppy wrote:
| php 7 has been released 9 years ago.
| noduerme wrote:
| Yeah, and I just finished porting an enormous amount of
| production code from PHP 5 to 7.x before fully moving it to
| 8. There are so many breaking changes in each major
| version, when you have a lot of live projects and clients
| don't have the budget to pay you to upgrade them, they can
| lay stagnant for years until way past EOL. It would have
| been nice to know, for instance, that future versions of
| PHP would throw warnings about undeclared variables or
| unaccessible named properties of "arrays" - which could
| previously be relied upon to be false-ish. That's a major
| pain point in code bases that treated arrays as simply
| dynamic objects that could be checked or defined at will.
| Lots of isset() and !empty() and other BS. Fine, but it
| takes time to sit down and check it all. I really preferred
| it when it let you just screw up or try to access a null
| property or define a variable inside a block and access it
| later without throwing any errors at all. Nothing about its
| actual functionality has changed in that regard; it's just
| errors you have to suppress or be more verbose to get
| around. In PHP 8 you can still do this:
|
| `if ($a) { $previouslyUndefined = 2; } if
| ($previouslyUndefined) { echo "yeah"; }`
|
| PHP still _knows_ what $previouslyUndefined is or isn 't at
| the second _if_ statement, but it 'll throw an error now in
| the first statement if you hadn't declared it outside the
| block. Why? Who cares? Scope in PHP is still understood to
| be inline, not in block; there is no equivalent to _let_ vs
| _var_ in JS. Stop telling me where I can check a variable
| if you 're not enforcing various kinds of scope.
| zerocrates wrote:
| Your $previouslyUndefined thing as something that's
| changed, as far as I know, isn't true? Unless I've missed
| some very recent change.
|
| If $a is true, that snippet will just execute with no
| errors. If $a is false you'll get a warning trying to
| check $previouslyUndefined in the second if. That
| behavior's been the same for a very long time. The blocks
| don't matter for scope but the fact that you never
| executed the line that would have defined the variable
| does.
|
| Similarly, warnings on accessing array keys that don't
| exist, that's been a thing forever too. Pretty sure both
| go back with the same behavior to PHP 4, and probably
| earlier.
| asddubs wrote:
| >Why? Who cares?
|
| I do, if I typoed previouslyUndefined the first time. I
| get it adds boilerplate, but it also catches stupid bugs
| reddalo wrote:
| The Laravel ecosystem folks seem to be always up to date in
| recent PHP developments. At least, that's my impression.
| naiv wrote:
| Symfony also does a great job adding polyfills way ahead of
| a PHP release , eg https://github.com/symfony/polyfill-
| php84
| withinboredom wrote:
| Yes, and this is incredibly annoying. Many packages add
| them as a dependency, and then you get subtle bugs
| because of it. Or worse, they add a dependency for the
| polyfill that is related to an extension and suffer
| performance issues when the extensions are not installed;
| yet no warning is output.
| chx wrote:
| Drupal is very hot on attributes, has fiber support, uses
| readonly (a PHP 8.2 feature) extensively, enums are used --
| overall it's fairly up to date.
| post_below wrote:
| PHP 5 is as close to phased out as it gets at this point. No
| doubt it's still in a lot of legacy enterprise codebases
| (lots of breaking changes going from 5 to 7 or 8), but
| outside of that no one is using it.
| tored wrote:
| I work on multiple projects from PHP 5.2 to PHP 8.3 and
| everything in between.
|
| Statistics based on packagist(composer)
|
| https://stitcher.io/blog/php-version-stats-january-2024
|
| Statistics based on web servers in the wild
|
| https://w3techs.com/technologies/details/pl-php
|
| https://w3techs.com/technologies/history_details/pl-php
| withinboredom wrote:
| I don't really understand the issue. Already if you have a
| mismatch, the only way you'd ever know is through static
| analysis. It will run and maybe crash during run time. I always
| joke that changing a function signature is the single most
| risky thing you can do in php (especially if you have any
| dynamic dispatch). Making it even more risky isn't the right
| answer, IMHO.
|
| Oh, and doing this would literally break class autoloading in
| symfony, and even the engine itself, which relies on this
| feature.
| p4bl0 wrote:
| > the only way you'd ever know is through static analysis
|
| Not for builtin PHP functions which already throw errors on
| arity mismatch.
|
| > this would literally break class autoloading in symfony,
| and even the engine itself, which relies on this feature
|
| I don't understand. Could you point to where in the Symfony
| code it relies on being able to wrongly call a function with
| more arguments than it expects and will use?
|
| For variadic functions there is the ... operator already in
| the language since version 5.6, and my proposal wouldn't
| break that. Also note that builtin functions already emit
| deprecated warning in PHP 8 when called with too many
| arguments.
|
| Here is the full thread discussing it on the PHP internal
| mailing list: https://news-web.php.net/php.internals/122928
| notresidenter wrote:
| You should look at `func_get_args()` usage in the wild.
| This is sometimes used for (mostly outdated) good-enough
| reasons and doing this might break it?
| p4bl0 wrote:
| I know of func_get_args, but proper variadic functions
| have been a thing since PHP 5.6 (released more than 10
| years ago) using the ... operator. Also, my initial
| proposal doesn't break existing code :).
| withinboredom wrote:
| Variadic functions serve a purpose but also change how
| the engine parses arguments. func_get_args is faster and
| more efficient.
| 0points wrote:
| IIRC, that's how symphony and other php frameworks do
| dependency injection.
| withinboredom wrote:
| > Not for builtin PHP functions which already throw errors
| on arity mismatch.
|
| It still only happens during run time. Having a never-
| called function with an incorrect number of arguments is
| not an error.
| p4bl0 wrote:
| Of course! And I strongly agree that static analysis is a
| good thing. But PHP still is a dynamically typed language
| and most of its development and usage is done with this
| dynamic approach in mind. It's not a XOR either, we can
| have better dynamic error reporting AND develop better
| static analysis tools at the same time.
|
| Also, due to the nature and usage of PHP, some things
| cannot be statically analyzed because they're inherently
| dynamic. A simple example would be MVC frameworks where
| the routing is done like so:
| /controller/action/param1/param2/param3 where
| "controller" references a class and "action" references a
| method, which will take the "paramN" as arguments through
| the splicing of an array: `$ctrl->$actn(...$args);`. In
| such situations it would be nice to have
| errors/exceptions raised automatically if the URL is
| wrong (not enough OR too much arguments) without having
| to manually assess everything inside each method. Since
| PHP 7 and 8 over we're moving away from long lines of
| isset() and !empty() (and verifications such as
| is_numeric() etc. thanks to argument typing).
| talkin wrote:
| To be specific about static analysis: Lots of tools catch
| this. Sure, making some checks native would be nice, but for
| instance PHPStan always catches this, and more.
|
| Regardless of the 'improve the language angle': Is somebody
| isn't running PHPStan (or Psalm, Sonar, etc), then they're
| missing out.
|
| PHPStan is currently so good that using it should be non-
| negiotable. So the question would then even be: "I'd like
| rule 123 of the tool to be native, we helps with the RFC?"
| withinboredom wrote:
| I find these tools to not be too useful. The things they
| catch is like trying to force it to be an entirely
| different language, and don't actually help with
| maintaining code. Then again, I'm usually writing low-level
| libraries that take advantage of quirks in the language for
| performance: $a = &$arr[]
|
| Gives you a reference to null and appends it to the array.
| Then you can pass $a to something to mutate the tail "from
| a distance". Most people never need this, nor should they
| use it. But when you are writing a streaming parser, it is
| quite handy as a one-liner instead of writing
| $a = null $arr[] = &$a
|
| or keeping track of the current index and dealing with off-
| by-one errors.
|
| For applications, these static analysis tools are great.
| For libraries, not so much.
| Cthulhu_ wrote:
| It might be too big a change on a language level given this has
| been in since forever, but it might be picked up by static
| analysis / a linter. I'd argue it's always better to have
| additional protections like this in a linter as the process of
| adding linter rules is easier and less impactful than making a
| language change.
|
| It's also always preferred to _not_ add anything to the
| language imo; in this case, I 'd opt to have the interpreter
| emit a warning or info message. It's not broken, it's a
| developer error.
| p4bl0 wrote:
| Indeed on the PHP internals mailing list some people were
| saying that it would be better to entirely deprecate passing
| extra arguments to a non-variadic function, without adding
| syntax/keyword to the language.
| Ayesh wrote:
| FWIW, core PHP functions do throw an ArgumentCountError when
| passing fewer OR more parameters than the signature allows.
| p4bl0 wrote:
| Yep! And currently the behavior is not consistent with user
| defined functions.
| rkharsan64 wrote:
| Somehow people seem to be missing the fact that this would've
| been an opt-in feature.
|
| > A way to bake that in without breaking old code would be to
| allow function definition to put an explicit stop to the
| argument list, ...
| mklepaczewski wrote:
| I'm not a fan of the void argument syntax. Wouldn't something
| like the code below work? We already do it with
| `strict_types=1`.
|
| <?php declare(strict_args=1);
| tored wrote:
| Mark the function with an attribute to allow the old
| behavior. See link for similar use case.
|
| https://www.php.net/manual/en/class.allowdynamicproperties.p.
| ..
| mklepaczewski wrote:
| Yup, that's even better.
| p4bl0 wrote:
| That's equivalent to my initial proposal, except that
| mine adds the information in the type signature of the
| function rather than in a decorator.
| tored wrote:
| If I understood your proposal correctly, to get the new
| behavior add an explicit stop to the function, my
| proposal add attribute to keep old behavior.
|
| Thus if understanding this right that would require to
| update every function signature to new behavior rather
| than marking a few functions to get the old behavior and
| automatically get the new better behavior of every other
| function for free.
| p4bl0 wrote:
| Oh okay, you would do it in reverse. I strongly agree
| with that. But that means the new feature is opt-out
| rather than opt-in, and it may break some old code. Maybe
| it should be done in two-steps (opt-in + deprecation,
| then opt-out).
| tored wrote:
| Typically you emit E_DEPRECATED for a full major version,
| then in the next major version you throw an error, e.g if
| it would land in PHP 9.0 then E_DEPRECATED for non-
| compliant functions and in PHP 10.0 start throwing
| errors.
| noduerme wrote:
| I think this would be nice ergonomically, from a coding
| perspective, but I'm curious as to how it would be a security
| threat to pass too many arguments. What's the potential exploit
| here?
| p4bl0 wrote:
| Exploit I don't know, but as any stricter type verification,
| it would catch some bugs for sure. Note that builtin
| functions already throw an ArgumentCountError when passing
| fewer OR more parameters than the signature allows. My
| proposal consists in (optionally in a first place) make this
| behavior consistent for user-defined functions.
| noduerme wrote:
| The trouble for me, where the rubber meets the road, is
| external API calls that spread their arguments into a PHP
| function that takes a bunch of args. So I would love a way
| to detect if they're sending too many, which I don't think
| currently exists (?) but not at the expense of breaking the
| API if they actually _do_ send too many.
| bwoebi wrote:
| One of the main advantages of actually allowing more arguments
| is forward compatibility:
|
| You can, within a library, provide an additional argument to a
| callback without actually introducing a BC break for all users.
|
| My favorite approach would be allowing too many args on dynamic
| calls (closures, and function calls with dynamic name, not
| method calls in general) and otherwise rejecting it.
| berkes wrote:
| There's no need to have this in the language just to solve
| the case you describe.
|
| "function current_thing(id: Int, callback: Fn(Int)) {}" and,
| when you decide you need more you have a myriad of options to
| add these. From the despised "function current_real_thing(id:
| Ind, success_callback: Fn(Int), error_callback: Fn(Error))
| {}" to "some_namespace:current_thing(...)" via
| "OtherClass::current_thing(...)" to "load current_thing from
| NewImplementationOfThing" and so on.
|
| Being strict and explicit isn't opposed to being flexible.
| And strictness and explicitness is most often a predicament
| to allow for future change, rather than hampering that future
| change.
|
| It's far easier to refactor, maintain, test and reason about
| strict and limited implementations than to do so with
| dynamic, runtime-magically-changing implementations.
| bwoebi wrote:
| I found this approach works best with languages having
| method overloading. For PHP it felt quite limiting, and it
| also requires you to have more complexity and overhead with
| wrapping.
|
| But I have no hard evidence at hand, only how I experienced
| that in PHP.
| piokoch wrote:
| Off topic: there are two key technologies that "digitalized and
| computerized" the World: Visual Basic and PHP. And Excel.
| canadiandev wrote:
| That's good, PHP is too permissive
| coding123 wrote:
| I found the solution:
|
| sudo apt-get purge php.*
___________________________________________________________________
(page generated 2024-11-15 23:00 UTC)