Hacker Timesnew | past | comments | ask | show | jobs | submitlogin

14 years of PHP here.

My year in PHP was spent counteracting godawful newbie PHP developers' idea of what is 'best practice'. "Framework convergence"? "A common autoloading strategy"? Come on. Perhaps 85% of PHP (we could almost say web) projects are fire-and-forget, with minimal maintenance.

No, I don't have sources, but yes, you know it's true. This is the web programming world's dirty-little secret. Same goes for RoR, and the rest of them.

What does this mean? The code produced simply doesn't matter. Bitrot is accepted. Nobody cares. Of course, then there are maintained projects, complex infrastructures, things that push the boundaries. But they are so few and far between that their lessons are difficult to generalize, certainly with any significant bearing on PHP as a language as opposed to general programming practice.

Meanwhile, people scream from the lamp-posts about 'best practice'. For example, I was informed by an inexperienced developer a couple of years ago that it was now considered (by who?) 'best practice' to leave out the closing tags in PHP files. WTF?

More muck - let's look at the article's topic of 'autoloading'.

Symptom: annoying code to type all over the place, thinks developer: "my HairyStinkySpittingCamelCaseClass extends GeneralObjectOrientedAnimalIrritantClass". Oops, need to also type in 'require_once('classes/irritants/animals/objectoriented/general.inc');' up there. Oh no, now I'm getting lazy. Oh but this framework has this autoloader thing! I should use that. That's what someone else did! How cool is that!" Wrong. You are incrementally introducing complexity, tight-coupling, and turning your execution flow in to spaghetti.

Probable cause: Extreme overuse of the OO model, generally.

Obvious fix: Stop (over)using OO.

Yes, you heard me right. Stop using OO. Just try it. Code immediately becomes so much more concise, readable, and re-usable. (Oh, for the days of PHP3! Hahah.) I challenge you or your team to refactor some part of your codebase in to non-OO and see if it doesn't improve. Of course, if you are really new then your whole codebase is linked to your framework's inherent model (probably some MVC thing that only partially functions architecturally) and you won't be able to figure out where to start with such a task. But do try, it will be interesting, I guarantee it.

I'm not saying OO is useless, just that most times it's used in PHP code it's contributing nothing useful and would be better having been left out. Look hard and I would be surprised if you don't concur.

So yes, for me, 2012 was mostly a year like any other in PHP. Ignoring vocal people while getting things done. Still amazed at how broken the whole pear thing is. And PHPUnit, hah. That thing is so PHP4+ Javafied best-practice Germanic, it should be in a modern art gallery. (And I say that as a nominal German.)

Anyway, 14 years and PHP is still the most bulletproof language for getting stuff done on the web.

So dear PHP authors, thanks for saving us from perl/cgi (though perl has it's place, it's not the best tool for the web). You deserve a medal. Particularly for early and reliable UTF8 support, which gave me a fine excuse not to switch to ruby 5+ years ago, even though I really, really wanted to, and still prefer its syntax and features. However, your OO implementation was crap, and your function naming and parameter ordering is impenetrably wacky, even after a decade and a half. But that's OK, nobody's perfect. We still love you :)

Happy new year, PHP community.



Ohh hey your that guy I have been cleaning up after. Thanks for making the lives of everyone who comes after you miserable. Keep up the good work. I will keep rewriting all your crap.


> For example, I was informed by an inexperienced developer a couple of years ago that it was now considered (by who?) 'best practice' to leave out the closing tags in PHP files. WTF?

With this statement, I can't decide if you are being serious or just having a good laugh.

> Perhaps 85% of PHP (we could almost say web) projects are fire-and-forget, with minimal maintenance.

Keep in mind, your knowledge is based on your environment. If you work with bad code, that's all you know. I don't, so I don't realize what it's like working "in the wild."


Please read the other comments in this thread with regards to the closing tag nonsense.

As for the "I don't work with bad code because I wrote it myself or in this particular small environment" comment, that's great. I have worked in many countries, so I have a fairly broad experience, and IMHO much of the webcode industry to be pretty fire-and-forget vs. other areas of programming.


You're probably a bit too hard on the emerging techniques - Class loading is easily one of the best things to happen to PHP in years (along side closures).

