Live data from Hacker News

A look at modern PHP

lwn.net

591–600 of 610 posts

Re: A look at modern PHP

#591
post #562
post #257

Earlier quoted context omitted.

Oh how I hated the fact that php.ini could change so much of the PHP behaviour... can't say I miss those days. Also, I don't know about now because I left this ecosystem long ago, but it was very common for apps to bundle their own custom installer scripts (access a webpage, fill a form and so on). Certainly useful for the users but it was never standard and required a lot of work for the developers (and came with th…

This is changing now. There are no new php.ini changes that would affect how the parser or VM works. The lessons from things like safe_mode and register_globals are learned so well.

and magic_quotes...

Re: A look at modern PHP

#592
post #142

Earlier quoted context omitted.

I still can't see how C++ can be "mature" if you have to indicate the type of object it is returning! I know everybody will say "just add a type declaration so the compiler can interpret it" but this should be a feature of the language. Just adding type declarations to hint to a compiler is not a real solution.

But it's not a hint to the compiler. It's stating a fact to the compiler. It'll stop compilation. If I have a basket of fruit, all the items in that basket container are fruit. I can't put anything other than fruit in it. It's a basket of fruit. I know how to interact with the fruit due to its type. If I am able to put dung into my basket, my fruit is spoiled and I cannot assume how to interact with the objects in th…

> But it's not a hint to the compiler. It's stating a fact to the compiler. It'll stop compilation.

So, if I type out that something's a Banana, and the compiler stops and tells me it's actually an Apple, why did I need to type anything?

> Did the other languages (C++, C#, Java) get it wrong?

I can only speak for Java, but here goes. Here's something that compiles without warning and crashes at runtime:

  Fruit[] basket = new Apple[] { new Apple(), new Apple() };
  basket[0] = new Apple();
  basket[1] = new Banana();  // Crash here
You and I know Dung doesn't belong in a basket, but Java sure doesn't. It will not warn about me comparing Fruit to Dung, nor is there a way to ask the compiler to warn me that I forgot to handle Banana:

  void handleFruit(Fruit fruit) {
    if (fruit instanceof Apple) {
        System.out.println("Apple");
    } else if (fruit instanceof Dung) {
        System.out.println("Dung");
    }
  }
Here's another one:

  void foo() {
    Fruit[] basket = new Apple[] { new Apple(), new Apple() };
    handleFruit(basket[0]);
    handleFruit(new Apple();
  }

  void handleFruit(Fruit fruit) {
    System.out.println("Do I get called?";
  }

  void handleFruit(Apple apple) {
    System.out.println("Or do I?";
  }
In the first code sample we established that the basket could only contain Apples, but now when you handle something from the basket, it's apparently any Fruit. And when you handleFruit an Apple, there's no warning that the compiler is making a choice between the two acceptable handleFruit functions.

Anyway, just like me, this Bucket is full of shit. Time to dump it all out. I could put it in the compost, or in the veggie garden. Anywhere that contains Dung. Likewise, the Fruit could go in a Bowl, or a Cupboard.

Here's a first pass at it:

  interface Transfer {
    void dump(F from, T to);
  }

  class FertiliseGarden implements Transfer {
    public void dump(Bucket from, Garden to) {
    }
  }

  class PutAwayFruit implements Transfer {
    public void dump(Basket from, Cupboard to) {
    }
  }
It compiles, but it's missing the only safety check I really cared about - the contents must match (even if the containers vary!) Let's introduce another type variable X to assert this:

  interface Transfer {
    void dump(F from, T to);
  }
Now it asserts what I want it to assert, but it doesn't compile.

I can't call how Java handles the above stuff as 'wrong', since that's stating it too objectively. I can only say I disagree with the above design decisions (if they were deliberate) or I find fault with them (if they just turned out that way).

Re: A look at modern PHP

#593
post #569

Earlier quoted context omitted.

I agree that Spring has a steeper learning curve than Django, but I disagree that Django is more similar to modern PHP frameworks than Spring. Django isn't MVC, it's an entirely different architecture. Symfony framework is heavily inspired by Spring [1], and modern frameworks like Laravel heavily influenced by it and extensively use its libraries. >You don't have the whole dependency injection lifecycle thing to gras…

Ah, that's new! had no idea PHP copied this concept from java. Rails completely avoids dependency injection. You know what, if the php community starts to heavily type annotate and use a framework like Symfony, I start to fail to see the point of using that and not java.

Indeed. PHP has been trying so hard for so long to be a dynamically-typed Java I don't know why they don't just rebrand as DJava or something like that. I've never known any commonly-used language relinquish its own identity the way PHP has.

Re: A look at modern PHP

#594
What put me off PHP for life was the assumption by employers and recruiters that PHP rates are at least 20% lower than for JS, Rails or Django. PHP just isn't respected professionally.

Re: A look at modern PHP

#595

Earlier quoted context omitted.

Hashing: Support for securely creating and verifying cryptographic hashes, like you'd need for password hashing. Encryption: Support for securely encrypting, signing, decrypting and verifying arbitrary payloads. In Laravel, you can do: $plaintext = 'foobar'; $encrypted = $encrypter->encrypt($plaintext); // this will encrypt the plain text, generate a MAC and combine everything into a base64 encoded payload $decrypted…

You mean, an crypto library exported by the framework instead of you specifically importing it? I don't see the gain (as a consequence, I have no idea if other frameworks do that). RoR and Django both have extensible management commands, and all frameworks that I have ever seen allow you to create independent CLI commands (it's on PHP that the CLI is a second class citizen).

I think having good, secure, easy to use and hard to misuse crypto makes a ton of sense for any framework. The framework needs these internally anyway (to offer encrypted sessions for example), so you might as well expose them to the developer too.

I might have missed it, but I couldn't find any documentation on how to create custom commands in RoR. For Django I found [1] (through "python manage.py" from what I understand) and that does look like it's more or less the same as Laravel's "php artisan", with commands provided by the framework as well as the ability to add your own.

Anyway, I wasn't trying to attack RoR or Django, as those are actually the best alternatives to Laravel I know of. I worked on an existing Django project for a bit and while I don't like Python, Django seemed just fine to me for the most part. I did want to express my disagreement when it comes to the original claim of "any framework in any language can do what PHP frameworks can do" though.

[1]: https://docs.djangoproject.com/en/3.0/howto/custom-managemen...

Re: A look at modern PHP

#596

Earlier quoted context omitted.

Where to begin indeed! > - No proper connection pooling with circuit breakers. PHP has had a "shared nothing" architecture since the very beginning, that includes DB connections. It helps it to scale (think micro-services being stateless in a modern context): nothing is shared between requests, again including connections, by design. > - No proper multithreading (that works in web environment) or parallelism in gener…

I once asked Rasmus about this face-to-face, during one of his presentations, specifically his thoughts about the pThread extension (https://www.php.net/manual/en/intro.pthreads.php), and he responded that it was not required in a web context, as web servers already have threads per request so its a mute point. if each web server thread that serves a request ends up spawning a full PHP process then it's not a mute po…

It's php-fpm persistent threads (seperate Daemon listening on port or socket), not web server threads, just to be specific. You have a lot of control of how many PHP threads you will allow per web node using php-fpm, very reliable tech. The days of mod_php are long gone.

So I meant one thread per request at the php-fpm level, not Nginx/HTTPD level.

* Edit for spelling

Re: A look at modern PHP

#597

Earlier quoted context omitted.

Where to begin indeed! > - No proper connection pooling with circuit breakers. PHP has had a "shared nothing" architecture since the very beginning, that includes DB connections. It helps it to scale (think micro-services being stateless in a modern context): nothing is shared between requests, again including connections, by design. > - No proper multithreading (that works in web environment) or parallelism in gener…

> PHP has had a "shared nothing" architecture since the very beginning, that includes DB connections. It helps it to scale (think micro-services being stateless in a modern context): nothing is shared between requests, again including connections, by design. A bit ironic that you compare it to microservices, because that exact property of PHP makes it massively unsuitable for microservices and scaling, because it req…

I've been hearing that "PHP does not scale" arguement for many, many, years, in many, many, variations.

When you really have to scale, infrastructure, resources, and networks will rapidly overtake any concerns around your choice of language. You can develop crappy architectures in any language, and the inverse is true.

Re: A look at modern PHP

#598
post #592

Earlier quoted context omitted.

But it's not a hint to the compiler. It's stating a fact to the compiler. It'll stop compilation. If I have a basket of fruit, all the items in that basket container are fruit. I can't put anything other than fruit in it. It's a basket of fruit. I know how to interact with the fruit due to its type. If I am able to put dung into my basket, my fruit is spoiled and I cannot assume how to interact with the objects in th…

> But it's not a hint to the compiler. It's stating a fact to the compiler. It'll stop compilation. So, if I type out that something's a Banana, and the compiler stops and tells me it's actually an Apple, why did I need to type anything? > Did the other languages (C++, C#, Java) get it wrong? I can only speak for Java, but here goes. Here's something that compiles without warning and crashes at runtime: Fruit[] baske…

Yes that Java example is bad and terrible. I'm honestly amazed you can do Fruit[] basket = new Apple[]. That's terrible.

You can't do that in C++. You can slice objects but you'll get a warning in any good compiler.

I would like to know the type of the object I am working with else it'd be "auto everything" in C++ and it makes the code unreadable.

That's basically what I am finding objectionable about PHP because you've got types added as return types from functions, and also types for parameters and you can enable strict checks for the types but none of it makes any sense when you can just get an array of unknown/any type.

It's like a C++ vector of void pointers that you can cast to whatever you'd like it to be and that's really bad. It's also not very maintainable, particularly in large codebases.

It's a strange oversight in PHP given the type "safety" enforced elsewhere. I suspect they just aren't doing it because so much code would break.

I would like to see this typed array introduced so you can look at horrible codebases like the Magento example (there's loads of it) and see at a glance what you're dealing within instead of "an array of unknown type".

I will use your FertiliseGarden function shortly, thanks.

Re: A look at modern PHP

#599

Earlier quoted context omitted.

I once asked Rasmus about this face-to-face, during one of his presentations, specifically his thoughts about the pThread extension (https://www.php.net/manual/en/intro.pthreads.php), and he responded that it was not required in a web context, as web servers already have threads per request so its a mute point. if each web server thread that serves a request ends up spawning a full PHP process then it's not a mute po…

It's php-fpm persistent threads (seperate Daemon listening on port or socket), not web server threads, just to be specific. You have a lot of control of how many PHP threads you will allow per web node using php-fpm, very reliable tech. The days of mod_php are long gone. So I meant one thread per request at the php-fpm level, not Nginx/HTTPD level. * Edit for spelling

> PHP threads

Still, my understanding is that php-fpm spawns processes, not threads. What is "persistent" is the php-fpm daemon itself that's connected to nginx, but each request spawns a whole process which has to bootstrap your whole framework every time. That's the reason frameworks like symfony run almost mandatorily with something like opcache.

Re: A look at modern PHP

#600

Earlier quoted context omitted.

You mean, an crypto library exported by the framework instead of you specifically importing it? I don't see the gain (as a consequence, I have no idea if other frameworks do that). RoR and Django both have extensible management commands, and all frameworks that I have ever seen allow you to create independent CLI commands (it's on PHP that the CLI is a second class citizen).

I think having good, secure, easy to use and hard to misuse crypto makes a ton of sense for any framework. The framework needs these internally anyway (to offer encrypted sessions for example), so you might as well expose them to the developer too. I might have missed it, but I couldn't find any documentation on how to create custom commands in RoR. For Django I found [1] (through "python manage.py" from what I under…

> I did want to express my disagreement when it comes to the original claim of "any framework in any language can do what PHP frameworks can do" though.

Oh, a complete agreement on that.

This conversation sidelined from some people talking about Java, .Net, Go and Rust. None have anything similar to the big web frameworks. And while I'm not completely sure about Rust, I do believe that none even can have it.

Post reply on HN