👉 This post was initially written in 2014 and referred to specific software versions. Phpdbg has now been merged to the main PHP sources. When tunning your system, always consider which version you are running. Information below may be outdated. Use it at your own risk.
PHP 5.6.0 has been released last month by the PHP Development Team. This new version includes some major changes and many improvements. See the release note.
Main features added:
- Constant scalar expressions.
- Variadic functions and argument unpacking using the … operator.
- Exponentiation using the ** operator.
- Function and constant importing with the use keyword.
- phpdbg as an interactive integrated debugger SAPI.
- php://input is now reusable, and $HTTP_RAW_POST_DATA is deprecated.
- GMP objects now support operator overloading.
- File uploads larger than 2 gigabytes in size are now accepted.
You can find the complete features list on the PHP Website.
One of the new features is the integrated phpdbg debugger which provides an interactive environment to debug your PHP code. phpdbg is implemented and distributed as an SAPI module. The phpdbg website has some good documentation, I recommend the Getting started with phpdbg section. This is not a replacement for XDebug.
Let’s cover how to get started with PHP 5.6.0 and phpdbg on Mac OS X.
On Mac OS you can easily install the latest PHP 5.6 with Homebrew. You may hit some errors while trying to enable phpdbg, see Compilation Error.
$ brew options php56
--disable-opcache
Build without Opcache extension
--disable-zend-multibyte
Disable auto-detection of Unicode encoded scripts (PHP 5.2 and 5.3 only)
--homebrew-apxs
Build against apxs in Homebrew prefix
--with-apache
Enable building of shared Apache 2.0 Handler module, overriding any options which disable apache
--with-cgi
Enable building of the CGI executable (implies --without-apache)
--with-debug
Compile with debugging symbols
--with-fpm
Enable building of the fpm SAPI executable (implies --without-apache)
--with-gmp
Build with gmp support
--with-homebrew-curl
Include Curl support via Homebrew
--with-homebrew-libxslt
Include LibXSLT support via Homebrew
--with-homebrew-openssl
Include OpenSSL support via Homebrew
--with-imap
Include IMAP extension
--with-libmysql
Include (old-style) libmysql support instead of mysqlnd
--with-mssql
Include MSSQL-DB support
--with-pdo-oci
Include Oracle databases (requries ORACLE_HOME be set)
--with-pgsql
Include PostgreSQL support
--with-phpdbg
Enable building of the phpdbg SAPI executable (PHP 5.4 and above)
--with-thread-safety
Build with thread safety
--with-tidy
Include Tidy support
--without-bz2
Build without bz2 support
--without-mysql
Remove MySQL/MariaDB support
--without-pcntl
Build without Process Control support
--without-pear
Build without PEAR
--without-snmp
Build without SNMP support
--HEAD
install HEAD version
Compilation Error
You may hit a bug while installing PHP 5.6 with phpdbg on Mac OS. While trying to install using brew install -v php56 --with-phpdbg
the compilation was failing with some errors:
/bin/sh /private/tmp/php56-SQBxFw/php-5.6.0/libtool --silent --preserve-dup-deps --mode=compile clang -D_GNU_SOURCE -Isapi/phpdbg/ -I/private/tmp/php56-SQBxFw/php-5.6.0/sapi/phpdbg/ -DPHP_ATOM_INC -I/private/tmp/php56-SQBxFw/php-5.6.0/include -I/private/tmp/php56-SQBxFw/php-5.6.0/main -I/private/tmp/php56-SQBxFw/php-5.6.0 -I/private/tmp/php56-SQBxFw/php-5.6.0/ext/date/lib -I/private/tmp/php56-SQBxFw/php-5.6.0/ext/ereg/regex -I/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk/usr/include/libxml2 -I/usr/local/opt/zlib/include -I/usr/local/opt/jpeg/include -I/usr/local/opt/libpng/include -I/usr/local/Cellar/freetype/2.5.3_1/include/freetype2 -I/usr/local/opt/gettext/include -I/usr/local/Cellar/icu4c/53.1/include -I/private/tmp/php56-SQBxFw/php-5.6.0/ext/mbstring/oniguruma -I/private/tmp/php56-SQBxFw/php-5.6.0/ext/mbstring/libmbfl -I/private/tmp/php56-SQBxFw/php-5.6.0/ext/mbstring/libmbfl/mbfl -I/private/tmp/php56-SQBxFw/php-5.6.0/ext/sqlite3/libsqlite -I/usr/include/libxml2 -I/private/tmp/php56-SQBxFw/php-5.6.0/ext/zip/lib -I/private/tmp/php56-SQBxFw/php-5.6.0/TSRM -I/private/tmp/php56-SQBxFw/php-5.6.0/Zend -no-cpp-precomp -I/usr/include -g -O2 -fvisibility=hidden -DZEND_SIGNALS -c /private/tmp/php56-SQBxFw/php-5.6.0/sapi/phpdbg/phpdbg_help.c -o sapi/phpdbg/phpdbg_help.lo
/private/tmp/php56-SQBxFw/php-5.6.0/sapi/phpdbg/phpdbg.c:1498:2: error: expected identifier or '('
if (cleaning || remote) {
^
/private/tmp/php56-SQBxFw/php-5.6.0/sapi/phpdbg/phpdbg.c:1508:2: error: expected identifier or '('
if (address) {
^
/private/tmp/php56-SQBxFw/php-5.6.0/sapi/phpdbg/phpdbg.c:1513:2: error: expected identifier or '('
if (sapi_name) {
^
/private/tmp/php56-SQBxFw/php-5.6.0/sapi/phpdbg/phpdbg.c:1520:9: error: a parameter list without types is only allowed in a function definition
unlink(bp_tmp_file);
^
/private/tmp/php56-SQBxFw/php-5.6.0/sapi/phpdbg/phpdbg.c:1523:2: error: expected identifier or '('
return 0;
^
/private/tmp/php56-SQBxFw/php-5.6.0/sapi/phpdbg/phpdbg.c:1524:1: error: extraneous closing brace ('}')
} /* }}} */
^
6 errors generated.
make: *** [sapi/phpdbg/phpdbg.lo] Error 1
make: *** Waiting for unfinished jobs....
==> Formula
Tap: homebrew/homebrew-php
Path: /usr/local/Library/Taps/homebrew/homebrew-php/Formula/php56.rb
==> Configuration
HOMEBREW_VERSION: 0.9.5
HEAD: 911331708b7e547a143f3e03af06ae1834a03290
CPU: 8-core 64-bit sandybridge
OS X: 10.9.4-x86_64
Xcode: 5.1.1
CLT: 5.1.0.0.1.1396320587
X11: N/A
==> ENV
HOMEBREW_CC: clang
HOMEBREW_CXX: clang++
MAKEFLAGS: -j8
CMAKE_PREFIX_PATH: /usr/local/opt/gettext:/usr/local/opt/icu4c:/usr/local/opt/zlib:/usr/local
CMAKE_INCLUDE_PATH: /usr/include/libxml2:/System/Library/Frameworks/OpenGL.framework/Versions/Current/Headers
CMAKE_LIBRARY_PATH: /System/Library/Frameworks/OpenGL.framework/Versions/Current/Libraries
PKG_CONFIG_PATH: /usr/local/opt/libpng/lib/pkgconfig:/usr/local/opt/freetype/lib/pkgconfig:/usr/local/opt/icu4c/lib/pkgconfig:/usr/local/opt/zlib/lib/pkgconfig
PKG_CONFIG_LIBDIR: /usr/lib/pkgconfig:/usr/local/Library/ENV/pkgconfig/10.9
ACLOCAL_PATH: /usr/local/opt/gettext/share/aclocal:/usr/local/share/aclocal
PATH: /usr/local/Library/ENV/4.3:/usr/local/opt/libpng/bin:/usr/local/opt/freetype/bin:/usr/local/opt/gettext/bin:/usr/local/opt/icu4c/bin:/usr/local/opt/jpeg/bin:/usr/local/opt/unixodbc/bin:/usr/local/opt/libtool/bin:/usr/bin:/bin:/usr/sbin:/sbin
Error: php56 5.6.0 did not build
Logs:
/Users/nicolas/Library/Logs/Homebrew/php56/01.configure
/Users/nicolas/Library/Logs/Homebrew/php56/01.configure.cc
/Users/nicolas/Library/Logs/Homebrew/php56/02.make
/Users/nicolas/Library/Logs/Homebrew/php56/02.make.cc
/Users/nicolas/Library/Logs/Homebrew/php56/config.log
To fix it I ended-up decompressing the file locally, patch phpdbg.c, tar again and edit the Homebrew formula to not check the SHA1.
$ diff -u php-5.6.0/sapi/phpdbg/phpdbg.c.orig php-5.6.0/sapi/phpdbg/phpdbg.c
--- php-5.6.0/sapi/phpdbg/phpdbg.c.orig 2014-09-13 17:52:20.000000000 -0700
+++ php-5.6.0/sapi/phpdbg/phpdbg.c 2014-09-13 17:39:58.000000000 -0700
@@ -1493,7 +1493,7 @@
sapi_shutdown();
- }
+ //}
if (cleaning || remote) {
goto phpdbg_main;
I replaced the initial archive tar zc php-5.6.0 > /Library/Caches/Homebrew/php56-5.6.0
, then using brew edit php56
I commented the checksum check.
$ diff -u php56.rb.orig php56.rb
--- php56.rb.orig 2014-09-13 17:56:17.000000000 -0700
+++ php56.rb 2014-09-13 17:43:52.000000000 -0700
@@ -5,7 +5,7 @@
include AbstractPhpVersion::Php56Defs
url PHP_SRC_TARBALL
- sha256 PHP_CHECKSUM[:sha256]
+ #sha256 PHP_CHECKSUM[:sha256]
version PHP_VERSION
head PHP_GITHUB_URL, :branch => PHP_BRANCH
Passed this issue, I was able to test PHP 5.6.0 with phpdbg.
$ php -v
PHP 5.6.0 (cli) (built: Sep 13 2014 18:17:01)
Copyright (c) 1997-2014 The PHP Group
Zend Engine v2.6.0, Copyright (c) 1998-2014 Zend Technologies
$ phpdbg -V
phpdbg 0.4.0 (built: Sep 13 2014 18:17:02)
PHP 5.6.0, Copyright (c) 1997-2014 The PHP Group
Zend Engine v2.6.0, Copyright (c) 1998-2014 Zend Technologies
update: I opened a bug on
GitHub. The issue is now
resolved in the master branch of phpdbg: Fix bug
#111 (compile error without ZEND_SIGNALS). It is not yet in the master branch of
PHP, once it is, you could use brew install php56 --with-phpdbg --head
. Also, the fix should be in the next official PHP 5.6 release.
update 2: The fix has been merged to the
PHP master branch. Using --head
option fix the issue.
First steps with phpdbg
You simply need to start the CLI using the command phpdbg. Inside the CLI, simply check the help.
phpdbg> help
To inspect or debug a PHP file, I will make an example using the judy.php example file from
Pecl PHP Judy (
Official Documentation,
GitHub). Judy can be installed with Homebrew using brew install php56-judy
.
$ phpdbg -e examples/judy.php
[Welcome to phpdbg, the interactive PHP debugger, v0.4.0]
To get help using phpdbg type "help" and press enter
[Please report bugs to <http://github.com/krakjoe/phpdbg/issues>]
[Attempting compilation of /Users/nicolas/Documents/php-judy/php-judy-git/examples/judy.php]
[Success]
phpdbg> run
PHP Judy Version: 1.0.2
Functions available in the judy extension:
judy_version()
judy_type()
Constants available in judy extension:
Judy class methods:
Judy::__construct()
Judy::__destruct()
Judy::getType()
Judy::free()
Judy::memoryUsage()
Judy::count()
Judy::byCount()
Judy::first()
Judy::next()
Judy::last()
Judy::prev()
Judy::firstEmpty()
Judy::nextEmpty()
Judy::lastEmpty()
Judy::prevEmpty()
Judy::offsetSet()
Judy::offsetUnset()
Judy::offsetGet()
Judy::offsetExists()
Judy::size()
To print the opcode of a function:
$ phpdbg -e examples/judy-bench-string_to_int.php
[Welcome to phpdbg, the interactive PHP debugger, v0.4.0]
To get help using phpdbg type "help" and press enter
[Please report bugs to <http://github.com/krakjoe/phpdbg/issues>]
[Attempting compilation of /Users/nicolas/Documents/php-judy/php-judy-git/examples/judy-bench-string_to_int.php]
[Success]
phpdbg> p f __convert
[User Function __convert]
L5-9 __convert() /Users/nicolas/Documents/php-judy/php-judy-git/examples/judy-bench-string_to_int.php
L5 0x106c8d3b0 ZEND_RECV <unused> <unused> $size
L7 0x106c8d3e0 ZEND_INIT_ARRAY C0 <unused> @0
L7 0x106c8d410 ZEND_ADD_ARRAY_ELEMENT C1 <unused> @0
L7 0x106c8d440 ZEND_ADD_ARRAY_ELEMENT C2 <unused> @0
L7 0x106c8d470 ZEND_ADD_ARRAY_ELEMENT C3 <unused> @0
L7 0x106c8d4a0 ZEND_ADD_ARRAY_ELEMENT C4 <unused> @0
L7 0x106c8d4d0 ZEND_ADD_ARRAY_ELEMENT C5 <unused> @0
L7 0x106c8d500 ZEND_ASSIGN $unit @0 @1
L8 0x106c8d530 ZEND_BEGIN_SILENCE <unused> <unused> @2
L8 0x106c8d560 ZEND_FETCH_R C6 <unused> @3
L8 0x106c8d590 ZEND_SEND_VAL C7 <unused> <unused>
L8 0x106c8d5c0 ZEND_SEND_VAR $size <unused> <unused>
L8 0x106c8d5f0 ZEND_SEND_VAL C8 <unused> <unused>
L8 0x106c8d620 ZEND_DO_FCALL C9 <unused> @4
L8 0x106c8d650 ZEND_SEND_VAR_NO_REF @4 <unused> <unused>
L8 0x106c8d680 ZEND_DO_FCALL C10 <unused> @5
L8 0x106c8d6b0 ZEND_ASSIGN $i @5 @6
L8 0x106c8d6e0 ZEND_SEND_VAR_NO_REF @6 <unused> <unused>
L8 0x106c8d710 ZEND_DO_FCALL C11 <unused> @7
L8 0x106c8d740 ZEND_DIV @3 @7 @8
L8 0x106c8d770 ZEND_SEND_VAL @8 <unused> <unused>
L8 0x106c8d7a0 ZEND_SEND_VAL C12 <unused> <unused>
L8 0x106c8d7d0 ZEND_DO_FCALL C13 <unused> @9
L8 0x106c8d800 ZEND_END_SILENCE @2 <unused> <unused>
L8 0x106c8d830 ZEND_CONCAT @9 C14 @10
L8 0x106c8d860 ZEND_FETCH_DIM_R $unit $i @11
L8 0x106c8d890 ZEND_CONCAT @10 @11 @12
L8 0x106c8d8c0 ZEND_RETURN @12 <unused> <unused>
L9 0x106c8d8f0 ZEND_RETURN C15 <unused> <unused>
To set a break point:
phpdbg> break 0x106c8d53
[Breakpoint #0 added at L8]
phpdbg> run
## Count: 100
-- ARRAY
[Breakpoint #1 in 0x106c8d530 at /Users/nicolas/Documents/php-judy/php-judy-git/examples/judy-bench-string_to_int.php:8, hits: 1]
00007: $unit=array('b','kb','mb','gb','tb','pb');
>00008: return @round($size/pow(1024,($i=floor(log($size,1024)))),2).' '.$unit[$i];
00009: }
00010:
To set a break point on a function:
phpdbg> b __convert
[Breakpoint #0 added at __convert]
phpdbg> rum
[The command "rum" could not be found]
phpdbg> run
## Count: 100
-- ARRAY
[Breakpoint #0 in __convert() at /Users/nicolas/Documents/php-judy/php-judy-git/examples/judy-bench-string_to_int.php:5, hits: 1]
00004:
>00005: function __convert($size)
00006: {
00007: $unit=array('b','kb','mb','gb','tb','pb');
Don’t be afraid to use the help
command, all the information you need are there.