

Ask HN: PHP Tricks and Best Practices? - jmtame

Hi everyone,<p>I have scoured the YC forum for a post on great PHP tricks and best practices, but found nothing.  Maybe I'm not looking hard enough, but I would appreciate it if anyone knows of great sites or tutorials.  I use CodeIgniter (excellent classes, typical MVC setup) and jQuery (uses a lot of method chaining, huge fan of this).  But I still find myself writing a lot of native PHP for my app.<p>For example, I wasn't aware of the list() function until someone was helping me write a method to convert times.  I've noticed when working with another programmer on a project that he's using sprintf() instead, and it surprisingly makes the code a lot cleaner.  I'm finding myself doing more algorithm-style methods, dealing a lot with arrays and a bunch of if's/conditionals (tertiary if's are great!).<p>Just using these as examples, I feel like there should be a cheatsheet of best practices and ways to minimize the amount of native code written somewhere but I'm not seeing it =]<p>*Edit: I'm going to open up CI's class files and look at how they wrote everything.  Perhaps a good way of doing this is to look at other frameworks?  Any suggestions there?
======
agotterer
You should learn how SPL (standard PHP library) works. Most PHP developers
don't even know it exists! In my opinion its one of the most powerful parts of
PHP if you can learn to use it correctly.

<http://us.php.net/spl>

<http://www.php.net/~helly/php/ext/spl/>

The documentation on php.net is pretty lacking. Heres are some tutorials and
examples:

<http://www.phpro.org/tutorials/Introduction-to-SPL.html>

