PHP logging

I’ve always thought the logging system in PHP rudimentary at best. Here is what i’ve ended up using…

    function log_message_stack( $message )
            $position = 'At ';
            foreach( debug_backtrace() as $index=>$stack )
                    if( array_key_exists( 'file', $stack ) )
                            $position .= ' '.$stack['file'].':'.$stack['line'];
            log_message( $position."|".$message );

    function log_message_r( $message_r )
            $message = print_r($message_r, true );
            return log_message( $message );

    function log_message( $message )
            $logFile = '/tmp/messages';
            // or something else

            $sid = session_id();
            if( strlen( $sid ) > 4 )
                    $s = substr( $sid, strlen( $sid ) - 4 );
                    $s = "NONE";
            $t = strftime( '%F %T' );
            $file = fopen( $logFile, "a+" );
            fwrite( $file, "$s:$t:" );
            fwrite( $file, $message );
            fwrite( $file, "\n" );
            fclose( $file );

There we go, now we can trace what is happening with session differentiation.

Postgres vs MySQL

As promised, here is the solution to the first non-configurational issue caused by my use of Postgres instead of MySQL.

The function delete_expired_transients() in wp-includes/option.php has this to say for itself.

  • The multi-table delete syntax is used to delete the transient record
  • from table a, and the corresponding transient_timeout record from table b.

Well, Postgres doesn’t have, nor likely will ever have, this multi-table delete syntax. It’s applied to a single table anyway, but we need a temporary table.

    $wpdb->query( $wpdb->prepare(
                    "create temporary table delme as select a.option_id as aid, a.option_name as aname, a.option_value as aval, b.option_id as bid, b.option_name as bname, b.option_value as bval FROM {$wpdb->options} a, {$wpdb->options} b
                    WHERE a.option_name LIKE %s
                    AND a.option_name NOT LIKE %s
                    AND b.option_name = CONCAT( '_transient_timeout_', SUBSTRING( a.option_name, 12 ) )
                    AND b.option_value < '%d'",
                    $wpdb->esc_like( '_transient_' ) . '%',
                    $wpdb->esc_like( '_transient_timeout_' ) . '%',

    $wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->options}  where option_id in (select aid from delme union select bid from delme)" ) );

There we go, fixed now.