Hacker News new | past | comments | ask | show | jobs | submit login
Modern PHP Cheat Sheet (front-line-php.com)
194 points by rehhouari 2 days ago | hide | past | favorite | 111 comments

I'm using Laravel/PHP for a new project and it's been a joy. A true joy. After spending the last 6+ years writing backend services in Node, PHP feels like a breath of fresh air. No restarting the server, no compiling errors from babel/typescript wackiness, no blocking threads, server-side templates out-of-the-box, and so much more.

PHP has come a really long way, I really hope to see it's resurgence some day after everyone has been burned enough from running JavaScript as their server.

It's so nice to see a comment giving PHP the praise it deserves. Honestly, PHP is a good, if not great, language to use for building solid web apps fast.

People seem to love to hate it because it's the "cool" thing to do. Yet PHP developers continue to ship things faster, while JS devs are probably still fiddling with their Node environment setup...

> People seem to love to hate it because it's the "cool" thing to do.

While I agree with this, I think the tone is slightly dismissive. From what I have seen, older people in our trade seem to recommend against PHP due to it having a terrible relationship with consistency, functionality, performance, etc. in its history. Though I have (thankfully) seen that the language and its standard library has undergone several large improvements, which is great to hear.

> Yet PHP developers continue to ship things faster, while JS devs are probably still fiddling with their Node environment setup...

On your point of JavaScript, the build environment nonsense can definitely get hairy. It's why we get things like Deno, which attempt to throw all this cruft away and start again. And sometimes that's a good idea. If you're dedicated to Node, replacing Webpack with Rollup seems to be what is generally recommended. The only obvious disadvantage there is compatibility with Webpack plugins.

It would be nice to have a type-checked JavaScript variant with a practically non-existent build environment (no Webpack, Rollup, etc.) As much as I adore TypeScript, the compiler itself is massive and takes quite a long time to even start.

> It's why we get things like Deno, which attempt to throw all this cruft away and start again

Doubt. Your "something@v1.2.3" in Deno is no different than "something": "^1.2.3" in npm. The problems will appear when you update stuff.

The only thing benefiting deno currently is the clean slate and the lack of hacks (for now).

They are different, currently no Deno registries have dynamic version resolution (no greater than operator). Once you have locked in on a version you are in it for good unless you change it manually

However if the argument is: updating libraries break stuff, that is gonna happen every time in every language. There is no guarantee the next version will just work as the last one did

> From what I have seen, older people in our trade seem to recommend against PHP due to it having a terrible relationship with consistency, functionality, performance,

As an older person in the trade, I don't agree with the other older persons. Only consistency is a problem with PHP code, and that is largely NOT caused by PHP. Inconsistency is the product of developers coding without any real thought about how to abstract things (ok, well, maybe not in the case of magic strings). You can do this with every language. Some languages do everything possible to force consistency, and developer still find a way to be delightfully inconsistent even with the syntactic equivilent of bowling gutter bumpers (see Cobol, Go, Java). Consistency is a developer problem. You can write great code in languages that are terrible.

PHP has never been slow (compared to other dynamic languages), or lacked functionality. If there is a rub on PHP it comes from no separation of code and presentation, which flew in the face of the MVC pattern which was THE WAY for a very long time. Now... well, JSX much? Anyhow, my team works with Go, JS, PHP and Python, and the code that takes the least effort to both extend and maintain is... the PHP.

I am honestly and truly trying my absolute best, but no matter how hard I try, I again and again completely fail to sufficiently and comprehensively put into meaningful words how the inconsistency of the PHP language doesn’t play a role AT ALL when building actual web applications for actual users.

It just. Doesn’t. Matter. Choose Symfony or Laravel, and you are in for a wonderful development experience, from setup to dependency management to architecture to implementation to testing to deployment – for certain kinds of projects it’s just perfect.

I agree with you, and it's super hard to explain. But if you have the right type of project requirements, Laravel is unbelievably great to work with. I love other languages more than PHP, but for a real world, client facing project that I want to be mostly hands off, Laravel would get my vote 9/10 times.

I think you've sufficiently and comprehensively put it into meaningful words above!

The truth is, those who care to use the language properly know this already. Those who wish to dismiss it always will, and this happens to be an easy angle of attack.

