top | item 16725492

Modern PHP without a framework

221 points| vanilla-almond | 8 years ago |kevinsmith.io | reply

182 comments

order
[+] Falkon1313|8 years ago|reply
While it's good in some respects, all this enterprisization is exhausting and can, perversely - counter to its intentions, be a significant drain on productivity. Once upon a time, we were focused on the important things - problem-solving, domain data, and business logic. But now we're almost entirely focused on abstraction, generics, and boilerplate while the important objective-related stuff that pays the bills just gets whatever scraps of time are leftover (if any).

We used to spend 90% of our time determining the right nail to use, the right wood to use it on, and where best to place it, and only 10% of our time on selecting and wielding the hammer. Now we spend 90+% of our time figuring out which GenericAbstractToolFactoryManagerFactoryInterface to invoke and how to properly invoke it a in such a way as to coerce it to ultimately generate something that eventually might generate something else that will hopefully drive some sort of fastener into something in such a way that will possibly hold it together, and the rest debugging why instead it is generating a generator that generates chisels that are chopping away at the foundation.

Yes, that's an exaggeration, but how much so? We are smart people, we do figure out how to use these complex combinations of systems to build functioning (bloated monstrosities of) applications. But are they really reducing technical debt or adding to it?

Are these systems really going to be easier to maintain in a few years when they have 357 dependencies that have each evolved over time (and or been abandoned)? Easier to optimize, when that means modifying what's going on under the hood of those dependencies? Easier to extend, when doing so would lead to conflicts with those dependencies?

I'm predicting that the next wave of discovery and hype in the field will be focused on improving productivity while reducing technical debt by removing the cruft that we're building now and replacing it with something simpler and more to-the-point.

[+] godot|8 years ago|reply
I started a startup in 2013, and I picked PHP for a core language since I had a decade~ experience with it by then and it was a good enough reason to use it. PHP 7 wasn't available yet and nodejs was only starting to take off and didn't seem like the future yet.