But... I'm inclined to agree with you about OO. It's far over used by developers who don't have the experience to know when to stop. Dependancy Injection? God damn, are we actually solving problems or covering up issues with a programming paradigm? This solves a problem I never knew I had...

Traits and "mix ins" blow my mind. How bout just using a bloody function call in a library (yes, these can be testable just fine too without the word "class" in there).

Maybe I've just head my head neck deep in functional/procedural code for too long to appreciate things, but none of my OO systems has ever achieved the need for overly complicated management systems like DI or traits.


There is certainly a line that can be crossed when it comes to over thinking OO. However, Dependency Injection enables you to write much more testable code where in many cases people would use static methods therefore breaking the ability to properly unit test.

As for your argument against traits, using global functions clutters up the global namespace and doesn't lend very well to modular development. Next thing you know you have two libraries with "create_hash($string)" or something similar that do two different things.

*Edit: clarification


(1) Though I am not familiar with the subject (I avoid OO PHP), you seem to raise a valid point; however one could also consider that the same could probably be achieved with less lines of code, arguably looser coupling, greater re-usability and increased conceptual clarity by not writing that code within an OO model at all. (2) The namespace argument is a valid one; however; in what percentage of deployment environments is such a concern truly likely to come to the fore? Usually very few, and when combined with non-braindead naming conventions (eg. 'mylibrary_function()') basically never.


> one could also consider that the same could probably be achieved with less lines of code, arguably looser coupling, greater re-usability and increased conceptual clarity by not writing that code within an OO model at all.

OO is all about loose coupling, greater re-usability, and conceptual clarity. That is literally the point of it all. You can fume about the abuse of OO but the exception is not the rule. It's quite unlikely that, in general, plain old procedural code is better for coupling, re-usability, or clarity unless your problems are boringly simple.


> OO is all about loose coupling

It's theoretically an interesting language pattern. However, it grew from controlled environment of experiments for which it is most suited.

It's perhaps telling that, today, a fairly large number of experienced programmers tend to avoid it. Have a look at the interviews in 'Coders at Work: Reflections on the Craft of Programming' for some good examples.

I actually just bought this book again specifically to find this quote, which is gold:

"Armstrong: I think the lack of reusability comes in object-oriented languages, not in functional languages. Because the problem with object-oriented languages is they've got all this implicit environment that they carry around with them. You wanted a banana but what you got was a gorilla holding the banana and the entire jungle. If you have referentially transparent code, if you have pure functions-all the data comes in its input arguments and everything goes out and leaves no state behind-it's incredibly reusable. You can just reuse it here, there, and everywhere. When you want to use it in a different project, you just cut and paste this code into your new project. Programmers have been conned into using all these different programming languages and they've been conned into not using easy ways to connect programs together. The Unix pipe mechanism-A pipe B pipe C-is trivially easy to connect things together. Is that how programmers connect things together? No. They use APIs and they link them into the same memory space, which is appallingly difficult and isn't cross-language. If the language is in the same family it's OK-if they're imperative languages, that's fine. But suppose one is Prolog and the other is C. They have a completely different view of the world, how you handle memory. So you can't just link them together like that. You can't reuse things. There must be big commercial interests for whom it is very desirable that stuff won't work together. It creates thousands of jobs for consultants. And thousands of tools to solve problems that shouldn't exist. Problems that were solved years ago."

Peter Seibel. Coders at Work: Reflections on the Craft of Programming (Kindle Locations 2680-2689). Kindle Edition.


> It's perhaps telling that, today, a fairly large number of experienced programmers tend to avoid it.

No, you have a small number of proponents of functional programming who avoid object oriented programming. These people are a statistical anomaly compared to the overwhelming number of experienced developers working in and on object-oriented technologies in the majority of platforms and languages. It's not even necessary to advocate for OOP anymore.

Perhaps if you were using functional programming instead of OOP I would give you points for this line of reasoning but you aren't.


> Perhaps if you were using functional programming instead of OOP I would give you points for this line of reasoning but you aren't.

Each to their own. FYI, I spoke at Code Generation 2010 at Cambridge University in the UK and generate much of my code from DSLs and/or other kinds of models these days.

Functional is good, pragmatism is also good. OO is in my view over-used and rarely the best solution.