Not only shipping things faster but testing faster, scaffolding faster, debugging faster ... the tooling for PHP is much more mature than it was 6-years ago and there are so many GOOD packages out there that haven't been forked and copied 20x over.

Really happy to be working with it again, even if on the side for now.

I agree.

Developer speed does not get enough coverage when comparing languages.

When I work with a Node project it's such a slow dragging build process.

Using PHP is like a fun superpower that lets me turn out things on timescales that are borderline miraculous to clients and management.

Hiring developers is rarely considered as well.

I can hire a top-notch PHP engineer for half of what a mid-level JS engineer would be asking.

It's not that PHP engineers are less qualified than JS. I think bootcamps shifted the market for JS developers and now really good engineers cost an arm and a leg while good junior engineers start around the $100k mark. The whole JS salary market is insane and as a startup, I can't afford it right now.

I think it’s interesting to me, as I see these comments a lot with PHP specifically and there is at any honest pushback on this, so here’s my attempt:

Just pay what good engineers should be paid. If there are PHP developers out there not getting the same salary as a their peers like this post mentions, you should leave that job for a better one. Please demand better, PHP developers, for all of our sakes. Business always wants to put downward pressure on salary and we need to be united against this regardless of preferred tech stacks

I agree but I'll counterpoint for just a moment. A lot of mature PHP engineers seem to be from Europe, or rather non-American. I'm often finding it's American salaries that are crazyyyy high, but factor in that health insurance isn't spectacular here it might all balance out.

I've run no numbers, I have nothing but infrences to base this on, but hiring a mature PHP engineer in Europe would 100% be cheaper in the long run than hiring a junior/mid-level JS engineer anywhere else.

There's an interesting comment/quote on an Hacker News post about Perl's "Laziness Impatience Hubris" mantra that I think of when people talk about developer speed.


This might be true for the web but for CLI apps etc I don't think this holds the case.

It’s exactly 180 degrees for me. Node js just seems to be super fast. And with typescript its heavenly.

I don't make a website and working on node js is fun. In PHP it is like doing something esoteric. Just a simple argument parsing is so hard in php compared to node js. In nodejs I use meow and even without docs, I can parse cli easily. In fact, I think Rust can be more easier than PHP in many cases. I usually rewrite in rust for long term daemons. Also in php I need to install php I don't know why I should install php-pdo etc. I mean why not just allow composer etc to handle like just like node do? I am frustrated with php stdlib which seems to be fossil at the moment.

The thing I like about PHP is laravel framework where I can set up websites instantly. Node js is fragmented with adonis and many other micro-framework.

Stuff like argument parsing is left to frameworks. Laravel’s Artisan command system has all sorts of built-in functionality for exactly that.

I don't want to install Laravel for cli apps. For that most devs use symphony


Installing laravel for cli is like buying thread ripper to run minesweeper.

Use whatever framework you like; the point is PHP leaves it largely up to them.

Anecdotal - my experience is the opposite. I have two large PHP side projects currently (vanilla and Drupal) and I find working with PHP and Composer to be a much slower experience overall than my day job developing with TypeScript/Node and JavaScript/React.

I would guess that a lot of the slowness is not from PHP itself, but the way your specific projects are using it. With the vanilla PHP project, the slow down may be caused by poor design decisions from other developers.

With Drupal, the code quality of the core is generally okay, however the added inertia may come from a "square peg, round hole" situation, where the CMS is being used for an obscure purpose for which it wasn't really designed. This is quite common in the wild, probably due to the low barrier to entry and the fact that people will use what they are comfortable with to solve every problem under the sun (not dissimilar to the prevalence of Excel throughout the world of finance for a variety of completely inappropriate use cases).

Much more than most other languages, PHP is purpose-built for serving web requests.

For example, PHP could get along without async/await and promises in a lot of situations, because threading was effectively subcontracted to the underlying web-server. You could just treat, say, a curl call as blocking-- resulting in a simpler code flow-- knowing that wouldn't lock your entire web server.

I'm writing PHP8 with the Symfony 5.3 framework at present too, and I'm also liking it. Provides what I need to build with and otherwise stays out the way.

The improvements over the lifespan of PHP7, and the new things in PHP8 make PHP such a nicer language to work with.

Not my cup of tea, but if you really want PHP-like with JS, EJS looks really close to "I wish server-side javascript worked like PHP":


Just needs a FastCGI wrapper.

