Rasmus Lerdorf
@rasmus
Subject: Announce: Personal Home Page Tools (PHP Tools)
Announcing the Personal Home Page Tools (PHP Tools) version 1.0.
These tools are a set of small tight cgi binaries written in C.
They perform a number of functions including:
. Logging accesses to your pages in your own private log files
. Real-time viewing of log information
. Providing a nice interface to this log information
. Displaying last access information right on your pages
. Full daily and total access counters
. Banning access to users based on their domain
. Password protecting pages based on users' domains
. Tracking accesses ** based on users' e-mail addresses **
. Tracking referring URL's - HTTP_REFERER support
. Performing server-side includes without needing server support for it
. Ability to not log accesses from certain domains (ie. your own)
. Easily create and display forms
. Ability to use form information in following documents
Here is what you don't need to use these tools:
. You do not need root access - install in your ~/public_html dir
. You do not need server-side includes enabled in your server
. You do not need access to Perl or Tcl or any other script interpreter
. You do not need access to the httpd log files
The only requirement for these tools to work is that you have
the ability to execute your own cgi programs. Ask your system
administrator if you are not sure what this means.
The tools also allow you to implement a guestbook or any other
form that needs to write information and display it to users
later in about 2 minutes.
The tools are in the public domain distributed under the GNU
Public License. Yes, that means they are free!
For a complete demonstration of these tools, point your browser
at: http://www.io.org/~rasmus
--
Rasmus Lerdorf
rasmus@io.org
http://www.io.org/~rasmus
void Cos(void) {
Stack *s;
char temp[64];
s = Pop();
if(!s) {
Error("Stack error in cos");
return;
}
sprintf(temp,"%f",cos(s->douval));
Push(temp,DNUMBER);
}
<html><head><title>Cos Example</title></head>
<body><h1>Cos Example</h1>
<?echo Cos($input)>
</body></html>
✔ engine improvements
✔ Abstract Syntax Tree
✔ Return Types
function get_config(): array {
return 42;
}
get_config();
// Catchable fatal error: Return value of get_config() must
// be of the type array, integer returned in %s on line %d
✔ Coercive Scalar Types
function logmsg(string $msg, int $level, float $severity) {
var_dump($msg); // string(1) "1"
var_dump($level); // int(2)
var_dump($severity); // float(3)
}
logmsg(1, "2.5", 3);
✔ Strict Scalar Types
declare(strict_types=1);
logmsg(1, "2.5", 3);
Fatal error: Argument 1 passed to logmsg() must be of the
type string, integer given
✔ Null Coalesce Operator
$a = NULL;
$b = 1;
$c = 2;
echo $a ?? $b; // 1
echo $c ?? $b; // 2
echo $a ?? $b ?? $c; // 1
echo $a ?? $x ?? $c; // 2
✔ Spaceship Operator
function cmp_php5($a, $b) {
return ($a < $b) ? -1 : (($a >$b) ? 1 : 0);
}
function cmp_php7($a, $b) {
return $a <=> $b;
}
✔ Exceptions on Fatals
function call_method($obj) {
$obj->method();
}
call_method(null);
// Fatal error: Call to a member function method() on a non-object
try {
call_method(null);
} catch (EngineException $e) {
echo "Exception: {$e->getMessage()}\n";
}
// Exception: Call to a member function method() on a non-object
✔ Added Closure::call()
$f = function () {
return $this->n;
};
class MyClass {
private $n = 42;
}
$myC = new MyClass;
$c = $f->bindTo($myC, "MyClass");
$c();
$f = function () {
return $this->n;
};
class MyClass {
private $n = 42;
}
$myC = new MyClass;
$f->call($myC);
✔ Removal of many deprecated features
(Your PHP4 code will break!)
- ext/ereg (use ext/pcre instead)
- ext/mysql (use ext/mysqli or ext/pdo_mysql instead)
- Assignment of new by reference
- Scoped calls of non-static methods from incompatible $this context
- dl() in php-fpm
- set_magic_quotes_runtime() and magic_quotes_runtime()
- set_socket_blocking() (use stream_set_blocking() instead)
- mcrypt_generic_end() (use mcrypt_generic_deinit() instead)
- mcrypt_ecb, mcrypt_cbc, mcrypt_cfb and mcrypt_ofb
(use mcrypt_encrypt() and mcrypt_decrypt() instead)
- datefmt_set_timezone_id() and IntlDateFormatter::setTimeZoneID()
(use datefmt_set_timezone() or IntlDateFormatter::setTimeZone() instead)
- xsl.security_prefs (use XsltProcessor::setSecurityPrefs() instead)
- iconv.input_encoding, iconv.output_encoding, iconv.internal_encoding,
mbstring.http_input, mbstring.http_output and mbstring.internal_encoding
(use php.input_encoding, php.internal_encoding and php.output_encoding instead)
- $is_dst parameter of the mktime() and gmmktime() functions
- # style comments in ini files (use ; style comments instead)
- String category names in setlocale() (use LC_* constants instead)
- Unsafe curl file uploads (use CurlFile instead)
- preg_replace() eval modifier (use preg_replace_callback() instead)
- PDO::PGSQL_ATTR_DISABLE_NATIVE_PREPARED_STATEMENT driver option
(use PDO::ATTR_EMULATE_PREPARES instead)
- CN_match and SNI_server_name stream context option (use peer_name instead)
✔ New reserved words:
✔ 64-bit integer support on Windows
✔ Cleanup edge-case integer overflow/underflow
✔ Support for strings with length >= 2^31 bytes in 64 bit builds.
✔ Parse error on invalid numeric literals
$mask = 0855; // Parse error: Invalid numeric literal
✔ Uniform variable syntax
// left-to-right
$this->$belongs_to['column']
// vs.
$this->{$belongs_to['column']}
// support missing combinations of operations
$foo()['bar']()
[$obj1, $obj2][0]->prop
getStr(){0}
// support nested ::
$foo['bar']::$baz
$foo::$bar::$baz
$foo->bar()::baz()
// support nested ()
foo()()
$foo->bar()()
Foo::bar()()
$foo()()
// support operations on arbitrary (...) expressions
(...)['foo']
(...)->foo
(...)->foo()
(...)::$foo
(...)::foo()
(...)()
// two more practical examples for the last point
(function() { ... })()
($obj->closure)()
// support all operations on dereferencable scalars
// (not very useful)
"string"->toLower()
[$obj, 'method']()
'Foo'::$bar
✔ Unicode Codepoint Escape Syntax
echo "\u{202E}Right-to-left text";
echo "\u{1F602}";
Right-to-left text😂
✔ ICU IntlChar class added to intl extension
More things will be added
First RC scheduled for June 2015
Time and number of machine instructions for 100 requests against Wordpress-3.6.0 front page
(click on legend items to show/hide data sets)
All versions of PHP compiled locally using gcc-4.9.2 -O2
configure flags
./configure --disable-debug --with-apxs2=/usr/bin/apxs2 \
--enable-zend-signals --with-gd \
--without-pear --with-jpeg-dir=/usr \
--with-png-dir=/usr --with-vpx-dir=/usr \
--with-t1lib=/usr --with-freetype-dir=/usr \
--enable-exif --enable-gd-native-ttf \
--with-zlib --with-mysql=/usr \
--with-gmp --with-zlib-dir=/usr \
--with-gettext --with-kerberos \
--with-imap-ssl --with-mcrypt=/usr/local \
--with-iconv --enable-sockets \
--with-openssl --with-pspell \
--with-pdo-sqlite --with-pdo-mysql=mysqlnd \
--enable-soap --enable-xmlreader \
--enable-phar=shared --with-xsl \
--enable-ftp --enable-cgi \
--with-curl=/usr --with-tidy \
--with-xmlrpc --enable-mbstring \
--enable-sysvsem --enable-sysvshm \
--enable-shmop --with-readline \
--enable-pcntl --enable-fpm \
--enable-intl --enable-zip \
--with-imap --with-mysqli=mysqlnd \
--enable-calendar --prefix=/usr/local \
--with-mysql-sock=/var/run/mysqld/mysqld.sock \
--with-config-file-scan-dir=/etc/php7/conf.d \
--with-config-file-path=/etc/php7
php.ini
[PHP]
zend.multibyte=On
date.timezone="America/Los_Angeles"
display_startup_errors=On
zend.enable_gc=Off
include_path="/usr/local/lib/php"
default_charset="UTF-8"
error_reporting=-1
variables_order=GPCS
sendmail_path=""
max_execution_time=60
memory_limit=512M
post_max_size=1024M
cgi.force_redirect=0
cgi.fix_pathinfo=1
magic_quotes=0
magic_quotes_gpc=0
user_ini.filename=
realpath_cache_size=2M
cgi.check_shebang_line=0
max_input_vars=1000
max_file_uploads=50
zend_extension=opcache.so
opcache.enable=1
opcache.memory_consumption=256
opcache.interned_strings_buffer=8
opcache.max_accelerated_files=10000
opcache.revalidate_freq=60
opcache.fast_shutdown=1
opcache.enable_cli=1
php-fpm.d/www.conf
[www]
user = www-data
group = www-data
listen = /var/run/php-fpm.sock
listen.owner = www-data
listen.group = www-data
listen.mode = 0660
pm = static
pm.max_children = 10
pm.status_path = /status
ping.path = /ping
ping.response = pong
nginx.conf
user www-data;
worker_processes 4;
pid /var/run/nginx.pid;
events {
worker_connections 768;
}
http {
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
include /etc/nginx/mime.types;
default_type application/octet-stream;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
gzip on;
gzip_disable "msie6";
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
php.conf
location ~ \.php {
include fastcgi_params;
fastcgi_keep_conn on;
fastcgi_index index.php;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_intercept_errors on;
fastcgi_pass unix:/var/run/php-fpm.sock;
}
hhvm.conf
location ~ \.php$ {
include fastcgi_params;
fastcgi_keep_conn on;
fastcgi_pass unix:/var/run/hhvm/server.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
sites-enabled/wordpress
server {
listen 80;
server_name wordpress;
root /var/www/wordpress;
access_log /var/log/nginx/wordpress-access.log;
error_log /var/log/nginx/wordpress-error.log;
location / {
index index.html index.htm index.php;
autoindex on;
}
location ~ /\. { return 403; }
include backend.conf;
}
HipHop VM 3.6.1 (rel) from http://dl.hhvm.com/ubuntu
server.ini
pid = /var/run/hhvm/pid
hhvm.server.file_socket = /var/run/hhvm/server.sock
hhvm.server.type = fastcgi
hhvm.server.default_document = index.php
hhvm.log.use_log_file = true
hhvm.log.file = /var/log/hhvm/error.log
hhvm.repo.central.path = /var/run/hhvm/hhvm.hhbc
php.ini
session.save_handler = files
session.save_path = /var/lib/php5
session.gc_maxlifetime = 1440
hhvm.log.level = Warning
hhvm.log.always_log_unhandled_exceptions = true
hhvm.log.runtime_error_reporting_level = 8191
hhvm.mysql.typed_results = false
Had to fix one line of code in the Avalon database library:
diff --git a/database/model.php b/database/model.php
index 6c5f7da..c93e726 100644
--- a/database/model.php
+++ b/database/model.php
@@ -397,7 +397,7 @@ public function __get($var) {
$belongs_to['column'] = $var . '_id';
}
$model = $belongs_to['model'];
- return $this->$var = $model::find($belongs_to['foreign_key'], $this->$belongs_to['column']);
+ return $this->$var = $model::find($belongs_to['foreign_key'], $this->{$belongs_to['column']});
} else {
$val = $this->$var;
Install Vagrant and Virtualbox
Then:
$ git clone https://github.com/rlerdorf/php7dev.git
$ cd php7dev
$ vagrant up
... (takes a bit - it is downloading 1.5G)
$ vagrant ssh
It will NAT, DHCP and also has a fixed address of 192.168.7.7
http://192.168.7.7/ will show you the PHP 7 phpinfo() page
Now you have a working Rasmus-approved dev box on your network
Switching PHP versions is trivial
vagrant@php7dev:~$ newphp 56
Activating PHP 5.6.6-dev and restarting php-fpm
vagrant@php7dev:~$ newphp 7 debug
Activating PHP 7.0.0-dev and restarting php-fpm
20 pre-compiled versions
/usr/local/php53 /usr/local/php54-zts /usr/local/php56-debug-zts
/usr/local/php53-debug /usr/local/php55 /usr/local/php56-zts
/usr/local/php53-debug-zts /usr/local/php55-debug /usr/local/php70
/usr/local/php53-zts /usr/local/php55-debug-zts /usr/local/php70-debug
/usr/local/php54 /usr/local/php55-zts /usr/local/php70-debug-zts
/usr/local/php54-debug /usr/local/php56 /usr/local/php70-zts
/usr/local/php54-debug-zts /usr/local/php56-debug
Build any version
$ makephp 7
Build log in /tmp/build.log
Building PHP 7.0
configuring...
compiling...
installing...
done
Building PHP 7.0-debug
configuring...
compiling...
installing...
done
or manually
$ cd php-src
$ git checkout PHP-5.6
$ git pull -r
$ make distclean
$ ./buildconf -f
$ ./cn56
$ make
$ sudo make install
Report Bugs
Useful bug reports, please!