Perl vs PHP

From WikiVS, the open comparison website
Jump to: navigation, search


Perl PHP
Perl
VS
PHP
http://www.perl.org http://www.php.net

Contents

[edit] Arrays

Referencing the last element of an array:

  • Perl:
   $array[-1]
  • PHP:
   end($array)  // moves the internal array pointer

In PHP, calling end($array) is not a read-only operation. The array's internal pointer is advanced, and the array is passed by reference. This means you must pass an actual variable, not a function returning an array.

[edit] Performance

[edit] Gotchas

In programming, a gotcha is a feature of a system, a program or a programming language that works in the way it is documented but is counter-intuitive and almost invites mistakes because it is both enticingly easy to invoke and completely unexpected and/or unreasonable in its outcome.

[edit] Magic Quotes

Some (still widely used) versions of PHP suffer from magic quotes. This is a measure that was made default in PHP 3 and 4, and is intended to protect beginner programmers from their own sloppiness by prepending an escape character to certain characters in $_COOKIE, $_GET, $_POST, and $_REQUEST environment variables. This protective mechanism was widely regarded as poorly conceived, especially considering that for experienced programmers who do not expect this behavior it can introduce bugs that are difficult to find. The magic quotes feature was based on the assumption that input from these sources would then automatically be passed on as part of a database query, a presumption that is not always true and can prove frustrating for developers who just want to be able to work directly with strings.

As a result of the feature's unpopularity, PHP documentation recommended turning off magic quotes, and as of PHP 5.3.0 it has been deprecated. The decision was made to remove the feature in PHP 6, in part due to security concerns in practical use because of the fact that magic quotes may be assumed to be turned on when code is written even if the code is deployed where they are not, and because of the tendency for less experienced developers to assume their code is safe from SQL injections if magic quotes are turned on when, in fact, several types of SQL injection attack may still be possible. A number of other problems also prompted the PHP core team to back off from magic quotes in versions 5.3.0+.

Portability has proven to be a problem for both cases of code being distributed to various systems running different specific PHP versions and cases of the PHP version being updated on a system running code that assumed a particular magic quotes setting, because of the changes in PHP's default behavior. Worse, even for PHP versions that all have magic quotes turned on in the default install, the fact that it is usually better to turn off magic quotes results in portability issues even between systems running the same version of PHP in many cases.

[edit] Namespace Separator

The PHP team decided that the namespace separator is going to be the backslash character. This has drawn protests from the community.

[edit] Quoting of array keys

In PHP, array keys can be constants or variables that evaluate to strings, or numbers. Constant strings should be enclosed within single quotes, or an E_NOTICE will be generated (and performance will also be slightly slower, as PHP will be looking for the constant first)[1]:

<?php
  $array = array(
      'foo' => 'bar'
  );
 
  print $array[foo];                // works, but generates E_NOTICE, and not recommended
  print $array['foo'];              // correct
  print("\nValue: $array['foo']");  // SYNTAX ERROR! "unexpected T_ENCAPSED_AND_WHITESPACE"
  print("\nValue: $array[foo]");    // correct (!)
 
?>

But inside strings, it's a syntax error to quote the array key. This is a well-known inconsistency and mentioned in the O'Reilly book "Programming PHP" by PHP author Rasmus Lerdorf[2].

[edit] Code base

PHP's codebase has developed in a somewhat haphazard fashion, with various developer teams piling up PHP code. As a consequence, random oddities can be found in the core, for example foreign token names. Compiling the code below,

<?php
  foreach($x as key)
?>

produces the following message:

Parse error: syntax error, unexpected ')', expecting T_PAAMAYIM_NEKUDOTAYIM

Note that T_PAAMAYIM_NEKUDOTAYIM is an official PHP token, listed at http://php.net/tokens, and has a Wikipedia entry. This is an extreme example of PHP's lack of clear and consistent naming conventions.

Perl's core team has maintained cleaner, more consistent control over the Perl user's development experience, so that function names and behaviors tend to be much more consistent than in PHP. The organization of Perl's libraries has benefited from better use of namespaces, where PHP's long-term lack of namespaces resulted in a number of dirty hacks to provide similar benefits proliferating over the years before PHP added namespaces, including core developers and contributors to the PHP implementation hacking ad-hoc pseudo-namespaces into function names. The result of the Perl team's greater attention to naming standards is a language whose core and standard library functions tend to be more predictable and more easily used without having to constantly refer to documentation.

On the other hand, Nat Torkington has famously described Perl internals as "an interconnected mass of livers and pancreas and lungs and little sharp pointy things and the occasional exploding kidney." This reflects the complexity of the Perl implementation's code base, though it is not something a typical Perl programmer ever encounters.

[edit] Types

Perl has different prefixes for $scalar, @array, and %hash variables. PHP uses the dollar sign ($) for all of these.

Perl's variable types are specified by the called value rather than by the complete variable type. Thus, @foo might be an array, but the single element of it $foo[2] is a scalar. Because PHP does not differentiate between these variable types syntactically, and only uses a single prefix sigil for all variables, scalar and collection contexts do not have different representations.

When specifying a particular element of a collection such as an array or hash in Perl, {braces} are used for hashes and [brackets] for arrays. Arrays are ordered according to their numeric indices, so that values are stored and returned in a predictable order. Hashes use a more performance-optimized internal storage mechanism, because unlike integer values the arbitrary string-or-integer keys of a hash cannot be predictably ordered by key.

