"PHP IN CONTRAST TO PERL"

This document is http://tnx.nl/php - If you replicate it, please do link. Trust HTTP headers for last-modified info. Corrections and additions are welcome at geeks#@tnx.nl.

PHP is a nice tool for adding dynamic parts to a small website. It is popular because it integrates very well with the popular Apache webserver, but also because the basics of PHP are very easy to learn. But is it wise to build applications or large websites with PHP? Perhaps Perl is a better solution.

This document compares PHP to Perl, because its author is very familiar with these two languages. It would be nice if others could write comparisons to Ruby, Python, and other dynamic programming languages.

A follow-up document is available, at http://tnx.nl/php5.

Table of contents

Arguments and return values are extremely inconsistent

To show this problem, here's a nice table of the functions that match a user defined thing: (with something inconsistent like this, it's amazing to find that the PHP documentation doesn't have such a table. Maybe even PHP people will use this document, just to find out what function to use :P)

replaces case gives s/m/x offset matches with insens number arrays matches flags (-1=end) ereg ereg no all no array no 0 ereg_replace ereg str no all no no no 0 eregi ereg yes all no array no 0 eregi_replace ereg str yes all no no no 0 mb_ereg ereg[1] no all no array no 0 mb_ereg_replace ereg[1] str/expr no all no no yes 0 mb_eregi ereg[1] yes all no array no 0 mb_eregi_replace ereg[1] str yes all no no no 0 preg_match preg[2] yes/no one no array yes 0 preg_match_all preg yes/no all no array yes 0 preg_replace preg str/expr yes/no n/all yes no yes 0 str_replace str str no all yes number no 0 str_ireplace str str yes all yes number no 0 strstr, strchr str/char no one no substr no 0 stristr str/char yes one no substr no 0 strrchr char no one no substr no -1 strpos str/char no one no index no n stripos str/char yes one no index no n strrpos char[3] no one no index no n strripos str yes one no index no -1 mb_strpos str[1] no one no index no n mb_strrpos str[1] yes one no index no -1

The problem exists for other function groups too, not just for matching.

(In Perl, all the functionality provided by the functions in this table is available through a simple set of 4 operators.)

[1] Handles multi-byte characters

[2] PCRE regex: so-called "Perl compatible" regular expressions.

[3] Also does strings in PHP 5

PHP has separate functions for case insensitive operations