Where is functional "good?" Other than in abstract math or FP advocates' heads? :D If it had been any good, it would have been used on a pretty large scale... we live in a pretty large world and someone would have figured it out... and then the others would have fallowed suit...


Nice troll.


Your criticism of autoloading comes as a surprise. During 2012 one of my colleagues squeezed a little extra performance out of our software by removing all the calls to require_once from our installation of Zend Framework, thus handing full control to the autoloader. It's a trick that's even mentioned in the official documentation: http://framework.zend.com/manual/1.12/en/performance.classlo.... Apparently it's quicker. Typical bloody PHP.


Zend is kind of bloated and tries giving you the world when you only need a form parser. require_once is also "slow" because it checks the list of required files each time you call require_once to make sure you aren't requiring the same file twice. It makes sense to stay away from that with a framework like Zend where it just wants to include so many files. With your typical app, not using require_once and only using require probably doesn't save much time


It's quicker to only load the files you're actually using for the request. If you explicitly require_once everything, then you're loading every class your application references even if they aren't ever used.


That's right. So like, show me the problem.

I think if you are working at a scale where this is even ridiculously relevant then you will prefer to manually specify required libraries and maintain a closer understanding of control flow at all times.

If not, then you would at least start measuring performance characteristics. When you do that, you will find that if you are pre-loading these things on your last query they will just live in OS filesystem cache (ie. already in memory). (Note: If your load time is disk-affected, a half decent sysadmin could just hard cache your code in memory anyway...)

Sure, you will have slightly longer interpreting time (again, not likely to matter, except at huge scale), but that will be offset by things like: (1) Any number of potential caching layers - OS filesystem, APC, etc. - which should maintain these cached either in memory or both in memory as PHP bytecode, thus largely effacing this concern (2) enhanced simplicity for everyone.

While I'm all for low-hanging performance fruit, this particular approach ('autoload') costs too much and delivers too little to be generally praiseworthy, whilst harming simplcity. It's justifying itself as optimization, and on many levels it just isn't. It's going backwards.


> I think if you are working at a scale where this is even ridiculously relevant then you will prefer to manually specify required libraries and maintain a closer understanding of control flow at all times.

I work at a scale where this is extremely relevant, and autoloading is a godsend. Manually including files is not only error-prone, but is tedious and requires development effort [time] that would be best utilized elsewhere.

> [...] this particular approach ('autoload') costs too much and delivers too little to be generally praiseworthy

Costs too much? Have you not implemented it? It's not hard at all to implement, even if you have an unorthodox file & class naming convention. The only caveat is that you can only have 1 class per file (which hopefully you'd agree is good practice in the first place).

Performance increases can be pretty large, too, especially at scale. Consider class A, which in some methods requires access to class B. You _could_ put the include inside those methods, but I can guarantee you that you'll see a noticeable performance hit if that method is called in iteration (we're talking a few seconds worth of time if iterated 1000+ times). That's non-trivial. So, what do you do? You could move it to the top of the file, so that it will only be required once. However, the problem here is you end up with 5-10+ includes at the top of every file. So now when you require that one file, you're now requiring an additional 5-10+ files, each with their own possible set of includes. I've seen instances of needing to require a single file result in having 100+ files being required due to the cascading. With an autoloader, that 100+ goes back to 1.

> whilst harming simplcity

This couldn't be further from the truth. You will have less LoC overall, less developer time spent trying to get the perfect set of includes so that you only require them once and only when they're needed. You will have fewer bugs due to the problems with manual includes, which again, means more time for developers to actually do stuff that matters.


> I work at a scale where this is extremely relevant

Really? You run Facebook or something? Got any figures?

> autoloading is a godsend. Manually including files is not only error-prone, but is tedious and requires development effort [time] that would be best utilized elsewhere.

Hang on. How many files are you including? Generally you only need to include one, right. Your framework, maybe an external library. Then you can call in whatever modules you need, as you need them. Right? Or are you using some weird kind of framework without modules?

> > [...] this particular approach ('autoload') costs too much and delivers too little to be generally praiseworthy > > [...] whilst harming simplcity > Costs too much? Have you not implemented it? It's not hard at all to implement, even if you have an unorthodox file & class naming convention. The only caveat is that you can only have 1 class per file (which hopefully you'd agree is good practice in the first place).

