PHP Idioms and Gotchas

Use includes to separate global variables into individual files and read parameters passed through serialized variables stored in temporary files

Use includes to dynamically concatenate multiple CSS files into a single PHP file, and set the Apache configuration to parse it as text/css using AddHandler application/x-httpd-php .css. Set the content type to CSS on the first line of the file using header(‘Content-type: text/css’); then add the cache_control and expires headers after the content type.

Use auto_prepend to automatically include application variables or header templates and auto_append to include footer templates or close handles, log requests, and cleanup temporary files

Use array_key_exists() to find values in arrays rather than in_array()

Use strict error reporting and a custom error handler to catch warnings of bad practices that may lead to bugs later on, such as using relative paths in an included file

Use absolute paths so that nothing breaks when you reference the path to a file from any other directory unless you move or delete the file itself

Use require over include to escalate file not found errors

Prefer require and include over require_once and include_once for better performance

Enclose literal strings in single quotes, and variable strings or strings concatenated with variables in double quotes

Use list to expand numeric array indexes into local variables, switch the values of two variables or reverse a string:

$a = 'a';
$b = 'b';

list($a, $b) = array($b, $a);

echo $a; // output: b
echo $b; // output: a

Use a colon after a conditional statement (if:, foreach:, etc.) and end statements(endif, endforeach, etc) to close scope instead of bracket notation to create conditional blocks

Use parentheses after a class name when creating an instance object

Static variables and constants can only be literals, so you can’t use them to store function return values or an object

Dot characters in form field names are converted to underscores during HTTP requests in PHP

Use the comma operator to concatenate object instances to strings

class A
  {
  private $foo = "bar";
  public function __toString()
    {
    return $this->foo;
    }
  }

$myObject = new A();
echo "The result is " , $myObject;

Post-increment operations don’t take affect until the next variable reference

$a = 4;
echo $a+++$a++; // Displays 9 since a++ only affects the second $a, and 4 + 5 = 9. $a is 6 afterwards.

Concatenate strings using echo instead of string functions

ob_start(); echo "whatever\n"; debug_print_backtrace(); $s = ob_get_clean();

Use settype to do explicit type coercion

settype($foo, "integer"); // $foo is now 5   (integer)

Use dynamic variable names to reference the value of one variable by assigning its name as the string literal value of the current variable

$foo = 'bar';
$bar = 'foobar';
echo $$foo;    //This outputs foobar

function bar()
  {
  echo 'Hello world!';
  }

function foobar()
  {
  echo 'What a wonderful world!';
  }
$foo();    //This outputs Hello world!

// You can also assign values using dynamic variables
$dress = 'purple';
$shoes = $handbag = 'silver';

echo "dress: $dress\n";         // displays 'dress: purple'
echo "handbag: $handbag\n";     // displays 'handbag: silver'
echo "shoes: $shoes\n";         // displays 'shoes: silver'

$favorite_accessory = 'handbag';
$$favorite_accessory = 'green';         // equivalent to $handbag = 'green';

echo "dress: $dress\n";         // displays 'dress: purple'
echo "handbag: $handbag\n";     // displays 'handbag: green'
echo "shoes: $shoes\n";         // displays 'shoes: silver'

//It is also useful for creating variables from the names of form fields:
foreach ($_POST as $key => $value):
  $allowed = array('username','password','repeat','email','why');
  if (in_array($key,$allowed)):
    $$key = $value;
  endif;
endforeach;

Use bracket notation to evaluate array index values and dynamic strings within double quotes

//Array index evaluation
$string = "{$person['name']} is {$person['age']} years old.";

//Dynamic variable assignment
$num=500;
${"id$num"} = 1234;
echo $id500;

Use extract to expand an associative array into a collection of local variables

$var_array = array("color" => "blue",
                   "size"  => "medium",
                   "shape" => "sphere");
extract($var_array, EXTR_PREFIX_SAME, "wddx");
echo "$color, $size, $shape, $wddx_size\n";

Use compact to import a list of local variables into an array

$city  = "San Francisco";
$state = "CA";
$event = "SIGGRAPH";
$location_vars = array("city", "state");
$result = compact("event", $location_vars);
echo $result;

Use the standard class data type instead of an array to hold attributes

//Array
$person = array('name' => 'bob', 'age' => 5);
//Standard Class
$person = new stdClass();
$person->name = 'bob';
$person->age = 5;

//This is particularly helpful when accessing these variables in a string
$string = $person['name'] . ' is ' . $person['age'] . ' years old.';
// vs
$string = "$person->name is $person->age years old.";

Stream Handlers allow you to extend the “FileSystem” with logic, such as using the MS-Excel Stream handler to create an Excel file:

$fp = fopen("xlsfile://tmp/test.xls", "wb");
if (!is_resource($fp)) {
    die("Cannot open excel file");
}

