Friday Mar 15, 2013

Using PHP 5.5's New "OPcache" Opcode Cache

Zend have contributed their Zend Optimizer+ opcode cache to PHP - thanks Zend!!! (Update 19 March 2013: the renaming to "Zend OPcache" is complete)

"The Zend OPcache provides faster PHP execution through opcode caching and optimization."

The new OPcache extension can be seen as substitute for the venerable APC cache, the maintenance of which had become an issue. Note: although OPcache is now readily available, there is currently nothing preventing you from using any available (working!) opcode cache in PHP 5.5.

A few minutes ago Dmitry Stogov did the physical merge to the PHP 5.5 source's ext/opcache directory. The current PHP 5.5 snapshot has the code. Future Alpha or Beta (and Production) releases will include it too.

Please test OPcache. It is not a panacea for all performance problems. There are a lot of settings which may need adjusting. Understanding how it works and identifying issues during the stabilization phase of PHP 5.5 release process will greatly help.

To build Zend OPcache for PHP 5.5:

When you configure PHP, add the option --enable-opcache like:

./configure ... --enable-opcache

Then make and make install, as normal. This will build OPcache shared extension. It's not possible to build it statically.

Find the shared library in your installation directory with a command like find /home/cjones/php55 -name opcache.so

Edit php.ini and add the extension with its full path:

zend_extension=/home/cjones/php55/lib/php/extension/debug-non-zts-20121212/opcache.so

Update (25 March 2013): Dmitry merged a PHP 5.5 change so that the full path is not required for zend_extension libraries in the extension_dir directory. You can now simply do zend_extension=opcache.so.

You'll want to enable OPcache too:

opcache.enable=On

The ext/opcache/README is the current source of documentation, and lists all the other php.ini parameters.

Problems can be reported in the Github issue tracker

Update (18 March 2013): In a commit over the weekend, the build option --enable-opcache is On by default. You will still need to update php.ini.

To build Zend OPcache for older versions of PHP:

You should be able to build OPcache with PHP 5.2 onwards

Install it by getting the source from Github. There is also a PECL repository; this is slightly out of date so I recommend using Github. Follow the README instructions to install it.

User-data cache:

The new opcode cache does not include a user-data cache. Joe Watkins recently started the APCu project to extract the user-data cache code from APC. Test this too!

Update 19 March 2013: Xinchen Hui is working on a lockless user-data cache, see https://github.com/laruence/yac and his blog about it here (in Chinese).

Tuesday Feb 12, 2013

The Mysterious PHP RFC Process and How You Can Change the Web

The PHP RFC process has been in place for a while, and users new to core PHP development are starting to use RFCs to propose desirable features.

