PHP Notes
---------
PHP Hypertext Processor.
Politically Harmonious Perl.
Perl, but Humane and Palatable.
Perl-like, but less Haunting and Peculiar.
Perl lite, less Heaving less Puking. (ok, ok, Perl is not nearly that bad...)
People-Happy Perl.
$variables
$ + letter|_ + letter|number|_ ... [a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*
CScs - case sensitive names
$a = 1; $A = 2; assert($a == 1);
$$variableVariables
$$symbol
$a = 42; $q = 'a'; assert($$q == 42);
There are no "var" (ala JS) statements, just assign to declare (unusual)
Errors
------
@function() (* soften: no warning or error message is output)
function() or die(msg) (* harden: fatal error if returning false)
Habitat
-------
Equivalent:
XML-legal
echo $x; ?> unless php.ini: short_open_tag = off
= $x; ?> unless php.ini: short_open_tag = off
<% echo $x; %> if php.ini: asp_tags = on
<%= $x; %> if php.ini: asp_tags = on
Equivalent:
echo 'stuff\\etc.';
echo('stuff\\etc.');
print 'stuff\\etc.';
print('stuff\\etc.');
?>stuff\etc.
='hello world'?>
Source Files
------------
include($sPath)
require($sPath)
require_once($sPath)
function __autoload($classname) { require_once("$classname.php"); }
Comments
--------
Equivalent:
echo ""; // comment
echo ""; /* comment */
echo ""; # comment
Types
-----
boolean $b
true or TRUE or false or FALSE
integer $i... or $n...
256 or 0400 or 0x100
"12" + 3 === 15 (-JS - would be "123")
float (* about 13 digits accuracy)
string $s
$s = 'string';
$s = 'one line
and a lot of spaces';
$s = "one line\n and a lot of spaces";
$s
(* backslash only needs doubling before a single quote or end of string)
(* backslash before any character other than ' or \ is literal and vis)
"\n\r\t\\\$\"\0377\xFF"
Heredoc (monstrous multi-line string literal) (yes it extrapolates $vars)
-------
(* not recommended because it thwarts the single most important
structural aspect of human-readable code: indentation)
(* The heredoc terminator is a LINE and not a character sequence.
The terminating LINE must contain the symbol or the symbol plus a ;
but NO WHITE SPACE of any kind, including indentation, or space
before or after the ; or comments)
$query = <<integer
---------
$i = (integer)$x; or (int)
$i = $x + 0; (-JS)
$i = intval($x);
->float
-------
$x = (float)$z; or (real) or (double)
settype($x=$z,'float'); (4.2, preferred)
settype($x=$z,'double'); (deprecated, but ancient)
->boolean
---------
$b = (boolean)$z; or (bool)
settype($b=$z,'boolean');
->string
--------
$s = (string)$x;
$s = $x . "";
$s = "$x";
$s = strval($z);
settype($s=$za'string');
when comparing anything with a string?
(array)
(object)
Scope
-----
all vars in a function are (b) local unless declared "global $xxx"
very common error if you ahem use global variables
fortunately newer PHP gives you a warning instead of a silent NULL
(declaration works at the start of the function, can it be elsewhere?)
Global Scope, etc.
Operators
---------
$o = new(classorsomething)
$z = $a[$z]
$n++ $n--
~ - (int) (float) (string) (array) (object) @
instanceof
!
* / %
+ - .
<< >>
< <= > >=
== != === !==
&
^
|
$b = $b && $b
$b = $b || $b
$z = ($b ? $z : $z) (b very loose binding, always outer-parenthesize)
= += -= *= /= .= %= &= |= ^= <<= >>=
and
xor
or
Reserved words
--------------
file:///C:/rfc/PHP%20Manual.htm#reserved
__CLASS__
__FILE__
__FUNCTION__
__LINE__
__METHOD__
and
array()
as
break
case
cfunction
class
const
continue
declare
default
die()
do
echo()
else
elseif
empty()
enddeclare
endfor
endforeach
endif
endswitch
endwhile
eval() (? there is no way to trap an eval(syntax error) is there?)
exception
exit()
extends
for
foreach
function
global
if
include()
include_once()
isset()
list()
new
old_function
or
php_user_filter
print()
require()
require_once()
return()
static
switch
unset()
use
var
while
xor
Arrays
------
$a = array(1,2,'three');
reset($a);
while (list($k,$v) = each($a)) {
$j .= "$k->$v ";
}
assert($j == "0->1 1->2 2->three ");
is a comma after the last element in a literal ignored? Null element?
array(0,1,2,)
$a = array(0 => 'zero', 1 => 'one');
$a = array('zero' => 0, 'one' => 1);
$a = array(0 => array('English' => 'zero', 'Spanish' => 'cero'));
$a = array('zero', 'one'); assert($a[0] == 'zero'); assert($a[1] == 'one');
Equivalent:
$a = array(0 => 'zero', 1 => 'one');
$a = array('zero', 'one');
unset($a); $a[0]='zero'; a[1]='one';
unset($a); $a[]='zero'; a[]='one';
Equivalent:
$a[] = $x; $a[] = $y; $n = key($a)+1; //? how (else) to get [] index?
$n = array_push($a, $x, $y);
Equivalent:
$a['key'] = 'value';
Perl stuff you can't do in PHP:
($x, $y) = array('x', 'y');
Interpoloation
--------------
echo "Terminated line.\n";
echo "A variable value is $value.\n";
echo 'Not a variable $value, just a literal dollar sign'
echo "This member value is $this->value.\n";
echo "This member value is {$this->value}.\n";
echo "This member value is {$this->arr[1][2]}.\n"; // braces required?
echo "This member value is {$this->arr['a']['b']}.\n"; // braces required?
echo "This return value is {$this->memberf('x')}.\n";
"{${$name}}";
bad: ${o->member}
"this works $a[key] only if there's no define('key',...)"
"this works {$a['key']} best"
"this fails $a['key'] trips up parser"
(? why doesn't this work: "blah blah {f($x)} blah blah" ?)
good: "\n";
bad?: '\n'; // (?) and is Perl different about this?
Iffies and Loopies
------------------
Similar:
foreach ($a as $v) {
echo $v;
}
foreach ($a as $k => $v) {
echo "$k => $v\n";
}
for ($i=0 ; $i < count($a) ; $i++) {
$v = $a[i];
echo $v;
}
reset($a);
while (($v=current($a)) !== FALSE) { // break if array contains FALSE?
...
next($a);
}
reset ($a);
while (list($k,$v) = each ($a)) { // nonempty arrays never convert to FALSE?
...
}
switch ($z) { (ala JS, ala C except strings allowed)
case z:
...
break;
case z
...
break;
default:
...
break;
}
if ($z) {
...
} elseif { (ala Perl except not Lary's tacky "elsif")
...
} else {
...
}
Object
------
class foo {
var $v; // member variable
function foo() { // constructor
}
function f($x) { // member function
}
}
o = new foo;
o->v = 2;
o->f(3);
(?) no literal object, as PHP array(...) or JavaScript {a:0, b:1,...}
oh wait, there's this:
o = (object)array('a' => 0, 'b' => 1);
assert(o->a === 0);
assert(o->b === 1);
OOP version 4-only features
---------------------------
is_a($o, 'C'); // is $Z of class C? Or a class extending C? (deprecated ==> instanceof)
=== means: same class, same property values -- essentially equivalent
assignment clones
(no destructors)
(get_parent_class() is parent of the instance NOT of the function you're in)
(var_export() useless)
OOP version 4 & 5 features (and 6...)
--------------------------
classname as constructor (ala C++) (beware name conflicts)
explicit $this inside methods
class Child extends Parent {}
manual base class construction: $this->ParentClassName(...);
var $property=CONSTANTEXPRESSION;
$this always explicit (b) (unlike C++)
ClassName::method()
parent::method()
== means: same class, same property values -- essentially equivalent
new classname
new classname(constructor args)
stdClass
is_subclass_of($o, 'C'); // is $Z of a class extending C? (deprecated)
__set()
__get() (v4: 2 params, v5: 1 param)
__call() (v4: 3 params, v5: 2 param)
__sleep()
__wakeup()
(no automatic base class construction)
(no multiple extension (inheritance) though v5 has multiple implements)
OOP version 5-only features (and 6...)
---------------------------
new self or new parent (v5 only?)
assign and pass by *reference* (v5 only?)
const
=== only if referring to the same physical instance
assignment refers (b)
abstract
interface, implements
instanceof
self::method()
static::method() // spooky
__construct()
__destruct()
__autoload (web only, not command line)
__toString()
__isset()
__unset()
var_export() outputs ClassName::__set_state(array(...)) call
private
protected
public (aka var)
clone
__clone() method (ala C++ copy constructor)
final
static
get_declared_interfaces()
interface_exists('I')
property_exists('C', 'property')
property_exists($o, 'property')
Functions
---------
function names are CcIi!!
Function Call
-------------
$y = f($x);
Function Definition (PHP3: define above call, PHP4: any order)
------------------- (CcIi - function names are case insensitive)
function f() { // definition
}
function f() {
return $y; // return value
}
function f($x) { // parameter
}
function f($x = 'default'); // default parameter value
}
function f() { // variable number of parameters
$a = func_get_args();
}
function f(&$x) { // input/output parameter (pass by ref)
$x .= 'appendage'; // (ala Perl)
}
if ($b) {
function g() { // conditional definition
}
}
function f() {
function g() { // nested
}
}
unlike JavaScript, PHP cannot undefine or redeclare functions
Functions, Built-In
-------------------
addcslashes
addslashes
array_join --> join()
$b = array_key_exists($key, $a); //~ in_array($value,$a)
array_merge($a, $a, ...)
array_merge_recursive($a, $a, ...); // tree merge
// example in manual is evil
$n = array_push($a, $x, ...);
array_slice(); // passive excerpting
array_splice() // destructive excerpting
chop trims trailing whitespace
$s = chr($n) (* ASCII encode, strlen($s) == 1) (~ord()) (+P)
$n = count($a); // (= sizeof()) // count('nonarray') == 1 count(NULL) == 0
$b = define($s, $v); // $v is simple (boolean,integer,float,string)
// (u C, Java)
$zreturn = eval($s); // unlike JS returns NULL unless $s has "return ...;"
~~~~ exit($rc); // (? no more html either? whence $rc on the web?)
$a = explode($separator, $s);
list($s,$s) = explode($separator, $s):
$a = explode($separator, $s, $nmax); // (? pattern or chars?)
// faster than split() or preg_split() regexp's
flush(); (tip: flush(); echo ''; if a lot more to come)
$x = func_get_arg($i); // 0 <= $i < func_num_args()
$a = func_get_args(); //
$n = func_num_args(); // # arguments actually passed by caller
$x = getmicrotime(); // microsecond-resolution (subtract to time)
$s = get_class($x);
$s = gettype($x); // ala JavaScript typeof()
returns a string:
"boolean"
"integer"
"double"
"string"
"array"
"object"
"resource"
"NULL"
"unknown type"
$s = htmlentities($s); '<' -> '$lt;' and all possible &xxx;
$s = html_entity_decode($s)
$s = htmlspecialchars($s); '<' -> '$lt;' '"' "'" '&' '>'
$b = in_array($value, $a); //~ array_key_exists($key, $a)
$b = in_array($value, $a, $type_strict);
$s = implode($sglue, $a); // same as join()
$b = is_array($x); // gettype($x) === "array"
$b = isset($x); // $x === NULL
$s = join($sglue, $a); // same as implode()
length --> strlen($s), count($a)
lower case -> strtolower($s)
$b = mqsql_close($db);
mysql_connect();
$hdlQuery = mysql_db_query($db, $query, [$hdlConnection])
mysql_db_name() (= mysql_result())
mysql_dbname() (x mysql_result())
mysql_error
$array = mysql_fetch_array($hdlQuery, MYSQL_ASSOC, _NUM, _BOTH);
$aarray = mysql_fetch_assoc($hdlQuery) (=mysql_fetch_array($h,MYSQL_ASSOC))
$x = $aarray['nameColumn'];
(4.0.3)
(b with MYSQL_BOTH if any column names are numbers, then
the _NUM numeric indices will be clobbered)
$narray = mysql_fetch_row($hdlQuery) (=mysql_fetch_array($h,MYSQL_NUM))
$x = $narray[indexColumn];
$object = mysql_fetch_object($hdlQuery)
$x = $object.nameColumn;
$structure = mysql_fetch_field($hdlQuery, $indexColumn)
$lengths = mysql_fetch_lengths($hdlQuery)
$hdlQuery = mysql_query($query, [$hdlConnection])
$x = mysql_result($hdlQuery, $row, [$column])
$n = mysql_num_rows()
$n = ord($s) (* ASCII decode, 1st char only) (~ chr()) (+P)
$s = phpversion();
$nmatches = preg_match("/$regexp/", $s[, &a[, $nflags[, $noffset]]]);
//contrast strpos()
$s = preg_replace($rold, $snew, $s, $mreps); // $old e.g. '/the/'
$s = preg_replace($aold, $snew, $s, $mreps); // $old e.g. array('/the/','/The/')
$s = preg_replace($aold, $anew, $s, $mreps); // arrays of old and new
$a = preg_replace($rold, $snew, $a, $mreps); // arrays of in and out
// $mreps defaults -1=infty (ala Perl 'g' option)
// "$1" or "\\1" in $new refers to the
// 1st parenthesized submatch in $old
// $old = '/blah/s' so . includes \n
// $old = '/blah/i' for case insensitivity
// $old = '/blah/g' illegal - omit $nreps instead
// problems with $ as start-of-string?
assert(preg_replace('/(a)(b)(c)/', "$3$2$1", 'abc') == 'cba');
preg_replace(,,,&$nreps) optional output, number of replacements
preg_replace_callback($old, "fcallback", $s, $mreps[, &$nreps]);
function fcallback($sold) {
return $snew;
}
$a = preg_split("/$regexp/", $s[, $nlimit[, $nflags]]);
print_r($z);
$s = print_r($z, TRUE); (4.3)
$x = round($x)
$x = round($x,nfrac) (4) (* 2 makes cents, -3 for 1000s)
$b = settype($x,'boolean');
settype($x,'integer');
settype($x,'float');
settype($x,'double');
settype($x,'string');
settype($x,'array');
settype($x,'object');
settype($x,'null'); (4.2)
$n = sizeof($a); // (= count())
$a = split($spat, $s, $nmax); // (bs) no /'s in $spat, e.g.: '[-_]'
$a = spliti($spat, $s, $nmax);
list($s,$s) = split($separator, $s); // wowee, shades of Perl or what
$s = sprintf($sformat, x, x, ...);
$numvars = sscanf($s, $sformat, $var1, $var2, ...)
$n0f = strpos($stringlooong, $stringshort)[, $noffset]);
$n = strcasecmp($s1,$s2); CcIi
$n = strcmp($s1,$s2); CScs
$s = stripslashes($s)
$s = stripcslashes($s) (* decodes C language \n etc.)
$s = strip_tags($s)
$s = strip_tags($s, ''); // exceptions - tags NOT to strip
$n = strlen($s)
$s = strtolower($s);
$s = strtoupper($s);
$s = str_replace($sold, $snew, $s);
$s = str_replace($aold, $anew, $s); // array of replacments
$a = str_split($s, [ $n ] )
$s = substr($s, $istart);
$s = substr($s, $istart, $ilength);
$i = substr_compare($slong, $sshort, $istart, $nlength, $bcasesensitive); (5)
substr_count
$s = substr_replace($s, $snew, $istart, $length); (4)
$s - trim($s) (* whitespace from both left and right) (unlike MySQL)
typeof --> gettype(), get_class()
$s = ucfirst($s); // Capitalize first letter
$s = ucwords($s); // Capitalize First Letter Of Every Word
upper case -> strtoupper($s)
Misc
----
functions must be defined before called (temporally, like JS?)
statements must end in ; (unlike JS, like Perl)
regular expressions are only in strings, not slashes (unlike JS, unlike Perl)
Tips
----
Everyone who uses PHP should probably write a function like this:
function bold($s) {
return "$s";
}
And they should never use it.
It's so neat and tidy when PHP syntax is beginning to make sense, who could
shelve it. But like a paperweight for Father's Day, you can like without
compulsion to use.
All functions should improve human readability. That one never will.
But wait, let's do the like-thing a bit.
There are many features in that short function that can be absorbed just by
looking at it. All the trimmings of a function definition are there, the
name, parameters, the braces, the return value.
And the purpose is so crystal clear. Bonus, there's the exotic interpolation
feature. (Isn't that a glamorous term? Compared to some others in
programming.) There's magic in the way that $s variable comes to life inside
the double-quoted string. Any language but PHP (and its rich uncle Perl)
would make you work harder.
Ok, the reason you should never use a function like this is it either
obscures without adding meaning, or it misses a chance to add meaning. The
code
bold($x)
may look tidy, but it raises questions to a fluent PHP reader.
"$x"
To the trained PHP eye, that's as plain as day. If there is good
reason to make a function do this, then you should not call it bold(). Take
the opportunity to do what HTML always dreamed of doing but never really
could: articulate meaning in your code. Call it emphasize(), or give some
clue why you're emphasizing here, danger() or price(). Good naming
considers all uses. If you have only one so far, that's another reason not to
invent a function yet.
Troubleshooting
---------------
Warning: Cannot send session cache limiter - headers already sent
some PHP code is in the body element when it should be before the
tag
syntax error, unexpected T_ENCAPSED_AND_WHITESPACE ...
syntax error, unexpected '.'
goofed up strings, forgetting dots or quotes or quote-escapes or something
or missing { } matching for interpolation
syntax error, unexpected ';'
too many '(' open parens?
Parse error: parse error, unexpected '='
= instead of == or === perhaps?
syntax error, unexpected '}' in .../path/filename... on line NNN
syntax error, unexpected '}', expecting ',' or ';'
syntax error, unexpected T_ECHO, expecting ',' or ';'
syntax error, unexpected T_STRING
missing ; on the line above
missing , on the line above
missing ' (close-single-quote) way above
missing or too many parentheses? maybe not...
syntax error, unexpected T_STRING, expecting T_VARIABLE
missing $ as in var p; -> var $p;
syntax error, unexpected T_STRING
quote mixup: $s='This can't be happening.'
$s="";
syntax error, unexpected T_CONSTANT_ENCAPSED_STRING
missing , in array literal: array('a'=>1 'b'=>2)
or function parens: f'x'
syntax error, unexpected $end in ...
Missing '}' -- unterminated curly-brace
Or it's complaining about the ?>
Look for an unexpected ?>
Here's an example of legit use going bad when commented!
NO: preg_replace('/<.*?>/', '' , $terms_title);
YES: // preg_replace('/<.*?>/', '' , $terms_title);
Anyway, another reason to use strip_tags()
parse error, unexpected $end in ...
Look for a missing close-curly brace '}'
PHP Notice: Undefined variable
(or other symptom when a variable is NULL or unchanges myseriously)
need global $variable; ? (this goof is VERY common)
(90% of midlevel bugs are caused by it)
PHP Notice: Undefined index
$value = $a[$key] ==> $value = array_key_exists($key, $a) ? $a[$key] : '';
PHP Notice: Undefined offset
PHP Notice: Use of undefined constant z - assumed 'z'
z ==> $z
z ==> z()
syntax error, unexpected T_INC
syntax error, unexpected T_DEC
z++ ==> $z++
$formfield isn't working
register_globals?
_GET[] isn't working
_POST[] isn't working
won't mysql_connect()
== broken?
=== instead? gotcha: 7331 == 'leet'
"The requested operation has failed" (popup starting Apache)
"Cannot load c:/php/php5apache2.dll into server:
The specified module could not be found" (from "httpd -t" command line)
PHP 5.1.6 not compatible with Apache 2.2.3. (works with Apache 2.0.59)
http://www.sitepoint.com/article/php-amp-mysql-1-installation/2
php.ini settings don't take effect
make sure you have the right php.ini
restart apache
Warning: Cannot modify header information -
headers already sent by (output started at ...filename...:linenumber)
in ...filename... on line linenumber
remove blank lines circa the output-started filename/linenumber
? nothing can come before ?
Warning: Invalid argument supplied for foreach()
foreach($notarray as $z) { }
Fatal error: Function name must be a string
$func() --> func()
1210 (HY000): Incorrect arguments to EXECUTE
Mismatch in PREPARE versus EXECUTE number of parameters
and/or type? not sure
Compilation failed: nothing to repeat at offset 0
bad: preg_replace("/?.*/", "", $THISURL); // ? is a dangling repeater
good: preg_replace("/\\?.*/", "", $THISURL); // ? is literal
?Mysteries?
-----------
How to figure out what index $a[] will assign to?
How to get the output of print_r() into a string?
DDooodooohead Mistakes -> Solutions
----------------------------------
$CONSTANT -> CONSTANT
variable -> $variable
"sum " . a+b -> "sum " . (a+b) (at least for a-b it's true)
function f() { $x==? } -> function f() { global $a; $x==! }
$func() -> func()
Review
------
http://www-128.ibm.com/developerworks/opensource/library/os-php-flexobj/?ca=dgr-lnxw01DynamicPHP
http://particletree.com/notebook/on-php-and-libraries/ (digg)
Keith Roberts' email about "most used and useful extensions"
http://www.php.net/tips.php @@@@
NULL
----
(b) '' == NULL
'' !== NULL
NULL === NULL (unlike SQL, similar to JavaScript?)
Legend
======
(* ...)
(x ...) deprecated in favor of ...
(4.0.3) started in version 4.0.3
(-JS) unlike JavaScript
(+P) like Pascal
(b) bomb (gotcha)
(b ...) bomb with explanation
(?...) mysteries to resolve
Bugs Reported
-------------
Bugs To Report
--------------
mysqli_report() is bizarre. Seems to affect either future requests, or same
requests BEFORE it's called. Spooky, haven't psyched it out. Plus it seems
to generate exceptions (which is not documented) and they are dysfunctional,
at least in 5.2.5:
mysqli_report(MYSQLI_REPORT_ALL);
try {
$resulti = $mysqli->query("SELECT * FROM t WHERE id!=666");
} catch (mysqli_sql_exception $e) {
assert(!isset($e));
}
Suggestions
-----------
From Scott Dale:
Yep - for PHP I'd put array management, function call syntax, include
mechanism, conversion functions, mysql_* library, globals and super globals,
string functions, and on.
JackDanials stuff is not dense enough which is why I like your stuff.
SD
Examples
--------
mysql_list_processes
mysql_query, fetch_array, num_fields, num_rows, field_name, etc.
mysql_query, get meta information, column names, widths, types?
contrast mysql_list_fields() columns with query SHOW COLUMNS rows?
and show the mysql_field_name and mysql_fetch_field ways too?
four ways to get the column field (fifth if you count mysql_fieldname)
2nd Edition
-----------
$_SERVER['HTTP_HOST'] domain as in the URL, e.g. www.visibone.com
$_SERVER['SERVER_NAME'] domain configured by web server, e.g. visibone.com
$_SERVER['SCRIPT_NAME'] no suffixes, exhumes index.php
$_SERVER['PHP_SELF'] will have /suffix, exhumes index.php
$_SERVER['REQUEST_URI'] will have /suffix and ?suffix
(ref http://php.about.com/od/learnphp/qt/_SERVER_PHP.htm)
$_SERVER['PATH_INFO'] has only the /suffix with the /
$_SERVER['QUERY_STRING'] has only the ?suffix without the ?
$_SERVER['argv'][0] is the first "part" of the ?suffix without the ?
mysqli_fetch_object DOES exist! (Even used in non-verbose data_seek example)
so don't snowflake mysql_fetch_object
error_log($sMessage); // httpd log, e.g. error_log
error_log($sMessage, 1, $sEmail);
error_log($sMessage, 2); // when --enable-debugger
error_log($sMessage."\n", 3, $sFilePath);
max_execution_time=0 -> add to list in Form example (T-Z page, lower left corner)
array versus object? (unlike Perl, they're not the same?)
references?
comment syntaxes? //... /*...*/ #...
"upload example" in table of contents for page 7 (ebk 26)
name="Upload" --> name="submit" value="Upload"
PHP types, integers, $i $ii $ii -> $iii $iv //ghostly shades of Perl, thx Norbert Rennert
array traversal methods (foreach, for, etc.) on array page
remove var_export() call (with bad paren!) from file upload example (t-z page)
uploads don't work checklist:
set form enctype
set form action (even if same php file!)
see ini settings
Functions I've wished were there
--------------------------------
readfile, fgets