To clarify, the overheads I was referring to were (1) conceptual; less "WTF" for new developers to deal with (2) complexity; code-flow is both simpler and more explicit.

> Performance increases can be pretty large, too, especially at scale. Consider...

If you can provide some demo code, I'd love to see it. I think you will find largely it's just a result of having a dumb framework or being ultra-contrived in your example to an unrealistic degree. I also think you'll find that second-guessing require_once (a language-level feature) is not going to be faster than simply using it.


This is a documented Zend Framework thing, so personally I wouldn't call it "contrived", "dumb" or "weird".

http://till.typepad.com/blog/2008/10/zendframework-performan...

    > Removing require_once in favour of __autoload shows
    > one of the biggest performance improvements in my
    > entire application - I shaved off roughly 220
    > milliseconds by removing about 15 (or so) calls to
    > require_once in my bootstrap.php file. And that's
    > with APC enabled, and a decent sized realpath.cache
    > (and .ttl).
Presumably this lazy loading approach starts being faster once your codebase exceeds a certain size. Everything you've said so far indicates that you tend to work on smaller, fire-and-forget PHP projects, so maybe this just doesn't resonate with your experience and I can certainly respect that.

No matter what your gut feeling about language-level features may be, I know that at my day job, we measured a clear performance boost when we removed require_once and switched completely to autoloading. For those of us working on very large, long-term PHP codebases, autoloading really is a good thing and I hope you can respect that in return.


Good answer. I'm not saying that including code you don't want to use isn't going to shave of milliseconds, I'm just not convinced that the problem is being adequately identified. The problem honestly sounds like the codebase itself. And if that's something built with Zend, then perhaps that doesn't reflect well on Zend's innate structure, and Zend's only effective way around this is through 'autoload'.


> The problem honestly sounds like the codebase itself.

Any reasonably sized codebase is going to load a lot of files. Because your projects are so small that this is not an issue is not a reflection on the quality of every one else's work.


The subject of the conversation: "Given that (a) we need to load files (b) loading files takes time ... do we, consider performance: (1) use an autoloader on some mega-framework; or (2) be explicit and require directly."

I feel this comment contributes nothing to the conversation but a baseless personal accusation.


On the subject of the conversation, we can either let the computer do the work for us or waste time specifying it manually in a way that it's nearly impossible to do as effectively.

The code is already explicit enough, requiring directly is pointless busy-work that is more likely to be wrong.


> Really? You run Facebook or something? Got any figures?

100 total devs, over 10 years of development, with the codebase spanning 5k files and over 1 million LoC.

> Hang on. How many files are you including? Generally you only need to include one, right. Your framework, maybe an external library. Then you can call in whatever modules you need, as you need them. Right? Or are you using some weird kind of framework without modules?

This is a homebrew framework, but you're missing the point: regardless of how you kick it off, the framework itself still has to include files left and right. And modules or not, some code somewhere still has to include supporting files.

For every single file in your codebase, you will have at least one include call to it somewhere, possibly many more. It's silly to look at this as a "how many includes do you need to launch a request", because any simpleton can make it so that all you see is a single include, but that doesn't stop the fact that you must still manually include each and every other file -- at some point in the framework -- before you can use it.

> (1) conceptual; less "WTF" for new developers to deal with

I'll point to the supporting evidence provided by others here that shows that pretty much every modern framework uses autoloading. Thus, I wouldn't say it's a WTF, rather, the opposite is probably more true: who manually includes files anymore?

> (2) complexity; code-flow is both simpler and more explicit.

Removing include calls does not make the code more complex nor harder to follow, any decent IDE will let you control-click into the definition of classes. I'd argue that less LoC is a good thing (so long as we're not talking about "clever code", which this isn't).

> If you can provide some demo code, I'd love to see it.

Or, you know, you can read what I said as I perfectly explained the situation. But I'll play along.

    // test 1
    $start = microtime(1);
    $i = 1000;
    while (--$i);
    $end = microtime(1) - $start;
    printf('%.7f', $end); // .00004s
    die;

    // test 2
    $start = microtime(1);
    $i = 1000;
    while (--$i) {
        require './test.php';
    }
    $end = microtime(1) - $start;
    printf('%.7f', $end); // .082s
