PHP

See the PHP Manual for more information.

Variables

Globals

Document root

Constants

// Define constants.
define("CONSTANT", "Hello world.");
echo CONSTANT; // Returns "Hello world."

Arrays

Define an array

// Define an array.
$my_array = [a,b,c,d];

// Define an array (the old standard way < php 5.3).
$my_array = array(a,b,c,d);

Get the last element of an array

$lastEl = array_pop((array_slice($array, -1)));

Count the number of element in an array

$total = count($array);

Double Quotes

// Using an object.
$my_class = new stdClass();
$my_class->animal_action = 'jumps';

echo "The quick brown fox $my_class->animal_action over the lazy dog.\n";

// Using an array.
$my_array = [
    'animal_action' => 'jumps'
];

echo "The quick brown fox {$my_array['animal_action']} over the lazy dog.\n";

// Using mixed array and object.
$my_class = new stdClass();
$my_class->animal_actions[] = 'jumps';

echo "The quick brown fox {$my_class->animal_actions[0]} over the lazy dog.\n";

Shorthand

Ternary Operators

$var = 5;
$var_is_greater_than_two = ($var > 2 ? true : false); // returns true.

Objects and Classes

In Object-Oriented Programming a container called a class holds a collection of functions (called methods when they are in a class). A class does nothing until an instance of it is created (instantiated). Once an instance of a class has been created the methods can be used. A program can use any number of classes.

Defining a Class

<?php
class SimpleClass
{
    // property declaration
    public $var = 'a default value';

    // method declaration
    public function displayVar() {
        echo $this->var;
    }
}
?>

Instantiating (Creating) a class instance

// Standard class instantiation.
$myClassInstance = new MyClass();
$myClassInstance = new child\MyChildClass();
$myClassInstance = new \MyRootLevelClass();
// PHP library classes
// Are always at the root so simply use one slash.
// Instantiate a class dynamically
$className = '\\Foo\\Bar\\MyClass';
$classInstance = new $className();
// Instantiate a new empty class
$myEmptyClassInstance = new stdClass();

Calling functions and methods

// Call a function programmatically
$func = 'my_function';
$func('param1'); // calls my_function('param1');
// Call a class method programmatically
$my_method_name = 'foo';
$my_class = new MyClass();
$my_class->$my_method_name(); // calls the MyClass->foo() method. 

Convert an object to an array

function obj_to_array($obj)
{
    return (array) $obj;
}

Autoloading

In order to instantiate (create an instance of) a class which is defined in a separate file, that file must be included or required into the file currently being executed.

Error Handling

Error Reporting

// Report all PHP errors.
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);

This alone doesn’t make PHP show parse errors. The only way to show parse errors is to set display_errors = on in the php.ini file.

Validation

Validation means testing a variable for specific requirements. If the requirements are met, validation passes, if not, validation fails. The value being tested is never altered.

Validation is used primarily when evaluating input parameters from GET or POST. PHP has provided a number of methods to work with input parameters.

Alphanumeric

ctype_alnum() will return false with blank strings.

// Validate an alphanumeric string.
function is_alphanumeric($string)
{
    if (ctype_alnum($string)) {
        echo "true\n";
    } else {
        echo "false\n";
    }
}

// test cases.
is_alphanumeric("a7jkB68J0qPfc"); // returns true.
is_alphanumeric("A"); // returns true.
is_alphanumeric("a"); // returns true.
is_alphanumeric("1"); // returns true.
is_alphanumeric("0"); // returns true.
is_alphanumeric(1); // returns false.
is_alphanumeric(0); // returns false.
is_alphanumeric(''); // returns false.
is_alphanumeric(""); // returns false.

Email Address

$email = "john.doe@example.com";

if (!filter_var($email, FILTER_VALIDATE_EMAIL) === false) {
  echo("$email is a valid email address");
} else {
  echo("$email is not a valid email address");
}

Filter and Sanitize

filter_input

// Sanitize input
if (is_numeric($_POST[$post_key])) {
    $filtered_db_inputs[$post_key] = filter_input(INPUT_POST, $post_key, FILTER_SANITIZE_NUMBER_INT);
} else {
    $filtered_db_inputs[$post_key] = filter_input(INPUT_POST, $post_key, FILTER_SANITIZE_STRING);
}

