
PHP: The Right Way - bencevans
http://www.phptherightway.com/
======
rickmb
Straight, simple and to the point. Nice.

Missing test and QA tools though. Probably an oversight, since the author does
suggest following Derick Rethans and Sebastian Bergmann.

And another one: read up on the SPL library before you start re-inventing that
wheel.

~~~
codeguy
All good points. If you'd like to submit a pull request, I'll be happy to
credit you with the additions and get them added to the site.

~~~
wyclif
This is a great idea. Quick grammar correction under Introduction>Input
Filtering: remove the apostrophe from "That lead's to dark and dangerous
places."

------
nikic
I like the general idea of this, but think that it is nearly useless in its
current form. It's way too superficial. To teach newbies how to do things
right it doesn't suffice to link to a few resources and hope that they'll read
them (hint: they won't). Instead one needs more concrete code examples, etc.
Which would obviously be too much for one page :)

~~~
codeguy
I agree. It's very much in a v1.0 form right now. Once I move over to GitHub
Pages, I hope to add more links to tutorials and code samples without bloating
the document itself.

~~~
ericd
I think it offers a great starting point, though, and even though I've worked
in PHP for a few years, I filled in a couple gaps in my knowledge. Thanks very
much.

------
gbog
PHP with these guidelines looks like JAVA to me, but without the relatively
sane foundations.

It is fun how much a very old moralist sentence by Confucius applies well to
PHP. He said 其本亂而末治者否矣 which can be translated, in software language
development context, as "Build a nice, reliable language on shitty definition?
Bullshit!".