Another "Node, but PHP like" project that compares itself to EJS and other similar things: https://github.com/Yahweasel/nodejs-server-pages#why-nodejs-...

same here. Been using Laravel has my framework of choice of my freelance work and I'm able to accomplish things fast. I just love to use it everyday!

If you really want things to happen fast, you can also take a look at api platform:


The comment on Numeric values is misleading:

> Use the _ operator to format numeric values:

> $price = 100_10;

> // $100 and 10 cents

Makes it sound like the underscore replaces the decimal, which it doesn't. The underscores are simply ignored by the PHP parser, so that 10_0.1 === 1_00.1.

You could afterwards use PHP to replace the `_` with a comma for display purposes, and I assume that is what they are trying to say.

Yeah, that's a terrible example since some places do use comma as a dollars/cents separator, and others don't. And some people use floats for currency (with the obvious caveats), and might read this as "_ is the same as a decimal point".

They really should just use a simpler example, like 10_000_000 being easier to read as "10 million" than 10000000.

  > They really should just use a simpler example, like 10_000_000 being easier to read as "10 million" than 10000000.
Declarations such as `$million = 1000 * 1000;` or `$seconds_in_day = 24 * 3600;` are very common, and in my opinion more readable than the ignored-underscore syntax.

Perhaps, though the underscore syntax works in Perl, Ruby, Java, etc.

And the context here is how to explain it, not whether it should exist and/or be used.

Yea, Credo[1], one of the static analysis tools for Elixir specifies it as:

  Numbers can contain underscores for readability purposes.
  These do not affect the value of the number, but can help read large numbers
  more easily.

      141592654 # how large is this number?

      141_592_654 # ah, it's in the hundreds of millions!

  Like all `Readability` issues, this one is not a technical concern.
  But you can improve the odds of others reading and liking your code by making
  it easier to follow.
Should make it more obvious that it is purely a readability thing, and that is obviously subjective anyway

[1] https://github.com/rrrene/credo/blob/master/lib/credo/check/...

I've never understood why some programmers like to use ligatures, especially on a cheat sheet like this, which will be used primarily by people who aren't familiar with the syntax.

It's not 'a' ⇒ 1, it's 'a' => 1, just write it out the correct way. Why are you trying to be fancy?

This is done by the used font, in the markup it's correct.

Looks like iosevka to me. Lovely font

EDIT: I wrongly assumed at a glance because of the shape of the $. On closer look the characters are much wider than iosevka. It's jetbrains mono

Because the characters '=>' have been used to simulate exactly the character '⇒' : to mean an arrow, not e.g. "equality then greater than".

Overall I think this is reasonable, but the font I'm using on my ide has ligatures and I think they provide a vastly better reading experience.

My absolute favorite thing about PHP is the arrays and the ease of working with them. Whenever I find myself working in another language dealing with loads of data I'm immediately thinking of how easy it would be to accomplish it in PHP.

And I've been loving all the new additions to PHP over the last few years as well. Version 5 was rather limited but since 7 it has grown into an actual programming language for which I feel I don't have to apologize for.

Is it really useful to have ordered map as the "only" collection type?

I guess it might be Stockholm syndrome - but I'm quite comfortable with a "list/array" type (numeric keys, ordered) and a "map/hash_map" type (objects as keys).