Trimming

Use trim, ltrim, and rtrim to remove substrings from the beginning and end of a string.

$string = ' _hello_ ';
$trimmed = trim( $string ); // Returns "_hello_"
echo trim( $trimmed, '_' ); // Returns "hello"

// Warning 'ltrim' and 'rtrim' remove all instances of all the characters passed
// to the function. It is not a string definition.
echo ltrim( $string, ' _' ); // Returns "hello_ "
echo = rtrim( $string, '_ ' ); // Returns " _hello"

Serializing

If your string contains a ", ', :, or ; character in any of the array values the serialization will get corrupted. In order to avoid this, always base64 encode and decode along with serializing.

// Safely serialize.
$safe_string_to_store = base64_encode(serialize($array));

// Safely  unserialize...
$array_restored_from_db = unserialize(base64_decode($array));

Concatenation

Using arrays

// Concatenate lines with an an array to maintain line breaks.
function get_div( $content )
{
    $output = array();

    $output[] = '<div>';
    $output[] = $content;
    $output[] = '</div>';
    
    return implode("\n", $output);
}

// Example:
echo get_div( 'hello' );

// Outputs:
// <div>
// hello
// </div>

URLs and File Paths

Get the current URL

$url =
    'http' . (isset($_SERVER['HTTPS']) ? 's' : '' ) .
    '://' . "{$_SERVER['HTTP_HOST']}{$_SERVER['REQUEST_URI']}";

Get parts of a URL

$url = 'http://username:password@hostname:9090/path?arg=value#anchor';

echo parse_url($url, PHP_URL_SCHEME); // Returns "http"
echo parse_url($url, PHP_URL_USER);   // Returns "username"
echo parse_url($url, PHP_URL_PASS); // Returns "password"
echo parse_url($url, PHP_URL_HOST); // Returns "hostname"
echo parse_url($url, PHP_URL_PORT); // Returns ""
echo parse_url($url, PHP_URL_PATH); // Returns "/path"
echo parse_url($url, PHP_URL_QUERY); // Returns "arg=value"
echo parse_url($url, PHP_URL_FRAGMENT); // Returns "anchor"

// Get all the URL parts in an array.
$url_parts = parse_url($url);

Get the current file path

//
// Get the absolute path to the directory containing the current working file.
var_dump(__DIR__); // Recommended fastest way, but only available for PHP >= 5.3.
var_dump(dirname(__FILE__));

// Example:
// Both methods produce exactly the same result:
// string '/home/squale/developpement/tests/temp' (length=37)

Get parts of a file path

$file_path = '/home/mydir/myfile.pdf';

// Get all the path parts in an array.
$file_path_parts = pathinfo( $file_path );

// Get each part separately
echo pathinfo( $file_path, PATHINFO_DIRNAME); // Returns "/home/mydir"
echo pathinfo( $file_path, PATHINFO_BASENAME); // Returns "myfile.pdf"
echo pathinfo( $file_path, PATHINFO_EXTENSION); // Returns "pdf"
echo pathinfo( $file_path, PATHINFO_FILENAME); // Returns "myfile"

Get a file extension

This is faster than using pathinfo() or getting the value from array if you just need the ext.

$ext = substr(strrchr($filename, "."), 1);

Get the headers of a remote file

Get the headers from a file hosted at a remote server without downloading the whole file.
Headers contain content-type and file size info.

$media_file_headers = array_change_key_case(get_headers($file_url, TRUE));

Check if a local file exists

$filename = $_SERVER['DOCUMENT_ROOT'] . 'images/myImage.png';

if (file_exists($filename)) {
     echo "The file $filename exists";
} else {
     echo "The file $filename does not exist";
}

Time

Unix Timestamp

The Unix Timestamp (Unix time, Unix epoch, or POSIX time) is the number of seconds that have elapsed since January 1, 1970 (midnight UTC/GMT).

# Get the current timestamp in seconds.
$current_time = time();

# Get the current timestamp in microseconds.
$current_microtime = microtime(true);

