PHP

Comments: C-style and shell-style

Types

Types: scalar: bool, int, float, string; compound: array, object, callable, iterable; special: resource, NULL

To check type is_type(). For debugging gettype() and var_dump().

Literals true and false are case insensitive

int literals:

  • binary, octal, decimal and hexadecimal

  • can contain underscore

  • 32 bit or 64 bit, no unsigned ints

  • interger division with intdiv(); 1/2 yields 0.5

  • Never cast an unknown fraction to int, as this can sometimes lead to unexpected results

float

  • can contain underscore

  • do not compare for equality

  • compare NAN only with is_nan()

string

  • implemented as byte arrays (buffer + length in bytes);

  • ignorant of encoding; pay attention if a function operating on strings uses encoding; compare strlen() vs mb_strlen()

  • characters can be accesed with [] like $str[5]; indices can be negative

String literals:

  • single quotes (text not parsed, just taken verbatim),

  • double quotes (text parsed, so php constructs are evaluated)

  • heredoc (<<<EOT ... EOT): act like double quotes

  • nowdoc (<<<'EOT' ... EOT): act like single quotes, so php code can be safely put inside

Expansion inside double quotes:

  • escaped characters: \n, \r, \xff, \uaaff etc.

  • variables consumed at max after $: "some $vars" vs "some {$var}s"

  • inside {}: "{$obj->values[3]->name}", "{${getName()}}" (inserts result of getName() call); "{$foo->{$baz[1]}}"; will also work

Numeric string: string containing numberal and possibly whitespaces. In numeric contexts evaluates to int (if possible) or float.

array

Ordered map. Key: int or string, value: any type.

Casts in keys:

  • Strings with valid decimal ints unless preceded by + are cast, so 1 is stored as 1.

  • Floats -> ints

  • bools -> ints

  • null ->

Identical keys: only last is stored.

If key omitted: the increment of the last int key is used.

Use trailing comma in multi-line definition.

$a = array(1, 2);
// but
$a = array(
    0 => 1,
    1 => 2,
);

Short syntax: $a = [0, 1];

Element access: use only []

To remove element: unset($arr[5]);. unset($arr); removes the whole array.

Adding value without key:

$arr = array(5=>1);
$arr[] = 2; // adds 6=>2
unset($arr[6]);
$arr[] = 3; // adds 7=>3, though there is not element with key 6; that's
            // because the array was not reindexed

unset() does not reindex. To reindex use $a=array_values($a);

Constants are not looked within strings

print "Hello $arr['fruit']"; // won't parse

print "Hello {$arr['fruit']}"; // ok

define ('foo', 'bar');
print "Hello {$arr[foo]}"; // ok

Inside a double-quoted string, it’s valid to not surround array indexes with quotes so "$foo[bar]" is valid.

Array unpacking

$arr1 = [1, 2, 3];
$arr3 = [0, ...$arr1, 4]; //[0, 1, 2, 3, 4]

With array unpacking later values overwrite former and integer keys are renumbered.

Use unpacking only with integer keys.

Changing element in the loop:

foreach ($colors as &$color) {
    $color = strtoupper($color);
}

Sequentially adding elements

// fill an array with all items from a directory
$handle = opendir('.');
while (false !== ($file = readdir($handle))) {
    $files[] = $file;
}
closedir($handle);

Array assignment always involves value copying. Use the reference operator (&) to copy an array by reference.

iterable

Pseudo-type used for type declaration in function params and function returns

enum

enum Suit
{
    case Hearts;
    case Diamonds;
    case Clubs;
    case Spades;
}
function do_stuff(Suit $s)
{
    // ...
}
do_stuff(Suit::Spades);