Taking learning from previous companies, I've found the main thing PHP was lacking at the time was a good routing mechanism. We obviously don't want to rely on Apache hitting .php files to handle requests. So we used ToroPHP (https://github.com/anandkunal/ToroPHP) for routing, which is a seriously lightweight routing lib. Indeed we used composer and a lot of dependencies, but for our own codebase we used manual includes instead of the autoloader. With the usual PHP production setup like APC with opcode caching enabled and file stat'ing off (later on opcache + APCu), we handled scale extremely well. (mentioning this because a counter-point for manual includes is that many requests would unnecessarily load way too many code files)

As far as codebase maintenance and growth go, that PHP codebase was actually very easily manageable even with manual includes. Having routing solved frees you up to organize your code files in any ways you want. Even today, I have a mini-framework structured this way for myself to start side projects and test ideas with. (Yes, using PHP5 for side projects in 2018 ;)

My point in bringing all this up is that the architecture this article is trying to take you in, seems unnecessarily complicated for PHP.

This past year I've been working in a full nodejs shop and this entire architecture (from this article) reminds me heavily of how a node/express app is structured. Someone else on this thread mentioned modern languages have their architectures converging. This is exactly what's happening. Even as a PHP fan, it makes me feel a bit of "Why use PHP at this point, instead of nodejs/go/python?" while reading this. It feels like if you wanted to go this route, nodejs is a better option on almost all fronts -- language syntax brevity, availability of packages, community, developer-availability. The only reason to use PHP at this point is nostalgia/sticking to PHP syntax.

[+] nikita2206|8 years ago|reply
The reason to use PHP over JS/Python or Ruby is that PHP supports strict typing and that makes code both more maintainable, understandable (Find Usage feature only works reliably when types are inferrable which is not always the case in those other theee langs) and refactorable.

Now the reason to use PHP over Java or Go is that PHP at this point has a type system that’s on par with Go’s but at the same time it gives you an advantage of fast development process thanks to the lack of need for compilation and/or restarting the container after each change in the code. I’m currently working with Java and before that I had a long experience of PHP, while I personally would choose Java over PHP almost in any case because I value type system features perhaps a bit too much, but I do suffer from those slow turnaround times (compile/restart TomCat) and I can see how it could potentially be bad for the business at early stages especially.

So the bottom line is PHP at this point has a nice balance which is hard to find atm in any other popular languages with evolved ecosystem

[+] treve|8 years ago|reply
As someone who's been doing PHP for nearly 15 years, but 2 years ago switched to Node.js for a job, I agree. This is even more true when switching to Typescript.

We introduced typing later in the project and wow what a step up in safety and productivity.

[+] gremlinsinc|8 years ago|reply
I'll go against the flow and say hell no!...

I've been part of teams that pride themselves on using propel + klein to build an app in a non-framework.

If you want a light framework just go with lumen, flask, sinatra. Ymmv.

All new devs wasted a lot of hours learning propel and klein and it didn't always do what they wanted/needed, and the code wasn't the prettiest, where as most knew laravel, and longed for the comfort/sanity of coding in laravel.

Sure, for a hobby project/side project this is a good practice to become a better dev, and understand how a mvc framework is built, but for a large code/team it's best to go with something established so new devs hit the ground running without having to learn a ton of stuff.

It's easier to find a 'laravel dev', than it is to find a 'custom built mvc dev with extensive experience in x, y, z packages'.

[+] wvenable|8 years ago|reply
I've worked in countless languages and used plenty of frameworks (and done a ton of PHP development) but I really don't understand Laravel.

You have to do a big dance of putting files in all right places and implementing all the right interfaces -- as you would with any framework -- but Laravel doesn't seem to give you anything for your trouble. Take, as one example, validation -- you still have to write virtually everything yourself! There are some very basic hooks and some wire but that's all. For all the trouble, I expect more actual features from my framework.

[+] AFNobody|8 years ago|reply
The simpler the abstraction, the more likely the end product will not be a disaster if it is a critical system.

Frameworks are development speed enhancements but frequently are not "better" in terms of mechanical function. Even "major" PHP applications built on frameworks (i.e. Magento 2) frequently lose site of those abstractions and create fundamentally flawed products where the solution is you need a software developer to spend hours on it just to make the thing "work" as advertised.

This rush to abstract everything is good for developer productivity, to a point, but I've rarely seen it result in a better/saner product.

[+] NightlyDev|8 years ago|reply
Though it's not like you don't need experience with those same packages if you go the laravel way.

A developer shouldn't have an issue working with either. It's all PHP and all sane PHP frameworks are mostly based on the same concepts, with some tradeoffs here and there...

[+] pan69|8 years ago|reply
One of the great developments in the PHP eco-system is the use of components and the inter-op standards developed around them [1].

For many years now, "frameworks" such as Symfony and Zend have been mainly been a set of components with an optional thin framework layer. So, not frameworks in the traditional sense.

For those interested, another great resource is "Create your own framework on top of the Symfony Components":

https://symfony.com/blog/create-your-own-framework-on-top-of...

[1] https://www.php-fig.org/

[+] foxfired|8 years ago|reply
3 years ago, I made a (not so successful) youtube series of building a website from scratch using php[1].

I'd basically record myself coding for 1h then add a voice over it as I speed up the video 3x.

Although my English falls apart fairly quickly, (if you ignore that) it is a good way to see the entire process of building a framework and understanding what each part does.

A lot of the things in this article are covered there, with a little bit of the why.

[1]: https://www.youtube.com/watch?v=0sYFo92sFLs&index=2&list=PLr...

[+] flanbiscuit|8 years ago|reply
I wanted to improve my PHP skills so I researched and taught myself how to build a PHP framework myself, without composer or any third party libraries. This was a while ago so it was for PHP5 and I used CodeIgnitor and CakePHP as my inspirations because that was what was chosen in the previous places I had worked at so I was familiar with them. I enjoyed the process and I learned a lot.

I encourage people to build their own framework without composer as a learning experience if they're looking to level up their PHP knowledge. I plan on going through it again from scratch but following modern standards: PHP7, PHP-FIG, strict_types

[+] throw2016|8 years ago|reply
PHP has been in a weird place for nearly a decade now in technical forums like HN where it is mocked endlessly often to signal a superior technical understanding by people who would not deign to use it. As if its the only language with shortcomings.

Yet it continued to be used in some of the most scalable and widely used apps of our generation from Wikipedia, Wordpress, Facebook, Slack and more.

It often feels other languages marketing teams have preyed on it in many ways to gain attention. And there has been some kind of war against simplicity that places an unearned respect for 'clever' abstractions under the guise of scalability often in pursuit of resume padding, or 'best practices' entryism and gaining influence in projects via package managers and the like.

[+] megous|8 years ago|reply
Anyway, if this is how people use PHP these days, why not just use Java? I guess deployment is different (PHP is not compiled), but code/concepts seem pretty much the same at this point if you want to use this style of programming.
[+] kilburn|8 years ago|reply
I'd say that web programming architecture has been converging between most languages. What's shown here is:

- Setup a library tracking system (composer, the autoload stuff)

- Setup basic Dependency Injection (using code in this case, but the same could be done through config files or annotations)

- Parse requests into a request class

- Setup a middleware chain, including a router, and dispatch a request through it

How is this different from flask/django (python), rails (ruby), or gin (golang)? I'd say the basic concepts are pretty much the same, except maybe the library handling part. In other words, I don't think there's enough "meat" in this example to appreciate actual relevant language differences.

Also, you can write "java-like, enterprisey" code (Symfony) that values explicitness over magic, or go the other way around following the "convention over configuration" mantra, and end up at Laravel that is much more Rails-like.

Finally, PHP is still has several advantages over java for many people out there:

- Every request starts from scratch, meaning it is impossible to accidentally provoke side-effects on other requests

- The package system (composer) is just a package management system, and hence MUCH simpler to understand than ant/maven/ivy, that are entire build systems that also want to control testing, deployment, and everything

- Development is faster-paced thanks to the lack of compilation. You can even easily setup an environment with auto-reloading and just "save updated code" -> "see result in less than a second".

- You can deploy your app to any of a horde of (cheap) hosting providers and let others deal with the ops side. The service may exist in java-land, but it certainly isn't as ubiquitous.

- PHP programmers are cheap (yes, cheaper than java-programmers).

[+] wvenable|8 years ago|reply
...or C# or anything else. I programmed in PHP for many years and I agree. I mean there are good reasons for maybe not using Java but it's hard to imagine a good excuse to start PHP these days if you don't already know PHP.

On the other hand, things in PHP-land are improving at such a rapid pace (but without the churn of JavaScript) that if you are a PHP developer there isn't much reason to switch to something different but similar.

[+] hrktb|8 years ago|reply
I think there is strong sense of “we’re not the old PHP anymore, we cut our hairs and wear suits with ties now” in the community.

In a lot of fronts it means mimicking Java, but I think it still is more flexible (and less reliable as the other side of the coin). It’s still very easy to drop down to “quick and dirty” code anywhere it’s needed, and it still benefits from a very low bootstrap cost to deal with single command/requests.

[+] patricklouys|8 years ago|reply
PHP handles null better than Java. That's the one thing that kept me from switching to Java tbh.
[+] tyingq|8 years ago|reply
Dynamic types, and less verbose.

Which, I agree, can be downsides as well.

[+] ubernostrum|8 years ago|reply
There's no such thing as web application development "without a framework".

There is only a choice between using someone else's framework, and inevitably building your own. If you reject all third-party frameworks, you will end up reinventing a bunch of design patterns from other frameworks. You will end up writing your own libraries to do the things the framework would have done. And you will -- no matter how good or fast it feels to you -- end up spending more time in the writing and maintenance of your private "non-framework" than you would have spent in deploying an existing one off-the-shelf.

[+] tannhaeuser|8 years ago|reply
Was hoping for a built-in mechanism for HTML-aware, injection-free templating given PHP is invoked via an SGML processing instruction from otherwise static HTML. Instead what's shown is massive Java-ish meta boilerplate for trivial HTTP request/response abstractions.
[+] liveoneggs|8 years ago|reply
welcome to New\PHP where looking like java is the goal
[+] mnm1|8 years ago|reply
For learning, this is great. For actual apps, this is plain stupid. Not to mention that no one has the time to cook up a framework every time one wants to build an app. Or all the rest of the components that are missing here. This whole PHP without a framework--whether it be creating your own framework or using raw PHP--trend seems like it's promoted only by inexperienced devs who don't need to work on real project in real companies in real life. I would literally fire someone if the insisted on doing this for wasting company resources and time unnecessarily.
[+] userbinator|8 years ago|reply
I'm seriously not sure if this is satire. It starts off with a simple example, and then goes down a rabbit-hole of massive complexity to ultimately do the same thing. This reminds me of the many OOP articles that were common shortly before the turn of the century, which would take as an example a perfectly straightforward and simple-to-understand piece of code and then bloat it into an asinine multilayered monstrosity by applying a generous amount of "OOP best practices and patterns" while straight-facedly enumerating all the alleged benefits.

When you first started with PHP, you may have used includes or requires statements throughout your app to bring in functionality or configuration from other PHP files. In general, we want to avoid that because it makes it much harder for a human to follow the code path and understand where dependencies lie.

Autoloading just means that when your application needs to use a class, PHP knows where to look for it and automatically loads it when it's called for.

How in $deity's name can you say that specifying immediately the exact path to the file included, in the file that includes it, is "much harder to follow" than hiding it behind the indirection of the autoloader and whatever it does!? Honestly, WTF!?

(Maybe the joke here is that everyone is just pretending to admire the emperor's new clothes, in which case I apologise.)

Edit: here's an example of the OOP articles I mentioned: https://csis.pace.edu/~bergin/patterns/ppoop.html

[+] contingencies|8 years ago|reply
Yes, unfortunately I don't think it is satire, unless they've gone to immense effort... see the guy's twitter feed, etc.

The author recommends building some kind of abstract structure factory which has perhaps five external dependencies per codeblock, a composer file, vague notions like dependency injection, auto-wiring, containers, routing, middleware, request factories, response interfaces, a class hierarchy and an obtuse non-production webserver in mental overhead ... lauding the design because he says it complies with a bunch of numbered standards that allow you to swap out your layers-of-assumption components.

This is blatant false economy. Nobody ever swaps out components. Nobody in fire-and-forget webdev land cares about standards. Just get the thing out the door, keep it simple, and thus keep it maintainable.

As others have commented, explicit code is clearer. Clearer code has less bugs.

Why not save the hassle and just use:

<html><head></head><body>Hello, <?php print anti_xss_function_of_choice($_GET['worldtype']); ?> world!</body></html>

This is the 'new PHP' from ~1995, seamlessly using decades of high efficiency improvements to kernel caches, networking gear, the interpreter itself and webservers. Zero complexity, not a class in sight, and definitely no middleware. It's a great language, when not misused.

[+] lkrubner|8 years ago|reply
I get downvoted when I say anything remotely negative about PHP, in threads devoted to PHP, but perhaps my thoughts will make sense if I emphasize that I used to love PHP. It was my first real language, and I built my first business around it. That was in the year 2000. That was in the era before modern package managers, when PHP's huge standard library was a tremendous benefit, because the alternative meant using something like Perl, where you had to download every module from CPAN and cobble it together yourself. PHP was a dream compared to that.

But 18 years have passed. Every language now has very good package managers. There is an abundance of dynamic languages, most of whom are more consistent than PHP.

I'm not going to waste your time with a long PHP rant. I just hope that everyone is aware that the huge benefits that PHP offered in 2000 are no longer valid. If you are programming in PHP, you owe it to yourself to explore some of the many options that are out there. There has been incredible innovation among software languages since 2000, but PHP has mostly tended to follow a conservative path, mostly imitating Java.

For anyone who won't be bored by another PHP rant, I wrote my thoughts on this subject back in 2014:

http://www.smashcompany.com/technology/why-php-is-obsolete

[+] sethrin|8 years ago|reply
Autoloading allows one to specify modules by their logical, namespaced identifiers rather than simply importing a file. One benefit is that one can swap out the implementation without necessarily changing the code. I've had to override some badly-behaved libraries that way.

Generally speaking, while I don't think this is satire, I would hate to see someone code this way, unless the point was simply to learn how the components of a web framework work together. This is not "framework-less PHP", it's just a DIY framework, and not a particularly good one. I think that attempting to create a web application without a framework is at best needlessly duplicative of effort, and at worst an open invitation to security flaws and spaghetti code.

The author says, "This is not an anti-framework screed," and it's certainly not polemical. However, I think it's probably more representative of the Zend-ecosystem way of doing things rather than PHP best practices: accretion, as opposed to design.

[+] slim|8 years ago|reply
Some time ago there a guy that posted a "Show hn" showing his "lightweight templating engine in php". He parsed a HTML file and replaced <% %> tags with some text. It never occurred to him that php is actually a templating engine
[+] slindsey|8 years ago|reply
Thank you. You stated what I was thinking much more clearly than I was able. I strongly prefer explicit code that states clearly what is happening without having to guess.
[+] lotyrin|8 years ago|reply
No, this is probably serious; this is The New PHP.

Seems we finally broke the fever of infectious imperative spaghetti and are coming around to OOP and patterns by following the trail left by JVM ecosystem and eating its droppings and clothing ourselves in its shed skin.

[+] colecut|8 years ago|reply
wow, PHP is on the front page, and it's positive

We have come a long way!

[+] aussieguy1234|8 years ago|reply
For one project, I used slim. It has routing, a simple container and that's about it. I made my own controllers and integrated them in. Super fast, for anything more I used composer packages.
[+] fulldecent|8 years ago|reply
I read this article and found it to be a great example of why we should NOT adopt modern PHP techniques at our company.

50 lines of code and contrived examples (is HelloWorld class a view or controller? AwesomeClass is a model?) get one line of HTML emitted in a barely readable way.

This article fails to motivate why each layer of complexity is added. It basically starts with the assumption that you want to use a framework and says "hey look you can do the same thing with 50 lines of boilerplate, not really, but kind of."

I would be much more impressed with an article that starts with the obvious way to write a PHP application (.htaccess, index.php, products.php, library/database.php, library/*.php) and then explains the actual problems that would make you want to opt for more complexity/organization/modern techniques.

[+] ramijames|8 years ago|reply
In my day job, I work on an application based on Drupal 5. It's not necessarily "without a framework", but really it might as well be.

It has absolutely made me a better developer because I've had to delve into how the system works more than I ever did with Laravel (or Ruby on Rails, in a previous life). Things don't just work (hell, sometimes they don't work at all) and poking around until I really understand why is a healthy thing for any mid-level dev to do.

That being said, I do miss a lot of the modern niceties and it can be really frustrating to work this way. I'm glad for the opportunity, but I would also like to be able to use more modern dev tools in the future.

[+] stevepurkiss|8 years ago|reply
Drupal 5? Wow! I began my Drupal journey on the 4.6/4.7 'cusp' after working with J2EE & although I like Drupal because I can see the 'bigger picture' of the business logic being infused into the API, i.e. business problems solved = code as opposed to using something like Laravel & creating new untried, untested code all the time, I only really started liking coding with Drupal 8 as it's almost a complete rewrite from procedural to mostly OO.

The major problem over the years of fire-fighting various dubious installs of Drupal is people hack core and contrib modules making it impossible to maintain - if you use the APIs, grow modules & extend instead of hacking then it makes life a whole load easier - all I do to update my sites now is 'composer update --with-dependencies' (well, there's a few more lines to update the db if needed, export config from db to code, etc. but it's super-simple).

I hope you have applied a patch to protect against the latest security issue found, here's a link to an unofficial patch for 5:

https://www.drupal.org/files/issues/2018-03-28/sa-core-2018-...

[+] patricklouys|8 years ago|reply
I like to use the same approach, I even wrote a tutorial [0] and a book [1] about it.

That being said, I am still forced to use Symfony at my current job. It only gets in the way sometimes, it's not too bad.

On my previous job we went from CodeIgniter to frameworkless and I really liked that. Not having framework constraints working against you was really enjoyable to work with.

[0] https://github.com/PatrickLouys/no-framework-tutorial

[1] https://patricklouys.com/professional-php/

[+] jwdunne|8 years ago|reply
I recently gave Sylius, based on Symfony, a spin. I wanted to add a field to a product, editable in the admin area. The additional code and the extensions were ok. Some of the config changes are understandable but I thought it a bit much when the number of additions to configuration outstripped the amount of code required.
[+] troels|8 years ago|reply
> So there you have it. With just 44 lines and the help of several widely-used, thoroughly-tested, reliably interoperable components, we have the bootstrap for a modern PHP application.

Uhm .. so ... a framework?

[+] paulddraper|8 years ago|reply
A microframework, at least.

Hardly close the complexity/features of CakePHP or others.

[+] dvt|8 years ago|reply
I haven't used PHP for almost a decade, but I agree with the sentiment of this article.

I built a web app back in 2009 in PHP and didn't use Code Igniter or Zend (basically the only two frameworks back then), opting to do it all by hand. And it ended up being a really valuable and formative experience. No matter what language I use, I understand how a web application really "fits together" under the hood and I think there's value there.

As a side-note, compared to Node.js or Rust or what-have-you, PHP just seems needlessly verbose.

[+] halfjoking|8 years ago|reply
I'm someone who uses a custom framework at work, and it's not verbose at all. Maybe I'm doing it wrong?

I just spl_autoload_register on a controllers directory.

Then based on the url, it creates a class for the first part of the url and passes in the rest... $class = new $class_name(); $class->index($url_parts);

That class always extends an output class which uses a template system to render a component. I also use an ORM with a models folder that has a bunch of static functions to get data in each model class.

I would love to hear from someone more knowledgable about the disadvantages of my approach or why this articles is a better way of doing it. Of course I use composer and use a bunch of libraries for aws, oauth, Google APIs... but for the actual framework I keep it simple and haven't had problems so far.

[+] clairity|8 years ago|reply
> "...Code Igniter or Zend (basically the only two frameworks back then)..."

wat?!

i coded php in the early/mid 2000's and had at least a half dozen frameworks available to choose from even then. for example, i used fusebox after starting to create my own framework and finding that it already (mostly) did what i had wanted to do.

[+] tyingq|8 years ago|reply
Good article, and hopefully contrasts today's php with yesterday's php.

To me, it's no worse than any other dynamically typed language now. And arguably better than similar peers because the barrier to entry is so low.

FastCGI and user space caching like apcu mitigate the old "one process per request" complaint.

It's a true workhorse. Sure, node.js and Golang have advantages, but so does modern php.

[+] rgomez|8 years ago|reply
Wait, this is far from vanilla PHP, is this not gloryfing "Composer" as the new meta-framework?
[+] sbarre|8 years ago|reply
Only if you consider gem and npm to also be frameworks. Or by further abstraction, Github.