Here are some personal observations and suggestions that show how I have seen feature acceptance and the RFC process work in practice. These notes augment the steps in How To Create an RFC. I hope they help set expectations about the PHP RFC process and feature acceptance in the PHP language.

  1. Before starting an RFC, review existing RFCs and search the mail list archives for similar ideas. Use this information to explain what your RFC will bring to the language.

  2. If you're new to PHP core development, mail the "internals" mail list to judge interest before you start your RFC. If you get no reaction (this is likely) or positive reaction then create the RFC. Core PHP developers with karma will know when they can skip this step.

  3. Avoid presenting an RFC idea to the "internals" mail list with email that begins "I don't know much about ... but ...". Do some research first.

  4. There are many really good ideas for improving PHP, however some of them are really tedious or technically risky or hard. If you are about to email the "internals" mail list saying "someone should do ...", then don't hit "Send". Work out how you could do it, and then send a patch.

  5. If the overall goals of PHP are not clear to you, you may not be alone. However, as an RFC writer you need to learn the general trajectory of the language and where web development is heading. You then need to enthuse everyone with your feature and show what it brings to the language.

  6. Don't start an RFC (or mail list discussion) about standardizing PHP function names and function argument orders. There are several historical reasons why the functions are what they are (including compatibility with underlying libraries), and many good reasons why the change would be counter-productive causing more end-user confusion, would lead to unmaintainable PHP engine code, and generally be a waste of everyone's time when they could be doing more interesting projects. This has been discussed ad infinitum. Review previous discussions and feel free to fork PHP on github.

  7. Your RFC should talk about all PHP areas that will be affected: php.ini, different SAPIs, engine, extensions, etc. List similar features. List similar features in other languages. Link to references. Give an estimate of the actual positive impact to user code. Put the proposed voting options in the RFC so they can be included in its discussion. Include the proposed acceptance criteria (2/3 or 50%+1 majority - see the original Voting RFC) to avoid later argument.

  8. Your RFC will be used to create the PHP documentation, so make its sections re-usable. Explain concepts and details. Keep the RFC technical and have plenty of examples.

  9. Many current PHP RFCs don't contain enough detail, nor do they capture the pros & cons that were discussed on the mail list. You can, and should, do better than these RFCs.

  10. An implementation is not mandatory while proposing an RFC but it can help persuade people and help fine-tune the design. Note that if you are unable to implement the RFC, and no one else volunteers during the discussion period, then your RFC is unlikely ever to be implemented.

  11. Don't start an implementation too early. Get support for the feature concept from the "internals" mail list before spending time on coding - unless you want a learning experience.

  12. If you do have an implementation, make it clear whether the implementation is a simple prototype or is expected to be the final code. This is specially important during the vote.

  13. It's easy to get sidetracked by mail list trolling or well intentioned but over-eager discussion. Take advice on board but make sure your feature doesn't end up being designed by a committee. Don't blame the "PHP core community" for derailing discussions when the issues of non- code-contributors on the mail list are at fault.

  14. For every user who wants a backwardly incompatible change to PHP, there is a user who will scream that this will be disastrous to them. As the RFC writer you need to walk the line between these groups. At voting time, other people may see the line in a different place than you do.

  15. There is no need to respond to every discussion email individually. You should batch up your responses and manage the discussion intelligently.

  16. Don't get side tracked by how long it will take a feature to reach end users. It will reach them eventually. You can always supply an unofficial patch or maybe create a PECL extension for users of current versions of PHP.

  17. Don't let mail list discussion drag on too long. High levels of discussion can be a symptom that an RFC is contentious. Having an early vote about only the feature's concept can prevent over-investment in an RFC and implementation.

  18. With long, fragmented discussions, not everyone will read every email. Update the RFC at regular intervals, and let people know what has changed. Include the RFC URL in all your emails so anyone dipping into a mail thread has a better chance of finding the RFC.

  19. PHP is popular so you can often find support from "many" people for cool language features. This doesn't mean those features are a "good thing" for the language or its implementation.

  20. There are multiple PHP communities. Don't interpret support in one community as universal support. Listen carefully to the key PHP developers on the "internals" mail list (they may not be the ones doing the most discussion). They are the people who will undoubtedly end up doing final integration of the feature (e.g. with the op-code cache), fixing edge cases, and maintaining it in the long term. They are the ones that have seen the PHP code base complexity grow and become more difficult to maintain and extend. Even if they like your idea, they may not be able to contribute time and effort to make it stable.

  21. The PHP core development community needs more end-users to become core language developers but the barrier to entry is high because of the complexity of the API, and because new features need very careful integration with a complex language. See the point above about existing developers not having enough time to support every good idea. This just means you need perseverance to become a core developer yourself. You can gain karma by being a regular code contributor before starting your magnum opus RFC.

  22. Some areas of PHP are complex or niche. Sometimes feature suggestions will be greeted by an apparent lack of interest. Don't be discouraged. This just means you need to take a stronger leadership role, and also prove your credentials by first working on the existing code base.

  23. Keep your RFC updated with a summary of all the positive and negative mail list discussion points and examples.

    • This prevents arguments being rehashed on the mail list each year.
    • Documentation will have clear use cases and show what does and doesn't work.
    • Future RFC writers can see trends and build on previous ideas.
  24. Before initiating a vote on your RFC, make sure the RFC contains enough detail so that the vote is solely on the RFC contents, not on any half-remembered or misinterpretable mail list discussions. Un- (or badly) expressed intentions will only cause you frustration when your RFC is rejected.

  25. Don't leave any ambiguity in the RFC. As well as stating what will be changed, also state what won't be changed. Ambiguity will hurt the chances of a successful outcome because voters will be unsure that the feature has been fully thought through. Make sure there are no "Open Issues" in the RFC when voting. Make a decision about the choices before opening the vote, or mark the issues clearly as "Future topics for exploration".

  26. Make sure any vote is clear about what is being voted on: is it the idea, the specification, or the implementation? Is a particular version of PHP being targeted? Is the implementation going to be merged to the core language or made as a PECL extension?

  27. Warn the "internals" mail list before starting the vote. This notification gives you a chance to fine tune the wording of your poll; this wording has caused contention in the past. The approaching deadline may also cause last-minute RFC responses. These may be significant enough to require further discussion.

  28. Set a deadline for the vote (sadly the current voting RFC doesn't require this). Having a deadline will forestall suggestions that a vote was deliberately left open until it succeeded, and then closed before the "negative" side could rally support.

  29. During the voting period, it is common for people to continue mail list discussion. You may need to halt the vote and address any issues.

  30. Prior to the end of the voting period, remind the mail list that the vote is about to close.

  31. Positive voting poll outcomes for RFs that are just "concepts" can be interpreted as support for "good ideas" rather than being a definitive guarantee that a feature will appear in a future version of PHP. As a feature is later investigated and further discussed, the early vote may become irrelevant. Similarly, where there is no chance of an implementation being written, a positive poll outcome is just an indicator of desire.

  32. If your RFC is rejected, it is not the end of the world. Sometimes ideas are submitted "before their time", and it takes an acclimatization period for other developers to see their value. As the core PHP developer base goes through natural turn-over, revisiting an idea after a (long) period may result in different appreciation. (This does not apply to some ideas, for example standardizing function names). See the previous points about becoming a core contributor - having karma goes a long way towards getting an RFC accepted, not only because experienced contributors know which RFCs are worth suggesting, and know how to make proposals understandable. When your RFC is rejected, continue working with the PHP core development community and revisit the RFC later.

  33. You can always fork PHP from github.

In summary, the PHP development process is an organic process and subject to flexibility. It is based heavily around users contributing features that they require. This therefore requires high investment from users who want change. Very rarely do PHP core developers have bandwidth to take on external ideas, no matter how good they are. Feature acceptance has to be pragmatic. The core PHP contributors would love to see more people get commit karma and contribute to PHP.

This post has gone on long enough. My notes are current for the time being. I'm sure there are observations or clarifications you can make. If you want to add anything, please post a comment.

(Note: this page has been augmented and re-ordered since first being published)

Thursday Jan 31, 2013

OS X Users! 11gR2 Oracle Instant Client 32 & 64-bit is now available

The Oracle 11g Release 2 (11.2.0.3) Database Instant Client for Apple OS X on Intel x86-64 is now available for download from OTN. It is supported on the two latest OS X releases: Lion (10.7) and Mountain Lion (10.8). It provides both 32-bit and 64-bit client support.

Oracle Instant Client is a simple bundle of libraries that client tools and programs (like PHP and Ruby) can link with. This allows those tools to access Oracle Databases.

Any issues with Instant Client can be posted to the OTN Instant Client Forum.

Tuesday Jan 29, 2013

MySQL Sessions at the ConFoo.ca conference

Who says direct marketing doesn't work? A personal request to blog the upcoming ConFoo conference (25 February - 1 March 2013 in Montreal, Canada) has, as you can see, been successful. Although it's been a few years since I spoke there, I recall how impressive the organization was. The diversity and continual growth trajectory of the conference over the years is a very good indicator that you should be involved.

While you're there, say Hi to Oracle Ace Director Sheeri Cabral who is giving a couple of MySQL talks.

Wednesday Jan 23, 2013

Quick Debugging of PHP Scripts in Emacs with Geben and Xdebug

When you want to test a PHP code snippet quickly, it's handy to do it within your day-to-day environment. For me, this environment is Emacs. The geben package for Emacs provides an interface to the DBGp protocol, such as used by Derick Rethans's standard Xdebug extension for PHP.

With the combination of geben and Xdebug, I can quickly and efficiently step through execution of local files, examining code flow and data values.

Working steps to install and use the debugger on command line PHP scripts are shown below. They are standard enough that they can be customized to your actual environment.

You probably already have Xdebug installed, since it is the common debugger and profiler used by most IDEs. Installing geben in Emacs is straight forward.

1. Download PHP 5.4 from http://php.net/downloads.php

2. Install PHP with:

$ tar -jxf php-5.4.11.tar.bz2
$ cd php-5.4.11
$ ./configure --prefix=/home/cjones/php54
$ make install
$ cp php.ini-development /home/cjones/php54/lib/php.ini

3. Download the source code for the Xdebug Debugger extension for PHP from http://xdebug.org/download.php

4. Install Xdebug into PHP with:

$ cd /home/cjones
$ tar -zxf xdebug-2.2.1.tgz
$ cd xdebug-2.2.1
$ export PATH=/home/cjones/php54/bin:$PATH
$ phpize
$ ./configure --enable-xdebug --with-php-config=/home/cjones/php54/bin/php-config
$ make install

More information is shown in http://xdebug.org/docs/install

5. Edit /home/cjones/php54/lib/php.ini and enable Xdebug by adding these lines:

zend_extension=/home/cjones/php54/lib/php/extensions/no-debug-non-zts-20100525/xdebug.so
xdebug.remote_enable=on
xdebug.remote_host=127.0.0.1

6. Install geben manually or use the Emacs 24 package repository (M-x package-list-packages)

To manually install geben, download it from http://code.google.com/p/geben-on-emacs/downloads/list and install it with:

$ cd /home/cjones
$ tar -zxf geben-0.26.tar.gz

8. Add the following to the Emacs initialization file /home/cjones/.emacs. When testing this blog post, my .emacs file only contained this code:

(setq load-path (cons "/home/cjones/geben-0.26" load-path))

(autoload 'geben "geben" "DBGp protocol frontend, a script debugger" t)

;; Debug a simple PHP script.
;; Change the session key my-php-54 to any session key text you like
(defun my-php-debug ()
  "Run current PHP script for debugging with geben"
  (interactive)
  (call-interactively 'geben)
  (shell-command
    (concat "XDEBUG_CONFIG='idekey=my-php-54' /home/cjones/php54/bin/php "
    (buffer-file-name) " &"))
  )

(global-set-key [f5] 'my-php-debug)

Experienced Emacs users will most likely use local-set-key in a php-mode hook to set a key mapping.

9. Start Emacs and load a PHP file:

$ emacs my.php

10. Press F5 to start the debugger. The script will open in geben mode and can be stepped through with the space bar.

Geben mode commands can be shown with '?'. They include 'v' for showing variables, 'c' for run-to-cursor, and 'g' for completing the program.

Geben can also be used for scripts called via a browser. Start the geben listener in Emacs with M-x geben and load a script in the browser, passing an Xdebug URL parameter setting the session name. This initiates the debug session in Emacs. E.g. Load http://localhost/my.php?XDEBUG_SESSION_START=my-php-54

11. When you are finished debugging, stop the debug server listener inside Emacs:

M-x geben-end

Tuesday Dec 11, 2012

Excitement! Updated Underground PHP and Oracle Manual is Available for Download

We're thrilled to have a major update of the free Underground PHP and Oracle Manual released on OTN.

The Underground PHP and Oracle Manual is designed to bridge the gap between the many PHP scripting language and the many Oracle Database books available. It contains unique material about PHP's OCI8 extension for Oracle Database, and about other components in the PHP-Oracle ecosystem. It shows PHP developers how to use PHP and Oracle together, efficiently and easily.

The book has been completely refreshed. It has been updated for Oracle XE 11g and the latest PHP OCI8 extension. There are new chapters about using PHP with Oracle TimesTen, NetBeans and Oracle Tuxedo. There is also a new chapter about installing PHP on Oracle Solaris. The book now clocks in at 347 pages of great content.

Acknowledgements are due to all those who have helped with this and previous editions of the book. Thanks to the product teams that assisted with brand new content. In particular Craig Mohrman contributed the chapter about PHP on Solaris. Jeffry Rubinoff contributed the base text for the chapter on PHP and NetBeans.

Thursday Dec 06, 2012

Adding DTrace Probes to PHP Extensions

The powerful DTrace tracing facility has some PHP-specific probes that can be enabled with --enable-dtrace.

DTrace for Linux is being created by Oracle and is currently in tech preview. Currently it doesn't support userspace tracing so, in the meantime, Systemtap can be used to monitor the probes implemented in PHP. This was recently outlined in David Soria Parra's post Probing PHP with Systemtap on Linux.

My post shows how DTrace probes can be added to PHP extensions and traced on Linux. I was using Oracle Linux 6.3.

Not all Linux kernels are built with Systemtap, since this can impact stability. Check whether your running kernel (or others installed) have Systemtap enabled, and reboot with such a kernel:

# grep CONFIG_UTRACE /boot/config-`uname -r`
# grep CONFIG_UTRACE /boot/config-*

When you install Systemtap itself, the package systemtap-sdt-devel is needed since it provides the sdt.h header file:

# yum install systemtap-sdt-devel

You can now install and build PHP as shown in David's article. Basically the build is with:

$ cd ~/php-src
$ ./configure --disable-all --enable-dtrace
$ make

(For me, running 'make' a second time failed with an error. The workaround is to do 'git checkout Zend/zend_dtrace.d' and then rerun 'make'. See PHP Bug 63704)

David's article shows how to trace the probes already implemented in PHP. You can also use Systemtap to trace things like userspace PHP function calls. For example, create test.php:

<?php

$c = oci_connect('hr', 'welcome', 'localhost/orcl');
$s = oci_parse($c, "select dbms_xmlgen.getxml('select * from dual') xml from dual");
$r = oci_execute($s);
$row = oci_fetch_array($s, OCI_NUM);
$x = $row[0]->load();
$row[0]->free();
echo $x;

?>

The normal output of this file is the XML form of Oracle's DUAL table:

$ ./sapi/cli/php ~/test.php
<?xml version="1.0"?>
<ROWSET>
 <ROW>
  <DUMMY>X</DUMMY>
 </ROW>
</ROWSET>

To trace the PHP function calls, create the tracing file functrace.stp:

probe process("sapi/cli/php").function("zif_*") {
    printf("Started function %s\n", probefunc());
}

probe process("sapi/cli/php").function("zif_*").return {
    printf("Ended function %s\n", probefunc());
}

This makes use of the way PHP userspace functions (not builtins) like oci_connect() map to C functions with a "zif_" prefix.

Login as root, and run System tap on the PHP script:

# cd ~cjones/php-src
# stap -c 'sapi/cli/php ~cjones/test.php' ~cjones/functrace.stp
Started function zif_oci_connect
Ended function zif_oci_connect
Started function zif_oci_parse
Ended function zif_oci_parse
Started function zif_oci_execute
Ended function zif_oci_execute
Started function zif_oci_fetch_array
Ended function zif_oci_fetch_array
Started function zif_oci_lob_load
<?xml version="1.0"?>
<ROWSET>
 <ROW>
  <DUMMY>X</DUMMY>
 </ROW>
</ROWSET>
Ended function zif_oci_lob_load
Started function zif_oci_free_descriptor
Ended function zif_oci_free_descriptor

Each call and return is logged. The Systemtap scripting language allows complex scripts to be built. There are many examples on the web.

To augment this generic capability and the PHP probes in PHP, other extensions can have probes too. Below are the steps I used to add probes to OCI8:

  1. I created a provider file ext/oci8/oci8_dtrace.d, enabling three probes. The first one will accept a parameter that runtime tracing can later display:

    provider php {
    	probe oci8__connect(char *username);
    	probe oci8__nls_start();
    	probe oci8__nls_done();
    };
    
  2. I updated ext/oci8/config.m4 with the PHP_INIT_DTRACE macro. The patch is at the end of config.m4. The macro takes the provider prototype file, a name of the header file that 'dtrace' will generate, and a list of sources files with probes. When --enable-dtrace is used during PHP configuration, then the outer $PHP_DTRACE check is true and my new probes will be enabled. I've chosen to define an OCI8 specific macro, HAVE_OCI8_DTRACE, which can be used in the OCI8 source code:

    diff --git a/ext/oci8/config.m4 b/ext/oci8/config.m4
    index 34ae76c..f3e583d 100644
    --- a/ext/oci8/config.m4
    +++ b/ext/oci8/config.m4
    @@ -341,4 +341,17 @@ if test "$PHP_OCI8" != "no"; then
         PHP_SUBST_OLD(OCI8_ORACLE_VERSION)
     
       fi
    +
    +  if test "$PHP_DTRACE" = "yes"; then
    +     AC_CHECK_HEADERS([sys/sdt.h], [
    +       PHP_INIT_DTRACE([ext/oci8/oci8_dtrace.d],
    +                       [ext/oci8/oci8_dtrace_gen.h],[ext/oci8/oci8.c])
    +         AC_DEFINE(HAVE_OCI8_DTRACE,1,
    +         [Whether to enable DTrace support for OCI8 ])
    +     ], [
    +       AC_MSG_ERROR(
    +         [Cannot find sys/sdt.h which is required for DTrace support])
    +     ])
    +   fi
    +
     fi
    
  3. In ext/oci8/oci8.c, I added the probes at, for this example, semi-arbitrary places:

    diff --git a/ext/oci8/oci8.c b/ext/oci8/oci8.c
    index e2241cf..ffa0168 100644
    --- a/ext/oci8/oci8.c
    +++ b/ext/oci8/oci8.c
    @@ -1811,6 +1811,12 @@ php_oci_connection *php_oci_do_connect_ex(char *username, int username_len, char
     		}
     	}
     
    +#ifdef HAVE_OCI8_DTRACE
    +    if (DTRACE_OCI8_CONNECT_ENABLED()) {
    +		DTRACE_OCI8_CONNECT(username);
    +	}
    +#endif
    +
     	/* Initialize global handles if they weren't initialized before */
     	if (OCI_G(env) == NULL) {
     		php_oci_init_global_handles(TSRMLS_C);
    @@ -1870,11 +1876,22 @@ php_oci_connection *php_oci_do_connect_ex(char *username, int username_len, char
     		size_t rsize = 0;
     		sword result;
     
    +#ifdef HAVE_OCI8_DTRACE
    +		if (DTRACE_OCI8_NLS_START_ENABLED()) {
    +			DTRACE_OCI8_NLS_START();
    +		}
    +#endif
     		PHP_OCI_CALL_RETURN(result, OCINlsEnvironmentVariableGet, (&charsetid_nls_lang, 0, OCI_NLS_CHARSET_ID, 0, &rsize));
     		if (result != OCI_SUCCESS) {
     			charsetid_nls_lang = 0;
     		}
     		smart_str_append_unsigned_ex(&hashed_details, charsetid_nls_lang, 0);
    +
    +#ifdef HAVE_OCI8_DTRACE
    +		if (DTRACE_OCI8_NLS_DONE_ENABLED()) {
    +			DTRACE_OCI8_NLS_DONE();
    +		}
    +#endif
     	}
     
     	timestamp = time(NULL);
    

    The oci_connect(), oci_pconnect() and oci_new_connect() calls all use php_oci_do_connect_ex() internally. The first probe simply records that the PHP application made a connection call. I already showed a way to do this without needing a probe, but adding a specific probe lets me record the username. The other two probes can be used to time how long the globalization initialization takes.

    The relationships between the oci8_dtrace.d names like oci8__connect, the probe guards like DTRACE_OCI8_CONNECT_ENABLED() and probe names like DTRACE_OCI8_CONNECT() are obvious after seeing the pattern of all three probes.

    I included the new header that will be automatically created by the dtrace tool when PHP is built. I did this in ext/oci8/php_oci8_int.h:

    diff --git a/ext/oci8/php_oci8_int.h b/ext/oci8/php_oci8_int.h
    index b0d6516..c81fc5a 100644
    --- a/ext/oci8/php_oci8_int.h
    +++ b/ext/oci8/php_oci8_int.h
    @@ -44,6 +44,10 @@
     #  endif
     # endif /* osf alpha */
     
    +#ifdef HAVE_OCI8_DTRACE
    +#include "oci8_dtrace_gen.h"
    +#endif
    +
     #if defined(min)
     #undef min
     #endif
    
  4. Now PHP can be rebuilt:

    $ cd ~/php-src
    $ rm configure && ./buildconf --force
    $ ./configure --disable-all --enable-dtrace \
                  --with-oci8=instantclient,/home/cjones/instantclient
    $ make
    

    If 'make' fails, do the 'git checkout Zend/zend_dtrace.d' trick I mentioned.

  5. The new probes can be seen by logging in as root and running:

    # stap -l 'process.provider("php").mark("oci8*")' -c 'sapi/cli/php -i'
    process("sapi/cli/php").provider("php").mark("oci8__connect")
    process("sapi/cli/php").provider("php").mark("oci8__nls_done")
    process("sapi/cli/php").provider("php").mark("oci8__nls_start")
    
  6. To test them out, create a new trace file, oci.stp:

    global numconnects;
    global start;
    global numcharlookups = 0;
    global tottime = 0;
    probe process.provider("php").mark("oci8-connect") {
        printf("Connected as %s\n", user_string($arg1));
        numconnects += 1;
    }
    probe process.provider("php").mark("oci8-nls_start") {
        start = gettimeofday_us();
        numcharlookups++;
    }
    probe process.provider("php").mark("oci8-nls_done") {
        tottime += gettimeofday_us() - start;
    }
    probe end {
        printf("Connects: %d, Charset lookups: %ld\n", numconnects, numcharlookups);
        printf("Total NLS charset initalization time: %ld usecs/connect\n", 
                            (numcharlookups > 0 ? tottime/numcharlookups : 0));
    }
    

    This calculates the average time that the NLS character set lookup takes. It also prints out the username of each connection, as an example of using parameters.

  7. Login as root and run Systemtap over the PHP script:

    # cd ~cjones/php-src
    # stap -c 'sapi/cli/php ~cjones/test.php' ~cjones/oci.stp
    Connected as cj
    <?xml version="1.0"?>
    <ROWSET>
     <ROW>
      <DUMMY>X</DUMMY>
     </ROW>
    </ROWSET>
    Connects: 1, Charset lookups: 1
    Total NLS charset initalization time: 164 usecs/connect
    

    This shows the time penalty of making OCI8 look up the default character set. This time would be zero if a character set had been passed as the fourth argument to oci_connect() in test.php.

Update: To use real (non-SystemTap) DTrace, the extension binary needs to be built slightly differently than shown above in step 2. Instead of modifying config.m4 to reuse PHP_INIT_DTRACE, an OCI8-specific variant of that macro is created. To see how this is done, look at the new OCI8_INIT_DTRACE macro definition and way it is used in PHP OCI8 2.0's ext/oci8/config.m4.

Sunday Nov 25, 2012

How (and when) to move users to mysqli and PDO_MYSQL?

An important discussion on the PHP "internals" development mailing list is taking place. It's one that you should take some note of. It concerns the next step in transitioning PHP applications away from the very old mysql extension and towards adopting the much better mysqli extension or PDO_MYSQL driver for PDO. This would allow the mysql extension to, at some as-yet undetermined time in the future, be removed. Both mysqli and PDO_MYSQL have been around for many years, and have various advantages: http://php.net/manual/en/mysqlinfo.api.choosing.php

The initial RFC for this next step is at https://wiki.php.net/rfc/mysql_deprecation I would expect the RFC to change substantially based on current discussion. The crux of that discussion is the timing of the next step of deprecation. There is also discussion of the carrot approach (showing users the benfits of moving), and stick approach (displaying warnings when the mysql extension is used). As always, there is a lot of guesswork going on as to what MySQL APIs are in current use by PHP applications, how those applications are deployed, and what their upgrade cycle is. This is where you can add your weight to the discussion - and also help by spreading the word to move to mysqli or PDO_MYSQL. An example of such a 'carrot' is the excellent summary at Ulf Wendel's blog: http://blog.ulf-wendel.de/2012/php-mysql-why-to-upgrade-extmysql/

I want to repeat that no time frame for the eventual removal of the mysql extension is set. I expect it to be some years away.

Wednesday Sep 12, 2012

Scripting Language Sessions at Oracle OpenWorld and MySQL Connect, 2012

This posts highlights some great scripting language sessions coming up at the Oracle OpenWorld and MySQL Connect conferences. These events are happening in San Francisco from the end of September. You can search for other interesting conference sessions in the Content Catalog. Also check out what is happening at JavaOne in that event's Content Catalog (I haven't included sessions from it in this post.)

To find the timeslots and locations of each session, click their respective link and check the "Session Schedule" box on the top right.

GEN8431 - General Session: What’s New in Oracle Database Application Development This general session takes a look at what’s been new in the last year in Oracle Database application development tools using the latest generation of database technology. Topics range from Oracle SQL Developer and Oracle Application Express to Java and PHP. (Thomas Kyte - Architect, Oracle)

BOF9858 - Meet the Developers of Database Access Services (OCI, ODBC, DRCP, PHP, Python) This session is your opportunity to meet in person the Oracle developers who have built Oracle Database access tools and products such as the Oracle Call Interface (OCI), Oracle C++ Call Interface (OCCI), and Open Database Connectivity (ODBC) drivers; Transparent Application Failover (TAF); Oracle Database Instant Client; Database Resident Connection Pool (DRCP); Oracle Net Services, and so on. The team also works with those who develop the PHP, Ruby, Python, and Perl adapters for Oracle Database. Come discuss with them the features you like, your pains, and new product enhancements in the latest database technology.

CON8506 - Syndication and Consolidation: Oracle Database Driver for MySQL Applications This technical session presents a new Oracle Database driver that enables you to run MySQL applications (written in PHP, Perl, C, C++, and so on) against Oracle Database with almost no code change. Use cases for such a driver include application syndication such as interoperability across a relationship database management system, application migration, and database consolidation. In addition, the session covers enhancements in database technology that enable and simplify the migration of third-party databases and applications to and consolidation with Oracle Database. Attend this session to learn more and see a live demo. (Srinath Krishnaswamy - Director, Software Development, Oracle. Kuassi Mensah - Director Product Management, Oracle. Mohammad Lari - Principal Technical Staff, Oracle )

HOL10068 - Run MySQL Applications Against the Latest Oracle Database Technology Have you ever wanted to run the same applications against both MySQL and Oracle Database or migrate MySQL applications to Oracle Database? MySQL DBAs, Oracle DBAs, MySQL developers, Oracle developers: participate in this hands-on lab to learn the commonalities and differences between MySQL and Oracle Database in terms of database types, DDL, and SQL syntax and then deploy and run a MySQL application (almost) unchanged against an Oracle Database instance. The lab preinstalls both MySQL and Oracle Database and furnishes a running MySQL application and a few step-by-step instructions for deploying and running it against the latest Oracle Database release. (Srinath Krishnaswamy - Director, Software Development, Oracle. Kuassi Mensah - Director Product Management, Oracle. Christopher Jones - Consulting Technical Staff, Oracle. Mohammad Lari - Principal Technical Staff, Oracle )

CON9167 - Current State of PHP and MySQL Together, PHP and MySQL power large parts of the Web. The developers of both technologies continue to enhance their software to ensure that developers can be satisfied despite all their changing and growing needs. This session presents an overview of changes in PHP 5.4, which was released earlier this year and shows you various new MySQL-related features available for PHP, from transparent client-side caching to direct support for scaling and high-availability needs. (Johannes Schlüter - SoftwareDeveloper, Oracle)

CON8983 - Sharding with PHP and MySQL In deploying MySQL, scale-out techniques can be used to scale out reads, but for scaling out writes, other techniques have to be used. To distribute writes over a cluster, it is necessary to shard the database and store the shards on separate servers. This session provides a brief introduction to traditional MySQL scale-out techniques in preparation for a discussion on the different sharding techniques that can be used with MySQL server and how they can be implemented with PHP. You will learn about static and dynamic sharding schemes, their advantages and drawbacks, techniques for locating and moving shards, and techniques for resharding. (Mats Kindahl - Senior Principal Software Developer, Oracle)

CON9268 - Developing Python Applications with MySQL Utilities and MySQL Connector/Python This session discusses MySQL Connector/Python and the MySQL Utilities component of MySQL Workbench and explains how to write MySQL applications in Python. It includes in-depth explanations of the features of MySQL Connector/Python and the MySQL Utilities library, along with example code to illustrate the concepts. Those interested in learning how to expand or build their own utilities and connector features will benefit from the tips and tricks from the experts. This session also provides an opportunity to meet directly with the engineers and provide feedback on your issues and priorities. You can learn what exists today and influence future developments. (Geert Vanderkelen - Software Developer, Oracle)

BOF9141 - MySQL Utilities and MySQL Connector/Python: Python Developers, Unite! Come to this lively discussion of the MySQL Utilities component of MySQL Workbench and MySQL Connector/Python. It includes in-depth explanations of the features and dives into the code for those interested in learning how to expand or build their own utilities and connector features. This is an audience-driven session, so put on your best Python shirt and let’s talk about MySQL Utilities and MySQL Connector/Python. (Geert Vanderkelen - Software Developer, Oracle. Charles Bell - Senior Software Developer, Oracle)

CON3290 - Integrating Oracle Database with a Social Network Facebook, Flickr, YouTube, Google Maps. There are many social network sites, each with their own APIs for sharing data with them. Most developers do not realize that Oracle Database has base tools for communicating with these sites, enabling all manner of information, including multimedia, to be passed back and forth between the sites. This technical presentation goes through the methods in PL/SQL for connecting to, and then sending and retrieving, all types of data between these sites. (Marcelle Kratochvil - CTO, Piction)

CON3291 - Storing and Tuning Unstructured Data and Multimedia in Oracle Database Database administrators need to learn new skills and techniques when the decision is made in their organization to let Oracle Database manage its unstructured data. They will face new scalability challenges. A single row in a table can become larger than a whole database. This presentation covers the techniques a DBA needs for managing the large volume of data in a standard Oracle Database instance. (Marcelle Kratochvil - CTO, Piction)

CON3292 - Using PHP, Perl, Visual Basic, Ruby, and Python for Multimedia in Oracle Database These five programming languages are just some of the most popular ones in use at the moment in the marketplace. This presentation details how you can use them to access and retrieve multimedia from Oracle Database. It covers programming techniques and methods for achieving faster development against Oracle Database. (Marcelle Kratochvil - CTO, Piction)

UGF5181 - Building Real-World Oracle DBA Tools in Perl Perl is not normally associated with building mission-critical application or DBA tools. Learn why Perl could be a good choice for building your next killer DBA app. This session draws on real-world experience of building DBA tools in Perl, showing the framework and architecture needed to deal with portability, efficiency, and maintainability. Topics include Perl frameworks; Which Comprehensive Perl Archive Network (CPAN) modules are good to use; Perl and CPAN module licensing; Perl and Oracle connectivity; Compiling and deploying your app; An example of what is possible with Perl. (Arjen Visser - CEO & CTO, Dbvisit Software Limited)

CON3153 - Perl: A DBA’s and Developer’s Best (Forgotten) Friend This session reintroduces Perl as a language of choice for many solutions for DBAs and developers. Discover what makes Perl so successful and why it is so versatile in our day-to-day lives. Perl can automate all those manual tasks and is truly platform-independent. Perl may not be in the limelight the way other languages are, but it is a remarkable language, it is still very current with ongoing development, and it has amazing online resources. Learn what makes Perl so great (including CPAN), get an introduction to Perl language syntax, find out what you can use Perl for, hear how Oracle uses Perl, discover the best way to learn Perl, and take away a small Perl project challenge. (Arjen Visser - CEO & CTO, Dbvisit Software Limited)

CON10332 - Oracle RightNow CX Cloud Service’s Connect PHP API: Intro, What’s New, and Roadmap Connect PHP is a public API that enables developers to build solutions with the Oracle RightNow CX Cloud Service platform. This API is used primarily by developers working within the Oracle RightNow Customer Portal Cloud Service framework who are looking to gain access to data and services hosted by the Oracle RightNow CX Cloud Service platform through a backward-compatible API. Connect for PHP leverages the same data model and services as the Connect Web Services for SOAP API. Come to this session to get an introduction and learn what’s new and what’s coming up. (Mark Rhoads - Senior Principal Applications Engineer, Oracle. Mark Ericson - Sr. Principle Product Manager, Oracle)

CON10330 - Oracle RightNow CX Cloud Service APIs and Frameworks Overview Oracle RightNow CX Cloud Service APIs are available in the following areas: desktop UI, Web services, customer portal, PHP, and knowledge. These frameworks provide access to Oracle RightNow CX Cloud Service’s Connect Common Object Model and custom objects. This session provides a broad overview of capabilities in all these areas. (Mark Ericson - Sr. Principle Product Manager, Oracle)

Monday Sep 10, 2012

NetBeans PHP Community Council

A new NetBeans PHP Community Council offers a chance to contribute to NetBeans. A guest post by Timur Poperecinii on the NetBeans blog explains the council.

Tuesday Aug 14, 2012

Using the PHP CLI Webserver to Identify and Test Memory Issues in PHP

The PHP 5.4 CLI webserver is being used more and more to identify and resolve PHP bugs. Following on from the CLI webserver tests that Xinchen Hui (aka "laruence") instigated for the PHP 5.4 release, Anatoliy Belsky (aka "weltling") begain adding CLI webserver tests for the APC package, which is currently undergoing some much needed fixups for PHP 5.4.

Rasmus Lerdorf has also been running some of the PHP command line tests through the CLI web server to identify crashes and memory corruption issues that the existing one-test-per-process tests can't identify. Even today a fix for a session issue was merged by Laruence. The symptom would have been a random crash that would have been very hard to reproduce and explain to the PHP developers.

Rasmus mentioned on IRC how he ran the tests: simply renaming the ".phpt" test files as ".php", and invoking them through the CLI webserver. The SKIPIF sections get executed, but that doesn't affect the desired outcome of testing multiple HTTP requests with different input scripts.

Below are some quick shell scripts I put together to automate testing the OCI8 extension with valgrind.

There are three scripts. The first creates a copy of all OCI8 tests with names changed to ".php":

    #!/bin/sh
    # NAME:    setup_tests.sh
    # PURPOSE: Copy .phpt files as .php
    #          Assumes a clean PHP-5.4 branch with no tests/*.diff files

    SD=$HOME/php-5.4/ext/oci8/tests

    cd /tmp && rm -rf tests && mkdir tests

    for F in $(echo $SD/*)
    do
        if [ "${F##*.}" = "phpt" ]; then
            # sym link with a .php file extension instead of .phpt
            N=$(basename $F .phpt).php
        else
            # sym link the unchanged filename
            N=$(basename $F)
        fi
        ln -s $F tests/$N
    done

The second script starts the PHP CLI webserver:

    #!/bin/sh
    # NAME:    start_ws.sh
    # PURPOSE: Start the CLI webserver

    PHP="$HOME/phpbuild/php54/sapi/cli/php"
    PHPOPTS="-d max_execution_time=600 -d log_errors=Off"
    PORT=4444
    VALGRIND=valgrind
    VALGRINDOPTS=" --tool=memcheck --suppressions=$HOME/.valgrind_supp"

    USE_ZEND_ALLOC=0 $VALGRIND $VALGRINDOPTS $PHP $PHPOPTS \
                               -t /tmp/tests -S localhost:$PORT

Here I'm running valgrind to check for memory issues. I set the execution time large, because several of the OCI8 tests take time, especially with valgrind.

The third script invokes all PHP tests sequentially:

    #!/bin/sh
    # NAME:    wg_all.sh
    # PURPOSE: Load all .php scripts sequentially

    PORT=4444

    cd /tmp/tests

    for F in *.php
    do
        wget -O /tmp/L.php_cli_test http://localhost:$PORT/$F
    done

You can change this script to call subsets of your own scripts, or repeatedly call scripts to check memory usage and cleanup code.

To use the scripts, start the webserver and wait for it to initialize:

    $ ./start_ws.sh 
    ==14170== Memcheck, a memory error detector
    ==14170== Copyright (C) 2002-2009, and GNU GPL'd, by Julian Seward et al.
    ==14170== Using Valgrind-3.5.0 and LibVEX; rerun with -h for copyright info
    ==14170== Command: php -d max_execution_time=600 -d log_errors=Off -t /tmp/tests -S localhost:4444
    ==14170== 
    PHP 5.4.5-dev Development Server started at Tue Aug 14 14:53:34 2012
    Listening on http://localhost:4444
    Document root is /tmp/tests
    Press Ctrl-C to quit.

This sits, waiting to handle requests.

In a second terminal run wg_all.sh to initiate requests:

    $ ./wg_all.sh
    --2012-08-14 14:38:41--  http://localhost:4444/tests/array_bind_001.php
    Resolving localhost... 127.0.0.1
    Connecting to localhost|127.0.0.1|:4444... connected.
    HTTP request sent, awaiting response... 200 OK
    Length: unspecified [text/html]
    Saving to: `/tmp/L.php_cli_test'

        [ <=>                                   ] 707         --.-K/s   in 0.003s  

    2012-08-14 14:38:44 (231 KB/s) - `/tmp/L.php_cli_test' saved [707]
    . . .

You could suppress this output by adding the option "-o /tmp/L.wg_output" to wg_all.sh. I didn't add it because, although I'm ignoring output, I like to see that the tests are really returning something.

The first terminal running the CLI web server shows each requested script:

    [Tue Aug 14 14:35:06 2012] 127.0.0.1:34006 [200]: /tests/array_bind_001.php
    [Tue Aug 14 14:35:06 2012] 127.0.0.1:34008 [200]: /tests/array_bind_002.php
    [Tue Aug 14 14:35:07 2012] 127.0.0.1:34010 [200]: /tests/array_bind_003.php
    [Tue Aug 14 14:35:07 2012] 127.0.0.1:34013 [200]: /tests/array_bind_004.php
    [Tue Aug 14 14:35:07 2012] 127.0.0.1:34015 [200]: /tests/array_bind_005.php
    [Tue Aug 14 14:35:07 2012] 127.0.0.1:34017 [200]: /tests/array_bind_006.php
    [Tue Aug 14 14:35:07 2012] 127.0.0.1:34019 [200]: /tests/array_bind_007.php
    [Tue Aug 14 14:35:08 2012] 127.0.0.1:34021 [200]: /tests/array_bind_008.php
    . . .

This is the output stream to monitor for valgrind issues.

You can remove the wget "-O /tmp/L.php_cli_test" option if you want to see the returned output from each test, e.g. to check that the tests are connecting to the database correctly.

Removing the php "-d log_errors=Off" option will show you errors in the CLI web server output. Many tests deliberately create errors, but issues with .phpt SKIPIF sections will be more obvious.

You can customize these scripts for your applications and help discover reproducible PHP bugs. With valid test cases, the PHP development team has a much better chance of resolving any problems.

Tuesday Mar 13, 2012

PHP-FPM FastCGI Process Manager with Apache 2

I've published some vanilla PHP 5.4.0 RPMs to make new feature testing easier.

Along with all the PHP 5.4 goodies, the php-fpm "FastCGI Process Manager" is available for the first time on oss.oracle.com. Php-fpm is an alternative FastCGI interface to PHP with various extra features such as load dependent spawning of processes. (For other features, see php-fpm.org). Php-fpm has been getting more and more traction in the PHP community and the EXPERIMENTAL flag was removed in PHP 5.4. You might want to test it out.

To use php-fpm with the default Apache web server, first install Oracle Linux 5.8 (64bit) using Oracle's free, public yum repository public-yum.oracle.com.

Install Apache, if not already installed:

  yum install httpd

Download and install the PHP 5.4 RPMs from oss.oracle.com/projects/php:

  rpm -i php54-common-5.4.0-1.el5.x86_64.rpm php54-fpm-5.4.0-1.el5.x86_64.rpm

Other extensions can also be installed, depending on the functionality you want to test.

Download and build FastCGI for Apache:

  wget http://www.fastcgi.com/dist/mod_fastcgi-current.tar.gz
  tar -zxf mod_fastcgi-current.tar.gz
  cd mod_fastcgi-2.4.6
  cp Makefile.AP2 Makefile
  make top_dir=/usr/lib64/httpd

Install FastCGI as root:

  make top_dir=/usr/lib64/httpd install

Edit /etc/httpd/conf/httpd.conf and comment out any existing references to PHP you might previously have added for testing:

# LoadModule php5_module        modules/libphp5.so
# AddType application/x-httpd-php .php

Add the php-fpm configuration to httpd.conf:

  LoadModule fastcgi_module modules/mod_fastcgi.so

  <IfModule mod_fastcgi.c>  
    FastCGIExternalServer /usr/sbin/php-fpm -host 127.0.0.1:9000
    AddHandler php-fastcgi .php  

    #<LocationMatch "/status">
    #  SetHandler php-fastcgi-virt
    #  Action php-fastcgi-virt /usr/sbin/php-fpm.fcgi virtual
    #</LocationMatch>

    Action php-fastcgi /usr/sbin/php-fpm.fcgi  
    ScriptAlias /usr/sbin/php-fpm.fcgi /usr/sbin/php-fpm  

    <Directory /usr/sbin>  
      Options ExecCGI FollowSymLinks  
      SetHandler fastcgi-script  
      Order allow,deny  
      Allow from all  
    </Directory>  
  </IfModule> 

Start php-fpm and Apache:

  service php-fpm start
  service httpd start

Test it out with your favorite script or create a file pi.php:

  <?php
    phpinfo();
  ?>

Save it in /var/www/html/pi.php or in $HOME/public_html/pi.php, if you have configured UserDir in httpd.conf.

In a browser load http://localhost/pi.php or http://localhost/~yourname/pi.php.

This will show the PHP configuration values.

To test php-fpm's built-in statistics, edit httpd.conf and uncomment the four lines of the LocationMatch section:

  <LocationMatch "/status">
    SetHandler php-fastcgi-virt
    Action php-fastcgi-virt /usr/sbin/php-fpm.fcgi virtual
  </LocationMatch>

Edit /etc/php-fpm.conf and uncomment the line:

  pm.status_path = /status

Restart php-fpm and Apache:

  service php-fpm restart
  service httpd restart

Run some load on the system:

  ab -c 10 -t 60 http://localhost/pi.php  

Now http://localhost/status gives you the status of the server:

  pool:                 www
  process manager:      dynamic
  start time:           13/Mar/2012:14:25:53 -0700
  start since:          26
  accepted conn:        50001
  listen queue:         0
  max listen queue:     6
  listen queue len:     128
  idle processes:       2
  active processes:     1
  total processes:      3
  max active processes: 5
  max children reached: 1

The php-fpm.conf file documents other output formats for the statistics. It also shows the extensive functionality available with php-fpm.

Documentation on php-fpm is not ideal, but you can see some at http://php.net/manual/en/install.fpm.php. The php-fpm.org site has more, including a forum and wiki.

Php-fpm is commonly used in conjunction with the nginx webserver. For this, you will need to compile nginx yourself. Because php-fpm is installed and managed separately from the webserver, the php-fpm RPM will still be usable. Now that Apache 2.4 has been released with claims of improved performance, it will be interesting to see if web server popularity swings back towards Apache.

Finally, remember that the PHP RPMs on oss.oracle.com are for testing purposes only. They are not supported.

Update: In the Underground PHP & Oracle Manual, I simplified the httpd.conf options to this (note PHP was installed in a different location):

<IfModule mod_fastcgi.c>
    FastCGIExternalServer /opt/php544/sbin/php-fpm -host 127.0.0.1:9000
    AddHandler php-fastcgi .php
    Action php-fastcgi /mycgi
    ScriptAlias /mycgi /opt/php544/sbin/php-fpm
</IfModule>

PHP 5.4.0 RPMs for 64bit Oracle Linux 5.x are available

I've published some vanilla PHP 5.4.0 RPMs to make new feature testing easier for Oracle Linux 5.x 64 bit users. The standard set of RPMs is at oss.oracle.com/projects/php. The OCI8 extension is also available (this requires the free Oracle Instant Client 11.2 from ULN or OTN.)

Some of the features of PHP 5.4 are:

  • Improved memory usage and performance. Some impressive preliminary reports of the benefits include: http://news.php.net/php.internals/57760 and http://news.php.net/php.internals/57747.

  • File Upload progress support is natively implemented.

  • Support for Traits now allows code reuse:

        trait t1 {
    	function m1() { echo "hi"; }
    	function m2() { echo "bye"; }
        }
    
        class my_c1 {
    	use t1;
    	/*...*/
        }
    
        class my_c2 extends c2 {
    	use t1;
    	/*...*/
        }
    
  • A built-in HTTP server for development is included:

      php -S 127.0.0.1:8888
    
  • Improvements were made to the interactive PHP shell (when PHP is compiled with readline).

  • A shortened array syntax was introduced: $a = [1,2,3];

  • The default character set for several internal functions was changed to UTF-8.

  • Support for multibyte languages is now configurable at run-time instead of compile-time.

  • The value echo tag "<?=" is now always on.

  • Binary number support was added.

  • DTrace support was added.

  • A new typehint indicates a function argument must be callable.

  • Session entropy uses /dev/urandom or /dev/arandom by default for extra security if either is present at compile time.

  • Function call results can now be immediately dereferenced as arrays: foo()[0]

  • Class members can be accessed on instantiation: (new foo)->method()

For more changes see the migration documentation.

Thursday Mar 01, 2012

PHP 5.4 is out; your work begins now

Exciting news: PHP 5.4 is out. Thanks to the release managers Stas & David for making it happen. The PHP code is syncing to mirrors. PHP documentation will take a day or two to build & sync. Take a look when it reaches you.

The announcement lists some of the features that have changed.

There is a current tidy up of documentation for new features and migration happening. There are some low priority bug fixes that are waiting merge. These came in during the extended release process and were left out to avoid destabilizing the code.

Some PECL extensions still need to make PHP 5.4 compatible releases. Rasmus helped out by making changes to some extension, but the package owners need to bundle up releases. Other extensions may need some work.

XDebug is due for a compatible release soon.

PHPUnit is said to be fine already.

APC has at least one pending fix too, for the "?:" operator.

In summary, PHP 5.4 is available and I expect this branch will stabilize quickly.

Thursday Jan 19, 2012

PHP VirtualBox VM has been refreshed

While I was recently on summer vacation (yes, it is summer in half the world), the VirtualBox VM for PHP was refreshed to a more recent Zend Server/Oracle Linux/Oracle Database XE stack.

I just pulled the VM down, imported it and had it booting and serving PHP pages in a very few minutes. VirtualBox really is marvelous. There is a link to download the VM near the foot of the Oracle Technology Network Developer VM page.

About

Tourists looking out over an Opal mine
I'm a Product Manager in Server Technologies, working on scripting languages and developer-access.
Email: christopher.jones@oracle.com
Twitter: http://twitter.com/ghrd
Book: Free PHP Oracle book
Download: PHP Linux RPMs with the OCI8 extension
Links: OTN PHP Developer Center

Search

Categories
Archives
« April 2014
SunMonTueWedThuFriSat
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
   
       
Today