Mixing MySQL InnoDB and MyISAM tables with transactions

Just learned this from personal experience.  Hoping to save someone else some pain.

I tried the following searches:

mysql transaction partial rollback
does fetching commit an innodb transaction
innodb rollback not working

The symptoms I was experiencing included inserted records were rolled back, but an update to a table was not. My PHP code threw an exception inside a transaction, and the catch did a rollback, but the update still went through.

The problem was that the table I was updating happened to be MyISAM. MySQL silently ignored the fact that I included a table in my transaction that couldn’t be rolled back. When the rollback occurred, this was also silently ignored.

Moral of the story: use all InnoDB if you’re going to be doing transactions.

Making Sense of Variable Scope in PHP 5 OOP

I’ve learned a lot about PHP5 OOP visibility recently.  I’m posting a test script that will share some of my discoveries.

Take away:

  1. Private really does mean private.
  2. Visibility keywords are honored while cloning
  3. PHP does not enforce the visibility keywords on variables using a fatal error.
    It uses an E_NOTICE : Notice: Undefined property
define( 'SCRIPT_EOL', '<br>' );

abstract class a_base_class
{
    private $name = 'Johannes Kepler';
    protected $color = 'Green';

    public function __set($name, $value)
    {
        throw new Exception( 'a_base_class - Undefined or private property: ' . $name );
    }

    public function __clone()
    {
        // this does work - $this->name is private but is accessible in this class
        $this->name = 'Isaac Newton';
    }

    public function getName()
    {
        return $this->name;
    }

    public function echoName()
    {
        echo $this->name;
    }
}

class exampleClass1 extends a_base_class
{
    function __clone()
    {
        // this does not work - $this->name is private to ac and can't be modified here
        $this->name = 'Isaac Newton';
    }

    function echoName()
    {
        // this will issue an E_NOTICE because the variable is undefined in this class (private variables do not carry through to descendants)
        echo $this->name;
    }

    function echoColor()
    {
        echo $this->color;
    }
}

class exampleClass2 extends a_base_class
{
    public function __clone()
    {
        $this->color = 'Red';
        // without this, $this->name will not get changed to Isaac Newton
        parent::__clone();
    }

    public function echoColor()
    {
        echo $this->color;
    }
}

echo '</pre>

<hr />

<pre>
';
echo '</pre>
<h2>exampleClass1</h2>
<pre>
';
$instance = new exampleClass1();
echo 'calling echoName()' . SCRIPT_EOL;
$instance->echoName();
echo 'echo $instance->name' . SCRIPT_EOL;
echo $instance->name . SCRIPT_EOL;
echo SCRIPT_EOL;
echo 'echoing getName()' . SCRIPT_EOL;
echo $instance->getName(); // calling public method on base class
echo SCRIPT_EOL;
echo 'calling echoColor()' . SCRIPT_EOL;
$instance->echoColor();
echo SCRIPT_EOL;

try
{
    $newInstance = clone $instance;
}
catch( Exception $e )
{
    echo SCRIPT_EOL . '------------------------------------------------' . SCRIPT_EOL;
    echo "Exception Thrown: " . $e->getMessage();
    echo SCRIPT_EOL;
echo '
';
    echo $e->getTraceAsString();
    echo '

';
    echo SCRIPT_EOL . '------------------------------------------------' . SCRIPT_EOL;
}
echo SCRIPT_EOL;
echo 'var_dump' . SCRIPT_EOL;
var_dump( $newInstance );

echo '</pre>

<hr />

<pre>
';
echo '</pre>
<h2>exampleClass2</h2>
<pre>
';

$instance = new exampleClass2();
echo 'calling echoName()' . SCRIPT_EOL;
$instance->echoName();
echo SCRIPT_EOL;
echo 'echo $instance->name' . SCRIPT_EOL;
echo $instance->name . SCRIPT_EOL;
echo 'echoing getName()' . SCRIPT_EOL;
echo $instance->getName(); // calling public method on base class
echo SCRIPT_EOL;
echo 'calling echoColor()' . SCRIPT_EOL;
$instance->echoColor();
echo SCRIPT_EOL;

try
{
    $newInstance = clone $instance;
}
catch( Exception $e )
{
    echo SCRIPT_EOL . '------------------------------------------------' . SCRIPT_EOL;
    echo "Exception Thrown: " . $e->getMessage();
    echo SCRIPT_EOL;
    echo $e->getTraceAsString();
    echo SCRIPT_EOL . '------------------------------------------------' . SCRIPT_EOL;
}

echo '
';
var_dump( $newInstance );
echo '

';

Output


exampleClass1

calling echoName()

Notice: Undefined property: exampleClass1::$name in /Users/timgallagher/Desktop/xampp/se/php5oop.php on line 43
echo $instance->name

Notice: Undefined property: exampleClass1::$name in /Users/timgallagher/Desktop/xampp/se/php5oop.php on line 73

echoing getName()
Johannes Kepler
calling echoColor()
Green

————————————————
Exception Thrown: a_base_class – Undefined or private property: name

#0 /Users/timgallagher/Desktop/xampp/se/php5oop.php(37): a_base_class->__set('name', 'Isaac Newton')
#1 /Users/timgallagher/Desktop/xampp/se/php5oop.php(84): exampleClass1->__clone()
#2 {main}

————————————————

var_dump

Notice: Undefined variable: newInstance in /Users/timgallagher/Desktop/xampp/se/php5oop.php on line 98
NULL


exampleClass2

calling echoName()
Johannes Kepler
echo $instance->name

Notice: Undefined property: exampleClass2::$name in /Users/timgallagher/Desktop/xampp/se/php5oop.php on line 108

echoing getName()
Johannes Kepler
calling echoColor()
Green

object(exampleClass2)#1 (2) {
  ["name:private"]=>
  string(12) "Isaac Newton"
  ["color:protected"]=>
  string(3) "Red"
}

New Version of WordPress Released

Just released

There is a ton of candy for developers as well. I’d recommend starting your exploration with the new editor API, new jQuery version, better ways to hook into the help screens, more performant post-slug-only permalinks, and of course the entire list of improvements on the Codex and in Trac.

Hiding values in URL’s using PHP

<?

header( 'content-type: text/plain' );
$h = '';
if ( array_key_exists( 'h', $_GET ) && ! empty( $_GET['h'] ) )
{
    $test = unserialize( gzuncompress( base64_decode( urldecode( urldecode( $_GET['h'] ) ) ) ) );
    if ( is_array( $test ) )
    {
        $h = $_GET['h'];
        $_GET = $test;
    }
}
elseif( count( $_GET) )
{
    $h = urlencode( urlencode( base64_encode( gzcompress( serialize( $_GET ), 9 ) ) ) );
}

list( $url ) = explode( '?', $_SERVER['REQUEST_URI'] );

if ( ! empty( $h ) )
{
    $url .= '?h=' . $h;
}

echo $url . "\n\n";

var_dump( $_GET );