7 ms·
XHP: A New Way to Write PHP (from Facebook)
- ivankirigin 17y agoXHP rocks so fucking hard, it isn't even funny. It is just so much better than alternatives. IMHO, It is the only PHP tool I use at facebook that is better than alternatives in other languages. I'm looking at you, django templates! The notation perfectly represents the objects, with no cruft associated with object oriented programming. That is really rare. You could argue that the markup syntax is cruft, but it really helps code readability to have two types of syntax, for code and for markup. $b = <span>quotes and variables</span>; $a = <div>omg, I can't "believe" how easy these {$b} are</div>;
- nostrademons 17y agoCouple questions: 1. How is this different from Django filters? Is it that the default is HTML escaping instead of having to specify the escaping with each template variable? 2. How does it handle different escaping contexts? For example, text in html attributes needs to be escaped differently from text in the body of the document. Text in URLs or JavaScript has to be escaped differently still, and often times you have to combine these escapings (eg. a JavaScript onClick attribute). Is XHP smart enough to recognize these different contexts and do the right thing, or do you need to fall back to some manual mechanism?
- ivankirigin 17y agoFilters are tags in django templates that live in .html files with a bit of logic in a bespoke mini language. XHP for python would be something like this. def view_foo( request ): baz = "roger, roger" return render_foo( baz ) def render_foo( name ): return <html><head></head><body>hi, {name}</body></html> The most glaring difference is that instead of template logic and keywords, you can use python. You definitely want to sequester rendering from the rest of your view, but I see little benefit to django templates. Missing from this code sample is some django middleware which renders a proper HttpResponse() from the XHP return. I don't know well enough to answer about escaping. Check out the framework, and try it for yourself :)
- drusenko 17y agoI'm also very interested in how it is able to escape properly... anybody?
- cmelbye 17y agoI've skimmed through the docs. Each tag that you can use is a PHP class. It knows exactly which attributes it can take and it can do some validations on the attribute values. I'd assume that it knows when there's supposed to be JS in an attribute value and when there's supposed to be text.
- jolie 17y agoI hope you don't mind, but I quoted/linked to this in my post on XHP: http://www.readwriteweb.com/archives/xhp_more_php_enhancement_from_facebook.php http://www.readwriteweb.com/archives/xhp_more_php_enhancemen... I really liked what you had to say! Please let me know if you want me to remove the quotation or change the links around it. I'm jolie@readwriteweb.com.
- rimantas 17y agoI fail to see how is this "so much better" than, say, Smarty.
- wendroid 17y agoIt's turd polish, that doesn't make anything shiny. If your code looks anything like that, or the examples on the Facebook page, you're doing it wrong.
- phatbyte 17y agoYou clearly don't have any idea how django template engine works lol. How can someone even compare this with django, beats me. But Hey, whatever works for you.
- thorax 17y agoThat is, it is impossible to generate malformed webpages while using XHP. While the purist in me thinks this is great if everyone else uses it, the immense amount of productivity lost when I first started using kid templating (e.g. http://turbogears.org/about/kid.html http://turbogears.org/about/kid.html ) really burned me on this whole concept. Sometimes I really do want to make a quick test page without crossing all my i's and dotting all the t's. Importing non-perfect markup from a designer is a big pain, too, in this kind of templating system. And, though it's unfair to say so, some companies do well enough without 100% valid XML markup: http://blog.errorhelp.com/2009/06/27/the-highest-traffic-site-in-the-world-doesnt-close-its-html-tags/ http://blog.errorhelp.com/2009/06/27/the-highest-traffic-sit...
- drusenko 17y agoSaving 14 bytes per request is something only a very few sites need to think about... For the rest of us, clarity and semantically correct code are much more useful.
- nostrademons 17y agoWasn't there just a thread complaining about how the end tags make HTML so much more verbose and difficult to read, and that's why people are writing preprocessors like HAML and XHP? I've found that the code is much clearer when you omit your end tags. As for semantic correctness - it's in the HTML spec, and every major modern browser handles it correctly. Sometimes I wonder if Google's the only folks who actually read the W3C specs, there's been so much cargo-cult advice passed down between web developers. The "always close your tags" advice came from the early 2000s, when people were pushing XHTML as a way to make your HTML pages XML compliant (the big buzzword back then). It gives essentially no benefit to users, no benefit to developers, costs you bandwidth, makes your pages slower, and clutters up your markup.
- seasoup 17y agoIf you don't close your tags, <div>foo<a>bar<span>baz box how can you tell the difference between, <div>foo<a>bar</a><span>baz</span> box</div> and <div>foo<a>bar<span>baz</span> box</a></div>
- drusenko 17y agovery, very cool. i can't wait to dig into this more... it looks like even the basic examples are cool, but there's lots of stuff under the hood waiting to be discovered.
- ashu 17y agoit is indeed one of the coolest things i have used. the fact that you have all the HTML stored as objects and available for manipulation makes all kinds of crazy post-processing (just before rendering) possible.
- andre 17y agoI'm going to give it a try, simply because of this: Facebook Lite site was written entirely with XHP.
- there 17y agoseems to me that if they went to the trouble to make it understand xml syntax and error out on invalid code, they should have just made it auto-close tags. on pages where there are heavily nested divs and other things, auto-closing the tags would make the code smaller while still generating valid xhtml and not bothering the developer with such trivial things. echo <div><strong><em>blah;
- andre 17y agoOne last feature of XHP, which has been invaluable to us at Facebook, is that you can define your own elements which can condense a complex component into a simple XHP tag. XHP has a rich collection of declarations which let you define new elements, configure their expected attributes, as well as describe their content model.
- Maascamp 17y agoWhile I understand where you're coming from, I feel like that would result in incredibly confusing markup and only lead to increased headaches down the road. I'm glad they left that out.
- deleted 17y ago[deleted]
- callmeed 17y agoThis sure would make working with WordPress themes easier.
- blasdel 17y agoThe useful abstraction might mean that they wouldn't need to be GPLed, especially if combined with a sane view/template separation (like Django's: the template just gets a dict as input and nothing else).
- fookyong 17y agomaybe I've misunderstood, but this seems to advocate mixing inline HTML and php logic - isn't that a huge step backwards in terms of web software architecture? I thought we were all using the MVC model by now... My head just hurts thinking how utterly unmaintainable all that spaghetti code must be.
- ashu 17y agoThis doesn't say that at all. The rendering code you write needs to be modular as well, and has quite a bunch of logic built into it (even when all the model and controller logic is separate.) So when you write your renderers as classes or functions, that is when you realize the benefit of XHP.
- flogic 17y agoNot really. You can still separate MVC style. Templates have always had some display logic, which is ok. What you don't want is intermixed application logic.
- commonsense 17y agoIn my opinion this "fuzzy" separation is exactly what frameworks like Django (and many existing PHP MVC frameworks) tries to avoid - they specifically disallow things like arithmetic in their templating language for this reason. As soon as you get more than one person working on a site, you're going to have an overly ambiguous demarcation point between the presentation and the logic layers and it's going to wreak havoc on the development process. It will take an enormous amount of discipline to have a parallel design/code workflow. Does this offer any benefits to XML comprehension beyond syntactical sugar to allow echo avoid the use of quotes and to remove the god-awful <?php ?> syntax (which puts it at par, at the very best, in my opinion)? Does it handle XML syntax errors gracefully? Can you do native transformations on bound variables, for example, or do any more sophisticated XML DOM-ish tag functions? The post doesn't mention anything about any of these issues, which is where the real advantage would lie. If any of that were possible, you could put the browser DOM (and validation) one step closer to the application logic. As far as I can tell this just attempts to ambiguate the VC in MVC, where Django tries to replace V with T (template). As far as I'm concerned this only increases the squinty-eyed "WTF" factor between PHP and other languages.
- jbyers 17y agoFor me, XHP is far more interesting than HipHop. And I say that as someone who administers a pile of single-application CPU-bound PHP servers. This completely and forever changes the templates-vs-just-PHP debate, and I'm glad -- it's the kind of evolution PHP needs to continue to be taken seriously.
- lanstein 17y agoStrangely enough, I'm reading your PHP code just now :)
- jbyers 17y agoHeh, which code is that? If it's anything to do with a certain salesforce-like system at a certain log-searching company, I apologize. :)
- jolie 17y agoHi James! I hope this is ok with you - I quoted & linked to this comment in my post on XHP tonight: http://www.readwriteweb.com/archives/xhp_more_php_enhancement_from_facebook.php http://www.readwriteweb.com/archives/xhp_more_php_enhancemen... If you want me to remove the quotation or change the links, just let me know. I'm jolie@readwriteweb.com.
- whalesalad 17y agoBTW for those of you interested in installing on Linux, you'll need php5-dev (so on deb/ubuntu machines a quick apt-get install php5-dev solves it). Run phpize from the root, then the normal ./configure, make, make install etc...
- bshep 17y agohas anyone gotten this to work on OSX? I get strange errors after I build and add the extension to php.ini LOG: http://pastie.org/817528 http://pastie.org/817528
- whalesalad 17y agoI have so many damn unnecessary problems with OS X that I've resorted to running a lightweight Debian VM with VMWare. It uses ~250mb out of my 4GB RAM and I can just suspend it whenever I'm not coding. Benefits: I can use apt-get and have all the other conveniences of a true *nix environment. I can update and try out new software easily (I had XHP running in about 5 minutes). Also, I can create snapshots of my OS so that when my environment is just the way I like it, I can always revert right back to it. I interact with certain paths on my virtual linux filesystem just as though they were local (like my ~/Sites dir) and have various dev domains in my /etc/hosts file pointing to the VM (which has it's own internal ip). Cons: It's a standalone VM so it consumes a consistent 250mb of memory. Never really looked at what mysql/apache were doing on my Mac previously (I would assume far less) but I haven't really ran into an issue where the VM is a big issue yet. The convenience far outweighs the chuck of memory it eats up :) I haven't had a single configuration problem yet ;) For developers the popular phrase is reversed, Debian "just works" and OS X is a pain in my ass.
- cmelbye 17y agoWorking perfectly for me on OS X snow leopard. It compiled cleanly.
- bshep 17y agoGot it compiled properly now, had to get one of the versions without the lexer/parser files included. However I'm still getting 'xhp_a' class not found errors with the basic tests from the wiki, the same as the other comments in the sibling thread. It seems to happen on several platforms so its probably a configuration error somewhere. Any help would be appreciated. EDIT: Figured it out. You need to include 'init.php' from 'php-lib' in your php scripts. I copied the directory from the xhp source to my site directory and included them from there.
- vl 17y agoI'm using PHPTal right now to achieve more or less same effects, but it's not the easiest solution - it becomes a bit cumbersome for long fragments. XHP looks very promising because it solves one of my problems with PHPTal - generating complex content in the loop (in PHPTal having multiple conditions in loop is possible, but not exactly elegant) For example: <?php $list = <ul />; foreach ($items as $item) { if ($item->bold) { $list->appendChild(<li><b>{$item}</b></li>); } else if ($item->foobar) { $list->appendChild(<li><i>{$item}</i></li>); } else { $list->appendChild(<li>{$item}</li>); } } ?>
- brown 17y agoThe sentiment here seems to be overwhelmingly positive. Call me a cynic, but this reminds me of "magic_quotes" all over again: a "feature" that tries to help, but masks the fundamental problem.
- jbyers 17y agoWhat is the fundamental problem it masks?
- spoondan 17y agoPresumably he means allowing users to thoughtlessly work with unsafe values. One way that XHP could mask this problem is clear by looking at: echo <span class="username">{$_POST['name']}</span>; Now someone comes along and decides the span is unnecessary, turning the code into the (erroneous): echo $_POST['name']; However, I don't think this is a problem with XHP's approach, except in the sense that XHP doesn't go far enough in fixing PHP's faults. If PHP gave all unsafe values the type "unsafe string" and disallowed all implicit conversion to safe types, then XHP's approach would be a welcome way of doing the right thing by default. Programmer-introduced errors like the above example would result in fatal type errors instead of exploits (presuming "echo" won't take unsafe strings and so requires a conversion function, like htmlspecialchars or the hypothetical unsafe_cast).
- wvenable 17y agoOne could simple write their own "echo" function which only takes an XML object parameter. // This works write(<span class="username">{$_POST['name']}</span>); // Where as this wouldn't work write($_POST['name']); I think perhaps the use of echo in these examples is just a simplification. More than likely, in Facebook, these XML classes are outputted by another function.
- commonsense 17y agoThe separation of presentation and logic. Anyone who's spent the 1990s coding Perl CGI will tell you just how big of a step backward this is.
- deleted 17y ago[deleted]
- est 17y agolooks like E4X, which security is a problem http://sla.ckers.org/forum/read.php?2,20408 http://sla.ckers.org/forum/read.php?2,20408 Any code mix operation & data is dangerous. That's all how overflow exp, injection and XSS works
- jerf 17y agoIn a previous job, we used Apache::ASP, which is basically PHP-style <? ?> tags, only with Perl in the insides. We got an awful lot of mileage out of simply re-writing the default <?= ?> equivalent to automatically HTML-escape the contents, and adding a new <?! ?> type thing to pass through the inside unescaped. It's less "cool" than this, certainly, but making the default reasonably safe and forcing you to ask for the dangerous level of output rather than defaulting to dangerous and having to ask for safe is a lot easier to implement.
- jolie 17y agoSee also: Rasmus Lerdorf's discussion of XHP: http://toys.lerdorf.com/archives/54-A-quick-look-at-XHP.html http://toys.lerdorf.com/archives/54-A-quick-look-at-XHP.html "...when you combine XHP with HipHop PHP you can start to imagine that the performance penalty would be a lot less than 75% and it becomes a viable approach. Of course, this also means that if you are unable to run HipHop you probably want to think a bit and run some tests before adopting this."
- stephen 17y agoScala does basically the same thing with XML: http://www.scala-lang.org/node/131 http://www.scala-lang.org/node/131 ...although I doubt it does escaping by default. Should be simple enough to add while you're converting the scala.xml.NodeSeq (iirc) to text. For an API that required both XML and JSON output, Scala's built-in XML support had us wishing the JSON version of the API was as easy as the XML version.
- leftnode 17y agoUgh, I dislike this a lot. I'm one of the guys who actually likes PHP, so this may be a bit skewed, but what's wrong with PHP's existing alternate syntax? Most people don't know about it, but it's clean and easy to follow: <?php if ( true === $some_value ): ?> <div>display this div</div> <?php else: ?> <div>display this div instead</div> <?php endif; ?> This way, you can keep basic logic in your templates (its inevitable and convenient), it's still PHP (there's endforeach, endfor, endwhile, etc.), and this method of templating is very clean. You can now have a class that sets variables through __set(), loads up a .phtml file, starts output buffering, renders the file with those variables, and then returns it. You can extend it further to automatically sanitize output variables for XSS and whatnot, cache output, etc. This way, you don't need some overly verbose system like smarty to do what PHP does already. XHP just looks like another smarty: solving a problem that I really don't think exists. Edit: Ok, I probably shouldn't say I dislike this a lot, I do love seeing Facebook sticking with PHP and ultimately helping it out.
- dtjm 17y agoThat sort of code can get really messy when you have to put PHP code inside the DIVs. I think I might like the more concise, readable syntax that XHP offers for interpolating {$variables} (and any PHP code for that matter).
- justinph 17y agoSure, let's take two clusterfucks, php and xml, and smash them together! Great idea! (Actually, this looks rather handy.. but there is a certain amount of initial WTF.)
- shaunxcode 17y agoAnother awesome example of the lengths people will go to compensate for a lack of macros. I would so much rather see (define table (html-table (map [tr (td _)] rows))) then $table = <table>; foreach($rows as $row) { $table->appendChild(<tr><td>{$row}</td></tr>); (assuming this is even possible?) }
- JoelMcCracken 17y agoI was just about to make this comment. I think one of lisp's adoption problems is that it makes things that are just simply amazing become commonplace.
- rockstarq 17y agohey