(This can be argued both ways. Some think it's good to have functions that combine functions, even if that means having dozens of extra names to remember)

In Perl, you use a double lc() (lowercase) or the /i flag where PHP usually provides a case insensitive variant. The case-insensitive versions have very inconsistent naming.

Perl: $foo cmp $bar lc $foo cmp lc $bar PHP: strcmp($foo, $bar) strcasecmp($foo, $bar) Perl: index($foo, $bar) index(lc $foo, lc $bar) PHP: strpos($foo, $bar) stripos($foo, $bar) Perl: $foo =~ s/foo/bar/ $foo =~ s/foo/bar/i PHP: $foo = str_replace('foo', 'bar', $foo) $foo = str_ireplace(...) PHP: $foo = ereg_replace('foo', 'bar' ,$foo) $foo = eregi_replace(...)

PHP has inconsistent function naming

Case insensitive functions have the 'i' or 'case' at different positions in their names.

There is no apparent system in underscore(s) versus no underscore(s): underscore no underscore: stream_get_line readline disk_free_space diskfreespace is_object isset mcal_day_of_week jddayofweek set_error_handler setlocale snmp_get_quick_print snmpget get_browser getallheaders base64_encode urlencode image_type_to_mime_type imagetypes msql_num_fields mysql_numfields php_uname phpversion strip_tags stripslashes bind_textdomain_codeset bindtextdomain cal_to_jd gregoriantojd str_rot13 strpos Perl has no core function names with underscores in them.

Perl has no core function names with underscores in them. PHP has unlink, link and rename (system calls), but touch (the system call is utime, not touch).

And they can't decide on word order: object verb: base64_decode, iptcparse, str_shuffle, var_dump verb object: create_function, recode_string Perl core functions are all "verb object" except the superseded dbm* functions. (Note that sys is a prefix, not an object. And that flock and lstat were named after the system calls. shm* and msg* are library calls)

"to" or "2"? ascii2ebcdic, bin2hex, deg2rad, ip2long, cal_to_jd (jdto*, *tojd), strtolower, strtotime,

PHP has no lexical scope

Perl has lexical scope and dynamic scope. PHP doesn't have these.

For an explanation of why lexical scope is important, see Coping with Scoping.

PHP Perl Superglobal Yes Yes [1] Global Yes Yes Function local Yes Yes [2] Lexical (block local) No Yes Dynamic No Yes

[1] Perl has variables that are always in the main:: namespace. These are like PHP's superglobals.

[2] Using a lexical variable in a sub routine's block, you get a function local variable.

PHP has too many functions in the main namespace

(Using the core binaries compiled with all possible extensions in the core distribution, using recent versions in November 2003.)

Number of PHP main functions: 3079 [1] Number of Perl main functions: 206 [2]

Median PHP function name length: 13 Mean PHP function name length: 13.67 Median Perl function name length: 6 Mean Perl function name length: 6.22

Note that Perl has short syntax equivalents for some functions:

readpipe('ls -l') ==> `ls -l` glob('*.txt') ==> readline($fh) ==> quotemeta($foo) ==> "\Q$foo" lcfirst($foo) ==> "\l$foo" (lc is \L) ucfirst($foo) ==> "\u$foo" (uc is \U)

[1] Source: PHP Quick Reference

[2] Source: perldoc perlfunc

PHP lacks abstraction and takes TIMTOWTDI to bad extremes

Why has PHP got 3079 functions while Perl does with only 206? In PHP, there are usually several functions that are very similar. In Perl, you have to know and remember less.

Another important factor is the use of modules, especially the DBI module which provides support for SQL databases, instead of bloating the core with lots of features that occupy memory but are rarely used.

(Modules that are more often not used than used don't count (This rules out PEAR for PHP and IO::File for Perl). Modules may be pulled in when the core provides no similar functionality. For simplicity, internal working is left out of this comparison.)

* Escaping: * PHP: (14) dbx_escape_string, escapeshellarg, escapeshellcmd, pg_escape_bytea, pg_escape_string, pg_unescape_bytea, addslashes, addcslashes, preg_quote, quotemeta, mysql_escape_string, mysql_real_escape_string, mysqli_real_escape_string, sqlite_escape_string * Perl: (2) [1] quotemeta, $dbh->quote * Sorting: * PHP: (16) sort, arsort, asort, krsort, ksort, natsort, natcasesort, rsort, usort, array_multisort, uasort, uksort, dbx_sort, imap_sort, ldap_sort, yaz_sort * Perl: (1) sort * Walking a list * PHP: (10) array_filter, preg_grep, array_search, array_unique, in_array, array_map, array_walk, array_count_values, array_change_key_case, array_sum * Perl: (2) map, grep * Splitting: * PHP: (8) split, explode, strtok, spliti, chunk_split, mb_split, preg_split, str_split * Perl: (1) split * Matching: * Strings: * PHP: (11) strstr, strchr, stristr, strpos, strrchr, stripos, mb_strpos, mb_strrpos, strrpos, strripos, substr * Perl: (3) index, rindex, substr * Regular expressions: * PHP: (6) ereg, eregi, mb_ereg, mb_eregi, preg_match, preg_match_all * Perl: (1) m// * Substituting a matched part: * PHP: (12) ereg_replace, eregi_replace, mb_ereg_replace, mb_eregi_replace, preg_replace, str_ireplace, str_replace, ltrim, rtrim, trim, nl2br * Perl: (1) s/// * Connecting to an SQL database: * PHP: (17) dbx_connect, fbsql_connect, ibase_connect, msql_connect, msql_pconnect, mssql_connect, mysql_connect, odbc_connect, pg_connect, pg_pconnect, sesam_connect, ifx_pconnect, ifx_connect, sqlite_open, sqlite_popen, mysqli_connect, mysqli_pconnect * Perl: (2) DBI->connect, DBI->connect_cached * Opening: * PHP: (5) dio_open, fopen, proc_open, popen, gzopen[2] * Perl: (2) open, sysopen * Reading/receiving: * PHP: (12) dio_read, fread, gzread[2], socket_read, socket_recv, socket_recvfrom, socket_recvmsg, readline, fgetc, fgets, stream_get_line, file * Perl: (5) read, readline, sysread, recv, getc * Printing/writing: * PHP: (14) print, echo, printf, fprintf, vprintf, dio_write, fwrite, fputs, gzwrite[2], socket_send, socket_sendmsg, socket_sendto, socket_write, socket_writev * Perl: (5) print, printf, syswrite, send, write * Closing: * PHP: (7) closelog, dio_close, fclose, gzclose[2], pclose, socket_close, proc_close * Perl: (1) close * Miscellaneous: * PHP: array_combine, array_fill, array_merge, list, range, count, create_function, strtr, pow, putenv, getenv, getmygid, getmypid, getmyuid * Perl: syntax or magic variables

[1] Because of system LIST syntax and DBI's placeholders, explicit escaping is usually not even needed.

[2] Handled in Perl by a PerlIO layer

Re^2: Is Perl a good career move? by Juerd, 2005 Still no namespaces No closures, not even anonymous functions No good HTML parser No easy MIME builder No good WWW library No CPAN No arrays Less useful logical operators

Yaywoo! by Dave Brown, 2004 No way to avoid the (unsafe) shell with system() XY-problem Huge proliferation of different functions to do more-or-less the same thing with minor variations Second parameter and return value make no sense Bad spelling in function names

Why PHP sucks by Edwin Martin, 2004 Bad recursion support PHP is not thread safe PHP is crippled for commercial reasons No namespaces Non-standard date format characters Confusing licenses Inconsequent function naming convention Magic quotes hell

Perl vs. PHP - octo's subjektiver Vergleich by Florian Forster, 2003 (German) Perl is faster than PHP Perl is more versatile than PHP Perl has better documentation than PHP PHP lacks support for modules PHP's here-docs are useless for Windows users PHP lacks a consistent database API PHP dangerously caches database query results For graphics, PHP is practically limited to GD

I hate PHP by Keith Devens, 2003 Idiotic call-time pass-by-reference deprecation

Experiences of Using PHP in Large Websites by Aaron Crane, 2002 PHP promotes interweaving presentation with business logic Not having namespaces causes problems Global configuration with php.ini Oversimplification leads to excessive complexity

PHP Annoyances by Neil de Carteret, 2002 No real references or pointers No idea of namespace No componentization Wants to be Perl, but doesn't want to be Perl No standard DB interface All PHP community sites are for non-programmers No chained method calls (Not true anymore --tnx.nl) No globals except by importation Both register_globals and $_REQUEST bite Arrays are hashes PEAR just ain't CPAN Arrays cannot be interpolated into strings No "use strict" like checking of variable names

PHP: A love and hate relationship by Ivan Ristic, 2002 (Mirrored locally, original link is dead) The community gets on my nerves Knowledgeable people are in a serious minority Zend publishes articles suggesting insecure practice

My list of PHP shortcomings by Nathan Torkington, 2001 No namespaces All functions are global No real references No real data structures (Not true anymore --tnx.nl) No anonymous functions



Quotes

Slashdot, BBC creates 'Perl on Rails': I am going to create "PHP off the Rails" for developers of PHP websites. PHP developers will need no training, as most of them are off the rails already! -- Anne Thwacks

EFnet #php: 19:45 <+Dragnslcr> Comparing PHP to Perl is like comparing pears to newspapers

Perl Monks: PHP - it's "training wheels without the bike" -- Randal L. Schwartz

lesscode.org: PHP has a very low barrier to entry; consequently, a lot of eye-wateringly bad programmers are writing code in it; hence, a lot of code written in PHP is awful. This is arguably a good thing. -- Aristotle Pagaltzis

use Perl;: We all know that, due to the poor design of the language, security and PHP applications don't mix well, because PHP makes writing secure code difficult; apparently security doesn't mix well either with the mindset of the PHP core developers. -- Rafael Garcia-Suarez

Perl Buzz: Sure, PHP 6 may have a shorter release cycle than Perl 6 has, but at the end of it all, we'll have Perl 6, and you'll still have PHP. Just sayin'. -- Andy Lester

FOSDEM: :I chose PHP because I thought it would be a better fit for the community I was targeting, which tended to have a lot of non-programmers in it. -- Patrick Michaud