Rasmus Lerdorf
@rasmus
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#define ishex(x) (((x) >= '0' && (x) <= '9') || ((x) >= 'a' && \
(x) <= 'f') || ((x) >= 'A' && (x) <= 'F'))
int htoi(char *s) {
int value;
char c;
c = s[0];
if(isupper(c)) c = tolower(c);
value=(c >= '0' && c <= '9' ? c - '0' : c - 'a' + 10) * 16;
c = s[1];
if(isupper(c)) c = tolower(c);
value += c >= '0' && c <= '9' ? c - '0' : c - 'a' + 10;
return(value);
}
void main(int argc, char *argv[]) {
char *params, *data, *dest, *s, *tmp;
char *name, *age;
puts("Content-type: text/html\r\n");
puts("<HTML><HEAD><TITLE>Form Example</TITLE></HEAD>");
puts("<BODY><H1>My Example Form</H1>");
puts("<FORM action=\"form.cgi\" method=\"GET\">");
puts("Name: <INPUT type=\"text\" name=\"name\">");
puts("Age: <INPUT type=\"text\" name=\"age\">");
puts("<BR><INPUT type=\"submit\">");
puts("</FORM>");
data = getenv("QUERY_STRING");
if(data && *data) {
params = data; dest = data;
while(*data) {
if(*data=='+') *dest=' ';
else if(*data == '%' && ishex(*(data+1))&&ishex(*(data+2))) {
*dest = (char) htoi(data + 1);
data+=2;
} else *dest = *data;
data++;
dest++;
}
*dest = '\0';
s = strtok(params,"&");
do {
tmp = strchr(s,'=');
if(tmp) {
*tmp = '\0';
if(!strcmp(s,"name")) name = tmp+1;
else if(!strcmp(s,"age")) age = tmp+1;
}
} while(s=strtok(NULL,"&"));
printf("Hi %s, you are %s years old\n",name,age);
}
puts("</BODY></HTML>");
}
use CGI qw(:standard);
print header;
print start_html('Form Example'),
h1('My Example Form'),
start_form,
"Name: ", textfield('name'),
p,
"Age: ", textfield('age'),
p,
submit,
end_form;
if(param()) {
print "Hi ",em(param('name')),
"You are ",em(param('age')),
" years old";
}
print end_html;
<html><head><title>Form Example</title></head>
<body><h1>My Example Form</h1>
<form action="form.phtml" method="POST">
Name: <input type="text" name="name">
Age: <input type="text" name="age">
<br><input type="submit">
</form>
<?if($name):?>
Hi <?echo $name?>, you are <?echo $age?> years old
<?endif?>
</body></html>
array_search($needle, $haystack);
strstr($haystack, $needle);
in_array($needle, $haystack);
substr_count($haystack, $needle);
array_key_exists($needle, $haystack);
strchr($haystack, $needle);
(Compiler-assisted Copy-and-Paste)
$a = [1, 2, 3];
$b = ['foo' => 'orange', 'bar' => 'apple'];
function fruits() {
return array('apple', 'banana', 'orange');
}
echo fruits()[0]; // Outputs: apple
?>
class Foo {
private $prop = "bar";
public function getPrinter() {
return function() { echo ucfirst($this->prop); };
}
}
$a = new Foo;
$func = $a->getPrinter();
$func(); // Outputs: Bar
?>
class Foo implements JsonSerializable {
private $data = 'Bar';
public function jsonSerialize() {
return array('data'=>$this->data);
}
}
echo json_encode(new Foo); // Outputs: {"data":"Bar"}
$mask = 0b010101;
PHP 5.4 + Opcache vs. PHP 5.3 + APC
user cpu
system cpu
memory
latency
✔ default charset is UTF-8 instead of ISO-8859-1
echo htmlspecialchars("abc".chr(0xE0)."def"); // 5.3 "abc�def"
echo htmlspecialchars("abc".chr(0xE0)."def", NULL, 'UTF-8'); // 5.3 ""
echo htmlspecialchars("abc".chr(0xE0)."def"); // 5.4 ""
echo htmlspecialchars("abc".chr(0xE0)."def", ENT_IGNORE); // 5.4 "abcdef"
✔ array to string conversion notice
echo [1,2,3];
// Notice: Array to string conversion in test.php code on line 1
array_diff([1,2,3], [1,2, [3] ]);
// Notice: Array to string conversion in test.php on line 2
✔ register_globals completely removed
✔ magic quotes completely removed
✔ removed variable break/continue
$var = 'label';
while(1) {
break $var;
continue $var;
}
label:
✔ max_input_vars (default 1000)
✔ "callable", "insteadof" and "trait" are now reserved words
✔ extending an abstract constructor must match the signature
abstract class Base {
abstract public function __construct();
}
class Foo extends Base {
public function __construct($bar) {}
// FATAL Declaration of Foo::__construct() must be compatible
// with Base::__construct()
}
✔ stream_select() preserves keys of array arg
✔ XSLT writes are disabled by default
✔ mcrypt_generic_end() removed in favour of mcrypt_generic_deinit()
✔ mysql_list_dbs() removed
✔ PDO needs at least mysql client lib 4.1 now
✔ Datetime ignores TZ env var and falls back to UTC if none set
✔ Tiger hash output fixed - See bug 61307
function xrange($start, $end) {
for ($i = $start; $i <= $end; $i ++) {
yield $i;
}
}
foreach (xrange(0, 5) as $i) {
echo $i, "\n";
}
function logger($fileName) {
$fileHandle = fopen($fileName, 'a');
while (true) {
fwrite($fileHandle, yield . "\n");
}
}
$logger = logger(__DIR__ . '/log');
$logger->send('Foo');
$logger->send('Bar');
For an advanced explanation of coroutines, read this article by Nikita Popov
$db = mysqli_connect();
try {
call_some_function($db);
} finally {
mysqli_close($db);
}
$names = [ ['John','Smith'], ['Fred','Johnson'] ];
foreach($names as list($first,$last)) {
echo $first,$last;
}
echo array(1, 2, 3)[0]; //output 1
echo "foobar"[3]; //output b
echo [1,3,4][2]; //output 4
// Hash
$hash = password_hash("super secret",PASSWORD_BCRYPT);
// To validate $pwd against the stored hash
if (password_verify($pwd, $hash)) {
echo 'Password is valid!';
} else {
echo 'Invalid password.';
}
class MySQL implements DB {
public function query($query, ...$params) {
$stmt = $this->pdo->prepare($query);
$stmt->execute($params);
return $stmt;
}
}
$q = 'SELECT * FROM users WHERE id = ?';
$user = $db->query($q, $userID)->fetch();
// A better call_user_func_args
$args1 = [1, 2, 3];
$args2 = [4, 5, 6];
test(...$args1, ...$args2); // [1, 2, 3, 4, 5, 6]
test(1, 2, 3, ...$args2); // [1, 2, 3, 4, 5, 6]
test(...$args1, 4, 5, 6); // Fatal error: Cannot use positional argument after argument unpacking
class Foo {
const FOO = 1 + 1;
const BAR = 1 << 1;
const GREETING = "HELLO";
const BAZ = self::GREETING." WORLD!"
}
echo 2 ** 3 ** 2; // 512 (not 64)
echo -3 ** 2; // -9 (not 9)
echo 1 - 3 ** 2; // -8
echo ~3 ** 2; // -10 (not 16)
echo 2**512;
echo "\n";
$n = gmp_init(2);
echo $n**512;
1.3407807929943E+154
13407807929942597099574024998205846127479365820592393377723561443721764030073546976801874298166903427690031858186486050853753882811946569946433649006084096
include 'template.inc';
include 'db.inc';
use function template\header, template\footer, db\query;
header('My Page');
query('select * from stuff');
footer();
eg. fastcgi_param DOCUMENT_ROOT $realpath_root;