(The word-by-word translation is "your - root - messy - and/but -
leaves/result - governed/orderly - have ? not - hey!")

This sentence also resonates with the odd Turkish encoding PHPbug recently
reported here: if you have so many wrong architecture decisions in the core of
your product, no amount of patching and "under the rub" filling will save you.

Edit: added word-by-word translation + typo fixes.

~~~
billpatrianakos
We get it, man. PHP sucks, you're cool/smarter/better because you use
something else, and you need to remind us all about it by jumping in every
time the letters P-H-P are seen in sequence to let us all know how it sucks by
retreading the same old lines used by the last fifty guys who said the same
thing but to your credit you really tried to be clever about it.

A good portion of why people like to mock PHP is due to the way people end up
using the language rather than the language's ugly parts. This guide is a
great step toward pointing people in the right direction with the language.
PHP has come a very long way and continues to improve. A big chunk of the
battle is having decent guides to replace all the crap that's out there
showing new PHP devs the wrong way. So why not talk about the merits of the
guide rather than taking an easy opportunity to shit on PHP. It's really
gotten old.

Hey, remember when JavaScript was like the worst language ever and everyone
felt the need to remind everyone about that constantly? I do. And now all of
them are writing blogs about how awesome node.js is.

~~~
gbog
I used PHP for five years professionally, I consider myself as well positioned
as many to have an informed opinion about PHP weaknesses and strengths. My
diagnostic is that PHP weaknesses are structural, and no amount of guidance
can fix that. If facing the choice, one should not choose PHP over other
solutions. (It happens also that I am working in Chinese tech sphere, where
many startup choose PHP just because it is used by Facebook and Wikipedia,
which is really sad.)

However, I appreciate very well the need for such a guide when you have no
other choice. I did not read all of it, but it is certainly necessary to have
strong coding conventions and a defined set of "must do/musn't do". I remember
we had even built a code checker that was forbiding the use of many php
functions and syntax, and had a set of wrappers around basic functionalities
like string functions or date functions.

~~~
jasonlotito
> I used PHP for five years professionally, I consider myself as well
> positioned as many to have an informed opinion about PHP weaknesses and
> strengths.

Yeah, that doesn't mean anything. In fact, to be frank, when I read that, I
fill in the underlying context:

"I used PHP for fives years professionally, and the code was horrible.
Granted, it was code I wrote because PHP let me write code that way..."

or

"I used PHP for fives years professionally, almost a decade ago..."

> I remember we had even built a code checker that was forbiding the use of
> many php functions and syntax, and had a set of wrappers around basic
> functionalities like string functions or date functions.

Yeah, that didn't do much to change my mind.

~~~
adeelk
Any reason for the personal attack (based on unfounded assumptions)?...

~~~
jasonlotito
No personal attack. You used your experience to justify your position, which
really means nothing. You then went on to describe practices that, if written
accurately aren't in anyone's book of good things to do.

If you take it personally, thats your issue, not mine,

~~~
adeelk
I’m not the OP.

------
aw3c2
___curl -s<http://getcomposer.org/installer> | php_ __

is creepy. Never ever run other people's code without at least giving it a
glance.

~~~
zdw
RVM's installation is similar:

<https://rvm.io/rvm/install/>

A far cry from the safer/verified "download this and check it's MD5 checksum"
method that I'd prefer.

Seriously, fixing package management so we can continuously integrate
arbitrary code would be great. Getting arbitrary OS package creation to be
almost as easy as pushing code to GitHub seems like a very worthy goal.

~~~
anthonyb
md5 is not going to protect you from much, especially if the md5 checksums are
hosted on the same server.

Also, pushing random code via apt-get is not going to win you any sysadmin
friends. They like their servers to be stable, and their packages to be well
tested.

~~~
zdw
Seeing as you can remove said code via apt, you'd likely win them over
compared to the alternative of being told to install compilers or some other
non package managed software bundler like cpan/rvm/npm that can't be canned
and easily deployed.

~~~
anthonyb
But why would you remove it? Because whatever you've installed has broken.

Much better not to be broken in the first place.

~~~
adient
It seems you live in an idyllic world far, far away from reality.

------
lukifer
While PSR-1 has pretty good universal guidelines, PSR-2 goes too far in
insisting on subjective preferences (spaces over tabs, 80-char lines,
bracketing styles). We should not pretend that there is a "correct" answer to
these choices, just as long as they stay consistent on a per-project basis.

All told, I love site, and I hope it keeps iterating. PHP may be ugly, but
it's powerful, and most of its bad reputation comes from good coders having to
pick up the pieces from bad coders.

~~~
robertpateii
PSR-2 isn't trying to say that there is one correct answer. Instead they're
trying to provide a single answer from the many valid possibilities.

"When various authors collaborate across multiple projects, it helps to have
one set of guidelines to be used among all those projects"

~~~
chrismsnz
Exactly, this is what infuriates me about the arguments and whining against
PSR-2.

Spaces, Tabs, OTBS, whatever. It doesn't matter which one was chosen, just
that something was chosen. Ask the Pythonista's what PEP8 did for their
developer's ecosystem.

Also it's important to note that that PSR-2 was based off already existing
coding standards like Zend's and Symfony's.

~~~
lukifer
And what do you do with all the coders like me who would refuse to change
their habits? Does the Python community have tabs holdouts who are github
lepers because no one wants their code "infected"? (I don't do much in Python,
I actually don't know what the community norms are.)

I think it's silly to pursue per-language consistency; it's a pipe-dream that
just leads to more religious wars over minutia. Per-project (or per-
organization) more than suffices.

~~~
batista
> _And what do you do with all the coders like me who would refuse to change
> their habits?_

Reformat their code.

As for "per language consistency", Go does it just fine...

------
jimmytucson
I didn't understand this:

    
    
        4.2. Properties
    
        This guide intentionally avoids any recommendation regarding the use of 
        $StudlyCaps, $camelCase, or $under_score property names.
    
        Whatever naming convention is used SHOULD be applied consistently within a 
        reasonable scope. That scope may be vendor-level, package-level, class-level, 
        or method-level.
    
        4.3. Methods
    
        Method names MUST be declared in camelCase().

~~~
RobAtticus
Methods should be camelCase(), but properties (fields?) can be any convention
as long as its consistent throughout.

~~~
jimmytucson
Yup, that's my basic reading comprehension dropping out again. Thank you, that
does make sense.

------
TylerE
Something to consider mentioning - there are some in PHP these days that take
this sort of stuff a bit too far. Drives me nuts to see people writing classes
to encapsulate a 3 column database result. So much overhead and boilerplate.

~~~
timaelliott
You should check out Java sometime.

~~~
pjmlp
The problem is not Java, but some types of architects that flourish in
corporations, usually doing designs with endless numbers of abstractions,
layer upon layer.

I've seen this happening in C, followed by C++, and now Java and C#.

They will do it regardless of the language being used.

~~~
timaelliott
This is an excellent point. I so often attribute my disdain to Java itself
when, in reality, the issue is the majority of Java engineers.

Java itself can be a beautifully terse language.

~~~
akavlie
"terse" is about the last word that I would use to describe Java.

Compared to almost every other language I've had exposure to, it's more
verbose.

------
postfuturist
As a part-time PHP hater who often has to work with it professionally, I
believe this is a fantastic resource. The bit on databases in particular is
something that all PHP devs should read.

That said, it is difficult to bring a legacy code base in line with modern
style, though you can improve it over time.

Also, this could benefit from some other gotchas, extremely surprising
behavior and best practices for avoiding common pitfalls.

~~~
grakic
On a database section, I am not a fan of PDO and I choose native interfaces
like mysqli for my DAO layer or opt for something high level like ORM
depending on the requirements.

But it goes without saying that protection from SQL injection is a must, it is
just PDO's statement binding is not the only way. MySQLi does support data
binding, and for others it is easy to DIY using sprintf and whatever is the
escaping method target native driver implements.

~~~
swivelmaster
You can use PDO to connect and run queries without using all the crazy
variable binding features.

------
kingkilr
One point in and its already dead wrong, you never filter input, only output.

Edit: Everyone talking about databases: paramaterized queries, check them out.

~~~
xd
SQL injection attacks alone are almost always a result of not filtering
input...

~~~
kellishaver
With parametrized queries, that becomes a non-issue, but I still see no point
in cluttering the database with data that's just going to be filtered out at
some point - might as well filter it before it goes into the DB to begin with.
The exception, of course, being those rare cases when some users need to see
the filtered data and others need to see the raw data, but even then, you
likely won't want to allow _everything_.

~~~
xd
Parametized queries are just another way of filtering input ..

~~~
mtts
No they're not. They're a method for ensuring that what is meant to go into
some field in some database actually ends up there and does not start doing
things it should not be doing.

------
_ikke_
I'm wondering why a specific code style is 'enforced' while it has nothing to
do with interoperability.

Libraries with different code styles can be used together without problems. It
seems like they are using the PSR to declare they're own style as superior.

~~~
jasonlotito
PSRs where decided based on the most common standards used by some of the
biggest PHP projects around. It wasn't a single person setting a standard.
PSRs are completely optional.

However, you miss the point. The point of this isn't really to define all the
options. Rather, it's to spell out best practices (and PSR-0 is really a best
practice, and all about interoperability) that the community generally agrees
with. Better to have a standard coding style than to have none at all, and if
you have to choose one, PSR-1 and 2 are an excellent choice (considering how
it was devised).

~~~
stephenr
Im sorry but accepting underscores as a valid alternative to namespaces in
2012, is not a "best practice".

The whole concept of PSR-0 is ridiculous anyway, because PHP supports
registering multiple class loaders. If a project wants to use a naming
convention that won't work with standard spl_autoload(), they can register
their own autoloader.

~~~
phpnode
except if you've ever had to work with lots of different autoloaders at once
you'll know that you regularly get conflicts, and getting the correct
autoloader order is often a case of trial and error. Using sane conventions
across libraries avoids all of this mess.

~~~
stephenr
i wouldn't call using underscores for namespaces and forced filenames "sane".

The built-in spl_autoload offers better support for modern code than the PSR-0
recommended autoloader

~~~
phpnode
The reason for underscores as namespaces is simply that some older libraries
want to maintain compatibility with 5.2X for whatever reasons. Of course it's
encouraged that newer libraries are written with proper namespaces and almost
all of them are.

------
stephenhandley
<http://jeena.net/images/2012/PHP-The-Good-Parts.pdf>

~~~
DCoder
There's an easier-to-read version for those who don't like PDF:
<http://jeena.net/images/2012/php-the-good-parts.jpeg> :-)

------
gabordemooij
I dont agree with the article all the way but it's certainly refreshing to see
people trying to improve PHP coding practices instead of just complaining.
Very well done.

That being said... Every language has its strengths and weaknesses. There is
nothing fundamentally wrong with PHP (except maybe that if you look at it it's
not a very exciting language, even a bit boring). Security for instance has
nothing to do with the language itself. And as for PHP syntax, it's a blessing
compared to some other languages; at least we don't have a semicolon debate in
PHP land ;-)

