INSERT INTO `ratings`
(`rating`, `ip`)
VALUES ('{$rating}', '{$_SERVER['REMOTE_ADDR']}')
In fairness these aren't your typical "straight out of $_GET" vulnerabilities, but they impart a lax attitude towards security. For example, in the latter example above, $rating is escaped just prior to its use in that query, but $_SERVER['REMOTE_ADDR'] isn't. In the former, there is no indication whatsoever of where the variable $articlesPerPage has come from so it's impossible to tell.
The notion that some variables are "safe enough" that they don't need escaping is naive. $_SERVER['REMOTE_ADDR'] is a global variable that any other code anywhere in the script can write to. While you can't get owned immediately after putting that code live, it is still a tiny little SQL injection vulnerability waiting behind the scenes for an attacker to chain it together with some other similarly minor flaw and break in.
To this day I still come across PHP code that is vulnerable to serious, immediate SQL injection vulnerabilities and it isn't always old code. I'm not so sure that the PHP community is so quick in learning from its mistakes.
Can you tell me which language is impervious to SQL vulnerabilities? Is there some magic language out there that cleans all external input for you? Pick a language, any language, and you will just about always find that GET and POST variables aren't cleaned for you and rightly so! The language should be a tool to let you do whatever you want and leave it up to the programmer to clean input. Now, if you want to talk about frameworks that's a different story.
You picked one site with one tutorial and based off that have basically proclaimed PHP to be an insecure language. For every tutorial that skips over security or has some mistake or vulnerability there are others out there that don't. The one you chose is in PHP but you can find tutorials in any language with the same flaws.
We all get it by now. PHP is lame and it's cool to bash it. It has a history of being crappy. Fine, we know. But PHP in past couple of years has begun to address those flaws and has come a long way. Now that it's starting to get better people seem to want to cheer for it to fail. No matter how uncool it is it's still incredibly popular even among people here on HN. It's just that they don't like to talk about it out loud because of the stigma it now has among the language snobs.
I mean, come on man. Was this really in fairness or just another cheap and easy shot. An opportunity to pile on.
And to address the quote you mention... the web may still have a lot of those old and awful tutorials but that doesn't mean the community hasn't learned. More recent tutorials and information you find online is much better and the community is far more cognizant of PHPs vulnerabilities and are now using best practices far more frequently. It's always fun to bash PHP but let's just give credit where credit is due. It has taken enough steps in the right direction for it to be worthy of people taking notice.
EDIT:
Also, the tutorial site you linked to is actually quite good. Tutorials are tutorials, not technical manuals. So when you want to show someone how to, for example, take GET or POST input and manipulate it somehow you want to focus on that and not explain every little thing like all the ways your GET or POST array can kill you via XSS or SQL injection. You might mention in passing that you'd better clean your input but unless the article is about sanitizing and escaping inputs itself I don't see why it has an obligation to go into that much depth.
Regardless of the state of PHP itself, the user base is severely misinformed and a large part of the blame comes to rest on people writing tutorials like this.
Python, Ruby, Perl, Java and even C# all have popular, widely used SQL interface libraries where placeholders are the norm. Only PHP even considers injecting user data into queries. This is extremely harmful.
Tutorials should show best practices, not just the first thing that works. There should be significant attention paid to how to construct a safe and reliable query. This is not a secondary concern, not when there are automatic hacking tools with a very scary list of features (http://sqlmap.org/) out there for anyone to download.
Microsoft used to be very hand-wavey about security issues and it cost them severely. Now they've tightened all the bolts and Windows is in much better shape because of it.
The PHP community needs to root out these poisonously bad tutorials and eliminate them from search results. How can this be done? By making better tutorials and linking to them more aggressively.
Stop pretending this isn't a problem and start fixing it.
One of the most important things that's about to happen for PHP security, is deprecating the 'mysql' extension[1], which doesn't support prepared statements.
Forcing cheapo web hosts to enable mysqli or PDO will hopefully help a great deal.
I just think they should have added E_DEPRECATED warnings in 5.4 - but I see why they didn't.
It's nice that it's generating warnings now, but the best thing for the community would be to completely remove it. It'd be better to answer questions about "Why doesn't my code work?" than "How can I fix my (horribly insecure) app?" where they're not even concerned about the security issues.
PHP 5.5 will produce warnings when using mysql_query. It's a small step forward.
I can totally sympathise with the slightly angry tone of this reply, as my post was in a similar vein so I kind of had it coming. You're correct in that this was kind of just a cheap shot and I agree that the community is at least heading in the right direction. You could easily argue that if I really feel so strongly about this issue, I ought to be contacting codular to discuss the issue instead of idly bitching behind their backs on HN.
I do disagree with you on some of your points about tutorials though. You claim it's possible to find such insecure example code for any language, and that's probably true. But is it easy? The first search result for "python mysql tutorial" [1] doesn't contain any SQL injection vulnerabilities. Neither does the first result for "ruby mysql tutorial" [2]. All seems well with "java mysql tutorial" [3] too. Surely the first Google result for "php mysql tutorial" [4] can't be that bad then?
$first=$_POST['first'];
$last=$_POST['last'];
$phone=$_POST['phone'];
$mobile=$_POST['mobile'];
$fax=$_POST['fax'];
$email=$_POST['email'];
$web=$_POST['web'];
mysql_connect(localhost,$username,$password);
@mysql_select_db($database) or die( "Unable to select database");
$query = "INSERT INTO contacts VALUES ('','$first','$last','$phone','$mobile','$fax','$email','$web')";
mysql_query($query);
Ouch. In this case, your point about this being an "old and awful" tutorial does apply. But the tutorials from my original post are new, as in "2013" new. And they were on the front page of HN not one week ago. It's like, finally here comes a fresh-looking new site that looks like it might even have a shot at knocking that garbage from "freewebmasterhelp.com" off the top spot on Google, and it's still not as good as it should be.
The tutorial you linked to shows a date of 1999-2001 (not 2013...). Considering the origins of PHP being predominantly a templating language targeting "webmasters", it's understandable that this link is at the top of the search results. Unfortunate, yes, but understandable.
However, PHP is no longer a templating language. It's a full featured programming language that is used to build a variety of different systems. Trained developers work with PHP every day to build solid, testable and secure code.
There is no excuse for any trained developer to write code like that. Perhaps you shouldn't judge the language just because some untrained idiot put up a bad tutorial.
I just took a quick peek at the Java and Ruby tutorials you linked, and indeed they both talk about prepared statements. Unfortunately for PHP, so many of the tutorials that are still around are very old. We have the same issues with Javascript. If one uses Google to search for a solution to a JS problem, often she or he is confronted with a solution from 1999... which is FAR from today's "best practices". Finding a 10 year old page discussing Python or Ruby connecting to MySQL is nearly impossible due to the newness in these languages in the web arena. (Yes, Zope existed way back when.)
I do agree that the above example is the rule rather than the exception as most books I've owned show something similar or worse:
foreach($_POST as $key => $value) {
${$key} = $value;
}
That's almost as convenient as that magic global form garbage they used to have turned on by default.
I was under the impression though that the MySQLi adapter and PDO both made use of prepared statements. All we need to do now, is clean up the last few years of cruft/misinformation still floating around.
I wasn't angry and didn't mean to come off that way. Text man, emotions just don't come through... unless you use emoticons... which I never do.
But anyway I think we might just view tutorials differently. To me, what's posted above is an outdated, insecure way to put data into a database but it definitely answers the question "how do I put stuff in a databse" simply and right to the point. And that's what I like about PHP tutorials. I'd rather put the onus on the programmer to learn how to put "way to do X' and "way to do Y" together on their own rather than muddy the waters with "here's how to do X but this is important too so let's show you how to do this other thing at the same time".
> Can you tell me which language is impervious to SQL vulnerabilities?
That's not the point. The point is that PHP tutorials/books/best practice guidelines repeatedly and consistently do this sort of thing.
Even "PHP: The Good Parts" spent most of the chapter on SQL without mentioning security until the very last part, where they sort of waved their hands at it.
Sounds like a documentation problem, not one of the language.
You can shoot yourself in the foot with any programming language. PHP just happens to have one of the shallowest learning curves and greatest availability, so simply by virtue of being everywhere it's responsible for a lot of damage. It doesn't help that a newbie that came up with a working (but dangerous/incorrect/...) solution can then easily start answering other newbies' questions, although that's hardly a PHP-specific thing.
Further - because it's so many people's first programming language, they don't even know to look for information about best practices, let alone go out of their way for it. It takes a seasoned programmer to go out of his/her way to avoid repeating other people's mistakes.
Documentation and Community are a huge part of a languages usefulness. Every language that I consider to be well done has extremely good documentation and a Community that ensures that documentation is up to par.
The argument that community is not relevant to a languages usefulness is simply wrong. PHP suffers from poorer community than other languages. This is improving as the article highlights but it still has a long way to go.
PHP's documentation is some of the best I've encountered (which is quite important, as you have to use it all the time even after ten years because of all the bizarre function names and signatures on the early "core" code).
I completely agree about the community (I'm not sure who your comment is addressing, as I never argued that community is irrelevant, nor did the person to whom I was responding). But on the flip side - having some single pool of up-to-date knowledge is different than a circlejerk, and the "our way or the highway" attitude is very prevalent in some programming communities. Besides being incredibly alienating to newbies, it actively holds back development of new features and discussion of new ideas because these community managers are not trying to solve the same set of problems as the developers using the language/framework.
Yes, it's a damn shame that plenty of PHP example code is from 2006 and still sitting at the top of Google - but by and large, it still works just fine and has accurate information. It may be doing messy stuff like mysql_real_escape_string instead of prepared statements, but the end result is the same.
All of the community and documentation in the world won't stop people from using the tools wrong, and if you take away all the potentially-dangerous tools, you're left with very few things that are actually useful. I'll reiterate my previous point here: something with a low barrier to entry will tend to attract novices, and novices tend to make a lot more mess than seasoned practitioners. If PHP didn't exist and Python or Ruby took its place as the easiest thing to get up and running with, most (no, not all - I've worked with PHP long enough to know which ones are genuinely PHP-specific, and it's not many) of these PHP-hate comments could be run through s/PHP/NEWLANG/g and be completely accurate. Even when you start looking for best practices on a new language you'll encounter a valid counterexample for every single one of them, since it depends on what you're doing.
Security is important, and I can't say your concern over it is unfounded. But it seems like its coming from PHPs reputation and not PHP as it stands today.
In the edit to my comment above I touched on this. In short, when you instruct someone on how to do something you put the focus on the task and not the peripheral stuff. You may mention it in passing but to explicitly go over certain things may not be the right thing to do. I can totally see any book or tutorial showing people how to do certain things without mentioning security or kind of glossing over them. That's because you want to make sure a person gets the concept first. Once a person gets how to work with GET/POST or do anything else for that matter, you can then explicitly go over security, mention where to look for vulnerabilities, where to use the security techniques etc.
I learned a touch of Ruby and I'm getting decent with Python right now and pretty much everything I've read either completely skipped security or mentioned it in passing. At a certain point security is introduced and by that point I understood the language enough to know where to apply it in the previous examples from whatever I read. I've also been reading a copy of "Javascript: The Good Parts" and it does much the same thing where you get comfortable with the concepts and security comes later.
I think that because of PHPs history of security problems people are extra sensitive to any PHP code they read online and are almost looking for any way to jump up and say "that's not secure!!". PHP deserves that because of how it used to be but things have and are still changing very much.
I looked at "PHP: The Good Parts" and it wasn't what I expected from the name, it just seemed like a standard "Intro to PHP" book, with all the problems that entails.
To be fair, prepared statements have been a solved problem in PHP for a fair long time now, and so it's totally okay to call out the notion of "quickly learning from mistakes" when a subset of that community still doesn't use or encourage them.
Sorry about this grumbling old man comment. I was bored and tired and I was meaning to delete it, but it has replies and stuff now so it seems a bit too sneaky. Something about HN brings out the angry jerk in me sometimes. My bad, though.
No need to apologize at all. Combined with your inner grumbling old man there are still not enough hackers bashing the stupid faulty practices PHP encourages.
Edit: "encourage" as in (a) not discouraging and (b) making them easier to use for novices (without understanding the consequences).
> To this day I still come across PHP code that is vulnerable to serious, immediate SQL injection vulnerabilities and it isn't always old code. I'm not so sure that the PHP community is so quick in learning from its mistakes.
Do you not find that with other languages as well? I do.
It's a bit harsh judging the entire PHP community by the presence of yet another crap tutorial on the internet. You can bet that the people who go to PHP conferences etc (and who comprise the core PHP "community") wouldn't write example code like that.
Judging the whole of PHP and its community on the basis of one very poor tutorial is very unfair to PHP and its community. There is a lot of good PHP code out there and successful applications which don't/rarely suffer these kind of exploits (at least no more so than other apps written in other languages).
I'm fairly sure crap tutorials and SQL injections are possible in every language.
Part of this problem is that a good part of the community is amateur/hobbyist, they won't learn anything.
Some people in the PHP community love to think that PHP is used like Java, but for most of the amateurs it's a "cut and paste what works" workflow.
HipHop making an alternative VM. I see that as the biggest change in PHP in 2012. Sure HipHop has a translator/compiler (HPHPc) for a while now, but now they have a full fledged VM with a JIT (HHVM). Maybe next year we can get a sane extension framework and make a less memory intensive construct then zvals.
HipHop is incredibly promising, though it basically wasn't used outside Facebook in 2012. I hope it will get more adoption in 2013, which (as well as the performance benefits) should make PHP play a bit better with the Heroku-style services. (Since it makes a full-on web server unnecessary.)
I think that's going to be difficult, at least initially. It looks like you at least get a MySQL client though, and it can run WordPress with only a few changes: http://www.hiphop-php.com/wp/?p=113
Hehehe so true. We use some odbc driver at my company and it had major memory leaks / seg faults. I had to compile debug versions and test it out to figure out what was going on. That being said, some PHP modules are really great and would be hard to live without. I need mysql, memcached, apc, json_decode, etc... I guess the extensions I've written myself I could rewrite to some hip hop spec?
> not including apc which shouldn't be necessary anymore
APC is a bit more than an opcode cache. It can be used like memcache, although restricted to the machine it's running on. It's my understanding that it is a part of hhvm?
Those are good and help a little, but the real issue isn't just the zval containers its zvals themselves. the Spl* structures are just proof that there is lots of room for improvement of the raw php data types.
I tried hiphop earlier this year, on a large WordPress installation, and it does not make the cut. It's unstable, crashes randomly. This on top of the pain of working around missing features, like eval or dynamic vars (think $$foo). It does show great promise, but until it gets heavy use outside of Facebook, it's not for me.
What still bothers me about PHP is the split personality between the old parts (global functions, bad defaults), and the newer OO parts. I want a proper string object that is natively unicode. I want methods on my primitives like in javascript.
I've done some experimenting with meta-programming that into PHP, but it should really be done at the language level.
I too have been doing some work with meta-programming in PHP (specifically working on a typed language that cross-compiles). PHP isn't completely object oriented...even new functions for password stuff in 5.5 are added as stateless global functions w/ params. At this point, it's not worth it to change the language significantly...everyone knows the mistakes made and they just move on.
As for your project, it's neat. Runtime parsing and handling of docblock annotations can be a tad heavy and cumbersome. Some kind of pre-compiler might be nice. Also, toss your stuff on composer/packagist and you might find https://github.com/phpDocumentor/ReflectionDocBlock helpful too.
I disagree that we should just accept that PHP's old parts are a mess and never revisit them. The date functions were revisited when the DateTime type was introduced. Nothing prevents the introduction of String and Array types. The legacy string and array API's are a mess, and they affect productivity and code quality.
In the way you explain it, PHP isn't that different from C++. In C++ you can ignore all OO concepts and simply write C style procedural programs as well. No one mentions this when they discuss C++. I don't see why this "split personality" should be a problem with PHP. It's simply a language evolving, just like C did when C++ came around by keeping the old stuff around and adding new features.
I agree with you and I always wondered why the internals team hadn't done this themselves and just left the original functions as warty aliases for backwards compatibility.
I hate how to this day PHP still lacks of an obvious way to write object literals, instead forcing you to either cast arrays, which is verbose and ugly, or use stdClasses, which personally I do but damn are they a pain to use and maintaining for nested structures. This reason alone is what would make me switch to nodejs next time I start something.
There has been support for object literals for quite some time now (https://wiki.php.net/rfc/objectarrayliterals) but maybe just not enough. It would definitely be a welcome addition to the language. At least we no longer need to write array() for arrays lol.
Only array literals were implemented though, not objects. That was long overdue, but in the age of JSON we live in it's not enough. For instance, the following in Javascript:
I know, note what I said "...maybe just not enough. It would definitely be a welcome addition to the language"
People have proposed it and commented on it but it does not get enough support (votes) from senior devs to get included. Maybe with more requests it will get included finally.
I thought the point of autoloading was to make things easier, not to replace require_once with something more verbose. Why should I have to import classes from within my own package?
It's a symptom of people trying to solve everything with one toolset ("Me know hammer, me use hammer!").
In practice, most OO projects regardless of language have classes like 'LatestThingOtherThingIKindaRememberSomethingSomeoneElseWroteDontTouchIt', combined with a non-negotiable and often intrinsically (looking directly at any given piece of code) inexplicit set of dependency assumptions around the global object model.
In general we need less OO, and more immediately apparent, procedural, loosely coupled code. Programs that "do one thing and do it well".
People seem to forget that enterprisey code is drastically different from your own small projects. Having even composer in multi-person dev teams that have niche understandings can drastically improve code quality because it tends to lend itself to componentized architecture. This alone will help you escape the typical procedural nightmares if you are so inclined to do so.
PEAR was crap and lent itself to crap code. Composer is the opposite and it shows. Github and composer really should be the winners of PHP 2012 (aside from the advancements in PHP itself) as they alone have transformed the landscape in very tangible ways. I'd give props to Symfony too as they have forced most other frameworks to begin thinking outside the monolithic framework mindset.
Then again I suppose it's a little naive to expect people to escape their bubble of understanding, but I can keep on hoping.
I don't really get Laravel. The docs talk about dependency injection but at the same time they really really love static function calls. For example there's no event manager class, only a single, global event manager: e.g. "Event::fire('loaded')".
What if I want to use a different event manager? (To pass event calls across the network, for example.) There doesn't seem to be any way to do this, and pretty much all the core classes are like this.
yesss, laravel is the most promising of all. few weeks ago, i wanted to make small site in php, i evaluated nette (poor docs, bugs), silex (couldn't get autoloading to work on shared host) and finaly laravel - by far best! especialy eloquent orm is simple yet very usable AR impl, all api's very simple and clean - this fw has very railsy feeling overall.
there is laravel 4 behind the doors, i was playing little bit with it, it's even better (copy of rails :-)) - autor claims full DI support so testing should be simple...
Laravel is my first experience with php frameworks.
I have yet to actually finish a project in it which is disappointing (for something whose entire purpose is to make finishing projects faster) but I really like it. It's been a huge educational experience for me.
Oh, no... I didn't mean to imply I was blaming the tools, it's entirely my fault. I need to stop starting new projects and dumping what I have with every crazy shiny new thing I find to start over and focus ... it is something I'm working on.
PHP is getting traits? The next thing you know PHP will be type safe and scale, heh, heh ;-)
Seriously, Wordpress with a custom theme is a nice way to slap some bling on the front end and provide clients with an excellent CMS, but otherwise, for custom functionality, PHP? Thanks, I'll pass.
Facebook is maybe not the best example. Remember, they did end up writing about 3 different implementations of PHP because of their scale. If anything, their case shows that they threw enough money at it to make it work.
PHP definitely has its annoyances: the function naming scheme alone still drives me mad after nearly 15 years of PHP experience.
That said though, like most IT projects, the more you put in at the start, the more you get out in the end. If you rush into a project and don't plan out even the basics, it only stands to reason that you'll end up in a mess.
Along these lines, I have to wonder how many problems the quick-fix tutorial-style articles cost after developers copy-and-paste in an attempt to hurry through a project. My guess: lots.
Personally, I think it's an exciting time to be in PHP. It's possible to put together complicated, scalable sites in what is really an incredibly short amount of time.
4 of years ago I liked symfony. Haven't really tested it in a while though but later versions look like improvements in everything but learning curve. But I'd say the same goes for rails.
I came up to speed with PHP recently and spent a lot of time searching for "best practices" or other variations of that keyword to see what I could build on. The stuff I found was generally quite frighteningly bad, mostly people getting excited about the most absurd micro-"optimisations" (and that's after explicitly discounting anything more than a few years old).
But the ecosystem around symfony 2 seems to be where all the sane (imho) PHP developers are heading. In particular they seem to have drawn a line under old versions of PHP and made good use of the newer features added to the language to build modular components.
For a while I wondered whether everyone who wanted to use these techniques had all been driven out into the arms of Ruby (on Rails) and Python. But the Symfony guys seem to have just re-imported a lot of the best ideas back into PHP from projects like Rack, Sinatra, Django, Rails, Cucumber etc.
Check out the symfony framework version 2.1+
Its the best way to write PHP applications today and i am pretty sure its ahead of the web frameworks in most other popular languages.
It's not that bad, really. Most people are using 5.3 and are either moving towards 5.4 or recently moved to 5.4.
Those on 5.2 are probably stuck there for reasons outside of their control. And 5.5 hasn't even been released, so you can completely ignore it for the most part.
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 :)
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.
(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.
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...
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.
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.
> 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.
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.
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.
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.
<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.
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.
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"?
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.
> 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.
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.
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?
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.
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.
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!
> 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.
http://codular.com/implementing-pagination
http://codular.com/part-2-rating-system In fairness these aren't your typical "straight out of $_GET" vulnerabilities, but they impart a lax attitude towards security. For example, in the latter example above, $rating is escaped just prior to its use in that query, but $_SERVER['REMOTE_ADDR'] isn't. In the former, there is no indication whatsoever of where the variable $articlesPerPage has come from so it's impossible to tell.The notion that some variables are "safe enough" that they don't need escaping is naive. $_SERVER['REMOTE_ADDR'] is a global variable that any other code anywhere in the script can write to. While you can't get owned immediately after putting that code live, it is still a tiny little SQL injection vulnerability waiting behind the scenes for an attacker to chain it together with some other similarly minor flaw and break in.
To this day I still come across PHP code that is vulnerable to serious, immediate SQL injection vulnerabilities and it isn't always old code. I'm not so sure that the PHP community is so quick in learning from its mistakes.