Especially give that with phps "power" you can:

  $array = array(
    1    => "a",
    "1"  => "b",
    1.5  => "c",
    true => "d",

  array(1) {
    string(1) "d"

That's indeed a case where it fails, but in all my years I have maybe ran into that problem once. But it's trivial to implement a more strict form of array if you wish. And if I remember correctly there are some standard extensions that have classes to do just that.

And for the record, it's not Stockholm syndrome, I use plenty of other languages and I know the benefits and drawbacks of each of those.

I remember inheriting a RoR v2 based project. Ended up virtualizing the entire server to migrate the damn thing as it was a big pile of dependency mess to port to a newer server stack. On a similar situation with a PHP 4 based codebase, adapting it to work on PHP 5.6 was a few hours work. Done. No other language can beat that. And thanks to a newer (and more open minded) generation of developers, PHP has a long way to go. The launch of the PHP Foundation by Jetbrains, Automattic and others - https://blog.jetbrains.com/phpstorm/2021/11/the-php-foundati... - is also a step towards a better future for PHP.

I like how PHP is evolving. I wouldn't say it's always a joy to use but it definitively improved a lot.

I really want to use PHP for one-off CGI scripts, (rsync files and done, deployed), but I really wish it had methods on primitive types. It hinders discoverability. It's annoying having to look up which function I need to use, and to find that there are many alternatives, most of which are deprecated.

PHP stdlib needs an overhaul, IMO.

I agree, it'd be nice if the built in was more standardized and had more features.

However you do have options to choose from with php these days. Really well maintained libraries exist for basically everything you could want, often they are fast, well tested and modular. And it's nice because you can even choose the style you prefer with this.

Grab the symphony string lib for instance: https://symfony.com/doc/current/components/string.html

Wouldn't that be pretty bad for backwards compatibility?

You can always keep the old.

However I don't think it is something that will ever be done, designing a good standard library is quite difficult, especially by email and rfc.

I think it is better if the community designs one that gets a lot of traction to become de facto standard. All the large frameworks already has their own standard library.

With the performance improvements to PHP over the years it is no longer a detriment to performance to write a standard library in PHP.

And if we can get the operator overloads rfc passed we can have userland scalar objects


The evolution of PHP has shown the difference that having engaged stewards of the language can make. Saw a list of quotes[1] from Rasmus Ledorf which I think explains it's stagnation. As someone who used to sneer at the language, modern PHP doesn't look out of place among Ruby, Python, etc.


I don't know how this really played out internally, but from the outside it feels like Hack/HHVM kicked the PHP core team in the gut and inspired them to improve things.

As a solo bootstrapped founder working on PHP (Laravel) every day, I was surprised to learn a LOT from this one page. Thanks for posting.

The guys behind it work at Spatie[1] which you have probably heard of some of their packages, and Freek has a blog[2] that has a lot of PHP stuff on - lots Laravel, and lots just general new language stuff (covering PHP8 features etc)

[1] https://spatie.be [2] https://freek.dev

A Reddit post from a few years ago explains pretty well why PHP has such a terrible reputation: https://www.reddit.com/r/webdev/comments/5tqoqa/web_devs_wha...

PHP should have chosen to undergo a rebranding a few years ago, if you ask me. The stigma it has to deal with is probably unsurmountable and will be forever. If you think PHP, you think WordPress and Joomla, and that means "hacks and vulnerabilities"...

It's a good language nowadays, with quirks like any other language, but I still have one big problem with it: There are too many "PHP developers" out there, and most of them are very bad, and many of the good ones are from poor regions in the world and you can find them on Fiverr doing kick-ass work for a grand total of $50.

My personal favorite PHP wtf is this one:

  if (md5('240610708') == md5('QNKCDZO')) {
    echo "true\n";
Though I do use php, and love many things about it.

Do you know why that is?

  php > echo md5('240610708');

  php > echo md5('QNKCDZO');

Would this be avoided by using a string comparison function?


Yes, or you can use ===, which will check the type as well. I am trying to get in the habit of using === everywhere now.


  php > echo strcmp(md5('240610708'), md5('QNKCDZO'));

Having been out of PHP for several years now, I assume that needs a === instead of ==? It's unfortunate that we have the need for a ===, but it's no different that JS in that regard.

The underlying issue is that while md5() thinks it is returning a hex number, if the hex number starts with 0e, php thinks it's 0^<whatever>.

How do you find those kickass ones on Fiverr among a sea of bad ones?

the good ones are not on fiverr ;)

PHP's main problem is its very shallow learning curve.

The 5840 built-in functions provide easy ways to get many useful things done with minimal dabbling.

In other words, one can be a "scripter" instead of a "programmer", and for many projects that's 100% OK.

Other languages automatically filter out "scripters" from their field by demanding a certain level of mental abstraction to produce anything moderately useful.

While there is absolutely no difference between a good programmer using PHP, or a good programmer using any other language/environment, but there is a big difference between the median levels and below.

This in turn lowers the reputation of the field, and it becomes uncool to put PHP on one's resume, therefore the more capable programmers propagate out to other languages, which further lowers the median, etc.

This happened with Perl, too...

I really wish Php added support for Perl's qq and q operators sometime too (1)

It would really make writing scripts a lot easier and cleaner.

(1) https://stackoverflow.com/a/41334570/1031454

I personally think it looks broken and wrong. For short strings I don't see the point and for multiline strings, use a heredoc.

The reason I never use Heredoc is because you need to abandon your indentation, otherwise your tabs/spaces get included in the string. Is there a way around that?

Not since PHP 7.3![1] If you indent the closing identifier, then the corresponding indentation will be removed from the content of the heredoc string.

[1]: https://www.php.net/manual/en/language.types.string.php#lang...

I thought they fixed this with [1] Flexible Heredoc in 2017 with PHP 7.3

[1] https://wiki.php.net/rfc/flexible_heredoc_nowdoc_syntaxes

I've gotten into the habit of generally using single quoted strings (with 'around them') which alleviates most problems with escaping double quotes. And for the odd string that needs to have a single quote inside I switch back to double quoting.

This approach also has the added bonus of stopping PHP from accidentally evaluating something inside the strings.

Genuine question from a php hobbyist : what is the equivalent of Typescript’s ability to declare an object’s structure?

It’s really weird to me, I mean don’t we do this all the time? Work with eg. an $options array/obj passedto a constructor, or say, a message decoded from JSON…

I could write $name = $message[‘username’] … and there is no checks in ide or runtime, while the phpdoc will just document $message to be an object or array… what am I missing?

It looks like php devs create full blown classes to represent just about every data strcuture, but what if it’s just data and you don’t need any attached logic’ Isn’t there a concise way to declare a complex type?

We do indeed create full blown classes for data objects. However, it is made easier with PHP 8.0 and 8.1 (released today).

Typed properties, constructor properties, and Read-only properties can significantly reduce the code bloat.

- https://php.watch/versions/8.0/constructor-property-promotio...

- https://php.watch/versions/8.1/readonly

Can you directly cast an object / assoc array to an instance of such a class?

If I have a function that receives eg a Message, it means an instance of the class right? So somehow my assoc.array/object still needs to be instanced, and if I do just $message = new Message($theData) … it doesn’t auto assign properties right? That would be handy though still very much boilerplate.

I guessthe language is just designed for how it’s been used so far, may e it will change if JIT makes php more open ended in its uses.

I never had to do this and I don't believe you can do this directly via a language construct but you can do it within a class via a method or trait or static function. This trait can then be applied to any class. Probably be better though to just have a create function that takes an input of type and coverts to class.

Anyway I was curious so I wanted to try this out with the trait method here is working code that illustrates this.


    /* trait to cast from any iterable to class */
    /* reusable - close to what I think you are asking for */
    trait castFrom
        static function castFrom($data)
            if (!is_iterable($data) and !is_array($data) and !is_object($data)) return null;
            $class = new self();
            foreach((array)$data as $key => $value)
                if (!property_exists($class, $key)) continue;
                $class->$key = $value;
            return $class;

    class Foo
        use castFrom; // use the castFrom trait
        public string $str = 'blah';
        public int $num = 5;
        public function hello() { echo "{$this->str} : {$this->num}\n"; }

    class Bar
       use castFrom; // we can use the castFrom trait again and again
       public int $x = 0;
       public int $y = 0;
       public function hello() { echo ($this->x * $this->y) . "\n"; }

    $data = ['str' => 'foo', 'num' => 7, 'x' => 3, 'y' => 7];

    $foo = Foo::castFrom($data);


    $obj = (object)$data;

    $bar = Bar::castFrom($obj);


    /* you could just use create functions form the class */
    class Creator
        static public function createFromArray($data)  {} // create from array
        static public function createFromObject($data) {}   // create from object
        static public function createFromSerial($data) {}   // etc..
        static public function createFromJson($data)   {}

EDIT: Added ugly check to make sure the type can be iterated over.

It's not clear to me what you're looking for. But you can cast arrays to objects. And you can use type declarations as arguments for functions.

Ok say I have a small class with an options object (I know perhaps not the best design...):

    class Foo {
      public function __construct(string $name, array $options)
        $this->name = $name;
        if ($options->enableFlag) { ...
I want to declare what $options are, in TS I could do:

type TFooOptions = { enableFlag: boolean; userIds: number[]; }


    function __construct(string $name, TFooOptions $options) ...
Otherwise how do I get proper typechecking if the IDE doesn't know what $options are?

>type TFooOptions

is that creating a JS class under the hood or is just a hint for the compiler?

What I do , but I don't work with recent PHP versions is to create this as a class, then to make this easy to construct objects from JSON i add a static function fromObject or fromJson that does it for me. Using real classes could prevent bugs when working with shit APIs like Microsoft TTS , where they have 2 endponts and one returns objects like voice: {name:"Bob"} and the other voice: {Name:"Bob"} so my code will wrap both type of responses into a well defined class.

I don't think there is a PHPDoc annotation just to hint what that object looks like but I will be happey to be shown a way.

Simple object type in TypeScript, the "type checking" abstraction layer on top of JS, which actually doesn't even need to be compiled (eg. esbuild strips all typing from the code before compiling).


Your approach is sensible. I remember using json_encode() indeed so I could declare some data in a php file with <<< HEREDOC in the Javascript short syntax (though short array syntax in php nowadays makes it less painful, JSON syntax still a bit less verbose).

I checked that example in TS playground and it does nothing when transpiling, so is only a compile type check. From my experience when I have an option object with many properties I would create a class both in PHP and JavaScript, usually functions that need an options object are very complex and many times you need to add even more options and having a class make it simple to do the changes and refactor.

You can get some basic checking, but not type in arrays [1]. Maybe using attributes you could check if it is?

  class TFooOptions
      public function __construct(
          public bool $enableFlag,
          public array $userIds = [],
      ) {

  $options = new TFooOptions(
      enableflags: true,
      userIds: [1,2,3]

  new Foo('Bob', $options);
Or if just for IDE checking, you could use the @property docblock value on the class.

[1] https://wiki.php.net/rfc/arrayof

PHP doesn't do such structural typing, but Psalm[1] can do it statically. It calls them object-like arrays.[2]

[1]: https://psalm.dev/ [2]: https://psalm.dev/docs/annotating_code/type_syntax/array_typ...

You can force a type check that it's a specific type of object or interface rather than an array. But, no, you can't do what you're asking for directly.

The language type system doesn't quite support that yet in all scenarios. As of php 7/8 it's getting there but for what you are describing you'd need to use a static analysis tool still unfortunately.

Here's two of the most common ones. These are very mature and are very broadly used. Most editors also come with some support for these annotations so you often get help in the editor when something is wrong.



I feel like TypeScript and Flow went down the structural typing path (rather than relying on nominal types) because they were following what was popular in JavaScript at the time, not because it is an unequivocally better solution. The last time I programmed PHP, I didn't feel having to define lightweight classes was a big deal.

The examples you mentioned are interesting because I consider `options` arguments to be a code smell that tends to happen because TypeScript is missing named parameters, which PHP has. And typing JSON messages is far from a solved problem in TypeScript, because there is no widespread solution for runtime type checking.

As a JS dev it’s nice to see php imitate some newer js syntax like nullish coalescing, arrow function, … helps me to switch between the languages.

It really needs a way to declare type of small data structures though, in a very concise way (no class boilerplate, for performance eg. going through 10000’s of entities).

PS : on the other hand I’m starting to dislike how languages become "designed by committee", and lose the purity of the original design.( thinking of JS mostly here with its gazillion rfcs)

PHP received the null coalescing operator in PHP 7 (roughly the end of 2014) after this RFC https://wiki.php.net/rfc/isset_ternary

JavaScripts nullish coalescing operator landed in chrome 80 (feb 2020) over 5 years later… more like it’s PHP syntax landing in JS land.

Perhaps worth noting - nullish coalescing is an old feature of the Unix shell. (From a quick skim through Wikipedia, it seems to have been added to `sh` in System III - released in 1981.)

As a very long time PHP developer I say this with love, because for PHP it's actually a blessing to be moving away from the "purity" of the original "design".

Super cool:

> Union Types - Combine several types into one union, which means that whatever input must match one of the given types: `function find(int|string $id)`

TypeScript and PHP have the distinct honor of being a popular language with ad-hoc union types (not the concrete subclass/enums that other languages seem to think are sufficient).

I'm not convinced by Enums having methods. For those of you using other languages that support this, do you find them useful?

Enums with methods are essentially a compiler supported way of having several static readonly instances on a class with a private constructor. It’s not always useful, but it can be nice, sometimes. I’ve had a few times working with C# where I’d have liked those.

I've found a couple odd instances where it'd be nice. But also utility classes work just fine too.

Borrowed from java...

The choice of colors for this page makes it really difficult to read

The use of ligatures in the code examples also isn't helpful for people not familiar with the syntax.

You mean '=>' becoming as if ⇒ (U+D1D2)? Yes, it gives you a moment of "Mh?!".

I also find the super slim scrollbar difficult to use.

It is actually impossible to grab for me in Safari.

I wish frontend developers would stop messing with UI :(

Is there some browser flag that disables custom scrollbars? Surely its a problem for accessibility.

In Firefox's about:config you can set layout.css.scrollbar-width.enabled to false.

... and yet another reason to use Firefox: enthusiast support available for free ;-)

Also no darkmode in 2021....

You should probably edit (in this case) the 'bg-blue-300' class in your broswer's "developer's tools".

Some of us edit the styles as normal practice for a large number of sites, especially after the widespresad use of thin fonts, grey text etc.

Surely there will also be tools (add-ons) to replace css elements as needed per domain...

What is modern PHP?

It commonly refers to PHP 7+ paired with clean code practices and SOLID principles.

The opposite is PHP5-style code from the early 2000s, no package management, no type strictness, no object orientation, just a giant spaghetti mix of JS, HTML, SQL and PHP in a 10kloc file.

Do you think spaghetti code won't come from folks who use Composer? Ha!

Having used PHP since version 4 (20 years ago), I can say with confidence that its had its peak. Everything new added since 7.4 is just fluff or bloat. Fixing long standing bugs and performance improvements is fine, of course. But everything new they introduce adds to the pile of warts that's PHP. I highly regard those that try to improve it, but with the current direction it'll remain the colloquial example of how not to design a programming language.

> Everything new added since 7.4 is just fluff or bloat.

The 7.4 did not finish the type system work. Docstrings were still needed for basic type hunting.

I found that php8 has brought numerous features that will formalize things I am currently doing as hacks and workarounds.

Exceptions as expressions--I can stop writing, `$x = $context['x'] ?? ThrowWrapper::missingValue('x');`

Named Arguments -- I use a hacky diy `Reflection` heavy version of this for an RMI/dispatch where json key-vals mapped to function params.

Static return type and union types -- I have been relying on PhpStorm docstring hacks for this sort of type-hinting.

`readonly` will be very helpful to express performant, immutable classes. I have a number of classes that are immutable-by-convention, trusting the caller not to monkey with the internals. (The idiomatic way to do this, `$immutable->getAttr()` is too costly in tight loops compared to `$immutable->attr`)

PHP still has lots of warts (function calls why you so aspensive?!?!?) but I keep being pleasantly surprised by how good of a tool it's evolving into.

Thank you. I don't need any of those, though. $immutable->getAttr() is easy to mock, easy to override, and allows for custom behavior (e.g. return clone $this->Attr).

Static return type, useful but since I use interfaces for everything it's not really needed. Union types, also not really needed because either 2 interfaces share a common ancestor or I'll have separate methods for different types. But most of the time, I encapsulate things behind interfaces that do one thing, so having different methods per type can often be avoided.

Named arguments are a pain for me since now I can't change parameter names anymore. This is particularly annoying with different coding styles in dependencies vs my own code. My code ends up not conforming to the coding standard that I've used since it was introduced (PSR-2R).

Exceptions as expressions is a nice to have, but exceptions in general are a thing to avoid doing. Not that things can't go wrong, not that chugging along in the face of errors is good, of course it's not. But if you have a lot of exceptions in your code, that's a smell of bad design. I've got 13 different exceptions used 20 times in total, over 4683 LoC on my current project. Mostly, whenever one of them is triggered, whatever I changed last was incomplete and led to an inconsistent configuration.

That said, your use case for PHP is probably very different. Especially since I don't care much at all about performance anymore. I used to, but CPUs are so much faster nowadays and PHP itself has improved.

I'm not sure the spread operator [or any form of apply()] is a good idea in a programming language. You've just added another bit of indirection that isn't even explicit, but is based on whatever the runtime state is. This is anathema to any sort of structured programming. The inferred state is just hand waved because any mismatch is pushed, as an incidental side effect, into the next function.

It wasn't designed, it was evolved. The author said as much. Evolution seldom produce clean designs.

JIT compilation certainly isn't fluff or bloat.

FFI too

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