Note that test.php was a completely empty file (and thus no parsing required); in reality, those files are often 1000+ lines of code and take much longer to parse.

Even with this simple example, the non-require version is 2000x's faster than the require version. This is also in a perfect world, e.g. there's no other files also being required that'd overflow the realpath cache, nor is there really any other OS activity that will hamper my tests. In the wild, there could be 50-100 requests being served concurrently, which would affect the system calls even more.

> I think you will find largely it's just a result of having a dumb framework or being ultra-contrived in your example to an unrealistic degree.

It's a dumb framework, but considering that it's a legacy project that has survived 10 years of organic growth and is still paying my salary (I've been here less than 1/2 of that time), it's not getting re-written anytime soon. But, weren't we talking about autoloading?


> 100 total devs, over 10 years of development, with the codebase spanning 5k files and over 1 million LoC.

OK, so your codebase is certainly large, ungodly large, and frankly worrisome, but that alone isn't that all that interesting. Is it possible to feed my curiosity and supply queries/sec? :)

> ... any simpleton can make it so that all you see is a single include, but that doesn't stop the fact that you must still manually include each and every other file -- at some point in the framework -- before you can use it.

No, you only need to include the files you actually use. When you use them.

There's a strong argument to be had for being explicit, especially once performance becomes a concern.

The thread here is about arguing for autoload on performance grounds, and my opposition to such.

> pretty much every modern framework uses autoloading.

Pretty much every framework is crap, and a very bad way to build larger, complex systems, and maintain them over time. The majority of them are CMS and conventional website oriented, and apply poorly to other use cases. But you are perfectly welcome to limit your perceptions based upon what you consider to be modern and popular frameworks if you wish; it's entirely possible that - as I suspect - my experiences going beyond the above are a bit abnormal.

> Removing include calls does not make the code more complex nor harder to follow, any decent IDE will let you control-click into the definition of classes. I'd argue that less LoC is a good thing (so long as we're not talking about "clever code", which this isn't).

If you are looking at a block of code and the execution flow is dependent on an entire framework's dependency resolution mechanism (autoload or similar), with inexplicit dependencies, then it seems to be an obtuse perspective to argue that the code has not lost the property of being explicit.

> Even with this simple example, the non-require version is 2000x's faster than the require version. This is also in a perfect world, e.g. there's no other files also being required that'd overflow the realpath cache, nor is there really any other OS activity that will hamper my tests. In the wild, there could be 50-100 requests being served concurrently, which would affect the system calls even more.

First of all, clarity of code is far more important than performance in almost every case. If you really want to justify the lack of explicit dependencies on a performance basis, my point is that it's not possible.

> with this simple example, the non-require version is 2000x's faster than the require version

Err, here's what I got.

test1: 0.0000250 test2: 0.0177090 test3: 0.0062518 (same as test2 but with require_once instead of require)

Yeah the overhead is larger, no it doesn't really mean anything. However you include, you still have to include. not including is faster than require_once() is faster than require(). Nothing shocking there. I believe if you add APC and php-cgi and/or tmpfs as a mountpoint (vs. raw disk) this will decrease markedly, with no requirement to alter code.

I remain unconvinced.

Props on the custom framework vibe, IMHO every time I've looked, what's out there prebuilt is all crap (not relevant for anything but web-only, OO-centric, high overhead both performance and cognitive).


> you will prefer to manually specify required libraries and maintain a closer understanding of control flow at all times.

Manually specifying the libraries creates the problem in the first place -- it's a very difficult problem when your dependencies have dependencies and so on. You have code that depends on resource A but doesn't use resource A on every request; how do you manage something like that manually in a huge project?

> Sure, you will have slightly longer interpreting time

If you have a large framework almost everything depends on everything else. So you end up loading and interpreting 100% of your framework on every request. Even worse, you load it all at the start of the request! If you code only uses a small fraction, lets say 20%, of the framework and only loads and interprets it on demand that will make a difference.

> While I'm all for low-hanging performance fruit, this particular approach ('autoload') costs too much and delivers too little to be generally praiseworthy, whilst harming simplcity.

I don't much care about the performance considerations but I find autoloading far simpler than manually specifying every dependency. In fact, most modern languages don't bother with that either -- going back to C/C++ from Java/C# gives the same sort of pain. I'm not sure why you think it "costs too much" given it's likely to cost less in performance and code written. Performance was not the main concern for the addition of autoloading.


It was only an example. Your commend ignores a programming fundamental: "premature optimization is the root of all evil". Clarity and simplicity for the programmer trump performance every time. Only in extreme cases, worry about it later, and don't use that as an excuse to break things for the rest of us.


> premature optimization is the root of all evil

Most misunderstood quote of programming. Premature is the qualifier.


When it's right to optimize: when (a) everything works, and (b) performance has become a meaningful cost, making it the most important issue to work on.

When it's right to care about simplicity and clarity: absolutely all the time.


> When it's right to optimize: when (a) everything works, and (b) performance has become a meaningful cost, making it the most important issue to work on.

Incorrect. There are things people do all the time with the understanding of mature optimization techniques. We know, for example, that certain algorithms perform better then a simple brute force technique, so we start there We might test various algorithms, too, before everything works. But we are testing.

Premature is not about time. It's about effectiveness. Sometimes you cannot gauge effectiveness until everything works, sure. But often times this is not the case.


> Incorrect

I'm not denying there's better code and worse code in a performance-measurable sense that's written before 'optimization' goes on later in a project.

However, in the real world, we deal with problems. If you have a performance characteristic that's causing issues and you can reproduce it, then you have a problem and you can work on it. The inverse is also true.

Point of premature optimization quote: Most of the time more than a passing / higher-level-architectural thought about performance is not a good idea.


Hmm, if you thought the person that told you that leaving out closing tags was a noob then what does that make you :)? It is a good practice to leave out closing tags, RTFM to learn when and why.

