Perl and PHP are more different than alike. Let's consider Perl 5, since Perl 6 is still under development. Some differences, grouped roughly by subject:
- Perl has native regular expression support, including regexp literals. PHP uses Perl's regexp functions as an extension.
- Perl has quite a few more operators, including matching (
=~
, !~
), quote-like (qw
, qx
&c.), exponentiation (**
), string repetition (x
) and range (..
and ...
). PHP has a few operators Perl doesn't, such as the error suppression operator (@
), instanceof
(though Perl does have the Universal::isa
method) and clone
.
- In PHP,
new
is an operator. In Perl, it's the conventional name of an object creation subroutine defined in packages, nothing special as far as the language is concerned.
Perl logical operators return their arguments, while they return booleans in PHP. Try:
$foo = '' || 'bar';
in each language. In Perl, you can even do $foo ||= 'default'
to set $foo to a value if it's not already set. The shortest way of doing this in PHP is $foo = isset($foo) ? $foo : 'default';
(Update, in PHP 7.0+ you can do $foo = $foo ?? 'default'
)
- Perl variable names indicate built-in type, of which Perl has three, and the type specifier is part of the name (called a "sigil"), so
$foo
is a different variable than @foo
or %foo
.
- (related to the previous point) Perl has separate symbol table entries for scalars, arrays, hashes, code, file/directory handles and formats. Each has its own namespace.
- Perl gives access to the symbol table, though manipulating it isn't for the faint of heart. In PHP, symbol table manipulation is limited to creating references and the
extract
function.
- Note that "references" has a different meaning in PHP and Perl. In PHP, references are symbol table aliases. In Perl, references are smart pointers.
- Perl has different types for integer-indexed collections (arrays) and string indexed collections (hashes). In PHP, they're the same type: an associative array/ordered map.
- Perl arrays aren't sparse: setting an element with index larger than the current size of the array will set all intervening elements to
undefined
(see perldata). PHP arrays are sparse; setting an element won't set intervening elements.
- Perl supports hash and array slices natively, and slices are assignable, which has all sorts of uses. In PHP, you use
array_slice
to extract a slice and array_splice
to assign to a slice.
- You can leave out the argument to the subscript operator in PHP for a bit of magic. In Perl, you can't leave out the subscript.
- Perl hashes are unordered.
- Perl has a large number of predefined and magic variables. PHP's predefined variables have quite a different purpose.
- Perl has statement modifiers: some control statements can be placed at the end of a statement.
- Perl supports dynamic scoping via the
local
keyword.
- In addition, Perl has global, lexical (block), and package scope. PHP has global, function, object, class and namespace scope.
- In Perl, variables are global by default. In PHP, variables in functions are local by default.
- Perl supports explicit tail calls via the
goto
function.
- Perl's prototypes provide more limited type checking for function arguments than PHP's type hinting. As a result, prototypes are of more limited utility than type hinting.
- In Perl, the last evaluated statement is returned as the value of a subroutine if the statement is an expression (i.e. it has a value), even if a return statement isn't used. If the last statement isn't an expression (i.e. doesn't have a value), such as a loop, the return value is unspecified (see perlsub). In PHP, if there's no explicit return, the return value is NULL.
Perl flattens lists (see perlsub); for un-flattened data structures, use references.
@foo = qw(bar baz);
@qux = ('qux', @foo, 'quux'); # @qux is an array containing 4 strings
@bam = ('bug-AWWK!', \@foo, 'fum'); # @bam contains 3 elements: two strings and a array ref
PHP doesn't flatten arrays.
- Perl has special code blocks (
BEGIN
, UNITCHECK
, CHECK
, INIT
and END
) that are executed. Unlike PHP's auto_prepend_file
and auto_append_file
, there is no limit to the number of each type of code block. Also, the code blocks are defined within the scripts, whereas the PHP options are set in the server and per-directory config files.
- In Perl, the semicolon separates statements. In PHP, it terminates them, excepting that a PHP close tag ("?>") can also terminate a statement.
- The value of expressions in Perl is context sensitive.
- Negative subscripts in Perl are relative to the end of the array.
$bam[-1]
is the final element of the array. Negative subscripts in PHP are subscripts like any other.
- In Perl 5, classes are based on packages and look nothing like classes in PHP (or most other languages). Perl 6 classes are closer to PHP classes, but still quite different. (Perl 6 is different from Perl 5 in many other ways, but that's off topic.) Many of the differences between Perl 5 and PHP arise from the fact that most of the OO features are not built-in to Perl but based on hacks. For example,
$obj->method(@args)
gets translated to something like (ref $obj)::method($obj, @args)
. Non-exhaustive list:
- PHP automatically provides the special variable
$this
in methods. Perl passes a reference to the object as the first argument to methods.
- Perl requires references to be blessed to create an object. Any reference can be blessed as an instance of a given class.
- In Perl, you can dynamically change inheritance via the packages
@ISA
variable.
- Perl supports operator overloading.
- Strictly speaking, Perl doesn't have multiline comments, but the POD system can be used for the same affect.
- In Perl,
//
is an operator. In PHP, it's the start of a one-line comment.
- Until PHP 5.3, PHP had terrible support for anonymous functions (the
create_function
function) and no support for closures.
- PHP had nothing like Perl's packages until version 5.3, which introduced namespaces.
- Arguably, Perl's built-in support for exceptions looks almost nothing like exceptions in other languages, so much so that they scarcely seem like exceptions. You evaluate a block and check the value of
$@
(eval
instead of try
, die
instead of throw
). The Error Try::Tiny module supports exceptions as you find them in other languages (as well as some other modules listed in Error's See Also section).
PHP was inspired by Perl the same way Phantom of the Paradise was inspired by Phantom of the Opera, or Strange Brew was inspired by Hamlet. It's best to put the behavior specifics of PHP out of your mind when learning Perl, else you'll get tripped up.
My brain hurts now, so I'm going to stop.