Convert Seconds to Readable Time

function get_time_from_seconds( $seconds )
{
    $hours = floor($seconds / 3600);
    $mins = floor($seconds / 60 % 60);
    $secs = floor($seconds % 60);

    $hours = ( $hours > 0 ? ltrim($hours, '0') . ':' : '' );

    $mins = ( $mins > 0 ? $mins : '0' );
    $mins = ( $mins > 9 ? $mins : '0' . $mins );
    $mins = ( $hours > 0 ? $mins : ltrim($mins, '0') );
    $mins = ( $mins == '' ? '0:' : $mins . ':' );

    $secs = ( $secs > 0 ? $secs : '0' );
    $secs = ( $secs > 9 ? $secs : '0' . $secs );

    return $hours . $mins . $secs;
}

// Run some tests.
echo get_time_from_seconds( '10' ) . "<br>"; // 0:10
echo get_time_from_seconds( '65' ) . "<br>"; // 1:05
echo get_time_from_seconds( '400' ) . "<br>"; // 6:40
echo get_time_from_seconds( '800' ) . "<br>"; // 13:20
echo get_time_from_seconds( '3600' ) . "<br>"; // 1:00:00
echo get_time_from_seconds( '3606' ) . "<br>"; // 1:00:06
echo get_time_from_seconds( '3660' ) . "<br>"; // 1:01:00

DOM and HTML Parsing

DOMDocument

PHP core comes with a very handy HTML parser called DOMDocument.

// Create a new DOMDocument object.
$dom = new DOMDocument; 
 
// Load the HTML content into the object.
$dom->loadHTML($html);

Once the HTML is loaded into the object, access nodes and child elements:

Get an element by it’s ID

$mydivObj = $dom->getElementById('mydiv');

Get all elements of a type

$anchors = $dom->getElementsByTagName('a'); 
foreach($anchors as $anchor)
{
    echo $dom->saveHTML( $anchor ); // Prints the text-only content of the anchor.
}

More Resources
Parse html DOM with DOMDocument

Remove Tag Attributes


function removeAttribute( $html, $attributeName )
{
    return preg_replace( '/(<[^>]+) ' . $attributeName . '=".*?"/i', '$1', $html );
}

echo removeAttribute( '<div style="color:#CCC;"></div>', 'style' ); // Prints '<div></div>'

Starts and Ends With

/**
 * Returns `true` if the string (haystack) stars with the search-string (needle).
 */
function starts_with( $haystack, $needle ){
    return substr( $haystack, 0, strlen( $needle ) ) === $needle;
}

// Tests.
$string = 'Test test test this is a test.';

echo ( starts_with( $string, '27' ) ? 1 : 0 ); // 0
echo ( starts_with( $string, 'Rest' ) ? 1 : 0 ); // 0
echo ( starts_with( $string, 'Test' ) ? 1 : 0 ); // 1
echo ( starts_with( $string, 'test test test' ) ? 1 : 0 ); // 0
echo ( starts_with( $string, 'Test test test' ) ? 1 : 0 ); // 1
echo ( starts_with( $string, 'Test test test this is a test.' ) ? 1 : 0 ); // 1

// Lowercase both input vars to check with case-insensitivity.
echo ( starts_with( strtolower($string), strtolower('Test') ) ? 1 : 0 ); // 1
/**
 * Returns `true` if the string (haystack) ends with the search-string (needle).
 */
function ends_with( $haystack, $needle ){
    return $needle === "" || (
        ( $temp = strlen( $haystack ) - strlen( $needle ) ) >= 0
        && strpos( $haystack, $needle, $temp) !== FALSE
    );
}
/**
 * Return characters from the beginning or end of a string.
 */
$string = 'testers';

// Get the first character of a string.
$newString = substr( $string, 1 ); // returns "t"

// Get the first three characters of a string.
$newString = substr( $string, 3 ); // returns "tes"

// Get the last character of a string.
$newString = substr( $string, -1 ); // returns "s"

// Get the last three characters of a string.
$newString = substr( $string, -3 ); // returns "ers"
/**
 * Remove characters from the beginning or end of a string.
 */