Edit: After reading the rest of your comment I don't think you really learned or experienced much over 14 years. It also goes to show how misleading experience in number of years can be.


There is a good reason to not include the closing tag. Silly people can add newlines after the ?>. That leads to random newlines in your output which are annoying to track down.


trivia - PHPStorm's code-inspectior reports closing php-tag at end of file as code smell.


<sarcasm>Oh my god thank you for your enlightened teachings I understand completely now.</sarcasm>

What is the effect of the additional text in the file with the closing tag? They are output, and visible.

What is the effect of the additional text in the file without the closing tag? It is interpreted as code, becoming a potential security issue.

Are they difficult to track down because your development process sucks, or because there's something illogical and mystical going on? (Hint: There's nothing illogical and mystical going on)

Using continuous integration (an RCS/VCS-linked automated testing scheme) you can trivially determine which change broke which part of a system. In fact, you don't have to, because the system will tell you.

If you are worried specifically about accidental newlines at the end of a file, you can just write a rule in ~project/.git/hooks/pre-commit (or similar on a server) that rejects checkins that don't match that style.

Going around telling the whole world to adopt some ridiculous habit because your development process is out of the stone age is a reflection on that process only.


It's like you've taken every good thing done recently to PHP and turned it on its head.

Protip: You exclude closing ?> tags from your files because if there's a new line after them, you'll get the headers already sent error, which is a big headache to track down.


Protip: If you're using a reasonable development process you don't have such issues. For example: file="~repo/.git/git-hooks/pre-commit";echo "#!/bin/bash">>$file;echo "find . -name *.php|xargs -n 1 php -l";chmod a+x $file # or there abouts.


Wow, yeah, you could do that.

Or you could just leave off the closing tags that serve no purpose?


Sigh. I .... can't believe an elegant solution gets downvoted and .... I have put put up with responses like this. I guess it's true what they say about the PHP community.


how is that an elegant solution to the problem?

a) you're assuming everyone uses git b) you're assuming everyone uses a cli interface to git c) you're relying on the PHP linter to identify errors. A trailing newline character is not a syntax error, it's just a potential gotcha in terms of the output that is sent to a browser. d) you're assuming that any such fix (assuming you actually removed the newlines instead of simply linting the files) has to apply to all files

All of that, because you specifically ADDED extra content to the file in the first place. Seriously, what drugs create a mind state where that is "elegant"?


> a) you're assuming everyone uses git

Did I say that? No. My assumption in that (concise) means of expression was that people can understand an example and extrapolate, ie. "if you are afraid of (easily detectable problem x), use the hooks provided by your version control system". Hooks exist in [an|ever]y half-baked version control system.