PHP's implementation of collections presents the user with what amounts to a single form of collection, in that whether using integer keys or string keys the resulting collection behavior is identical, though PHP documentation does differentiate between standard arrays and associative arrays. By default, PHP collections are organized by the order in which new elements are added to them.

PHP automagically translates strings used as collection keys that take the form of standard numeric representations, such as "3" and "2.5", into their respective numeric data types (integers and floating point numbers). It also performs integer truncation of floating point number keys, turning "2.5" into the integer "2".

Perl accepts only integer values as array keys. Floating point number hash keys are truncated to produce integers, as in PHP collections, but strings are not converted to numeric types, which means that "2.5" and "2" remain distinct as long as the decimal number is represented as a string. This provides a means to avoid the PHP problem of trying to specify two separate values with a key for one that takes the form of an integer and a key for the other that takes the form of a floating point number, but having whichever is assigned second overwriting the first.

Perl:

my $text = 'The answer to life, the universe, and everything';
my $number = 42;
my @array = ($text, $number); # $text is in $array[0], $number is in $array[1]
my %hash = ('quote' => $text, 'author' => 'Douglas Adams'); # $text is in $hash{'quote'}, 'Douglas Adams' is in $hash{'author'}
print($hash{'author'}); # Correct
print(%hash{'author'}); # Incorrect, expecting hash as return value
print($hash('author')); # Incorrect, $hash is not a function (sub)
print($hash['author']); # Incorrect, trying to reference @hash array which doesn't exist

PHP:

<?php
$text = 'The answer to life, the universe, and everything';
$number = 42;
$php_array = array($text, 'author' => 'Douglas Adams'); // $text is in $php_array[0], 'Douglas Adams' is in $php_array['author']
?>

[edit] Contextual symbols

Perl can use the same symbols to mean different things in different contexts. Braces ({}) are used to delimit sub-routine and loop code as well as access hash elements and create anonymous hash references. In PHP braces are only used to delimit function and loop code.

Perl:

sub things {
  my $hash_ref = {'cat' => 'furry', 'fish' => 'wet', 'ice' => 'cold'};
  print $hash_ref->{'fish'};
  foreach my $example_key (keys %$hash_ref) {
    print $example_key, ' = ', $hash_ref->{$example_key}, "\n";
  }
}

PHP:

<?php
function things {
  $array_ref = &array('cat' => 'furry', 'fish' => 'wet', 'ice' => 'cold');
  print $array_ref['fish'];
  foreach ($array_ref as $example_key) {
    echo $example_key, ' = ', $array_ref[$example_key], "\n";
  }
}
?>

[edit] Regex

Perl has a built-in regex operator =~ (and !~) whereas PHP has several built-in functions to provide regex support. It can be very easy to change Perl code quickly but slower in PHP. On the other hand, the PHP functions let an inexperienced programmer know what the code is expected to do.

Perl:

my $text = 'A string to test';
my @one_word = ($text =~ /\w+/);
my @words    = ($text =~ /\w+/g);
$text =~ s/t/h/g; # Substitute all 't's with 'h'

PHP:

<?php
$text = 'A string to test';
preg_match    ('/\w+/', $text, $one_word);
preg_match_all('/\w+/', $text, $words);
preg_replace  ('/t/', 'h', $text);
?>

[edit] Function parentheses

Perl allows code without parentheses in many cases. The following two lines produce identical results:

print('Hello!');
print 'Hello';

This can produce subtle mistakes or can obscure the intent of the original programmer:

print join ' x ', 1, 2, 3, 4, ' = 24', '. ', 'This is called factorial.';

will print "1 x 2 x 3 x 4 x = 24 x . x This is called factorial.". To produce the correct output the code should be:

print(join(' x ', 1, 2, 3, 4), ' = 24', '. ', 'This is called factorial.');

This flexibility of language syntax in Perl may, however, also be used judiciously to improve readability of code where parentheses may otherwise simply contribute to syntactic clutter.

PHP requires that all functions use parentheses, though language primitives such as echo may not require parentheses and, in some cases, even prohibit their use. This can serve to some extent to guard against programmer sloppiness as in the above Perl example, at the cost of the benefits of greater syntactic flexibility, but the inconstant standard for parenthesis requirements can also contribute to confusing runtime error conditions.

[edit] Web application development

Perl's flagship web application frameworks are Catalyst and Mojolicious. Perl is the most widely supported CGI development language. A more PHP-like approach is provided by projects like HTML::Mason, though this approach of mixing programming statements and HTML code is no longer recommended.

PHP has over 20 competing web application frameworks, though the majority of Web development in PHP is done without using such frameworks by way of relatively simple forms and template-based dynamic page construction (possibly backed by function collection and separate processing files of various sorts).

[edit] Rants

I used to cut PHP programmers some slack... newbies have to start somewhere, said I... After this past week... I am firmly of the opinion, if you can't quite grok a real language, maybe you shouldn't be programming. I've written semi-decent code in PHP... When PHP was required, but nothing else was required. Problem seems to be that php programmers are pathologically broken-headed. They hear of things like 'frameworks' and 'MVC' and they read half of the wikipedia page and go write something that is almost entirely, but not quite, unlike a framework / MVC. I mean... seriously. what's the point of an MVC framework if you have to write all the M functions yourself, manually include them into each 'action' and then manually load a view class and call the view. It's the 'bring lots of wood so you can build your own ladder' framework.

Jay Kuri, CPAN contributor (after a particularly bad php project)

[edit] Links

See Also the Following Articles

Personal tools
Namespaces
Variants
Actions
Navigation
Ads
Toolbox