------
etanol
The comments about namespace are somehow ironic: is it very common to find
developers that know what classes are but not namespaces? The namespace
concept is much simpler than class. Which makes me wonder: who is the target
audience?

~~~
jmadsen
possibly. Namespaces are very new to php, so programmers who taught themselves
via php might not have much experience using or general knowledge of them

------
xd
Hey, nice work. Wouldn't a wiki platform work better however, instead of git?

Edit: also might be worth adding a bit about steering clear of phpclasses.org
as well as w3schools, they bother contain far more bad, than good code.

~~~
codeguy
Will be moving over to GitHub pages w/ Jekyll soon to automate build process.

------
socratic
Are there any good books (or other resources) on modern PHP?

I last used PHP back with PHP3 (and then went C++ => Java => Python =>
Python/JavaScript => Ruby => Python/R), but a bunch of code I want to read at
work uses PHP (with Zend). I no longer remember most of what I learned about
PHP3, though obviously the PHP syntax seems to be at least somewhat readable
as a sort of amalgam of Perl and C++ syntax and idioms. What does, e.g.,
Facebook use to get engineers who don't know PHP (but might know C++ or
Python) up and running?

~~~
nbm
As far as I know, at Facebook we don't give pre-emptively/usually give people
a book to learn PHP. Those that don't know PHP (or are rusty) can generally
get the syntax/keywords right in an hour, and then there's a longer time spent
getting familiar with both the standard library and our own
frameworks/libraries.

