Little known PHP Idioms etc.

Ye' old general discussion board. Basically, for everything that isn't covered elsewhere. Come here to shoot the breeze, shoot your mouth off, or whatever suits your fancy.
This forum is not for asking programming related questions.

Moderator: General Moderators

User avatar
Ollie Saunders
DevNet Master
Posts: 3179
Joined: Tue May 24, 2005 6:01 pm
Location: UK

Post by Ollie Saunders »

Incidentally unset() accepts multiple args too but empty() does not

Code: Select all

public function testUnset()
{
    $foo = $bar = $zim = 1;
    unset($foo, $bar, $zim);
    // These pass
    $this->assertFalse(isset($foo));
    $this->assertFalse(isset($bar));
    $this->assertFalse(isset($zim));
}
public function testEmpty()
{
    $foo = $bar = 1;
    // E_FATAL Syntax error; amazingly
    empty($foo, $bar);
}
I might keep this thread alive with other hints as I come across them and I encourage others to do the same. :D
User avatar
Ollie Saunders
DevNet Master
Posts: 3179
Joined: Tue May 24, 2005 6:01 pm
Location: UK

Post by Ollie Saunders »

Oh yeah I wrote this a while back but never posted it, might be interesting to some:

Code: Select all

<?php
// Want to set key's value to 10 via variable variable
$target = array('key' => 5);
$varvar = 'target';
// This should have done it
$$varvar['key'] = 10;

echo $$varvar['key'], '<br />';             // Outputs: 10
echo print_r($target, true), '<br />';     // Outputs: Array ( [key] => 5 )
echo print_r($varvar, true), '<br />';     // Sanity check; outputs: target
echo print_r(${'target'}, true), '<br />'; // Sanity check; Outputs: Array ( [key] => 5 )

// Where has 10 actually been stored?!

print_r(get_defined_vars()); // Reveals a variable 't' has been defined with 10
echo $t; // Outputs: 10

$varvar = 'parget';
$$varvar['key'] = 9;
echo $p; // Outputs: 9

$varvar = 'target';
// {$$varvar['key']} = 9; // syntax error
// $$varvar{['key']} = 9; // syntax error
${$varvar}['key'] = 8;
echo $target['key']; // Outputs: 8, YAY!
This is what I think is happening here:

Code: Select all

$varvar = 'target';
$$varvar['key'] = 10;
$varvar['key'] is evaluated first. The array subscript is used as string offset and, PHP being a loosely typed language, 'key' is automatically casted to int.

Code: Select all

$result = (int)'key'; // $result is 0
So $$varvar['key'] = 10 is functionally equivalent to:

Code: Select all

$varvar = 'target';
$phpTmp = $varvar[0]; // $phpTmp is 't'
$$phpTmp = 10;
So if you ever want to obfuscate some code....:P
User avatar
Ollie Saunders
DevNet Master
Posts: 3179
Joined: Tue May 24, 2005 6:01 pm
Location: UK

Post by Ollie Saunders »

The difference between array_key_exists and isset with arrays:

Code: Select all

$array = array('foo' => null);             // Note: key 'bar' not defined

var_dump(isset($array['bar']));            // bool(false)
var_dump(array_key_exists('bar', $array)); // bool(false)

var_dump(isset($array['foo']));            // bool(false)
var_dump(array_key_exists('foo', $array)); // bool(true)
User avatar
Luke
The Ninja Space Mod
Posts: 6424
Joined: Fri Aug 05, 2005 1:53 pm
Location: Paradise, CA

Post by Luke »

ole wrote:The difference between array_key_exists and isset with arrays:

Code: Select all

$array = array('foo' => null);             // Note: key 'bar' not defined

var_dump(isset($array['bar']));            // bool(false)
var_dump(array_key_exists('bar', $array)); // bool(false)

var_dump(isset($array['foo']));            // bool(false)
var_dump(array_key_exists('foo', $array)); // bool(true)
very cool... thanks for that :)
User avatar
julian_lp
Forum Contributor
Posts: 121
Joined: Sun Jul 09, 2006 1:00 am
Location: la plata - argentina

Post by julian_lp »

ole wrote:The difference between array_key_exists and isset with arrays: *****
Many thanks for that, very useful ;)
User avatar
Ollie Saunders
DevNet Master
Posts: 3179
Joined: Tue May 24, 2005 6:01 pm
Location: UK

Post by Ollie Saunders »

Turns out you can't throw an exception in __autoload()

Code: Select all

function __autoload($class)
{
    throw new Exception('foo');
}
$obj = new SomeClass();
Gives you
PHP wrote:Fatal error: Class 'SomeClass' not found in...
Rather than an uncaught exception error.
User avatar
Ambush Commander
DevNet Master
Posts: 3698
Joined: Mon Oct 25, 2004 9:29 pm
Location: New Jersey, US

Post by Ambush Commander »

There are a few places where you're not allowed to throw exceptions. Error handler is another one of those places.
User avatar
Ollie Saunders
DevNet Master
Posts: 3179
Joined: Tue May 24, 2005 6:01 pm
Location: UK

Post by Ollie Saunders »

That one really caught me out because I had loadClass() method that would throw an exception if the load failed. But from the error it just appeared as if __autoload() was never being called. A quick var_dump() prooved that wasn't the case; it was a head scratcher for a while.
User avatar
Maugrim_The_Reaper
DevNet Master
Posts: 2704
Joined: Tue Nov 02, 2004 5:43 am
Location: Ireland

Post by Maugrim_The_Reaper »

If you think about it - many people throw exceptions using subclasses Exception classes. If __autoload does not work, then looking up the subclassed Exception class would be impossible (using __autoload). So it's easy to see why it's not advisable :).
Post Reply