What is this?
I had two requirements.
- Learn enough PHP to be able to deal with WordPress.
- Get acquainted with the contours of the language, and its ecosystem, so that I know where to go if I ever have to write PHP code in anger.
What you’ll find below is the sort of the cliff notes that came out of this exercise. I use a MacBook Pro, so some of these notes are OS X centric. OS X comes with an Apache server out of the box, with PHP pre-installed. I only had to turn on PHP, which turned out to be trivial.
This will not be much use for a beginner. Someone with a passing acquaintance with the DNA of programming languages, and web frameworks might be able to use this as a road-map to study PHP further. That is how I intend to use this document myself.
Configuring PHP
Much of the behavior of the PHP engine seems to be configured in a single file, php.ini, which in OS X, was at /etc/php.ini.
The default php.ini is large, and seems to be well documented.
What version of HTML does PHP generate?
Does it generate HTML 5? I have not been able to find a definitive answer. I wonder if PHP is considered to be independent of HTML.
I wonder if PHP can be easily made to generate some other markup, like Markdown, or XUL. But why would you want to?
At the web server, what exactly triggers the PHP processor?
http://httpd.apache.org/docs/2.2/mod/mod_mime.html
See the notes on TypesConfig, and AddType. These are all settings in the Apache server’s httpd.conf file.
http://chibimagic.wordpress.com/2009/02/27/apache-htaccess-mac-os-x/
A note on how to control this on OS X.
Essentially, this is a configuration at the web server. For Apache, you are able to tie various file extensions like ‘php‘, ‘html‘, ‘htm‘, etc, to the PHP mime type, application/x-httpd-php. Any file with that extension is run through the PHP processor. Usually, the default setting sends only files with the extension, ‘php‘ through the PHP processor.
You probably want to be discriminating about this, because you want to avoid unnecessarily invoking the PHP processor on files that, in fact, do not have PHP in them. There seems to be a way to specify individual files too.
In particular, PHP code is written like the Java in a JSP – in between special tags. The starting tag is ‘<?php‘, and the ending tag is ‘?>‘. There are alternate tags, which you turn on and off in php.ini.
Basic language
PHP has dynamic typing. Besides that there is little that is out of the ordinary.
Data Types
- PHP defines scalar types (integer, float, boolean, string), and one vector (array). What PHP calls an array, is both a numeric indexed data structure, and an associative array (a Java Map).
- String interpolation is available. Double quoted strings can contain references to variables (how about whole expressions). Single quoted strings are just plain literals.
- Manifest constants are available.
define(PI, 3.14)
Facilities for dynamic programming
- PHP uses dynamic typing. Meaning, you don’t declare a variable’s type in your code. A variable’s type is determined at run-time.
- PHP calls them ‘variable variables’, which is simply the ability to pass around variable’s name as data.
$aBatsman = 'opener' $$aBatsman = 'no 2' assert $opener == 'no 2'
- There are functions for determining the type of a piece of data – gettype, settype, is_null, is_double, is_array, etc. In well written code, you should not see much use of these. Expect maybe for ‘is_null‘.
- PHP does have some form of garbage collection. However, you can also explicitly mark a variable for destruction, with the function, unset.
Operators
- All the usual suspects exist. Some items of note, are listed below.
- A reference operator, ‘&’, which is not exactly related to pointers. I don’t understand what this is.
- The comparison operator ‘==’ compares value only. This new one, ‘===’ compares both value, and data type, and the operation reads, ‘is identical’.
- External, system, commands can be specified within backquotes (`), just like in Unix shell scripts.
- For arrays, PHP has the following operations
- union (+)
- equality (==): everything on the lhs exists on the rhs
- identity (===): equal, as defined above, and the entries exist in the same order too.
Statements
All the expected types of conditional, and iterative statements exist. Only two points worth mentioning.
- You can step through the elements of a PHP array with the foreach statement.
- The cases of a switch statement can be any scalar value at all, rather than just an integral value, which is the case in Java.
Functions
Little out of the ordinary here. Here are the few wrinkles.
- Code meant to be re-used can be included in PHP files through the require, require_once, include, and include_once functions. These works pretty much like the #include directive in C.
- Function names are not case-sensitive, even though variable names are.
- A function’s scope is the PHP file that it is defined in.
- Variables defined in a PHP file, but outside all functions, are not visible within a function. Yet, these are referred to as globals. There is something called a superglobal, which is visible everywhere. Not sure how to define these.
- Closures are available. You can supply the name of a function as a parameter to another function, where you can invoke the incoming function. PHP calls these ‘variable functions‘.
- You can specify default values for parameters. This allows optional parameters.
function create( $data, $border = 1, $cellpadding = 4, $cellspacing = 4)
$border, $cellpadding, $cellspacing, have default values, and are optional.
- Pass by reference parameters are also available. The syntax seems identical to C.
function increment(&$value, $amount = 1) { $value = $value + $amount; } $value is passed by reference into the above function. Notice the leading ampersand.
Objects
PHP’s object-oriented features are almost identical to that of Java, with a few small exceptions.
- Classes don’t seem to have access modifiers. Member fields, and methods do.
class HelloPhp { private $name; private function sayHello($myName) { return "Hello $myName! My name is $name"; } }
- Class members are public by default.
- The access modifier ‘protected’ makes a member private to the declaring class, and its sub-classes. There is nothing equivalent to Java’s package visibility.
- A class’ constructor is the function, __construct. There is an equivalent __destruct method.
- You refer to a class’ member like this: $this->attribute.
- PHP’s version of private property access happens through two special accessor functions, __get, and __set. You must explicitly define these two functions, as shown below, in order to be able to access private, and protected member variables. If the accessor methods do not exist, the parser throws an error. You can get to public member variables without these accessor methods in place.
class Accessors { private $bird; private $fish; public __set($name, $value) { $this->$name = $value; } public __get($name) { return $this->$name; } } $test = new Accessors(); $test->fish = 'Shark'; $test->bird = 'Crow'; echo "My $test->fish can eat your $test->bird";
- You can iterate through the fields of a class, using foreach. Javascript has this.
- Inheritance works pretty much as it does in Java.
- Visibility rules for class members are the same.
- You can override method definitions.
- Sub-classing, and overriding can be prevented with the ‘final’ modifier.
- Multiple inheritance is not available.
- You can invoke super class behavior with ‘parent::someMethod‘.
- Abstract methods and classes are available, and look identical to Java.
- Functions for cloning (__clone), and a converting to strings (__toString) exist. Are these just optional methods that are magically called by the PHP runtime? Or are they methods in some mother of all base classes, like in Java. Not clear.
- You can define static methods, static fields, and static constants. Note, in a bit of unnecessary weirdness, the names of constants cannot have the leading ‘$’.
class Math { const pi = 3.14159; static $fahToCel = "F = C * 9/5 + 32"; static function squared($input) { return $input * $input; } }
echo "Math::pi = " . Math::pi . "</br>"; echo Math::squared(8) . </br>; echo "Celsius to Fahrenheit: " . Math::$fahToCel
Interfaces
- Interfaces exist, and they are meant to work exactly like in Java. A class may implement multiple interfaces.
interface Displayable { function display(); } class WebPage implements Displayable { function display() { // … } }
Templating
- While PHP has the building blocks with which to build a templating system, it does not natively provide an easy to use engine with which to separate data and views. However, popular frameworks exist, which contain template engines.
- See Symfony, Laravel, CodeIgniter, Zend, etc. These days you would not create a serious PHP based web application with core PHP alone. You will use one of these frameworks.
Namespace management
- Java has packages, and PHP has namespaces. Namespace declaration, and use, in PHP, seems to have more options than in Java, which mostly just creates more room to hang yourself.
- Nevertheless, the PHP runtime does not have a system by which it can automatically locate artifacts. The Java runtime has the notion of a classpath. PHP has no equivalent. Instead, the latest versions of PHP prescribe a pre-defined method, __autoload, that it will call when it needs to locate an artifact. You are expected to define __autoload anyway you wish. Essentially, they are letting each implementor define their own notion of a Java classpath. The various PHP frameworks come to the rescue again. They all have their own facilities of handling this. They often seem to be called bundles. Nuts. So each framework might do this differently.
Third Party Repositories
Repositories of third party libraries exist, along with tools for locating, and including dependencies into your project.
Debugging, and Development Environments
- Error logs, and display have to be turned on in php.ini. See these directives, error_reporting, display_errors, display_startup_errors, html_errors, log_errors, error_log, etc.
- On OS X, all failures are also written to Apache’s logs. On my machine, I turned on ErrorLog in httpd.conf. These errors show up in the OS X console too.
- I believe there are special purpose PHP IDEs and visual debuggers. I did not look into these. I just used php-mode in emacs, and Adobe Dreamweaver for the few small pieces of PHP code that I wrote.
- You can also run PHP scripts from the command line. Just do php <script file>. I did not try this, and I wonder what this does with HTML.
Why would you want to use PHP?
If all your expertise was in PHP, then go with PHP.
I haven’t seen anything to suggest it is intrinsically worse than the alternatives. The quality of what you produce will depend more on the quality of the engineering that your developers are capable of, and this is independent of the choice between PHP, Python, Ruby, Java, etc.
I wonder if there are PHP frameworks out there with very good built-in components for certain types of verticals, like e-commerce, and content management, especially content management (WordPress, Joomla, Drupal). I wonder if that is a reason for its popularity.
Also, the platform frameworks (Symfony, Laravel, etc.) seem to offer many of the modern features (template engines, object patterns, unit testing, native class loading schemes, etc.) that the Java ecosystem has taught us to expect.
The converse is also true. If I had all the choice in the world, I see little reason to pick PHP over one of the alternatives like Python, Ruby, Scala/Groovy/Java, etc. In fact, personally, I find those alternatives more elegant, and interesting (except for Java, which you use to put bread on the table). PHP feels like a little bit like a kluge – as if it started as one small, simple, thing, and slowly was forced to turn into something else, in order to catch up with advances that the alternatives were natively born with. Funny, that description probably fits Java too.