There is a lot of good code to look at and learn from, and the Bootcamp
program teaches a bunch of our own library and some guidance on what good and
bad standard library functions are for certain cases. We also have a "newbie"
group where people can ask questions about the codebase. And if you do
something without knowledge of a built-in (or Facebook) function/class and
make things more complex than they need to be, your code reviewer will let you
know how to do it easier/more idiomatically. Every once in a while there are
language tech talks, and sometimes even whole-day training sessions (we did
one on exciting new C++11 features).

Besides that, I definitely spent a lot of my time with php.net/function_name
open and exploring when I couldn't remember all the functions available or the
parameters and order.

------
btbytes
I suggest that you open up the doc source on github so that you can attract
contributions from people while still maintaining editorial control.

A good example is: python-guide.org -- <http://docs.python-
guide.org/en/latest/index.html>

~~~
codeguy
As mentioned elsewhere in the comments, I'll be moving over to GitHub Pages
tonight to do exactly this.

------
aichi
Why the hell is required space indentation instead of tabs? Don't you know how
to setup your editor? Don't you know that there are coders with special needs
and they would like to setup another indentation, because they are using e.g.
font size 20px to see your code?

------
countessa
this is great stuff - I'm a casual php hacker and this is just the sort of
thing I need to help me out when I'm working in the language - saves me from
having to be deeply embedded in the culture of a language I don't use "all day
every day"....so thanks!