[http://devzone.zend.com/article/2565-The-Standard-PHP-
Librar...](http://devzone.zend.com/article/2565-The-Standard-PHP-Library-SPL)

~~~
neovive
For some more SPL examples, read through the source of the KohanaPHP framework
(<http://www.kohanaphp.com>). The framework was originally a fork of
CodeIgniter, but has evolved into a completely new and powerful framework --
completely written in PHP5. The framework source is very well written and has
some excellent examples of using SPL and OOP along with some nice helpers and
libraries.

------
ericwaller
Something that took me a number of projects and maintenance type work to
realize is to use "helper" functions wherever possible.

For example, a profile link:

    
    
        <a href="/user/profile/<?=$user->id?>"><?=$user->name?></a>
    

Write a simple function:

    
    
        function user_profile_link ($user) {
            return '<a href="/user/profile/$user->profile">$user->name</a>';
        }
    

And use it:

    
    
        <?=user_profile_link($user)?>
    

I used to think the extra code upfront wasn't worth it, but after dealing with
a bunch of 300+ line templates for a while, I can tell you that it definitely
is.

Also, you can see a use of string interpolation (a common use case for
sprintf), ie "count is: $count"

~~~
pwoods
So is anyone using Smarty anymore? Or is this short form php now all the rage?
Just curious because I'd update if it was.

~~~
bprater
I could never understand the advantage of using a templating system inside
another templating system. Smarty has loops. PHP has loops. Did I miss the
train?

~~~
kwamenum86
Smarty produces slightly cleaner code but is worthless otherwise IMHO.

------
rshao
This is a bit of a specific one, but the array_shift function is really slow
on large arrays. The workaround I found is to use array_slice and unset the
array index afterward.

Overall though, I find out about a lot of cool things just from the comments
on the php.net site. For example, I learned how to use pcntl_fork from the
socket_accept page, and then I found out about socket_create_listen from one
of the process control pages.

My approach is basically just to figure out what I want to do on a higher
level, and look for sample code on all the individual parts. Then who knows, I
might discover something amazing.

------
texec
If you want to review very clean code you should better look at the Zend
Framework. It's very good object orientated PHP 5 Code.

------
auston
Have you looked through this: <http://codeigniter.com/user_guide/> ?

It has a lot of a lot, so you don't have to write so much native PHP. Even
Rasmus recommends it as his "framework" of choice (although he does not "like"
frameworks).

------
gearslips
Some of the stuff you've mentioned is really good old-school stuff, like list
and sprintf, that's fallen out of vogue.

With regard to suggestions to check out Zend Framework, my advice is: Don't.

~~~
RossM
I'd say check it out - to read - but don't use it. They've got some
interesting things in there, like OpenID implementation that's worth a read.

------
shaunxcode
fluent expressions (when uses appropriately) can be great for constructing
DSLs. Also any time you see boiler plate code take the time to refactor to
eliminate it - often times figuring out how to do that will make new
abstractions apparent. As a matter of practice search for the coolest things
you can do in python (list comprehensions etc.), lisp and ruby and figure out
how to do things in a similar way (if possible) in php.

Such as:

    
    
      //python version:
      noprimes = [j for i in range(2, 8) for j in range(i*2, 50, i)]
      primes = [x for x in range(2, 50) if x not in noprimes]
    
      //phparrayplus version:
      $noprimes = xR(2,8)->for_each('xR($x*2,50,$x)->out()')->flatten();
      $primes = xR(2,50)->diff($noprimes);
    
      //common lisp:
      (loop for x from 0 to 100 if (> (* x x) 3) collect (* 2 x))
    
      //phparrayplus version:
      $C = xR(100)->if_only('($x*$x) > 3')->for_each('2*$x');
    
      //factorial in phparrayplus, nothing else to compare this too  - just cool:
      function fac($n){
        return xR(1,$n)->reduce('$x*$y'); 
      }

~~~
apgwoz
Is "phparrayplus" a library you wrote. If so, where can it be had?

~~~
shaunxcode
yes, it should be available next week on
<http://code.google.com/p/phparrayplus>

------
DanHulton
I've had trouble for a while now with chained ifs, as in:

    
    
      [CHUNK A]
      if (chunk a succeeds) {
          [CHUNK B]
          if (chunk b succeeds) {
              [CHUNK C]
              if (chunk c succeeds) {
                  echo 'yay!'
              }
              else {
                  echo 'boo!';
              }
          }
          else {
              echo 'boo!';
          }
      }
      else {
          echo 'boo!';
      }
    

This gets messy if there's anything interesting in those chunks. Instead, take
advantage of short-circuiting and put those chunks in functions. Then you can
rewrite the above as:

    
    
      $success = do_chunk_a();
      
      $success = $success && do_chunk_b();
      
      $success = $success && do_chunk_c();
      
      echo $success ? 'yay!' : 'boo!';
    

Also, use the ternary operator EVERYWHERE YOU CAN - you'll clean up so much
code with it.

~~~
nuclear_eclipse
even better is:

    
    
        $success =
            do_chunk_a() &&
            do_chunk_b() &&
            do_chunk_c();
        ...

------
pwoods
Don't look at other frameworks. I did that and found it a complete waste of
time. The best I found was to loosely follow the Ideals of a framework you
like. I say loosely because frameworks always have the best intentions but
they can't be built for everyone. So sometime I've had to cheat. I've seen
code where somebody has made a work around instead of cheating and it's a
mess.

Other than that my personal preference is to use jquery for form submits and
manipulation, smarty for templating and everything is tied together following
MVC ideals. Class inheritance is where it's at too. Simple one is that your
Page class inherits the functions in your DB access class which inherits your
config class. Silly I know but it works great for me. Which in the end is the
point.

~~~
pwoods
Oh and also sometime I stop writing features and review the code base thus
far. This allows me to bring everything up to snuff with the the latest Ideas
I may have had. I've rewritten my own code about 20 times and it's now the way
I like it.

------
grotesk
If PHP is your choice and not the result of prior mismanagement, then I would
immediately schedule a two-week vacation. Rent a suite at a hotel with no
internet service. Bring your laptop. Pick a language: Scheme, Groovy, Python,
Ruby, Clojure, scala, Haskell... and implement something fun for twelve days.
Do nothing but immerse yourself in the language. Take a couple days of rest.
Then return to work freed of the huge mistake that is PHP.

------
senthil_rajasek
More a trick than a best practice, heredoc

[http://us.php.net/manual/en/language.types.string.php#langua...](http://us.php.net/manual/en/language.types.string.php#language.types.string.syntax.heredoc)

You should recognize this immediately if you have done any unix shell
scripting.

I use it to spit out large pieces of HTML.

------
kwamenum86
Write your own collection of object oriented php classes or use someone
else's. This will speed up your projects a ton. I tend to stay away from
frameworks unless it is commissioned work that involves a lot of boiler plate
code (forum, blog, etc.).

------
haasted
I think it would be a better idea to look at an application than a framework.
It will likely match your future work better.

MediaWiki has in my experience a very well-written codebase, so I would
designate it a good candidate for code-reading.

------
sunkencity
if speed of execution is relevant, just use echo (which takes any number of
arguments), and single quoted strings (concatenating, or parsing double quoted
strings is slower):

function user_profile_link ($user) { echo '<a href="/user/', $user->profile,
'">', $user->name, '</a>'; }

------
thwarted
list() isn't a function, it just looks like one, just like array() looks like
a function but isn't. There apparently wasn't enough syntax to spend on making
things like this less ambiguous, but now we do have \ as a namespace
separator.

------
andreyf
Cool PHP trick: write a compiler from a better language to PHP and write your
code in that ;)