$string = 'testers';

// Remove the first character from a string.
$newString = substr($string, 0, 1); // returns "esters"

// Remove the first three characters from a string.
$newString = substr($string, 0, -3); // returns "ters"

// Remove the last character from a string.
$newString = substr($string, 0, -1); // returns "tester"

// Remove the last three characters from a string.
$newString = substr($string, 0, -3); // returns "test"
/**
 * Returns all characters from the string after
 * the last occurrence of the substring.
 */
function get_after_last_occurance( $string, $substring ){
    return array_pop(explode( $substring, $string));
}

Random String Generator

Run this code on 3v4l.org

/**
 * Generate a random string, using a cryptographically secure 
 * pseudorandom number generator (random_int)
 * 
 * per https://stackoverflow.com/a/31107425
 */
function get_random_string($length = 16, $keyspace = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ')
{
    $str = '';
    $max = mb_strlen($keyspace, '8bit') - 1;
    for ($i = 0; $i < $length; ++$i) {
        $str .= $keyspace[random_int(0, $max)];
    }
    return $str;
}

// Tests.
echo 'Test 01: ' . get_random_string() . "\n";
echo 'Test 02: ' . get_random_string(2) . "\n";
echo 'Test 03: ' . get_random_string(32) . "\n";
echo 'Test 04: ' . get_random_string(16, '1234567') . "\n";
echo 'Test 05: ' . get_random_string(16, '123abcABC') . "\n";
echo 'Test 06: ' . get_random_string(16, 'ABC') . "\n";
echo 'Test 07: ' . get_random_string(16, '10') . "\n";

Parsing Directories

/**
 * Converts a nested directory tree into a multidimensional array
 * structured to represent the nesting hierarchy of all
 * files and directories defined by '$startpath'.
 */
function get_recursive_dir_file_listings( $startpath )
{
    $listings_array = array();

    $raw_listings = new RecursiveIteratorIterator(
        new RecursiveDirectoryIterator( $startpath ),
        RecursiveIteratorIterator::CHILD_FIRST
    );

    foreach ($raw_listings as $splFileInfo)
    {
        if( $splFileInfo->isDir() )
        {
            $path = array( $splFileInfo->getFilename() => array() );
        }
        else
        {
            $path = array( $splFileInfo->getFilename() ); 
        }

        for( $depth = $raw_listings->getDepth() - 1; $depth >= 0; $depth-- )
        {
           $path = array( $raw_listings->getSubIterator( $depth )->current()->getFilename() => $path ); 
        } 

        $listings_array = array_merge_recursive( $listings_array, $path ); 
    } 

    return $listings_array;
}

// Example:
// This will print an array containing the contents of
// the current directory and everything under it.

print_r( get_recursive_dir_file_listings( __DIR__ ) ) ;

Abbr Bytes

/**
 * Convert bytes to proper abbreviation.
 */
private function format_bytes($bytes, $precision = 2) { 
    $units = array('B', 'KB', 'MB', 'GB', 'TB'); 
    $bytes = max($bytes, 0); 
    $pow = floor(($bytes ? log($bytes) : 0) / log(1024)); 
    $pow = min($pow, count($units) - 1); 
    $bytes /= pow(1024, $pow);
    return round($bytes, $precision) . ' ' . $units[$pow]; 
}

Loop Over New Lines

foreach(preg_split("/((\r?\n)|(\r\n?))/", $subject) as $line){
    // do stuff with $line
} 

Bootstrap a PHP App

Route all requests the server to one index.php file. This technique is known as bootstrapping. It transfers the routing responsibility from the web server to the app.

The first step is to setup an Apache virtual host which will follow SymLinks and allow overrides from mod rewrite.

# httpd.conf
<VirtualHost *>
    ServerName mydomain.com
    DocumentRoot "/abs/path/to/mywebroot"
    <Directory />
        Options Indexes FollowSymLinks
        AllowOverride All
    </Directory>
</VirtualHost>

A .htaccess file must exist in the same directory as the index.php file.

# .htaccess
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule ^(.*)/$ /$1 [L,R=301] # This enforces NO trailing slashes
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>