------
pjmlp
This is a very nice guide for everyone that has to work with PHP.

------
leke
Nice read. TIL I should be doing some things differently in PHP.

------
kaolinite
Really hope they fix the formatting. Unreadable for me, the font is way too
big.

~~~
kaffeinecoma

        user:	kaolinite
        20 year old Python/PHP/C developer
    

That font will be just perfect for you in about 15-20 years.

~~~
kaolinite
In 15-20 years, I will zoom as required. The issue really is less the font
size and more the way the text stretches to the window, so if you zoom out
then the sentences become far too long. I ended up having to alter my browser
window size.

Edit: Just checked, definitely just the stretching, though a bit smaller would
be better for me.

~~~
bjt
Tangentially related: Smashing Magazine recently did an outstanding article on
readable web typography. (See
[http://www.smashingmagazine.com/2012/05/02/applying-
macrotyp...](http://www.smashingmagazine.com/2012/05/02/applying-
macrotypography-for-readable-web-page/)). They say 8-12 words per line is
ideal, though their example exercise seems to average closer to 15.

------
sneak
PHP: Not even once.

------
ObnoxiousJul
Right way to write PHP indeed. Sometimes I wish PHP itself was written this
way.

Oh! The guide does not mention the case: if a class contains only one static
method, please, use a function. It does not look as educated, but it's
obviously a function.

Not PHP specific, I admit.

~~~
lotyrin
Oh god yes. I ran into an extreme case of this recently. 200 something lines
of class definition, class variables and internal private methods that end up
chaining 5-deep, with a single public method.

Refactoring to a single function took it down to under 20 lines.

I wish I knew what motivated people to do things like this.

~~~
FuzzyDunlop
From my own experience, PHP developers who are introduced to OOP often get
taught the Java-esque flavour of it. Classes for everything, abstractions and
base classes and inheritance all over the place.

Hell, I even went there myself at one point, at first doing it to DRY up a
bunch of procedural scripts, but later introducing more abstractions to bend
the existing code to my will.

Now, I prefer simplicity and will often scrap code that jumps through all
sorts of hoops just to do something simple.

------
wseymour
I think that Lithium (www.lithify.me) would be really great to mention under
the 'popular frameworks' section.

~~~
codeguy
Thanks for the suggestion. Feel free to send a pull request and I'll be happy
to add it in!

------
erikb
I like it. Would be smart to add some kind of picture for sharing Facebook is
more successful if people not just see text.

~~~
erikb
lol. downvotes for wanting to share someone's idea. that one I really don't
get...

~~~
mikeash
Probably because your comment is extremely difficult to understand and looks a
lot like spam.

~~~
erikb
What is hard to understand about it? Most link sharing happens on facebook. If
you share a link in facebook, people will click on it, IF there is a picture
that interests them. If there is no picture 99% of people will ignore the
shared link. So for the author of this website it would make sense to add any
picture at all. When someone shares the link to his website, FB will
automatically find the picture. But there is none.

~~~
mikeash
What's hard to understand about it is that it's a mishmash of words thrown
together with no coherency. Your point about having an image to make Facebook
sharing makes sense, but there's no way to extract that point from your
original post.

~~~
erikb
There is a dot missing between "sharing" and "Facebook". I just see that now.
If there are more grammar issues, I am always open to learn. It's not my
mothertounge, though. And I think I have that attribute in common with a lot
of readers here...

------
BadCRC
These guidelines won't save you from some bullshit PHP "rules", such as:
[http://stackoverflow.com/questions/5810168/php-foreach-by-
re...](http://stackoverflow.com/questions/5810168/php-foreach-by-reference-
causes-weird-glitch-when-going-through-array-of-objects)

~~~
xd
How is that a "bullshit PHP rule"? If you for loop in C, setting a pointer
each iteration, you would expect the pointer to still be set the the last
assignment in the loop once you're out of it.

~~~
LnxPrgr3
C lets you define variables with block scope:

    
    
      int main(int argc, char *argv[]) {
      	for(int i=0;i<10;++i)
      		printf("%d\n", i);
      	printf("%d\n", i);
      }
    

The last line fails to compile—'i' is no longer defined after exiting the
loop.

Java:

    
    
      public static void main(String[] args) {
      	for(int i=0;i<10;++i)
      		System.out.println(i);
      	System.out.println(i);
      }
    

That also won't compile.

Coming from a language that supports variables with block scope, PHP's
behavior is very surprising indeed. If the first mention of $object is in the
loop, I can understand someone expecting $object in the second loop to be a
distinct variable that just happens to share the same name.

This behavior is even surprising coming from Perl, though for a slightly
different reason:

    
    
      @array = ('c', 'c++', 'java', 'perl');
      foreach $item (@array) {
          if($item eq 'perl') {
              $item = 'php';
          }
      }
      foreach $item (@array) {
          print $item . "\n";
      }
    

For that matter, PHP's reference semantics are a little surprising in general
coming from any other language I've ever used.

~~~
xd
I was thinking more of:

    
    
      #include <stdio.h>
      int main()
      {
              int arr[10] = {1,2,3,4,5,6,7,8,9,0}, *ptr;
    
              for(int i = 10; i>=0; i--)
              {
                      ptr = &arr[i];
                      printf("%d\n", *ptr);
              }
              printf("%d\n", *ptr);
      }

~~~
LnxPrgr3
Sure, but you defined ptr outside of the loop. Who defined $object outside of
the loop in the PHP example?

Also note that, in C, you have to explicitly dereference pointers:

    
    
      ptr = 42;
    

You should get a warning from your compiler if you try that. PHP effectively
goes ahead and changes it to:

    
    
      *ptr = 42;
    

Perl requires you to explicitly dereference references as well:

    
    
      @array = ('c', 'c++', 'java', 'perl');
      $item = \$array[3];
      $item = 'php'; # Does NOT replace the item in the array
      foreach $item (@array) {
          print $item . "\n";
      }
    

PHP is weird in this regard: if you ever assign a reference to a variable,
later assignments go through that reference automatically. To convert the
variable back to a normal variable, you have to unset it. I don't know of
another language that acts like this. Can you think of one?

Combine that with the lack of block scope, and you get surprises like the
example BadCRC linked.

~~~
ufo
WTF. Sometimes I wonder if I'm being unfairly prejudiced by not learning PHP
myself and making my own decision about it but things like this make me change
my mind.

~~~
smsm42
You are completely correct - you are being unfairly prejudiced by judging PHP
on explanations of people that do not understand it instead of learning it. If
you learned it, you would know references work exactly like they supposed to,
and do exactly what they are meant to do - just because they are not, as
parent assumes, pointers, he misunderstands them and thinks they are weird.
Moreover, he thinks since PHP in not like C and does not have C-like pointers
PHP is weird. Please read <http://us2.php.net/references> if you want real
information instead of collection of misunderstanding.

~~~
ufo
I think the whole point here is why does PHP even _have_ references like that.
Right now the only mainstream language I know that does that is C++ and well,
its C++ and mutable references are actually not frequently used in practice.
Most other languages stay with pass by value most of the time and PHP
references kind of look like a leaky abstraction from the underlying C
implementation...

~~~
xd
I use references for passing around large arrays of data for instance, rather
than having copies made all over the place (class instances are passed by
reference no matter what you do).

~~~
ufo
What I meant is that people usually pass things via a pointer (that needs to
be explicitly dereferrenced) or via const references (where there is no
mutation to worry about). Mutable references are rarer and usually they are
function arguments and are relatively "obvious"