> b) you're assuming everyone uses a cli interface to git

Hooks work through any interface... and can often be applied on the server, so they remain constant for all members of a development team.

> c) you're relying on the PHP linter to identify errors

No, I was giving an example. The PHP linter can surely be configured to pick up lack of a closing tag, if not then it could easily be convinced to do so.

> d) you're assuming...

No, again. This is an example.

To re-iterate: if you want to enforce something, you enforce it programatically. You don't go around telling people to change their more-correct habits and shouting from the roof tops about how your perspective is technically superior, because, quite frankly, it isn't.

I agree that not having closing tags as a coding style might be admittedly handy if you're dealing with the average (ie. low skilled) set of people and a crappy development process, but it's not something to aspire to - or defend.

> Seriously, what drugs create a mind state where that is "elegant"?

Drugs. Mmm. Don't want to get on to a tangent now, do we?

Objectively, elegance is correctness. Good development process is elegant. In fact, it follows that elegance in process is more important than elegance in code, because it produces demonstrably correct code as a side-effect. This is the same "one level up" power-of-abstraction that code can wield on data, or LISP can wield on itself. Sorry to have to spell it out.

I hope this inspires you to investigate improving your development process.


> Objectively, elegance is correctness. Good development process is elegant.

So how is deliberately adding an un-needed line that is known to cause problems to the end of a file, only to have to implement a pre-commit hook in your vcs to remove it or trailing whitespace, an elegant solution.

Surely the elegant solution is to not type the line in the first place.


Ignore troll, it's fairly obvious he has no aspirations to improving his own skillset and instead prefers to sit on his glass throne and throw stones.

Bad developers will remain bad developers if they want - they are an unmovable force ... and this guy appears to be a horrible developer. If he ever somehow managed to weasel into a team of mine, I'd fire him with a quickness.


Seeing all the bashing of your anti OO comment, I must leave a note of appreciation. PHP is not Java. All framework developers should write that phrase 100 times, Bart Simpson style before designing their framework.

It's not acceptable having to import a monolithic framework to write a simple webapp. All webapps start simple...

It's not acceptable having MVC crammed down my throat, when MVC, which fits desktop development perfectly, feels shoehorned in webapp environments.

So many frameworks have great code in there only to be unusable because it's trapped in monolithic OO monsters. I'm looking at you Zend, or Cake, or even symphony...

That being said, nicer frameworks are appearing. Aura and Fuel both look great.


> Seeing all the bashing of your anti OO comment, I must leave a note of appreciation.

Thanks, much appreciated.


> The code produced simply doesn't matter. Bitrot is accepted. Nobody cares.

It's a real bug-bear of mine that, in the profession as a whole, this attitude is rarely criticised, and sometimes even praised (especially on HN with the JUST SHIP IT startup mentality).

A lot of people are fine with this and can probably offer a lot of reasons pertaining to business interests, which is fine. Those can be measured, deliberate compromises backed by sound reasoning and opportunity cost. But there's this other school of thought that just thinks, "fuck it, it's just code innit."

And it seems that newcomers to programming (in PHP/on the web) are still being taught at that school.


Total agreement. Thank you for offsetting the large number of critical but unstimulating responses with this quality one. Maintenance of a codebase is perhaps the most important part of programming. Until someone's been forced to do it long term in an environment with viciously changing requirements, they will have problems designing new, maintainable software of nontrivial complexity, in my experience.

My point in mentioning this (little discussed, IMHO) property of web development in general was that many people's experience in PHP is limited to such projects, and therefore their notional understanding of software design from a maintenance perspective is limited; most of the community are not experienced programmers. IMHO this limit has been further amplified by a reliance on frameworks which are themselves often based upon fairly questionable design decisions, and are blindly worshipped as some kind of gospel.


Seriously, leave off the closing tags. They can only hurt you when you accidentally commit trailing whitespace.


Seriously, "accidentally commit?". See ~project/.git/git-hooks/pre-commit. Only a sloppy train of thought can hurt you when programming.


I cannot seem to find a major PHP framework that leaves it in so I will go ahead and officially call leaving off the closing tag a best practice by reason of: common sense, prevention is better than cure, type less--not more, etc.