$data= array(
    array("Name" => "Bob Loblaw", "Age" => 50,
    array("Name" => "Popo Jijo", "Age" => 75,
    array("Name" => "Tiny Tim", "Age" => 90
); 

fwrite($fp, serialize($data));
fclose($fp);

Use the ‘or’ operator to assign default values to variables

Use the ‘and’ operator to guard for short-circuit evaluation of null variables and simple conditions

Use short_open_tag = Off if you have parse errors with XML documents

Use key/value pairs for one dimensional arrays with zeroed values to enable fast key lookup searches on arrays

Use string functions instead of regular expressions where appropriate. To find if a string is contained in another string use strpos or stripos. To replace values in a string when you don’t need regular expressions, use str_replace. To compare strings use strncmp instead of substr

Don’t use leading zeros for numbers because they will be evaluated as octal numbers instead of base ten

Use the strict equality operators to avoid type coercion errors when checking for falsy values and string to number comparisons

Constants have their names assiagned as the default value, so boolean comparisons will return true

Put short circuit expressions in parentheses to avoid precedence gotchas, or always use the operators && and || instead:

$x = true and false;
var_dump($x); //outputs bool(true)
$y = ($x = true and false);
var_dump($x); //outputs bool(true)
var_dump($y); //outputs bool(false)

Use an extra assignment statement or the ternary operator to return literal values from short-circuit operations instead of Boolean values:

$my_var = $some_setting || $my_var = $default_setting;
$my_var = ($some_setting ? $some_setting : $default_setting);

Use the comma operator when doing multiple echo statements

$x = 'Pass';
$y = 'the';
$z = 'beer';

// Very slow.
echo $x;
echo $y;
echo $z;

// Faster.
echo $x . $y . $z;

// Even faster than concatenation. Most of the time this
// is the preferred way to do things.
echo $x, $y, $z;

Replace foreach loops with map functions for quicker iteration

function activate_user($user)
  {
  if ($user->completed_registration())
  $user->activate_account();
  }

foreach ($users as &$user)
  {
  activate_user($user);
  }

// This accomplishes the same thing as the foreach above
$users = array_map('activate_user', $users);

Use output buffering to cache the output string internally and send it to the user in one shot. This reduces networking overhead substantially at the cost of more memory and an increase in latency:

ob_start();
for ($j=0, $max = sizeof($arr), $s = ''; $j<$max; $j++)
   echo $arr[$j]."<br>";

Output buffering with ob_start() can be used as a global optimization for all PHP scripts. In long-running scripts, you will also want to flush the output buffer periodically so that some feedback is sent to the HTTP client. This can be done with ob_end_flush(). This function also turns off output buffering, so you might want to call ob_start() again immediately after the flush.

Use ip2long() and long2ip() to store IP addresses as integers instead of strings in a database. This will reduce the storage space by almost a factor of four (15 bytes for char(15) vs. 4 bytes for the integer), make it easier to calculate whether a certain address falls within a range, and speed-up searches and sorts (sometimes by quite a bit).

Use checkdnsrr to resolve a domain name to an IP address. This is useful for partial validation of emails.

If you are using cookie-based sessions, you must call session_start() before anything is outputted to the browser.

Store CSS image paths as string variables in PHP and make them empty unless the URL matches the page which needs them to minimize HTTP requests

Flush the page after the head to clear the buffer and repaint the browser on pages that scroll excessively or include a repetitive header or navigation

Assign array properties such as length to local variables before referencing them in loops

Put global variables in an application.php page

PHP 5 provides a way for objects to be defined so it is possible to iterate through a list of items, with,
for example a foreach statement. By default, all visible properties will be used for the iteration.

When an object is cloned, PHP 5 will perform a shallow copy of all of the object’s properties

PHP 5 introduces Type Hinting, which binds function arguments to specific objects or strongly types them
as array objects

Use function myfunc($var = default) to set default values for function arguments

PHP 5 comes with a complete reflection API that adds the ability to reverse-engineer classes, interfaces,
functions and methods as well as extensions. Additionally, the reflection API also offers ways of
retrieving doc comments for functions, classes and methods.

Static references to the current class like self:: or __CLASS__ are resolved using the class in which the
function belongs, as in where it was defined. Late static binding uses the keyword static to change the
context of a static reference to the calling object, instead of the prototype, which allows child classes
to inherit static methods which reference themselves rather than their parents.

References

11 Cool Things about PHP that most People Overlook
Ten things you probably didn’t know about PHP
10 Tools for Modern PHP Development
PHP Guidelines by Eric Ritz
Pragmatic PHP
PHP and MySQL Application Development Articles
PHP Idioms
Optimizing and Debugging PHP
The SEO PHP Crash Course Tutorial
PHP Optimization Tips
Debugging PHP
One year of PHP
PHP Gotchas Part 1
PHP Gotchas Part 2
PHP Gotchas Blog
Avoid these Common PHP Gotchas
PHP WTF
PHP Idioms
Advanced PHP Optimization Tips
PHP Timer Benchmarking
Caching PHP with PEAR
PHP Optimization Tips
PHP Optimization Tricks
PHP Techniques I use all the Time
PHP Code Optimization Tips
PHP Optimization to Improve Performance
PHP Optimization and Security Tips
PHP Optimization Myths
PHP Optimization Tips
40 Tips for Optimizing your PHP Code
Multiple File Uploads
Command Line Interface
HTTP Authentication
HTTP Connection Handling
PHP Design Decisions
Getting Rich with PHP5
Why I Love Output Buffering
PHP OOP
Writing MySQL scripts with PHP and PDO
How to develop multilingual, Unicode applications with PHP
Interactive CLI password prompt in PHP
Hidden Features of PHP
On PHP 5.3’s Namespace Backslash Backlash
The PHP Scalability Myth
PHP Without PHP
Using the MySQL Native Driver for PHP
Send Mail using SMTP and PHP
Embedding Base64 Images using Data:URIs and MHTML

Study Notes

method visibility
method overloading
session registration
Dynamic Methods/Metaprogramming
Recursive Anonymous Functions
Method Chaining
Object Overloading

TrackBack URI

Blog at WordPress.com. | Theme: Pool by Borja Fernandez.
Entries and comments feeds.