Let's also hope that no noobs that were doing, or trying to do, the right thing (formal company coding practice aside) were negatively impacted in the process through performance reviews, perception, compensation, or otherwise. We understand that best practices are subjective to a degree, and that features of any language or platform will be abused. I also take this opportunity to encourage the PHP developers to add features that they believe solve real world problems and continue to make life easier for other developers.

slams gavel

Thank you for watching Coding Court lmao


So you're advocating both adding an unnecessary and meaningless text to every file in the project and adding an external process to protect against accidental mistakes... instead of simply getting rid of both?


See below.

Why on earth are you, the guy preaching simplicity, advocating for including absolutely useless, unneeded code at the end of every file?

How does that reconcile?


Greetings encoderer. Let's discuss the encodering problem at hand. So you have this scope thing yeah. In there you can put code, and in there you can't. Cool? Cool.

Now, if you open it and don't close it, that's gonna be working, but it's gonna be working using an assumption. Yeah? Yeah. So like, what is the mother of all screwups? The assumption.

So why would you ever remove it? Well now there's like all these other people claiming they wasted some time 'cause they like pressed enter a few times after the end of the scope. I mean, how much time did they waste? And was that because they were simply unfamiliar with the issue or execution environment? And who's fault is that? Really? It's not PHP's, and it's certainly not the set of other people who happen to bother being explicit as good practice.


I pity your co-workers.

What is the "assumption" I'm making? That my .php files will only have php code? YES! That's correct! Because we're not co-mingling PHP and HTML like it's 1999.

There is absolutely zero valid reason to have a PHP closing tag at the end of a PHP-only script.

Zero.

End of discussion.


OK, this is a semi-valid train of thought. It certainly beats the "in case of extra whitespace!" line.

And, on the face of it, it seems logical.

Unfortunately, it's not very good practice, for the reasons I have already outlined around relying on assumptions. (Edit: Oh, you missed the assumption - that the PHP interpreter will deal with your laziness)

For just one example, assume I have one file that produces a header, one file with some static content, and one file that produces a footer. For some reason, I want to refactor them in to a single file.

With explicit close, I can just concatenate the files. With the leave it out method (or, "look mom I saved two keystrokes after my MegaSillyStupidIndentFactoryClassMethod!"), you wind up with parser issues.

In short: If you want files with just PHP code in them, write files with just PHP code in them, and feed them to the PHP interpreter. If you want files with open tags in them, then use close tags.

"zero end of discussion i win mirror haha". Child.


If the files use mode switching and generate markup, feel free to put a closing ?> at the end of the php in that file. It's a template and it's expected that you would be switching in and out of html/php modes.

The recommendation is to not put them at the end of files that declare symbols, e.g. class files (or function files if you're allergic to OOP), as those files shouldn't have html mode output anyway.


> 'cause they like pressed enter a few times after the end of the scope

A large number of text editors automatically add a newline at the end of a non-empty final line. This problem doesn't have to come up because of some explicit action.


> A large number of text editors automatically add a newline at the end of a non-empty final line

... and doesn't PHP ignore it? I believe so. You actually need two newlines to cause issue, ie. "?>\n\n".

And, anyway, the solution is trivial and good practice anyway, on a number of levels. So why continue to argue? Sometimes people don't like to change their habits.

PS. Many editors can be configured to add "?>" for you, too!


Yea PHP is wrong because of autoloading... Everything you wrote, applies only to small projects.


> Particularly for early and reliable UTF8 support

What do you mean by that? It has a rather simple concept of strings and a very interesting set of mb_... functions as far as I remember. PHP strings are just bytes and are not even encoding-aware themselves.


Back in the day, when Ruby was almost inoperable with UTF8, you could basically just run strings through PHP's normal functions and all would work well. So, code just worked. Even with MySQL, if you had utf8 tables. The only time you needed 'mb_' IIRC was for regex or unicode character based length checking.

In hindsight I think having this just work for a lot of people is where PHP trumped perl and ruby in a way.


Hmm... I don't know what ruby and perl did, but "not barfing at 8bit characters" means something completely different for me than "unicode support". The second would know about various encodings, normalisation, sane comparisons, etc. Depends on your use case I guess.




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

Search: